pax_global_header00006660000000000000000000000064116732121170014513gustar00rootroot0000000000000052 comment=4de2b81f25ac13c0dd6ead19398fb638760102f1 sfact-2011.12.18/000077500000000000000000000000001167321211700132105ustar00rootroot00000000000000sfact-2011.12.18/.gitignore000066400000000000000000000000311167321211700151720ustar00rootroot00000000000000*.pyc *.gcode priv_* zzz*sfact-2011.12.18/SFACT Readme.txt000066400000000000000000000162331167321211700157740ustar00rootroot00000000000000I have modified Skeinforge to be more practical and easier to tune. features include: A more up to date version could be found at http://dl.dropbox.com/u/38819298/SFACT%20Readme.txt Also trying to get the SFACT wiki up and running: https://github.com/ahmetcemturan/SFACT/wiki SFACT is at home: http://www.reprapfordummies.net -Will not mess up your old Skeinforge settings as it will use its own sfact_settings directory inside its own folder. -Deleted unused plugins and unused settings. -Namings changed to be more understandable. -Important settings moved to top of Plugin Tab. -Default values give good prints rightaway. -Internally used Gcode files use extension .gmc now. -Most Feedrates are now entered as values (mm/s) and their respective flowrates are 1 so you dont have to enter everything twice. CARVE: -Extrusion width is now entered in mm instead of a ratio to layer height. CHAMBER: -Moved Turn Extruder off at shutdown to Chamber. -Added Turn PrintBed off at shutdown. CLIP: Clip over Perimeter width is now calculated automatically. The default is 1 and can be tuned from there. DIMENSION: -Added feature for calibration. -Retract can be set conditionally depending on extrusion amount before retract and the travel move in retracted state. Also retract can be forced to happen if moving over loops. EXPORT: Replaced Export plugin with Gary Hodgson's plugin. -Option to export settings as Zip file or a single CSV file for sharing. -Option to individually name the exported gcode files with description, timestamp and profile used. FILL: -Infill width over layerthickness setting is replaced by Extrusion Lines Extra spacing. -Extrusion Lines Extra spacing is calculated automatically and defaults to 1 for tuning. -Infill Overlap over Perimeter is also calculated internally and defaults to 1 so it can be easily tweaked. INSET: The inset value is now Overlap Removal and is also calculated internally with default 1 for tweaking. PREFACE: -Added the option to send Extruder reset (G92 E0) command before print so that the extruder does not spool back after priming. (Even without start.gmc file) RAFT: -Ordering, grouping and namings changed to reflect the use of interface settings for the support structures. -Support feedrate and support flowrate can be set seperately. -Support extension(s) are now more understandable. -First Layer feedrates are given in mm/s instead of a ratio to the main feedrate. -A travel feedrate for the first layer can be specified now. SPEED: -Feedrates are entered as values with respective flowrates as 1, instead of entering same value again. (except for Bridge Feedrate). -Note that Flowrates are always in reference to the respective Feedrate. (No need to change the flowrate when you change the speed, the ratio is calculated accordingly..) -Nozzle Lift setting has been changed to "Extra nozzle Lift over object" and defaults to 0. -Wipe is on by default and is around the 0 point (CAUTION: If you want to use SFACT from within Pronterface, you need to copy the files into a folder called skeinforge within the folder of Pronterface. Then you will need to manually copy or move the sfact_profiles folder into that directory as otherwise SFACT wont see the default profiles shipped with it.) For alterations files to work You need to put the alterations files into: ..\skeinforge_application\alterations\ directory... The latest working version is available here: http://www.reprapfordummies.net/downloads/SFACT.rar The latest development version is: https://github.com/ahmetcemturan/SFACT You need to have Python installed (if you had Skeinforge running before thats sufficent) 1-Extract the contents of the RAR file into a Folder of your choice :) Go into folder skeinforge_application. 2-Click skeinforge.py 3-Go to DIMENSION tab and enter your "measured" filament diameter. 4-Go to Carve, enter reasonable Layer height and Extrusion width values.(this step is not necessary for the first try) (Try to have layer height slightly lower than nozzle diameter and Extrusion width slightly wider than nozzle diameter.) 5-Click Skeinforge at the bottom of the tab and choose the STL file to slice. 6-Generated Gcode will be created in the same folder as the STL file. Enjoy good Prints. CALIBRATION: If you should feel the need to calibrate: 1-Print a thin walled test object (Single wall) Measure the width of the wall. 2-Go to Dimension and check the Calibration Checkbox. 3-Enter the Measured value. 4-ReSkein and print the object. (During the Skein the command window will display a packing ratio. Note it somewhere (the first 4 digits are enough) 5-If satisfied with the print, go to DIMENSION tab uncheck the calibration checkbox and enter that value into the packing density Box. 6-You are done. Repeat when needed. Changing extrusion values should not necessarily arise the need for recalibration... Known Bugs: -Skin plugin skips first extra perimeter loop if extra perimeters set to 1. Works when 0 or >=2. -will not create correct Updated and working versions of SFACT and help are under : www.reprapfordummies.net and the development is under: https://github.com/ahmetcemturan/SFACT (Master branch) License is same as Skeinforge (GNU Affero General Public License) 14.9.2011 Main changes: DIMENSION:Retraction handled differently. Now the only variable is the Oozerate. SFACt automatically does retraction based on the duration of the move that it will do in retracted state. SPEED and INSET Bridging: Bridge settings are calculated automatically so that your extrusion xsection equals the nozzle-orifice x-section.. As it will not change the layer height it will alter the extrusion width to achieve that. The default bridge feedrate is now referencing the perimeter feedrate. Also the settings for bridge spacing in INSET is now calculated according to the newly calculated extrusion width of the bridge extrusion. You can experiment with values from 1-2 for the spacing that should all give decent results. ý personally prefer closer to 2 and have set default accordingly. RAFT: Raft feed and flowrates are working now. First layer travel feedrate now controls all travel moves.. EXPORT: The export archiving commands have moved to the top menu. (>Analyze>Synopsis) There is also an option for Gen3 users to have small gcode with their Z-commands on a seperate line (for faster Z moves) If you get memory errors during skein disable skeiniso. (enabled by default) For being able to open a preview lateron you should enable exporting penultimate gcode. CARVE:Extra decimals range is now 2-6 with 4 as default. (needed for the finer printing possibilities..) COOL: You can now specify a minimum feedrate so you dont end up having the printhead move at 2mm/s and ruining your top layer. SKIN and LEADIN: Is calculating the flow correctly now. But a bug prevents the inner ring from being extruded when the extra perimeters option in Fill is set to 1. (0 or more than one works without problems..) Also I found that the option to prefer loops in INSET produces better result hence is set as default. GENERAL:I also changed most of the broken links that were in the top menu. A more detailed explanation will be posted at www.reprapfordummies.net sfact-2011.12.18/__init__.py000066400000000000000000000000001167321211700153070ustar00rootroot00000000000000sfact-2011.12.18/calibration/000077500000000000000000000000001167321211700154775ustar00rootroot00000000000000sfact-2011.12.18/calibration/_33x10.STL000066400000000000000000002542741167321211700170160ustar00rootroot00000000000000solid _33 facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.740765e+001 2.621576e+001 1.000000e+001 vertex 1.766044e+001 2.642788e+001 1.000000e+001 vertex 1.663596e+001 2.703370e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.663596e+001 2.703370e+001 1.000000e+001 vertex 1.766044e+001 2.642788e+001 1.000000e+001 vertex 1.686242e+001 2.727374e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.663596e+001 2.703370e+001 1.000000e+001 vertex 1.686242e+001 2.727374e+001 1.000000e+001 vertex 1.577452e+001 2.775653e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.577452e+001 2.775653e+001 1.000000e+001 vertex 1.686242e+001 2.727374e+001 1.000000e+001 vertex 1.597159e+001 2.802123e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.577452e+001 2.775653e+001 1.000000e+001 vertex 1.597159e+001 2.802123e+001 1.000000e+001 vertex 1.483500e+001 2.837447e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.483500e+001 2.837447e+001 1.000000e+001 vertex 1.597159e+001 2.802123e+001 1.000000e+001 vertex 1.500000e+001 2.866026e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.483500e+001 2.837447e+001 1.000000e+001 vertex 1.500000e+001 2.866026e+001 1.000000e+001 vertex 1.383009e+001 2.887915e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.383009e+001 2.887915e+001 1.000000e+001 vertex 1.500000e+001 2.866026e+001 1.000000e+001 vertex 1.396080e+001 2.918216e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.383009e+001 2.887915e+001 1.000000e+001 vertex 1.396080e+001 2.918216e+001 1.000000e+001 vertex 1.277339e+001 2.926376e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.277339e+001 2.926376e+001 1.000000e+001 vertex 1.396080e+001 2.918216e+001 1.000000e+001 vertex 1.286803e+001 2.957990e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.277339e+001 2.926376e+001 1.000000e+001 vertex 1.286803e+001 2.957990e+001 1.000000e+001 vertex 1.167918e+001 2.952309e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.167918e+001 2.952309e+001 1.000000e+001 vertex 1.286803e+001 2.957990e+001 1.000000e+001 vertex 1.173648e+001 2.984808e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.167918e+001 2.952309e+001 1.000000e+001 vertex 1.173648e+001 2.984808e+001 1.000000e+001 vertex 1.056226e+001 2.965364e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.056226e+001 2.965364e+001 1.000000e+001 vertex 1.173648e+001 2.984808e+001 1.000000e+001 vertex 1.058145e+001 2.998308e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.056226e+001 2.965364e+001 1.000000e+001 vertex 1.058145e+001 2.998308e+001 1.000000e+001 vertex 9.437739e+000 2.965364e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.437739e+000 2.965364e+001 1.000000e+001 vertex 1.058145e+001 2.998308e+001 1.000000e+001 vertex 9.418551e+000 2.998308e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.437739e+000 2.965364e+001 1.000000e+001 vertex 9.418551e+000 2.998308e+001 1.000000e+001 vertex 8.320822e+000 2.952309e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.320822e+000 2.952309e+001 1.000000e+001 vertex 9.418551e+000 2.998308e+001 1.000000e+001 vertex 8.263518e+000 2.984808e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.320822e+000 2.952309e+001 1.000000e+001 vertex 8.263518e+000 2.984808e+001 1.000000e+001 vertex 7.226613e+000 2.926376e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.226613e+000 2.926376e+001 1.000000e+001 vertex 8.263518e+000 2.984808e+001 1.000000e+001 vertex 7.131968e+000 2.957990e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.226613e+000 2.926376e+001 1.000000e+001 vertex 7.131968e+000 2.957990e+001 1.000000e+001 vertex 6.169909e+000 2.887915e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.169909e+000 2.887915e+001 1.000000e+001 vertex 7.131968e+000 2.957990e+001 1.000000e+001 vertex 6.039202e+000 2.918216e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.169909e+000 2.887915e+001 1.000000e+001 vertex 6.039202e+000 2.918216e+001 1.000000e+001 vertex 5.165000e+000 2.837447e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.165000e+000 2.837447e+001 1.000000e+001 vertex 6.039202e+000 2.918216e+001 1.000000e+001 vertex 5.000000e+000 2.866026e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.165000e+000 2.837447e+001 1.000000e+001 vertex 5.000000e+000 2.866026e+001 1.000000e+001 vertex 4.225476e+000 2.775653e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.225476e+000 2.775653e+001 1.000000e+001 vertex 5.000000e+000 2.866026e+001 1.000000e+001 vertex 4.028414e+000 2.802123e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.225476e+000 2.775653e+001 1.000000e+001 vertex 4.028414e+000 2.802123e+001 1.000000e+001 vertex 3.364043e+000 2.703370e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.364043e+000 2.703370e+001 1.000000e+001 vertex 4.028414e+000 2.802123e+001 1.000000e+001 vertex 3.137583e+000 2.727374e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.364043e+000 2.703370e+001 1.000000e+001 vertex 3.137583e+000 2.727374e+001 1.000000e+001 vertex 2.592350e+000 2.621576e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.592350e+000 2.621576e+001 1.000000e+001 vertex 3.137583e+000 2.727374e+001 1.000000e+001 vertex 2.339556e+000 2.642788e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.592350e+000 2.621576e+001 1.000000e+001 vertex 2.339556e+000 2.642788e+001 1.000000e+001 vertex 1.920832e+000 2.531375e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.920832e+000 2.531375e+001 1.000000e+001 vertex 2.339556e+000 2.642788e+001 1.000000e+001 vertex 1.645122e+000 2.549509e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.920832e+000 2.531375e+001 1.000000e+001 vertex 1.645122e+000 2.549509e+001 1.000000e+001 vertex 1.358572e+000 2.433989e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.358572e+000 2.433989e+001 1.000000e+001 vertex 1.645122e+000 2.549509e+001 1.000000e+001 vertex 1.063674e+000 2.448799e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.358572e+000 2.433989e+001 1.000000e+001 vertex 1.063674e+000 2.448799e+001 1.000000e+001 vertex 9.131720e-001 2.330733e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.131720e-001 2.330733e+001 1.000000e+001 vertex 1.063674e+000 2.448799e+001 1.000000e+001 vertex 6.030733e-001 2.342020e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.131720e-001 2.330733e+001 1.000000e+001 vertex 6.030733e-001 2.342020e+001 1.000000e+001 vertex 5.906559e-001 2.223005e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.906559e-001 2.223005e+001 1.000000e+001 vertex 6.030733e-001 2.342020e+001 1.000000e+001 vertex 2.695508e-001 2.230616e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.906559e-001 2.223005e+001 1.000000e+001 vertex 2.695508e-001 2.230616e+001 1.000000e+001 vertex 3.953846e-001 2.112262e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.953846e-001 2.112262e+001 1.000000e+001 vertex 2.695508e-001 2.230616e+001 1.000000e+001 vertex 6.761588e-002 2.116093e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.953846e-001 2.112262e+001 1.000000e+001 vertex 6.761588e-002 2.116093e+001 1.000000e+001 vertex 3.300002e-001 2.000000e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 1.000000e+001 vertex 6.761588e-002 2.116093e+001 1.000000e+001 vertex 0.000000e+000 2.000000e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 1.000000e+001 vertex 0.000000e+000 2.000000e+001 1.000000e+001 vertex 3.300002e-001 5.000000e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.300002e-001 5.000000e+000 1.000000e+001 vertex 0.000000e+000 2.000000e+001 1.000000e+001 vertex 0.000000e+000 5.000000e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.300002e-001 5.000000e+000 1.000000e+001 vertex 0.000000e+000 5.000000e+000 1.000000e+001 vertex 3.874954e-001 4.269451e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 1.000000e+001 vertex 0.000000e+000 5.000000e+000 1.000000e+001 vertex 6.155763e-002 4.217827e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 1.000000e+001 vertex 6.155763e-002 4.217827e+000 1.000000e+001 vertex 5.585663e-001 3.556890e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 1.000000e+001 vertex 6.155763e-002 4.217827e+000 1.000000e+001 vertex 2.447171e-001 3.454915e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 1.000000e+001 vertex 2.447171e-001 3.454915e+000 1.000000e+001 vertex 8.389996e-001 2.879864e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 1.000000e+001 vertex 2.447171e-001 3.454915e+000 1.000000e+001 vertex 5.449671e-001 2.730047e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 1.000000e+001 vertex 5.449671e-001 2.730047e+000 1.000000e+001 vertex 1.221891e+000 2.255043e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 1.000000e+001 vertex 5.449671e-001 2.730047e+000 1.000000e+001 vertex 9.549148e-001 2.061074e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 1.000000e+001 vertex 9.549148e-001 2.061074e+000 1.000000e+001 vertex 1.697811e+000 1.697811e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 1.000000e+001 vertex 9.549148e-001 2.061074e+000 1.000000e+001 vertex 1.464466e+000 1.464466e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 1.000000e+001 vertex 1.464466e+000 1.464466e+000 1.000000e+001 vertex 2.255043e+000 1.221891e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 1.000000e+001 vertex 1.464466e+000 1.464466e+000 1.000000e+001 vertex 2.061074e+000 9.549148e-001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 1.000000e+001 vertex 2.061074e+000 9.549148e-001 1.000000e+001 vertex 2.879864e+000 8.389996e-001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 1.000000e+001 vertex 2.061074e+000 9.549148e-001 1.000000e+001 vertex 2.730047e+000 5.449671e-001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 1.000000e+001 vertex 2.730047e+000 5.449671e-001 1.000000e+001 vertex 3.556890e+000 5.585663e-001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 1.000000e+001 vertex 2.730047e+000 5.449671e-001 1.000000e+001 vertex 3.454915e+000 2.447171e-001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 1.000000e+001 vertex 3.454915e+000 2.447171e-001 1.000000e+001 vertex 4.269451e+000 3.874954e-001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 1.000000e+001 vertex 3.454915e+000 2.447171e-001 1.000000e+001 vertex 4.217827e+000 6.155763e-002 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 1.000000e+001 vertex 4.217827e+000 6.155763e-002 1.000000e+001 vertex 5.000000e+000 3.300002e-001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 1.000000e+001 vertex 4.217827e+000 6.155763e-002 1.000000e+001 vertex 5.000000e+000 0.000000e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 1.000000e+001 vertex 5.000000e+000 0.000000e+000 1.000000e+001 vertex 1.967000e+001 3.300002e-001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 1.000000e+001 vertex 5.000000e+000 0.000000e+000 1.000000e+001 vertex 2.000000e+001 0.000000e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 1.000000e+001 vertex 2.000000e+001 0.000000e+000 1.000000e+001 vertex 1.967000e+001 2.000000e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.967000e+001 2.000000e+001 1.000000e+001 vertex 2.000000e+001 0.000000e+000 1.000000e+001 vertex 2.000000e+001 2.000000e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.967000e+001 2.000000e+001 1.000000e+001 vertex 2.000000e+001 2.000000e+001 1.000000e+001 vertex 1.960462e+001 2.112262e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.960462e+001 2.112262e+001 1.000000e+001 vertex 2.000000e+001 2.000000e+001 1.000000e+001 vertex 1.993238e+001 2.116093e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.960462e+001 2.112262e+001 1.000000e+001 vertex 1.993238e+001 2.116093e+001 1.000000e+001 vertex 1.940934e+001 2.223005e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.940934e+001 2.223005e+001 1.000000e+001 vertex 1.993238e+001 2.116093e+001 1.000000e+001 vertex 1.973045e+001 2.230616e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.940934e+001 2.223005e+001 1.000000e+001 vertex 1.973045e+001 2.230616e+001 1.000000e+001 vertex 1.908683e+001 2.330733e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.908683e+001 2.330733e+001 1.000000e+001 vertex 1.973045e+001 2.230616e+001 1.000000e+001 vertex 1.939693e+001 2.342020e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.908683e+001 2.330733e+001 1.000000e+001 vertex 1.939693e+001 2.342020e+001 1.000000e+001 vertex 1.864143e+001 2.433989e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.864143e+001 2.433989e+001 1.000000e+001 vertex 1.939693e+001 2.342020e+001 1.000000e+001 vertex 1.893633e+001 2.448799e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.864143e+001 2.433989e+001 1.000000e+001 vertex 1.893633e+001 2.448799e+001 1.000000e+001 vertex 1.807917e+001 2.531375e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.807917e+001 2.531375e+001 1.000000e+001 vertex 1.893633e+001 2.448799e+001 1.000000e+001 vertex 1.835488e+001 2.549509e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.807917e+001 2.531375e+001 1.000000e+001 vertex 1.835488e+001 2.549509e+001 1.000000e+001 vertex 1.740765e+001 2.621576e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.740765e+001 2.621576e+001 1.000000e+001 vertex 1.835488e+001 2.549509e+001 1.000000e+001 vertex 1.766044e+001 2.642788e+001 1.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.437739e+000 2.965364e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 1.056226e+001 2.965364e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.056226e+001 2.965364e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.056226e+001 2.965364e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 1.167918e+001 2.952309e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.167918e+001 2.952309e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.167918e+001 2.952309e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.277339e+001 2.926376e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.277339e+001 2.926376e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.277339e+001 2.926376e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.383009e+001 2.887915e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.383009e+001 2.887915e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.383009e+001 2.887915e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.483500e+001 2.837447e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.483500e+001 2.837447e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.483500e+001 2.837447e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.577452e+001 2.775653e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.577452e+001 2.775653e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.577452e+001 2.775653e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.663596e+001 2.703370e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.663596e+001 2.703370e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.663596e+001 2.703370e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.740765e+001 2.621576e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.740765e+001 2.621576e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.740765e+001 2.621576e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.807917e+001 2.531375e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.807917e+001 2.531375e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.807917e+001 2.531375e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.864143e+001 2.433989e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.864143e+001 2.433989e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.864143e+001 2.433989e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.908683e+001 2.330733e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.908683e+001 2.330733e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.908683e+001 2.330733e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.940934e+001 2.223005e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.940934e+001 2.223005e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.940934e+001 2.223005e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.960462e+001 2.112262e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.960462e+001 2.112262e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.960462e+001 2.112262e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 1.967000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.967000e+001 2.000000e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.967000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 1.967000e+001 3.300002e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 3.300002e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 4.269451e+000 3.874954e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 3.556890e+000 5.585663e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 2.879864e+000 8.389996e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.255043e+000 1.221891e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 1.697811e+000 1.697811e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 1.221891e+000 2.255043e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 8.389996e-001 2.879864e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 5.585663e-001 3.556890e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 3.874954e-001 4.269451e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 3.300002e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.300002e-001 5.000000e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.300002e-001 5.000000e+000 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 3.300002e-001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 3.953846e-001 2.112262e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.953846e-001 2.112262e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.953846e-001 2.112262e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 5.906559e-001 2.223005e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.906559e-001 2.223005e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.906559e-001 2.223005e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 9.131720e-001 2.330733e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.131720e-001 2.330733e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.131720e-001 2.330733e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 1.358572e+000 2.433989e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.358572e+000 2.433989e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.358572e+000 2.433989e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 1.920832e+000 2.531375e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.920832e+000 2.531375e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.920832e+000 2.531375e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 2.592350e+000 2.621576e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.592350e+000 2.621576e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.592350e+000 2.621576e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 3.364043e+000 2.703370e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.364043e+000 2.703370e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.364043e+000 2.703370e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 4.225476e+000 2.775653e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.225476e+000 2.775653e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.225476e+000 2.775653e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 5.165000e+000 2.837447e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.165000e+000 2.837447e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.165000e+000 2.837447e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 6.169909e+000 2.887915e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.169909e+000 2.887915e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.169909e+000 2.887915e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 7.226613e+000 2.926376e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.226613e+000 2.926376e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.226613e+000 2.926376e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 8.320822e+000 2.952309e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.320822e+000 2.952309e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.320822e+000 2.952309e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 9.437739e+000 2.965364e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.437739e+000 2.965364e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 endloop endfacet facet normal 9.992487e-001 3.875592e-002 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 1.000000e+001 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 endloop endfacet facet normal 9.969914e-001 7.751183e-002 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 1.000000e+001 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 1.000000e+001 endloop endfacet facet normal 9.879928e-001 1.544996e-001 0.000000e+000 outer loop vertex 1.993238e+001 2.116093e+001 1.000000e+001 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 endloop endfacet facet normal 9.812515e-001 1.927314e-001 0.000000e+000 outer loop vertex 1.993238e+001 2.116093e+001 1.000000e+001 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 1.000000e+001 endloop endfacet facet normal 9.633761e-001 2.681538e-001 0.000000e+000 outer loop vertex 1.973045e+001 2.230616e+001 1.000000e+001 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 endloop endfacet facet normal 9.522419e-001 3.053445e-001 0.000000e+000 outer loop vertex 1.973045e+001 2.230616e+001 1.000000e+001 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 1.000000e+001 endloop endfacet facet normal 9.257313e-001 3.781818e-001 0.000000e+000 outer loop vertex 1.939693e+001 2.342020e+001 1.000000e+001 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 endloop endfacet facet normal 9.103549e-001 4.138285e-001 0.000000e+000 outer loop vertex 1.939693e+001 2.342020e+001 1.000000e+001 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 1.000000e+001 endloop endfacet facet normal 8.755676e-001 4.830956e-001 0.000000e+000 outer loop vertex 1.893633e+001 2.448799e+001 1.000000e+001 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 endloop endfacet facet normal 8.561568e-001 5.167161e-001 0.000000e+000 outer loop vertex 1.893633e+001 2.448799e+001 1.000000e+001 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 1.000000e+001 endloop endfacet facet normal 8.135634e-001 5.814762e-001 0.000000e+000 outer loop vertex 1.835488e+001 2.549509e+001 1.000000e+001 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 endloop endfacet facet normal 7.903807e-001 6.126159e-001 0.000000e+000 outer loop vertex 1.835488e+001 2.549509e+001 1.000000e+001 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 1.000000e+001 endloop endfacet facet normal 7.405571e-001 6.719934e-001 0.000000e+000 outer loop vertex 1.766044e+001 2.642788e+001 1.000000e+001 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 endloop endfacet facet normal 7.139161e-001 7.002313e-001 0.000000e+000 outer loop vertex 1.766044e+001 2.642788e+001 1.000000e+001 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 1.000000e+001 endloop endfacet facet normal 6.575360e-001 7.534231e-001 0.000000e+000 outer loop vertex 1.686242e+001 2.727374e+001 1.000000e+001 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 endloop endfacet facet normal 6.277969e-001 7.783771e-001 0.000000e+000 outer loop vertex 1.686242e+001 2.727374e+001 1.000000e+001 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 1.000000e+001 endloop endfacet facet normal 5.656230e-001 8.246640e-001 0.000000e+000 outer loop vertex 1.597159e+001 2.802123e+001 1.000000e+001 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 endloop endfacet facet normal 5.331879e-001 8.459968e-001 0.000000e+000 outer loop vertex 1.597159e+001 2.802123e+001 1.000000e+001 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 1.000000e+001 endloop endfacet facet normal 4.660608e-001 8.847528e-001 0.000000e+000 outer loop vertex 1.500000e+001 2.866026e+001 1.000000e+001 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 endloop endfacet facet normal 4.313685e-001 9.021758e-001 0.000000e+000 outer loop vertex 1.500000e+001 2.866026e+001 1.000000e+001 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 1.000000e+001 endloop endfacet facet normal 3.601959e-001 9.328767e-001 0.000000e+000 outer loop vertex 1.396080e+001 2.918216e+001 1.000000e+001 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 endloop endfacet facet normal 3.237155e-001 9.461545e-001 0.000000e+000 outer loop vertex 1.396080e+001 2.918216e+001 1.000000e+001 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 1.000000e+001 endloop endfacet facet normal 2.494600e-001 9.683850e-001 0.000000e+000 outer loop vertex 1.286803e+001 2.957990e+001 1.000000e+001 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 endloop endfacet facet normal 2.116849e-001 9.773380e-001 0.000000e+000 outer loop vertex 1.286803e+001 2.957990e+001 1.000000e+001 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 1.000000e+001 endloop endfacet facet normal 1.353506e-001 9.907978e-001 0.000000e+000 outer loop vertex 1.173648e+001 2.984808e+001 1.000000e+001 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 endloop endfacet facet normal 9.679149e-002 9.953047e-001 0.000000e+000 outer loop vertex 1.173648e+001 2.984808e+001 1.000000e+001 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 1.000000e+001 endloop endfacet facet normal 1.941080e-002 9.998116e-001 0.000000e+000 outer loop vertex 1.058145e+001 2.998308e+001 1.000000e+001 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 endloop endfacet facet normal -1.941080e-002 9.998116e-001 0.000000e+000 outer loop vertex 1.058145e+001 2.998308e+001 1.000000e+001 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 1.000000e+001 endloop endfacet facet normal -9.679149e-002 9.953047e-001 0.000000e+000 outer loop vertex 9.418551e+000 2.998308e+001 1.000000e+001 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 0.000000e+000 endloop endfacet facet normal -1.353506e-001 9.907978e-001 0.000000e+000 outer loop vertex 9.418551e+000 2.998308e+001 1.000000e+001 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 1.000000e+001 endloop endfacet facet normal -2.116849e-001 9.773380e-001 0.000000e+000 outer loop vertex 8.263518e+000 2.984808e+001 1.000000e+001 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 0.000000e+000 endloop endfacet facet normal -2.494600e-001 9.683850e-001 0.000000e+000 outer loop vertex 8.263518e+000 2.984808e+001 1.000000e+001 vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 1.000000e+001 endloop endfacet facet normal -3.237155e-001 9.461545e-001 0.000000e+000 outer loop vertex 7.131968e+000 2.957990e+001 1.000000e+001 vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 endloop endfacet facet normal -3.601959e-001 9.328767e-001 0.000000e+000 outer loop vertex 7.131968e+000 2.957990e+001 1.000000e+001 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 1.000000e+001 endloop endfacet facet normal -4.313685e-001 9.021758e-001 0.000000e+000 outer loop vertex 6.039202e+000 2.918216e+001 1.000000e+001 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 endloop endfacet facet normal -4.660608e-001 8.847528e-001 0.000000e+000 outer loop vertex 6.039202e+000 2.918216e+001 1.000000e+001 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 1.000000e+001 endloop endfacet facet normal -5.331879e-001 8.459968e-001 0.000000e+000 outer loop vertex 5.000000e+000 2.866026e+001 1.000000e+001 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 endloop endfacet facet normal -5.656230e-001 8.246640e-001 0.000000e+000 outer loop vertex 5.000000e+000 2.866026e+001 1.000000e+001 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 1.000000e+001 endloop endfacet facet normal -6.277969e-001 7.783771e-001 0.000000e+000 outer loop vertex 4.028414e+000 2.802123e+001 1.000000e+001 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 endloop endfacet facet normal -6.575360e-001 7.534231e-001 0.000000e+000 outer loop vertex 4.028414e+000 2.802123e+001 1.000000e+001 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 1.000000e+001 endloop endfacet facet normal -7.139161e-001 7.002313e-001 0.000000e+000 outer loop vertex 3.137583e+000 2.727374e+001 1.000000e+001 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 endloop endfacet facet normal -7.405571e-001 6.719934e-001 0.000000e+000 outer loop vertex 3.137583e+000 2.727374e+001 1.000000e+001 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 1.000000e+001 endloop endfacet facet normal -7.903807e-001 6.126159e-001 0.000000e+000 outer loop vertex 2.339556e+000 2.642788e+001 1.000000e+001 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 endloop endfacet facet normal -8.135634e-001 5.814762e-001 0.000000e+000 outer loop vertex 2.339556e+000 2.642788e+001 1.000000e+001 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 1.000000e+001 endloop endfacet facet normal -8.561568e-001 5.167161e-001 0.000000e+000 outer loop vertex 1.645122e+000 2.549509e+001 1.000000e+001 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 endloop endfacet facet normal -8.755676e-001 4.830956e-001 0.000000e+000 outer loop vertex 1.645122e+000 2.549509e+001 1.000000e+001 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 1.000000e+001 endloop endfacet facet normal -9.103549e-001 4.138285e-001 0.000000e+000 outer loop vertex 1.063674e+000 2.448799e+001 1.000000e+001 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 endloop endfacet facet normal -9.257313e-001 3.781818e-001 0.000000e+000 outer loop vertex 1.063674e+000 2.448799e+001 1.000000e+001 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 1.000000e+001 endloop endfacet facet normal -9.522419e-001 3.053445e-001 0.000000e+000 outer loop vertex 6.030733e-001 2.342020e+001 1.000000e+001 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 endloop endfacet facet normal -9.633761e-001 2.681538e-001 0.000000e+000 outer loop vertex 6.030733e-001 2.342020e+001 1.000000e+001 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 1.000000e+001 endloop endfacet facet normal -9.812515e-001 1.927314e-001 0.000000e+000 outer loop vertex 2.695508e-001 2.230616e+001 1.000000e+001 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 endloop endfacet facet normal -9.879928e-001 1.544996e-001 0.000000e+000 outer loop vertex 2.695508e-001 2.230616e+001 1.000000e+001 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 1.000000e+001 endloop endfacet facet normal -9.969914e-001 7.751183e-002 0.000000e+000 outer loop vertex 6.761588e-002 2.116093e+001 1.000000e+001 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal -9.992487e-001 3.875592e-002 0.000000e+000 outer loop vertex 6.761588e-002 2.116093e+001 1.000000e+001 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 1.000000e+001 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 1.000000e+001 vertex 0.000000e+000 2.000000e+001 1.000000e+001 vertex 0.000000e+000 5.000000e+000 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 0.000000e+000 2.000000e+001 1.000000e+001 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal -9.986320e-001 -5.228807e-002 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 1.000000e+001 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 endloop endfacet facet normal -9.945168e-001 -1.045761e-001 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 1.000000e+001 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 1.000000e+001 endloop endfacet facet normal -9.781576e-001 -2.078648e-001 0.000000e+000 outer loop vertex 6.155763e-002 4.217827e+000 1.000000e+001 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 endloop endfacet facet normal -9.659134e-001 -2.588654e-001 0.000000e+000 outer loop vertex 6.155763e-002 4.217827e+000 1.000000e+001 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 1.000000e+001 endloop endfacet facet normal -9.335976e-001 -3.583232e-001 0.000000e+000 outer loop vertex 2.447171e-001 3.454915e+000 1.000000e+001 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 endloop endfacet facet normal -9.135259e-001 -4.067805e-001 0.000000e+000 outer loop vertex 2.447171e-001 3.454915e+000 1.000000e+001 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 1.000000e+001 endloop endfacet facet normal -8.660493e-001 -4.999585e-001 0.000000e+000 outer loop vertex 5.449671e-001 2.730047e+000 1.000000e+001 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 endloop endfacet facet normal -8.386444e-001 -5.446792e-001 0.000000e+000 outer loop vertex 5.449671e-001 2.730047e+000 1.000000e+001 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 1.000000e+001 endloop endfacet facet normal -7.771761e-001 -6.292831e-001 0.000000e+000 outer loop vertex 9.549148e-001 2.061074e+000 1.000000e+001 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 endloop endfacet facet normal -7.431127e-001 -6.691663e-001 0.000000e+000 outer loop vertex 9.549148e-001 2.061074e+000 1.000000e+001 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 1.000000e+001 endloop endfacet facet normal -6.691663e-001 -7.431127e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 1.000000e+001 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 endloop endfacet facet normal -6.292831e-001 -7.771761e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 1.000000e+001 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 2.061074e+000 9.549148e-001 1.000000e+001 endloop endfacet facet normal -5.446792e-001 -8.386444e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549148e-001 1.000000e+001 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 endloop endfacet facet normal -4.999585e-001 -8.660493e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549148e-001 1.000000e+001 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 1.000000e+001 endloop endfacet facet normal -4.067805e-001 -9.135259e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449671e-001 1.000000e+001 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 endloop endfacet facet normal -3.583232e-001 -9.335976e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449671e-001 1.000000e+001 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 1.000000e+001 endloop endfacet facet normal -2.588654e-001 -9.659134e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447171e-001 1.000000e+001 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 endloop endfacet facet normal -2.078648e-001 -9.781576e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447171e-001 1.000000e+001 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 4.217827e+000 6.155763e-002 1.000000e+001 endloop endfacet facet normal -1.045761e-001 -9.945168e-001 0.000000e+000 outer loop vertex 4.217827e+000 6.155763e-002 1.000000e+001 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal -5.228807e-002 -9.986320e-001 0.000000e+000 outer loop vertex 4.217827e+000 6.155763e-002 1.000000e+001 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 0.000000e+000 1.000000e+001 vertex 5.000000e+000 0.000000e+000 1.000000e+001 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 1.000000e+001 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 1.000000e+001 vertex 2.000000e+001 0.000000e+000 1.000000e+001 vertex 2.000000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 1.000000e+001 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 9.992487e-001 -3.875592e-002 0.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 1.000000e+001 vertex 3.300002e-001 2.000000e+001 0.000000e+000 vertex 3.953846e-001 2.112262e+001 0.000000e+000 endloop endfacet facet normal 9.969914e-001 -7.751183e-002 0.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 1.000000e+001 vertex 3.953846e-001 2.112262e+001 0.000000e+000 vertex 3.953846e-001 2.112262e+001 1.000000e+001 endloop endfacet facet normal 9.879928e-001 -1.544996e-001 0.000000e+000 outer loop vertex 3.953846e-001 2.112262e+001 1.000000e+001 vertex 3.953846e-001 2.112262e+001 0.000000e+000 vertex 5.906559e-001 2.223005e+001 0.000000e+000 endloop endfacet facet normal 9.812515e-001 -1.927314e-001 0.000000e+000 outer loop vertex 3.953846e-001 2.112262e+001 1.000000e+001 vertex 5.906559e-001 2.223005e+001 0.000000e+000 vertex 5.906559e-001 2.223005e+001 1.000000e+001 endloop endfacet facet normal 9.633761e-001 -2.681538e-001 0.000000e+000 outer loop vertex 5.906559e-001 2.223005e+001 1.000000e+001 vertex 5.906559e-001 2.223005e+001 0.000000e+000 vertex 9.131720e-001 2.330733e+001 0.000000e+000 endloop endfacet facet normal 9.522419e-001 -3.053445e-001 0.000000e+000 outer loop vertex 5.906559e-001 2.223005e+001 1.000000e+001 vertex 9.131720e-001 2.330733e+001 0.000000e+000 vertex 9.131720e-001 2.330733e+001 1.000000e+001 endloop endfacet facet normal 9.257313e-001 -3.781818e-001 0.000000e+000 outer loop vertex 9.131720e-001 2.330733e+001 1.000000e+001 vertex 9.131720e-001 2.330733e+001 0.000000e+000 vertex 1.358572e+000 2.433989e+001 0.000000e+000 endloop endfacet facet normal 9.103549e-001 -4.138285e-001 0.000000e+000 outer loop vertex 9.131720e-001 2.330733e+001 1.000000e+001 vertex 1.358572e+000 2.433989e+001 0.000000e+000 vertex 1.358572e+000 2.433989e+001 1.000000e+001 endloop endfacet facet normal 8.755676e-001 -4.830956e-001 0.000000e+000 outer loop vertex 1.358572e+000 2.433989e+001 1.000000e+001 vertex 1.358572e+000 2.433989e+001 0.000000e+000 vertex 1.920832e+000 2.531375e+001 0.000000e+000 endloop endfacet facet normal 8.561568e-001 -5.167161e-001 0.000000e+000 outer loop vertex 1.358572e+000 2.433989e+001 1.000000e+001 vertex 1.920832e+000 2.531375e+001 0.000000e+000 vertex 1.920832e+000 2.531375e+001 1.000000e+001 endloop endfacet facet normal 8.135634e-001 -5.814762e-001 0.000000e+000 outer loop vertex 1.920832e+000 2.531375e+001 1.000000e+001 vertex 1.920832e+000 2.531375e+001 0.000000e+000 vertex 2.592350e+000 2.621576e+001 0.000000e+000 endloop endfacet facet normal 7.903807e-001 -6.126159e-001 0.000000e+000 outer loop vertex 1.920832e+000 2.531375e+001 1.000000e+001 vertex 2.592350e+000 2.621576e+001 0.000000e+000 vertex 2.592350e+000 2.621576e+001 1.000000e+001 endloop endfacet facet normal 7.405571e-001 -6.719934e-001 0.000000e+000 outer loop vertex 2.592350e+000 2.621576e+001 1.000000e+001 vertex 2.592350e+000 2.621576e+001 0.000000e+000 vertex 3.364043e+000 2.703370e+001 0.000000e+000 endloop endfacet facet normal 7.139161e-001 -7.002313e-001 0.000000e+000 outer loop vertex 2.592350e+000 2.621576e+001 1.000000e+001 vertex 3.364043e+000 2.703370e+001 0.000000e+000 vertex 3.364043e+000 2.703370e+001 1.000000e+001 endloop endfacet facet normal 6.575360e-001 -7.534231e-001 0.000000e+000 outer loop vertex 3.364043e+000 2.703370e+001 1.000000e+001 vertex 3.364043e+000 2.703370e+001 0.000000e+000 vertex 4.225476e+000 2.775653e+001 0.000000e+000 endloop endfacet facet normal 6.277969e-001 -7.783771e-001 0.000000e+000 outer loop vertex 3.364043e+000 2.703370e+001 1.000000e+001 vertex 4.225476e+000 2.775653e+001 0.000000e+000 vertex 4.225476e+000 2.775653e+001 1.000000e+001 endloop endfacet facet normal 5.656230e-001 -8.246640e-001 0.000000e+000 outer loop vertex 4.225476e+000 2.775653e+001 1.000000e+001 vertex 4.225476e+000 2.775653e+001 0.000000e+000 vertex 5.165000e+000 2.837447e+001 0.000000e+000 endloop endfacet facet normal 5.331879e-001 -8.459968e-001 0.000000e+000 outer loop vertex 4.225476e+000 2.775653e+001 1.000000e+001 vertex 5.165000e+000 2.837447e+001 0.000000e+000 vertex 5.165000e+000 2.837447e+001 1.000000e+001 endloop endfacet facet normal 4.660608e-001 -8.847528e-001 0.000000e+000 outer loop vertex 5.165000e+000 2.837447e+001 1.000000e+001 vertex 5.165000e+000 2.837447e+001 0.000000e+000 vertex 6.169909e+000 2.887915e+001 0.000000e+000 endloop endfacet facet normal 4.313685e-001 -9.021758e-001 0.000000e+000 outer loop vertex 5.165000e+000 2.837447e+001 1.000000e+001 vertex 6.169909e+000 2.887915e+001 0.000000e+000 vertex 6.169909e+000 2.887915e+001 1.000000e+001 endloop endfacet facet normal 3.601959e-001 -9.328767e-001 0.000000e+000 outer loop vertex 6.169909e+000 2.887915e+001 1.000000e+001 vertex 6.169909e+000 2.887915e+001 0.000000e+000 vertex 7.226613e+000 2.926376e+001 0.000000e+000 endloop endfacet facet normal 3.237155e-001 -9.461545e-001 0.000000e+000 outer loop vertex 6.169909e+000 2.887915e+001 1.000000e+001 vertex 7.226613e+000 2.926376e+001 0.000000e+000 vertex 7.226613e+000 2.926376e+001 1.000000e+001 endloop endfacet facet normal 2.494600e-001 -9.683850e-001 0.000000e+000 outer loop vertex 7.226613e+000 2.926376e+001 1.000000e+001 vertex 7.226613e+000 2.926376e+001 0.000000e+000 vertex 8.320822e+000 2.952309e+001 0.000000e+000 endloop endfacet facet normal 2.116849e-001 -9.773380e-001 0.000000e+000 outer loop vertex 7.226613e+000 2.926376e+001 1.000000e+001 vertex 8.320822e+000 2.952309e+001 0.000000e+000 vertex 8.320822e+000 2.952309e+001 1.000000e+001 endloop endfacet facet normal 1.353506e-001 -9.907978e-001 0.000000e+000 outer loop vertex 8.320822e+000 2.952309e+001 1.000000e+001 vertex 8.320822e+000 2.952309e+001 0.000000e+000 vertex 9.437739e+000 2.965364e+001 0.000000e+000 endloop endfacet facet normal 9.679149e-002 -9.953047e-001 0.000000e+000 outer loop vertex 8.320822e+000 2.952309e+001 1.000000e+001 vertex 9.437739e+000 2.965364e+001 0.000000e+000 vertex 9.437739e+000 2.965364e+001 1.000000e+001 endloop endfacet facet normal 1.941080e-002 -9.998116e-001 0.000000e+000 outer loop vertex 9.437739e+000 2.965364e+001 1.000000e+001 vertex 9.437739e+000 2.965364e+001 0.000000e+000 vertex 1.056226e+001 2.965364e+001 0.000000e+000 endloop endfacet facet normal -1.941080e-002 -9.998116e-001 0.000000e+000 outer loop vertex 9.437739e+000 2.965364e+001 1.000000e+001 vertex 1.056226e+001 2.965364e+001 0.000000e+000 vertex 1.056226e+001 2.965364e+001 1.000000e+001 endloop endfacet facet normal -9.679149e-002 -9.953047e-001 0.000000e+000 outer loop vertex 1.056226e+001 2.965364e+001 1.000000e+001 vertex 1.056226e+001 2.965364e+001 0.000000e+000 vertex 1.167918e+001 2.952309e+001 0.000000e+000 endloop endfacet facet normal -1.353506e-001 -9.907978e-001 0.000000e+000 outer loop vertex 1.056226e+001 2.965364e+001 1.000000e+001 vertex 1.167918e+001 2.952309e+001 0.000000e+000 vertex 1.167918e+001 2.952309e+001 1.000000e+001 endloop endfacet facet normal -2.116849e-001 -9.773380e-001 0.000000e+000 outer loop vertex 1.167918e+001 2.952309e+001 1.000000e+001 vertex 1.167918e+001 2.952309e+001 0.000000e+000 vertex 1.277339e+001 2.926376e+001 0.000000e+000 endloop endfacet facet normal -2.494600e-001 -9.683850e-001 0.000000e+000 outer loop vertex 1.167918e+001 2.952309e+001 1.000000e+001 vertex 1.277339e+001 2.926376e+001 0.000000e+000 vertex 1.277339e+001 2.926376e+001 1.000000e+001 endloop endfacet facet normal -3.237155e-001 -9.461545e-001 0.000000e+000 outer loop vertex 1.277339e+001 2.926376e+001 1.000000e+001 vertex 1.277339e+001 2.926376e+001 0.000000e+000 vertex 1.383009e+001 2.887915e+001 0.000000e+000 endloop endfacet facet normal -3.601959e-001 -9.328767e-001 0.000000e+000 outer loop vertex 1.277339e+001 2.926376e+001 1.000000e+001 vertex 1.383009e+001 2.887915e+001 0.000000e+000 vertex 1.383009e+001 2.887915e+001 1.000000e+001 endloop endfacet facet normal -4.313685e-001 -9.021758e-001 0.000000e+000 outer loop vertex 1.383009e+001 2.887915e+001 1.000000e+001 vertex 1.383009e+001 2.887915e+001 0.000000e+000 vertex 1.483500e+001 2.837447e+001 0.000000e+000 endloop endfacet facet normal -4.660608e-001 -8.847528e-001 0.000000e+000 outer loop vertex 1.383009e+001 2.887915e+001 1.000000e+001 vertex 1.483500e+001 2.837447e+001 0.000000e+000 vertex 1.483500e+001 2.837447e+001 1.000000e+001 endloop endfacet facet normal -5.331879e-001 -8.459968e-001 0.000000e+000 outer loop vertex 1.483500e+001 2.837447e+001 1.000000e+001 vertex 1.483500e+001 2.837447e+001 0.000000e+000 vertex 1.577452e+001 2.775653e+001 0.000000e+000 endloop endfacet facet normal -5.656230e-001 -8.246640e-001 0.000000e+000 outer loop vertex 1.483500e+001 2.837447e+001 1.000000e+001 vertex 1.577452e+001 2.775653e+001 0.000000e+000 vertex 1.577452e+001 2.775653e+001 1.000000e+001 endloop endfacet facet normal -6.277969e-001 -7.783771e-001 0.000000e+000 outer loop vertex 1.577452e+001 2.775653e+001 1.000000e+001 vertex 1.577452e+001 2.775653e+001 0.000000e+000 vertex 1.663596e+001 2.703370e+001 0.000000e+000 endloop endfacet facet normal -6.575360e-001 -7.534231e-001 0.000000e+000 outer loop vertex 1.577452e+001 2.775653e+001 1.000000e+001 vertex 1.663596e+001 2.703370e+001 0.000000e+000 vertex 1.663596e+001 2.703370e+001 1.000000e+001 endloop endfacet facet normal -7.139161e-001 -7.002313e-001 0.000000e+000 outer loop vertex 1.663596e+001 2.703370e+001 1.000000e+001 vertex 1.663596e+001 2.703370e+001 0.000000e+000 vertex 1.740765e+001 2.621576e+001 0.000000e+000 endloop endfacet facet normal -7.405571e-001 -6.719934e-001 0.000000e+000 outer loop vertex 1.663596e+001 2.703370e+001 1.000000e+001 vertex 1.740765e+001 2.621576e+001 0.000000e+000 vertex 1.740765e+001 2.621576e+001 1.000000e+001 endloop endfacet facet normal -7.903807e-001 -6.126159e-001 0.000000e+000 outer loop vertex 1.740765e+001 2.621576e+001 1.000000e+001 vertex 1.740765e+001 2.621576e+001 0.000000e+000 vertex 1.807917e+001 2.531375e+001 0.000000e+000 endloop endfacet facet normal -8.135634e-001 -5.814762e-001 0.000000e+000 outer loop vertex 1.740765e+001 2.621576e+001 1.000000e+001 vertex 1.807917e+001 2.531375e+001 0.000000e+000 vertex 1.807917e+001 2.531375e+001 1.000000e+001 endloop endfacet facet normal -8.561568e-001 -5.167161e-001 0.000000e+000 outer loop vertex 1.807917e+001 2.531375e+001 1.000000e+001 vertex 1.807917e+001 2.531375e+001 0.000000e+000 vertex 1.864143e+001 2.433989e+001 0.000000e+000 endloop endfacet facet normal -8.755676e-001 -4.830956e-001 0.000000e+000 outer loop vertex 1.807917e+001 2.531375e+001 1.000000e+001 vertex 1.864143e+001 2.433989e+001 0.000000e+000 vertex 1.864143e+001 2.433989e+001 1.000000e+001 endloop endfacet facet normal -9.103549e-001 -4.138285e-001 0.000000e+000 outer loop vertex 1.864143e+001 2.433989e+001 1.000000e+001 vertex 1.864143e+001 2.433989e+001 0.000000e+000 vertex 1.908683e+001 2.330733e+001 0.000000e+000 endloop endfacet facet normal -9.257313e-001 -3.781818e-001 0.000000e+000 outer loop vertex 1.864143e+001 2.433989e+001 1.000000e+001 vertex 1.908683e+001 2.330733e+001 0.000000e+000 vertex 1.908683e+001 2.330733e+001 1.000000e+001 endloop endfacet facet normal -9.522419e-001 -3.053445e-001 0.000000e+000 outer loop vertex 1.908683e+001 2.330733e+001 1.000000e+001 vertex 1.908683e+001 2.330733e+001 0.000000e+000 vertex 1.940934e+001 2.223005e+001 0.000000e+000 endloop endfacet facet normal -9.633761e-001 -2.681538e-001 0.000000e+000 outer loop vertex 1.908683e+001 2.330733e+001 1.000000e+001 vertex 1.940934e+001 2.223005e+001 0.000000e+000 vertex 1.940934e+001 2.223005e+001 1.000000e+001 endloop endfacet facet normal -9.812515e-001 -1.927314e-001 0.000000e+000 outer loop vertex 1.940934e+001 2.223005e+001 1.000000e+001 vertex 1.940934e+001 2.223005e+001 0.000000e+000 vertex 1.960462e+001 2.112262e+001 0.000000e+000 endloop endfacet facet normal -9.879928e-001 -1.544996e-001 0.000000e+000 outer loop vertex 1.940934e+001 2.223005e+001 1.000000e+001 vertex 1.960462e+001 2.112262e+001 0.000000e+000 vertex 1.960462e+001 2.112262e+001 1.000000e+001 endloop endfacet facet normal -9.969914e-001 -7.751183e-002 0.000000e+000 outer loop vertex 1.960462e+001 2.112262e+001 1.000000e+001 vertex 1.960462e+001 2.112262e+001 0.000000e+000 vertex 1.967000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal -9.992487e-001 -3.875592e-002 0.000000e+000 outer loop vertex 1.960462e+001 2.112262e+001 1.000000e+001 vertex 1.967000e+001 2.000000e+001 0.000000e+000 vertex 1.967000e+001 2.000000e+001 1.000000e+001 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 1.000000e+001 vertex 3.300002e-001 5.000000e+000 1.000000e+001 vertex 3.300002e-001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 0.000000e+000 vertex 3.300002e-001 5.000000e+000 1.000000e+001 vertex 3.300002e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 5.228807e-002 9.986320e-001 0.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 1.000000e+001 vertex 5.000000e+000 3.300002e-001 0.000000e+000 vertex 4.269451e+000 3.874954e-001 0.000000e+000 endloop endfacet facet normal 1.045761e-001 9.945168e-001 0.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 1.000000e+001 vertex 4.269451e+000 3.874954e-001 0.000000e+000 vertex 4.269451e+000 3.874954e-001 1.000000e+001 endloop endfacet facet normal 2.078648e-001 9.781576e-001 0.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 1.000000e+001 vertex 4.269451e+000 3.874954e-001 0.000000e+000 vertex 3.556890e+000 5.585663e-001 0.000000e+000 endloop endfacet facet normal 2.588654e-001 9.659134e-001 0.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 1.000000e+001 vertex 3.556890e+000 5.585663e-001 0.000000e+000 vertex 3.556890e+000 5.585663e-001 1.000000e+001 endloop endfacet facet normal 3.583232e-001 9.335976e-001 0.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 1.000000e+001 vertex 3.556890e+000 5.585663e-001 0.000000e+000 vertex 2.879864e+000 8.389996e-001 0.000000e+000 endloop endfacet facet normal 4.067805e-001 9.135259e-001 0.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 1.000000e+001 vertex 2.879864e+000 8.389996e-001 0.000000e+000 vertex 2.879864e+000 8.389996e-001 1.000000e+001 endloop endfacet facet normal 4.999585e-001 8.660493e-001 0.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 1.000000e+001 vertex 2.879864e+000 8.389996e-001 0.000000e+000 vertex 2.255043e+000 1.221891e+000 0.000000e+000 endloop endfacet facet normal 5.446792e-001 8.386444e-001 0.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 1.000000e+001 vertex 2.255043e+000 1.221891e+000 0.000000e+000 vertex 2.255043e+000 1.221891e+000 1.000000e+001 endloop endfacet facet normal 6.292831e-001 7.771761e-001 0.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 1.000000e+001 vertex 2.255043e+000 1.221891e+000 0.000000e+000 vertex 1.697811e+000 1.697811e+000 0.000000e+000 endloop endfacet facet normal 6.691663e-001 7.431127e-001 0.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 1.000000e+001 vertex 1.697811e+000 1.697811e+000 0.000000e+000 vertex 1.697811e+000 1.697811e+000 1.000000e+001 endloop endfacet facet normal 7.431127e-001 6.691663e-001 0.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 1.000000e+001 vertex 1.697811e+000 1.697811e+000 0.000000e+000 vertex 1.221891e+000 2.255043e+000 0.000000e+000 endloop endfacet facet normal 7.771761e-001 6.292831e-001 0.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 1.000000e+001 vertex 1.221891e+000 2.255043e+000 0.000000e+000 vertex 1.221891e+000 2.255043e+000 1.000000e+001 endloop endfacet facet normal 8.386444e-001 5.446792e-001 0.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 1.000000e+001 vertex 1.221891e+000 2.255043e+000 0.000000e+000 vertex 8.389996e-001 2.879864e+000 0.000000e+000 endloop endfacet facet normal 8.660493e-001 4.999585e-001 0.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 1.000000e+001 vertex 8.389996e-001 2.879864e+000 0.000000e+000 vertex 8.389996e-001 2.879864e+000 1.000000e+001 endloop endfacet facet normal 9.135259e-001 4.067805e-001 0.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 1.000000e+001 vertex 8.389996e-001 2.879864e+000 0.000000e+000 vertex 5.585663e-001 3.556890e+000 0.000000e+000 endloop endfacet facet normal 9.335976e-001 3.583232e-001 0.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 1.000000e+001 vertex 5.585663e-001 3.556890e+000 0.000000e+000 vertex 5.585663e-001 3.556890e+000 1.000000e+001 endloop endfacet facet normal 9.659134e-001 2.588654e-001 0.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 1.000000e+001 vertex 5.585663e-001 3.556890e+000 0.000000e+000 vertex 3.874954e-001 4.269451e+000 0.000000e+000 endloop endfacet facet normal 9.781576e-001 2.078648e-001 0.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 1.000000e+001 vertex 3.874954e-001 4.269451e+000 0.000000e+000 vertex 3.874954e-001 4.269451e+000 1.000000e+001 endloop endfacet facet normal 9.945168e-001 1.045761e-001 0.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 1.000000e+001 vertex 3.874954e-001 4.269451e+000 0.000000e+000 vertex 3.300002e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 9.986320e-001 5.228807e-002 0.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 1.000000e+001 vertex 3.300002e-001 5.000000e+000 0.000000e+000 vertex 3.300002e-001 5.000000e+000 1.000000e+001 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 1.000000e+001 vertex 1.967000e+001 3.300002e-001 1.000000e+001 vertex 5.000000e+000 3.300002e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 0.000000e+000 vertex 1.967000e+001 3.300002e-001 1.000000e+001 vertex 1.967000e+001 3.300002e-001 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 1.000000e+001 vertex 1.967000e+001 2.000000e+001 1.000000e+001 vertex 1.967000e+001 3.300002e-001 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 0.000000e+000 vertex 1.967000e+001 2.000000e+001 1.000000e+001 vertex 1.967000e+001 2.000000e+001 0.000000e+000 endloop endfacet endsolidsfact-2011.12.18/calibration/_33x20.STL000066400000000000000000002457211167321211700170140ustar00rootroot00000000000000solid _33x20 facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.239316e+001 2.970942e+001 2.000000e+001 vertex 1.120537e+001 2.992709e+001 2.000000e+001 vertex 1.060718e+001 2.965092e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.060718e+001 2.965092e+001 2.000000e+001 vertex 1.120537e+001 2.992709e+001 2.000000e+001 vertex 1.000000e+001 3.000000e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.060718e+001 2.965092e+001 2.000000e+001 vertex 1.000000e+001 3.000000e+001 2.000000e+001 vertex 9.392816e+000 2.965092e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.392816e+000 2.965092e+001 2.000000e+001 vertex 1.000000e+001 3.000000e+001 2.000000e+001 vertex 8.794633e+000 2.992709e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.392816e+000 2.965092e+001 2.000000e+001 vertex 8.794633e+000 2.992709e+001 2.000000e+001 vertex 8.188023e+000 2.949872e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.188023e+000 2.949872e+001 2.000000e+001 vertex 8.794633e+000 2.992709e+001 2.000000e+001 vertex 7.606843e+000 2.970942e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.188023e+000 2.949872e+001 2.000000e+001 vertex 7.606843e+000 2.970942e+001 2.000000e+001 vertex 7.011806e+000 2.919672e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.011806e+000 2.919672e+001 2.000000e+001 vertex 7.606843e+000 2.970942e+001 2.000000e+001 vertex 6.453951e+000 2.935016e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.011806e+000 2.919672e+001 2.000000e+001 vertex 6.453951e+000 2.935016e+001 2.000000e+001 vertex 5.882714e+000 2.874968e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.882714e+000 2.874968e+001 2.000000e+001 vertex 6.453951e+000 2.935016e+001 2.000000e+001 vertex 5.352768e+000 2.885456e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.882714e+000 2.874968e+001 2.000000e+001 vertex 5.352768e+000 2.885456e+001 2.000000e+001 vertex 4.818554e+000 2.816465e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.818554e+000 2.816465e+001 2.000000e+001 vertex 5.352768e+000 2.885456e+001 2.000000e+001 vertex 4.319352e+000 2.822984e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.818554e+000 2.816465e+001 2.000000e+001 vertex 4.319352e+000 2.822984e+001 2.000000e+001 vertex 3.836110e+000 2.745086e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.836110e+000 2.745086e+001 2.000000e+001 vertex 4.319352e+000 2.822984e+001 2.000000e+001 vertex 3.368773e+000 2.748511e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.836110e+000 2.745086e+001 2.000000e+001 vertex 3.368773e+000 2.748511e+001 2.000000e+001 vertex 2.950873e+000 2.661957e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.950873e+000 2.661957e+001 2.000000e+001 vertex 3.368773e+000 2.748511e+001 2.000000e+001 vertex 2.514892e+000 2.663123e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.950873e+000 2.661957e+001 2.000000e+001 vertex 2.514892e+000 2.663123e+001 2.000000e+001 vertex 2.176805e+000 2.568388e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.176805e+000 2.568388e+001 2.000000e+001 vertex 2.514892e+000 2.663123e+001 2.000000e+001 vertex 1.770161e+000 2.568065e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.176805e+000 2.568388e+001 2.000000e+001 vertex 1.770161e+000 2.568065e+001 2.000000e+001 vertex 1.526115e+000 2.465856e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.526115e+000 2.465856e+001 2.000000e+001 vertex 1.770161e+000 2.568065e+001 2.000000e+001 vertex 1.145439e+000 2.464723e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.526115e+000 2.465856e+001 2.000000e+001 vertex 1.145439e+000 2.464723e+001 2.000000e+001 vertex 1.009061e+000 2.355976e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.009061e+000 2.355976e+001 2.000000e+001 vertex 1.145439e+000 2.464723e+001 2.000000e+001 vertex 6.498378e-001 2.354605e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.009061e+000 2.355976e+001 2.000000e+001 vertex 6.498378e-001 2.354605e+001 2.000000e+001 vertex 6.338004e-001 2.240483e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.338004e-001 2.240483e+001 2.000000e+001 vertex 6.498378e-001 2.354605e+001 2.000000e+001 vertex 2.905819e-001 2.239316e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.338004e-001 2.240483e+001 2.000000e+001 vertex 2.905819e-001 2.239316e+001 2.000000e+001 vertex 4.062504e-001 2.121197e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.062504e-001 2.121197e+001 2.000000e+001 vertex 2.905819e-001 2.239316e+001 2.000000e+001 vertex 7.291138e-002 2.120537e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.062504e-001 2.121197e+001 2.000000e+001 vertex 7.291138e-002 2.120537e+001 2.000000e+001 vertex 3.300002e-001 2.000000e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 2.000000e+001 vertex 7.291138e-002 2.120537e+001 2.000000e+001 vertex 0.000000e+000 2.000000e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 2.000000e+001 vertex 0.000000e+000 2.000000e+001 2.000000e+001 vertex 3.300002e-001 5.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.300002e-001 5.000000e+000 2.000000e+001 vertex 0.000000e+000 2.000000e+001 2.000000e+001 vertex 0.000000e+000 5.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.300002e-001 5.000000e+000 2.000000e+001 vertex 0.000000e+000 5.000000e+000 2.000000e+001 vertex 3.874954e-001 4.269451e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 2.000000e+001 vertex 0.000000e+000 5.000000e+000 2.000000e+001 vertex 6.155763e-002 4.217827e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 2.000000e+001 vertex 6.155763e-002 4.217827e+000 2.000000e+001 vertex 5.585663e-001 3.556890e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 2.000000e+001 vertex 6.155763e-002 4.217827e+000 2.000000e+001 vertex 2.447171e-001 3.454915e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 2.000000e+001 vertex 2.447171e-001 3.454915e+000 2.000000e+001 vertex 8.389996e-001 2.879864e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 2.000000e+001 vertex 2.447171e-001 3.454915e+000 2.000000e+001 vertex 5.449671e-001 2.730047e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 2.000000e+001 vertex 5.449671e-001 2.730047e+000 2.000000e+001 vertex 1.221891e+000 2.255043e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 2.000000e+001 vertex 5.449671e-001 2.730047e+000 2.000000e+001 vertex 9.549148e-001 2.061074e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 2.000000e+001 vertex 9.549148e-001 2.061074e+000 2.000000e+001 vertex 1.697811e+000 1.697811e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 2.000000e+001 vertex 9.549148e-001 2.061074e+000 2.000000e+001 vertex 1.464466e+000 1.464466e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 2.000000e+001 vertex 1.464466e+000 1.464466e+000 2.000000e+001 vertex 2.255043e+000 1.221891e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 2.000000e+001 vertex 1.464466e+000 1.464466e+000 2.000000e+001 vertex 2.061074e+000 9.549148e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 2.000000e+001 vertex 2.061074e+000 9.549148e-001 2.000000e+001 vertex 2.879864e+000 8.389996e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 2.000000e+001 vertex 2.061074e+000 9.549148e-001 2.000000e+001 vertex 2.730047e+000 5.449671e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 2.000000e+001 vertex 2.730047e+000 5.449671e-001 2.000000e+001 vertex 3.556890e+000 5.585663e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 2.000000e+001 vertex 2.730047e+000 5.449671e-001 2.000000e+001 vertex 3.454915e+000 2.447171e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 2.000000e+001 vertex 3.454915e+000 2.447171e-001 2.000000e+001 vertex 4.269451e+000 3.874954e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 2.000000e+001 vertex 3.454915e+000 2.447171e-001 2.000000e+001 vertex 4.217827e+000 6.155763e-002 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 2.000000e+001 vertex 4.217827e+000 6.155763e-002 2.000000e+001 vertex 5.000000e+000 3.300002e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 2.000000e+001 vertex 4.217827e+000 6.155763e-002 2.000000e+001 vertex 5.000000e+000 0.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 2.000000e+001 vertex 5.000000e+000 0.000000e+000 2.000000e+001 vertex 1.967000e+001 3.300002e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 2.000000e+001 vertex 5.000000e+000 0.000000e+000 2.000000e+001 vertex 2.000000e+001 0.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 2.000000e+001 vertex 2.000000e+001 0.000000e+000 2.000000e+001 vertex 1.967000e+001 2.000000e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.967000e+001 2.000000e+001 2.000000e+001 vertex 2.000000e+001 0.000000e+000 2.000000e+001 vertex 2.000000e+001 2.000000e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.967000e+001 2.000000e+001 2.000000e+001 vertex 2.000000e+001 2.000000e+001 2.000000e+001 vertex 1.959375e+001 2.121197e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.959375e+001 2.121197e+001 2.000000e+001 vertex 2.000000e+001 2.000000e+001 2.000000e+001 vertex 1.992709e+001 2.120537e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.959375e+001 2.121197e+001 2.000000e+001 vertex 1.992709e+001 2.120537e+001 2.000000e+001 vertex 1.936620e+001 2.240483e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.936620e+001 2.240483e+001 2.000000e+001 vertex 1.992709e+001 2.120537e+001 2.000000e+001 vertex 1.970942e+001 2.239316e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.936620e+001 2.240483e+001 2.000000e+001 vertex 1.970942e+001 2.239316e+001 2.000000e+001 vertex 1.899094e+001 2.355976e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.899094e+001 2.355976e+001 2.000000e+001 vertex 1.970942e+001 2.239316e+001 2.000000e+001 vertex 1.935016e+001 2.354605e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.899094e+001 2.355976e+001 2.000000e+001 vertex 1.935016e+001 2.354605e+001 2.000000e+001 vertex 1.847389e+001 2.465856e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.847389e+001 2.465856e+001 2.000000e+001 vertex 1.935016e+001 2.354605e+001 2.000000e+001 vertex 1.885456e+001 2.464723e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.847389e+001 2.465856e+001 2.000000e+001 vertex 1.885456e+001 2.464723e+001 2.000000e+001 vertex 1.782319e+001 2.568388e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.782319e+001 2.568388e+001 2.000000e+001 vertex 1.885456e+001 2.464723e+001 2.000000e+001 vertex 1.822984e+001 2.568065e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.782319e+001 2.568388e+001 2.000000e+001 vertex 1.822984e+001 2.568065e+001 2.000000e+001 vertex 1.704913e+001 2.661957e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.704913e+001 2.661957e+001 2.000000e+001 vertex 1.822984e+001 2.568065e+001 2.000000e+001 vertex 1.748511e+001 2.663123e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.704913e+001 2.661957e+001 2.000000e+001 vertex 1.748511e+001 2.663123e+001 2.000000e+001 vertex 1.616389e+001 2.745086e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.616389e+001 2.745086e+001 2.000000e+001 vertex 1.748511e+001 2.663123e+001 2.000000e+001 vertex 1.663123e+001 2.748511e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.616389e+001 2.745086e+001 2.000000e+001 vertex 1.663123e+001 2.748511e+001 2.000000e+001 vertex 1.518144e+001 2.816465e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.518144e+001 2.816465e+001 2.000000e+001 vertex 1.663123e+001 2.748511e+001 2.000000e+001 vertex 1.568065e+001 2.822984e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.518144e+001 2.816465e+001 2.000000e+001 vertex 1.568065e+001 2.822984e+001 2.000000e+001 vertex 1.411729e+001 2.874968e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.411729e+001 2.874968e+001 2.000000e+001 vertex 1.568065e+001 2.822984e+001 2.000000e+001 vertex 1.464723e+001 2.885456e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.411729e+001 2.874968e+001 2.000000e+001 vertex 1.464723e+001 2.885456e+001 2.000000e+001 vertex 1.298819e+001 2.919672e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.298819e+001 2.919672e+001 2.000000e+001 vertex 1.464723e+001 2.885456e+001 2.000000e+001 vertex 1.354605e+001 2.935016e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.298819e+001 2.919672e+001 2.000000e+001 vertex 1.354605e+001 2.935016e+001 2.000000e+001 vertex 1.181198e+001 2.949872e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.181198e+001 2.949872e+001 2.000000e+001 vertex 1.354605e+001 2.935016e+001 2.000000e+001 vertex 1.239316e+001 2.970942e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.181198e+001 2.949872e+001 2.000000e+001 vertex 1.239316e+001 2.970942e+001 2.000000e+001 vertex 1.060718e+001 2.965092e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.606843e+000 2.970942e+001 0.000000e+000 vertex 8.794633e+000 2.992709e+001 0.000000e+000 vertex 9.392816e+000 2.965092e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.392816e+000 2.965092e+001 0.000000e+000 vertex 8.794633e+000 2.992709e+001 0.000000e+000 vertex 1.000000e+001 3.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.392816e+000 2.965092e+001 0.000000e+000 vertex 1.000000e+001 3.000000e+001 0.000000e+000 vertex 1.060718e+001 2.965092e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.060718e+001 2.965092e+001 0.000000e+000 vertex 1.000000e+001 3.000000e+001 0.000000e+000 vertex 1.120537e+001 2.992709e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.060718e+001 2.965092e+001 0.000000e+000 vertex 1.120537e+001 2.992709e+001 0.000000e+000 vertex 1.181198e+001 2.949872e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.181198e+001 2.949872e+001 0.000000e+000 vertex 1.120537e+001 2.992709e+001 0.000000e+000 vertex 1.239316e+001 2.970942e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.181198e+001 2.949872e+001 0.000000e+000 vertex 1.239316e+001 2.970942e+001 0.000000e+000 vertex 1.298819e+001 2.919672e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.298819e+001 2.919672e+001 0.000000e+000 vertex 1.239316e+001 2.970942e+001 0.000000e+000 vertex 1.354605e+001 2.935016e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.298819e+001 2.919672e+001 0.000000e+000 vertex 1.354605e+001 2.935016e+001 0.000000e+000 vertex 1.411729e+001 2.874968e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.411729e+001 2.874968e+001 0.000000e+000 vertex 1.354605e+001 2.935016e+001 0.000000e+000 vertex 1.464723e+001 2.885456e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.411729e+001 2.874968e+001 0.000000e+000 vertex 1.464723e+001 2.885456e+001 0.000000e+000 vertex 1.518144e+001 2.816465e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.518144e+001 2.816465e+001 0.000000e+000 vertex 1.464723e+001 2.885456e+001 0.000000e+000 vertex 1.568065e+001 2.822984e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.518144e+001 2.816465e+001 0.000000e+000 vertex 1.568065e+001 2.822984e+001 0.000000e+000 vertex 1.616389e+001 2.745086e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.616389e+001 2.745086e+001 0.000000e+000 vertex 1.568065e+001 2.822984e+001 0.000000e+000 vertex 1.663123e+001 2.748511e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.616389e+001 2.745086e+001 0.000000e+000 vertex 1.663123e+001 2.748511e+001 0.000000e+000 vertex 1.704913e+001 2.661957e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.704913e+001 2.661957e+001 0.000000e+000 vertex 1.663123e+001 2.748511e+001 0.000000e+000 vertex 1.748511e+001 2.663123e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.704913e+001 2.661957e+001 0.000000e+000 vertex 1.748511e+001 2.663123e+001 0.000000e+000 vertex 1.782319e+001 2.568388e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.782319e+001 2.568388e+001 0.000000e+000 vertex 1.748511e+001 2.663123e+001 0.000000e+000 vertex 1.822984e+001 2.568065e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.782319e+001 2.568388e+001 0.000000e+000 vertex 1.822984e+001 2.568065e+001 0.000000e+000 vertex 1.847389e+001 2.465856e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.847389e+001 2.465856e+001 0.000000e+000 vertex 1.822984e+001 2.568065e+001 0.000000e+000 vertex 1.885456e+001 2.464723e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.847389e+001 2.465856e+001 0.000000e+000 vertex 1.885456e+001 2.464723e+001 0.000000e+000 vertex 1.899094e+001 2.355976e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.899094e+001 2.355976e+001 0.000000e+000 vertex 1.885456e+001 2.464723e+001 0.000000e+000 vertex 1.935016e+001 2.354605e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.899094e+001 2.355976e+001 0.000000e+000 vertex 1.935016e+001 2.354605e+001 0.000000e+000 vertex 1.936620e+001 2.240483e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.936620e+001 2.240483e+001 0.000000e+000 vertex 1.935016e+001 2.354605e+001 0.000000e+000 vertex 1.970942e+001 2.239316e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.936620e+001 2.240483e+001 0.000000e+000 vertex 1.970942e+001 2.239316e+001 0.000000e+000 vertex 1.959375e+001 2.121197e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.959375e+001 2.121197e+001 0.000000e+000 vertex 1.970942e+001 2.239316e+001 0.000000e+000 vertex 1.992709e+001 2.120537e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.959375e+001 2.121197e+001 0.000000e+000 vertex 1.992709e+001 2.120537e+001 0.000000e+000 vertex 1.967000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.967000e+001 2.000000e+001 0.000000e+000 vertex 1.992709e+001 2.120537e+001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.967000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 1.967000e+001 3.300002e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 3.300002e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 4.269451e+000 3.874954e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 3.556890e+000 5.585663e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 2.879864e+000 8.389996e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.255043e+000 1.221891e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 1.697811e+000 1.697811e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 1.221891e+000 2.255043e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 8.389996e-001 2.879864e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 5.585663e-001 3.556890e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 3.874954e-001 4.269451e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 3.300002e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.300002e-001 5.000000e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.300002e-001 5.000000e+000 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 3.300002e-001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 4.062504e-001 2.121197e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.062504e-001 2.121197e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 7.291138e-002 2.120537e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.062504e-001 2.121197e+001 0.000000e+000 vertex 7.291138e-002 2.120537e+001 0.000000e+000 vertex 6.338004e-001 2.240483e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.338004e-001 2.240483e+001 0.000000e+000 vertex 7.291138e-002 2.120537e+001 0.000000e+000 vertex 2.905819e-001 2.239316e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.338004e-001 2.240483e+001 0.000000e+000 vertex 2.905819e-001 2.239316e+001 0.000000e+000 vertex 1.009061e+000 2.355976e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.009061e+000 2.355976e+001 0.000000e+000 vertex 2.905819e-001 2.239316e+001 0.000000e+000 vertex 6.498378e-001 2.354605e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.009061e+000 2.355976e+001 0.000000e+000 vertex 6.498378e-001 2.354605e+001 0.000000e+000 vertex 1.526115e+000 2.465856e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.526115e+000 2.465856e+001 0.000000e+000 vertex 6.498378e-001 2.354605e+001 0.000000e+000 vertex 1.145439e+000 2.464723e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.526115e+000 2.465856e+001 0.000000e+000 vertex 1.145439e+000 2.464723e+001 0.000000e+000 vertex 2.176805e+000 2.568388e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.176805e+000 2.568388e+001 0.000000e+000 vertex 1.145439e+000 2.464723e+001 0.000000e+000 vertex 1.770161e+000 2.568065e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.176805e+000 2.568388e+001 0.000000e+000 vertex 1.770161e+000 2.568065e+001 0.000000e+000 vertex 2.950873e+000 2.661957e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.950873e+000 2.661957e+001 0.000000e+000 vertex 1.770161e+000 2.568065e+001 0.000000e+000 vertex 2.514892e+000 2.663123e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.950873e+000 2.661957e+001 0.000000e+000 vertex 2.514892e+000 2.663123e+001 0.000000e+000 vertex 3.836110e+000 2.745086e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.836110e+000 2.745086e+001 0.000000e+000 vertex 2.514892e+000 2.663123e+001 0.000000e+000 vertex 3.368773e+000 2.748511e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.836110e+000 2.745086e+001 0.000000e+000 vertex 3.368773e+000 2.748511e+001 0.000000e+000 vertex 4.818554e+000 2.816465e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.818554e+000 2.816465e+001 0.000000e+000 vertex 3.368773e+000 2.748511e+001 0.000000e+000 vertex 4.319352e+000 2.822984e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.818554e+000 2.816465e+001 0.000000e+000 vertex 4.319352e+000 2.822984e+001 0.000000e+000 vertex 5.882714e+000 2.874968e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.882714e+000 2.874968e+001 0.000000e+000 vertex 4.319352e+000 2.822984e+001 0.000000e+000 vertex 5.352768e+000 2.885456e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.882714e+000 2.874968e+001 0.000000e+000 vertex 5.352768e+000 2.885456e+001 0.000000e+000 vertex 7.011806e+000 2.919672e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.011806e+000 2.919672e+001 0.000000e+000 vertex 5.352768e+000 2.885456e+001 0.000000e+000 vertex 6.453951e+000 2.935016e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.011806e+000 2.919672e+001 0.000000e+000 vertex 6.453951e+000 2.935016e+001 0.000000e+000 vertex 8.188023e+000 2.949872e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.188023e+000 2.949872e+001 0.000000e+000 vertex 6.453951e+000 2.935016e+001 0.000000e+000 vertex 7.606843e+000 2.970942e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.188023e+000 2.949872e+001 0.000000e+000 vertex 7.606843e+000 2.970942e+001 0.000000e+000 vertex 9.392816e+000 2.965092e+001 0.000000e+000 endloop endfacet facet normal 9.991899e-001 4.024415e-002 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 2.000000e+001 vertex 2.000000e+001 2.000000e+001 6.938894e-015 vertex 1.992709e+001 2.120537e+001 6.938894e-015 endloop endfacet facet normal 9.967556e-001 8.048830e-002 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 2.000000e+001 vertex 1.992709e+001 2.120537e+001 6.938894e-015 vertex 1.992709e+001 2.120537e+001 2.000000e+001 endloop endfacet facet normal 9.870538e-001 1.603898e-001 0.000000e+000 outer loop vertex 1.992709e+001 2.120537e+001 2.000000e+001 vertex 1.992709e+001 2.120537e+001 6.938894e-015 vertex 1.970942e+001 2.239316e+001 6.938894e-015 endloop endfacet facet normal 9.797863e-001 2.000470e-001 0.000000e+000 outer loop vertex 1.992709e+001 2.120537e+001 2.000000e+001 vertex 1.970942e+001 2.239316e+001 6.938894e-015 vertex 1.970942e+001 2.239316e+001 2.000000e+001 endloop endfacet facet normal 9.605242e-001 2.781965e-001 0.000000e+000 outer loop vertex 1.970942e+001 2.239316e+001 2.000000e+001 vertex 1.970942e+001 2.239316e+001 6.938894e-015 vertex 1.935016e+001 2.354605e+001 6.938894e-015 endloop endfacet facet normal 9.485295e-001 3.166887e-001 0.000000e+000 outer loop vertex 1.970942e+001 2.239316e+001 2.000000e+001 vertex 1.935016e+001 2.354605e+001 6.938894e-015 vertex 1.935016e+001 2.354605e+001 2.000000e+001 endloop endfacet facet normal 9.199880e-001 3.919466e-001 0.000000e+000 outer loop vertex 1.935016e+001 2.354605e+001 2.000000e+001 vertex 1.935016e+001 2.354605e+001 6.938894e-015 vertex 1.885456e+001 2.464723e+001 6.938894e-015 endloop endfacet facet normal 9.034411e-001 4.287122e-001 0.000000e+000 outer loop vertex 1.935016e+001 2.354605e+001 2.000000e+001 vertex 1.885456e+001 2.464723e+001 6.938894e-015 vertex 1.885456e+001 2.464723e+001 2.000000e+001 endloop endfacet facet normal 8.660363e-001 4.999811e-001 0.000000e+000 outer loop vertex 1.885456e+001 2.464723e+001 2.000000e+001 vertex 1.885456e+001 2.464723e+001 6.938894e-015 vertex 1.822984e+001 2.568065e+001 6.938894e-015 endloop endfacet facet normal 8.451784e-001 5.344843e-001 0.000000e+000 outer loop vertex 1.885456e+001 2.464723e+001 2.000000e+001 vertex 1.822984e+001 2.568065e+001 6.938894e-015 vertex 1.822984e+001 2.568065e+001 2.000000e+001 endloop endfacet facet normal 7.994559e-001 6.007248e-001 0.000000e+000 outer loop vertex 1.822984e+001 2.568065e+001 2.000000e+001 vertex 1.822984e+001 2.568065e+001 6.938894e-015 vertex 1.748511e+001 2.663123e+001 6.938894e-015 endloop endfacet facet normal 7.745912e-001 6.324623e-001 0.000000e+000 outer loop vertex 1.822984e+001 2.568065e+001 2.000000e+001 vertex 1.748511e+001 2.663123e+001 6.938894e-015 vertex 1.748511e+001 2.663123e+001 2.000000e+001 endloop endfacet facet normal 7.212176e-001 6.927086e-001 0.000000e+000 outer loop vertex 1.748511e+001 2.663123e+001 2.000000e+001 vertex 1.748511e+001 2.663123e+001 6.938894e-015 vertex 1.663123e+001 2.748511e+001 6.938894e-015 endloop endfacet facet normal 6.927086e-001 7.212176e-001 0.000000e+000 outer loop vertex 1.748511e+001 2.663123e+001 2.000000e+001 vertex 1.663123e+001 2.748511e+001 6.938894e-015 vertex 1.663123e+001 2.748511e+001 2.000000e+001 endloop endfacet facet normal 6.324623e-001 7.745912e-001 0.000000e+000 outer loop vertex 1.663123e+001 2.748511e+001 2.000000e+001 vertex 1.663123e+001 2.748511e+001 6.938894e-015 vertex 1.568065e+001 2.822984e+001 6.938894e-015 endloop endfacet facet normal 6.007248e-001 7.994559e-001 0.000000e+000 outer loop vertex 1.663123e+001 2.748511e+001 2.000000e+001 vertex 1.568065e+001 2.822984e+001 6.938894e-015 vertex 1.568065e+001 2.822984e+001 2.000000e+001 endloop endfacet facet normal 5.344843e-001 8.451784e-001 0.000000e+000 outer loop vertex 1.568065e+001 2.822984e+001 2.000000e+001 vertex 1.568065e+001 2.822984e+001 6.938894e-015 vertex 1.464723e+001 2.885456e+001 6.938894e-015 endloop endfacet facet normal 4.999811e-001 8.660363e-001 0.000000e+000 outer loop vertex 1.568065e+001 2.822984e+001 2.000000e+001 vertex 1.464723e+001 2.885456e+001 6.938894e-015 vertex 1.464723e+001 2.885456e+001 2.000000e+001 endloop endfacet facet normal 4.287122e-001 9.034411e-001 0.000000e+000 outer loop vertex 1.464723e+001 2.885456e+001 2.000000e+001 vertex 1.464723e+001 2.885456e+001 6.938894e-015 vertex 1.354605e+001 2.935016e+001 6.938894e-015 endloop endfacet facet normal 3.919466e-001 9.199880e-001 0.000000e+000 outer loop vertex 1.464723e+001 2.885456e+001 2.000000e+001 vertex 1.354605e+001 2.935016e+001 6.938894e-015 vertex 1.354605e+001 2.935016e+001 2.000000e+001 endloop endfacet facet normal 3.166887e-001 9.485295e-001 0.000000e+000 outer loop vertex 1.354605e+001 2.935016e+001 2.000000e+001 vertex 1.354605e+001 2.935016e+001 6.938894e-015 vertex 1.239316e+001 2.970942e+001 6.938894e-015 endloop endfacet facet normal 2.781965e-001 9.605242e-001 0.000000e+000 outer loop vertex 1.354605e+001 2.935016e+001 2.000000e+001 vertex 1.239316e+001 2.970942e+001 6.938894e-015 vertex 1.239316e+001 2.970942e+001 2.000000e+001 endloop endfacet facet normal 2.000470e-001 9.797863e-001 0.000000e+000 outer loop vertex 1.239316e+001 2.970942e+001 2.000000e+001 vertex 1.239316e+001 2.970942e+001 6.938894e-015 vertex 1.120537e+001 2.992709e+001 6.938894e-015 endloop endfacet facet normal 1.603898e-001 9.870538e-001 0.000000e+000 outer loop vertex 1.239316e+001 2.970942e+001 2.000000e+001 vertex 1.120537e+001 2.992709e+001 6.938894e-015 vertex 1.120537e+001 2.992709e+001 2.000000e+001 endloop endfacet facet normal 8.048830e-002 9.967556e-001 0.000000e+000 outer loop vertex 1.120537e+001 2.992709e+001 2.000000e+001 vertex 1.120537e+001 2.992709e+001 6.938894e-015 vertex 1.000000e+001 3.000000e+001 6.938894e-015 endloop endfacet facet normal 4.024415e-002 9.991899e-001 0.000000e+000 outer loop vertex 1.120537e+001 2.992709e+001 2.000000e+001 vertex 1.000000e+001 3.000000e+001 6.938894e-015 vertex 1.000000e+001 3.000000e+001 2.000000e+001 endloop endfacet facet normal -4.024415e-002 9.991899e-001 0.000000e+000 outer loop vertex 1.000000e+001 3.000000e+001 2.000000e+001 vertex 1.000000e+001 3.000000e+001 6.938894e-015 vertex 8.794633e+000 2.992709e+001 6.938894e-015 endloop endfacet facet normal -8.048830e-002 9.967556e-001 0.000000e+000 outer loop vertex 1.000000e+001 3.000000e+001 2.000000e+001 vertex 8.794633e+000 2.992709e+001 6.938894e-015 vertex 8.794633e+000 2.992709e+001 2.000000e+001 endloop endfacet facet normal -1.603898e-001 9.870538e-001 0.000000e+000 outer loop vertex 8.794633e+000 2.992709e+001 2.000000e+001 vertex 8.794633e+000 2.992709e+001 6.938894e-015 vertex 7.606843e+000 2.970942e+001 6.938894e-015 endloop endfacet facet normal -2.000470e-001 9.797863e-001 0.000000e+000 outer loop vertex 8.794633e+000 2.992709e+001 2.000000e+001 vertex 7.606843e+000 2.970942e+001 6.938894e-015 vertex 7.606843e+000 2.970942e+001 2.000000e+001 endloop endfacet facet normal -2.781965e-001 9.605242e-001 0.000000e+000 outer loop vertex 7.606843e+000 2.970942e+001 2.000000e+001 vertex 7.606843e+000 2.970942e+001 6.938894e-015 vertex 6.453951e+000 2.935016e+001 6.938894e-015 endloop endfacet facet normal -3.166887e-001 9.485295e-001 0.000000e+000 outer loop vertex 7.606843e+000 2.970942e+001 2.000000e+001 vertex 6.453951e+000 2.935016e+001 6.938894e-015 vertex 6.453951e+000 2.935016e+001 2.000000e+001 endloop endfacet facet normal -3.919466e-001 9.199880e-001 0.000000e+000 outer loop vertex 6.453951e+000 2.935016e+001 2.000000e+001 vertex 6.453951e+000 2.935016e+001 6.938894e-015 vertex 5.352768e+000 2.885456e+001 6.938894e-015 endloop endfacet facet normal -4.287122e-001 9.034411e-001 0.000000e+000 outer loop vertex 6.453951e+000 2.935016e+001 2.000000e+001 vertex 5.352768e+000 2.885456e+001 6.938894e-015 vertex 5.352768e+000 2.885456e+001 2.000000e+001 endloop endfacet facet normal -4.999811e-001 8.660363e-001 0.000000e+000 outer loop vertex 5.352768e+000 2.885456e+001 2.000000e+001 vertex 5.352768e+000 2.885456e+001 6.938894e-015 vertex 4.319352e+000 2.822984e+001 6.938894e-015 endloop endfacet facet normal -5.344843e-001 8.451784e-001 0.000000e+000 outer loop vertex 5.352768e+000 2.885456e+001 2.000000e+001 vertex 4.319352e+000 2.822984e+001 6.938894e-015 vertex 4.319352e+000 2.822984e+001 2.000000e+001 endloop endfacet facet normal -6.007248e-001 7.994559e-001 0.000000e+000 outer loop vertex 4.319352e+000 2.822984e+001 2.000000e+001 vertex 4.319352e+000 2.822984e+001 6.938894e-015 vertex 3.368773e+000 2.748511e+001 6.938894e-015 endloop endfacet facet normal -6.324623e-001 7.745912e-001 0.000000e+000 outer loop vertex 4.319352e+000 2.822984e+001 2.000000e+001 vertex 3.368773e+000 2.748511e+001 6.938894e-015 vertex 3.368773e+000 2.748511e+001 2.000000e+001 endloop endfacet facet normal -6.927086e-001 7.212176e-001 0.000000e+000 outer loop vertex 3.368773e+000 2.748511e+001 2.000000e+001 vertex 3.368773e+000 2.748511e+001 6.938894e-015 vertex 2.514892e+000 2.663123e+001 6.938894e-015 endloop endfacet facet normal -7.212176e-001 6.927086e-001 0.000000e+000 outer loop vertex 3.368773e+000 2.748511e+001 2.000000e+001 vertex 2.514892e+000 2.663123e+001 6.938894e-015 vertex 2.514892e+000 2.663123e+001 2.000000e+001 endloop endfacet facet normal -7.745912e-001 6.324623e-001 0.000000e+000 outer loop vertex 2.514892e+000 2.663123e+001 2.000000e+001 vertex 2.514892e+000 2.663123e+001 6.938894e-015 vertex 1.770161e+000 2.568065e+001 6.938894e-015 endloop endfacet facet normal -7.994559e-001 6.007248e-001 0.000000e+000 outer loop vertex 2.514892e+000 2.663123e+001 2.000000e+001 vertex 1.770161e+000 2.568065e+001 6.938894e-015 vertex 1.770161e+000 2.568065e+001 2.000000e+001 endloop endfacet facet normal -8.451784e-001 5.344843e-001 0.000000e+000 outer loop vertex 1.770161e+000 2.568065e+001 2.000000e+001 vertex 1.770161e+000 2.568065e+001 6.938894e-015 vertex 1.145439e+000 2.464723e+001 6.938894e-015 endloop endfacet facet normal -8.660363e-001 4.999811e-001 0.000000e+000 outer loop vertex 1.770161e+000 2.568065e+001 2.000000e+001 vertex 1.145439e+000 2.464723e+001 6.938894e-015 vertex 1.145439e+000 2.464723e+001 2.000000e+001 endloop endfacet facet normal -9.034411e-001 4.287122e-001 0.000000e+000 outer loop vertex 1.145439e+000 2.464723e+001 2.000000e+001 vertex 1.145439e+000 2.464723e+001 6.938894e-015 vertex 6.498378e-001 2.354605e+001 6.938894e-015 endloop endfacet facet normal -9.199880e-001 3.919466e-001 0.000000e+000 outer loop vertex 1.145439e+000 2.464723e+001 2.000000e+001 vertex 6.498378e-001 2.354605e+001 6.938894e-015 vertex 6.498378e-001 2.354605e+001 2.000000e+001 endloop endfacet facet normal -9.485295e-001 3.166887e-001 0.000000e+000 outer loop vertex 6.498378e-001 2.354605e+001 2.000000e+001 vertex 6.498378e-001 2.354605e+001 6.938894e-015 vertex 2.905819e-001 2.239316e+001 6.938894e-015 endloop endfacet facet normal -9.605242e-001 2.781965e-001 0.000000e+000 outer loop vertex 6.498378e-001 2.354605e+001 2.000000e+001 vertex 2.905819e-001 2.239316e+001 6.938894e-015 vertex 2.905819e-001 2.239316e+001 2.000000e+001 endloop endfacet facet normal -9.797863e-001 2.000470e-001 0.000000e+000 outer loop vertex 2.905819e-001 2.239316e+001 2.000000e+001 vertex 2.905819e-001 2.239316e+001 6.938894e-015 vertex 7.291138e-002 2.120537e+001 6.938894e-015 endloop endfacet facet normal -9.870538e-001 1.603898e-001 0.000000e+000 outer loop vertex 2.905819e-001 2.239316e+001 2.000000e+001 vertex 7.291138e-002 2.120537e+001 6.938894e-015 vertex 7.291138e-002 2.120537e+001 2.000000e+001 endloop endfacet facet normal -9.967556e-001 8.048830e-002 0.000000e+000 outer loop vertex 7.291138e-002 2.120537e+001 2.000000e+001 vertex 7.291138e-002 2.120537e+001 6.938894e-015 vertex 0.000000e+000 2.000000e+001 6.938894e-015 endloop endfacet facet normal -9.991899e-001 4.024415e-002 0.000000e+000 outer loop vertex 7.291138e-002 2.120537e+001 2.000000e+001 vertex 0.000000e+000 2.000000e+001 6.938894e-015 vertex 0.000000e+000 2.000000e+001 2.000000e+001 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000000e+001 vertex 0.000000e+000 2.000000e+001 2.000000e+001 vertex 0.000000e+000 5.000000e+000 6.938894e-015 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 6.938894e-015 vertex 0.000000e+000 2.000000e+001 2.000000e+001 vertex 0.000000e+000 2.000000e+001 6.938894e-015 endloop endfacet facet normal -9.986320e-001 -5.228807e-002 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000000e+001 vertex 0.000000e+000 5.000000e+000 6.938894e-015 vertex 6.155763e-002 4.217827e+000 6.938894e-015 endloop endfacet facet normal -9.945168e-001 -1.045761e-001 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000000e+001 vertex 6.155763e-002 4.217827e+000 6.938894e-015 vertex 6.155763e-002 4.217827e+000 2.000000e+001 endloop endfacet facet normal -9.781576e-001 -2.078648e-001 0.000000e+000 outer loop vertex 6.155763e-002 4.217827e+000 2.000000e+001 vertex 6.155763e-002 4.217827e+000 6.938894e-015 vertex 2.447171e-001 3.454915e+000 6.938894e-015 endloop endfacet facet normal -9.659134e-001 -2.588654e-001 0.000000e+000 outer loop vertex 6.155763e-002 4.217827e+000 2.000000e+001 vertex 2.447171e-001 3.454915e+000 6.938894e-015 vertex 2.447171e-001 3.454915e+000 2.000000e+001 endloop endfacet facet normal -9.335976e-001 -3.583232e-001 0.000000e+000 outer loop vertex 2.447171e-001 3.454915e+000 2.000000e+001 vertex 2.447171e-001 3.454915e+000 6.938894e-015 vertex 5.449671e-001 2.730047e+000 6.938894e-015 endloop endfacet facet normal -9.135259e-001 -4.067805e-001 0.000000e+000 outer loop vertex 2.447171e-001 3.454915e+000 2.000000e+001 vertex 5.449671e-001 2.730047e+000 6.938894e-015 vertex 5.449671e-001 2.730047e+000 2.000000e+001 endloop endfacet facet normal -8.660493e-001 -4.999585e-001 0.000000e+000 outer loop vertex 5.449671e-001 2.730047e+000 2.000000e+001 vertex 5.449671e-001 2.730047e+000 6.938894e-015 vertex 9.549148e-001 2.061074e+000 6.938894e-015 endloop endfacet facet normal -8.386444e-001 -5.446792e-001 0.000000e+000 outer loop vertex 5.449671e-001 2.730047e+000 2.000000e+001 vertex 9.549148e-001 2.061074e+000 6.938894e-015 vertex 9.549148e-001 2.061074e+000 2.000000e+001 endloop endfacet facet normal -7.771761e-001 -6.292831e-001 0.000000e+000 outer loop vertex 9.549148e-001 2.061074e+000 2.000000e+001 vertex 9.549148e-001 2.061074e+000 6.938894e-015 vertex 1.464466e+000 1.464466e+000 6.938894e-015 endloop endfacet facet normal -7.431127e-001 -6.691663e-001 0.000000e+000 outer loop vertex 9.549148e-001 2.061074e+000 2.000000e+001 vertex 1.464466e+000 1.464466e+000 6.938894e-015 vertex 1.464466e+000 1.464466e+000 2.000000e+001 endloop endfacet facet normal -6.691663e-001 -7.431127e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 2.000000e+001 vertex 1.464466e+000 1.464466e+000 6.938894e-015 vertex 2.061074e+000 9.549148e-001 6.938894e-015 endloop endfacet facet normal -6.292831e-001 -7.771761e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 2.000000e+001 vertex 2.061074e+000 9.549148e-001 6.938894e-015 vertex 2.061074e+000 9.549148e-001 2.000000e+001 endloop endfacet facet normal -5.446792e-001 -8.386444e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549148e-001 2.000000e+001 vertex 2.061074e+000 9.549148e-001 6.938894e-015 vertex 2.730047e+000 5.449671e-001 6.938894e-015 endloop endfacet facet normal -4.999585e-001 -8.660493e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549148e-001 2.000000e+001 vertex 2.730047e+000 5.449671e-001 6.938894e-015 vertex 2.730047e+000 5.449671e-001 2.000000e+001 endloop endfacet facet normal -4.067805e-001 -9.135259e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449671e-001 2.000000e+001 vertex 2.730047e+000 5.449671e-001 6.938894e-015 vertex 3.454915e+000 2.447171e-001 6.938894e-015 endloop endfacet facet normal -3.583232e-001 -9.335976e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449671e-001 2.000000e+001 vertex 3.454915e+000 2.447171e-001 6.938894e-015 vertex 3.454915e+000 2.447171e-001 2.000000e+001 endloop endfacet facet normal -2.588654e-001 -9.659134e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447171e-001 2.000000e+001 vertex 3.454915e+000 2.447171e-001 6.938894e-015 vertex 4.217827e+000 6.155763e-002 6.938894e-015 endloop endfacet facet normal -2.078648e-001 -9.781576e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447171e-001 2.000000e+001 vertex 4.217827e+000 6.155763e-002 6.938894e-015 vertex 4.217827e+000 6.155763e-002 2.000000e+001 endloop endfacet facet normal -1.045761e-001 -9.945168e-001 0.000000e+000 outer loop vertex 4.217827e+000 6.155763e-002 2.000000e+001 vertex 4.217827e+000 6.155763e-002 6.938894e-015 vertex 5.000000e+000 0.000000e+000 6.938894e-015 endloop endfacet facet normal -5.228807e-002 -9.986320e-001 0.000000e+000 outer loop vertex 4.217827e+000 6.155763e-002 2.000000e+001 vertex 5.000000e+000 0.000000e+000 6.938894e-015 vertex 5.000000e+000 0.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 0.000000e+000 2.000000e+001 vertex 5.000000e+000 0.000000e+000 2.000000e+001 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 2.000000e+001 vertex 5.000000e+000 0.000000e+000 6.938894e-015 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 2.000000e+001 vertex 2.000000e+001 0.000000e+000 2.000000e+001 vertex 2.000000e+001 2.000000e+001 6.938894e-015 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 6.938894e-015 vertex 2.000000e+001 0.000000e+000 2.000000e+001 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 9.991238e-001 -4.185114e-002 0.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 2.000000e+001 vertex 3.300002e-001 2.000000e+001 6.938894e-015 vertex 4.062504e-001 2.121197e+001 6.938894e-015 endloop endfacet facet normal 9.964908e-001 -8.370229e-002 0.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 2.000000e+001 vertex 4.062504e-001 2.121197e+001 6.938894e-015 vertex 4.062504e-001 2.121197e+001 2.000000e+001 endloop endfacet facet normal 9.860001e-001 -1.667446e-001 0.000000e+000 outer loop vertex 4.062504e-001 2.121197e+001 2.000000e+001 vertex 4.062504e-001 2.121197e+001 6.938894e-015 vertex 6.338004e-001 2.240483e+001 6.938894e-015 endloop endfacet facet normal 9.781425e-001 -2.079357e-001 0.000000e+000 outer loop vertex 4.062504e-001 2.121197e+001 2.000000e+001 vertex 6.338004e-001 2.240483e+001 6.938894e-015 vertex 6.338004e-001 2.240483e+001 2.000000e+001 endloop endfacet facet normal 9.573266e-001 -2.890083e-001 0.000000e+000 outer loop vertex 6.338004e-001 2.240483e+001 2.000000e+001 vertex 6.338004e-001 2.240483e+001 6.938894e-015 vertex 1.009061e+000 2.355976e+001 6.938894e-015 endloop endfacet facet normal 9.443683e-001 -3.288898e-001 0.000000e+000 outer loop vertex 6.338004e-001 2.240483e+001 2.000000e+001 vertex 1.009061e+000 2.355976e+001 6.938894e-015 vertex 1.009061e+000 2.355976e+001 2.000000e+001 endloop endfacet facet normal 9.135554e-001 -4.067142e-001 0.000000e+000 outer loop vertex 1.009061e+000 2.355976e+001 2.000000e+001 vertex 1.009061e+000 2.355976e+001 6.938894e-015 vertex 1.526115e+000 2.465856e+001 6.938894e-015 endloop endfacet facet normal 8.957008e-001 -4.446571e-001 0.000000e+000 outer loop vertex 1.009061e+000 2.355976e+001 2.000000e+001 vertex 1.526115e+000 2.465856e+001 6.938894e-015 vertex 1.526115e+000 2.465856e+001 2.000000e+001 endloop endfacet facet normal 8.553770e-001 -5.180060e-001 0.000000e+000 outer loop vertex 1.526115e+000 2.465856e+001 2.000000e+001 vertex 1.526115e+000 2.465856e+001 6.938894e-015 vertex 2.176805e+000 2.568388e+001 6.938894e-015 endloop endfacet facet normal 8.329077e-001 -5.534120e-001 0.000000e+000 outer loop vertex 1.526115e+000 2.465856e+001 2.000000e+001 vertex 2.176805e+000 2.568388e+001 6.938894e-015 vertex 2.176805e+000 2.568388e+001 2.000000e+001 endloop endfacet facet normal 7.837087e-001 -6.211286e-001 0.000000e+000 outer loop vertex 2.176805e+000 2.568388e+001 2.000000e+001 vertex 2.176805e+000 2.568388e+001 6.938894e-015 vertex 2.950873e+000 2.661957e+001 6.938894e-015 endloop endfacet facet normal 7.569790e-001 -6.534392e-001 0.000000e+000 outer loop vertex 2.176805e+000 2.568388e+001 2.000000e+001 vertex 2.950873e+000 2.661957e+001 6.938894e-015 vertex 2.950873e+000 2.661957e+001 2.000000e+001 endloop endfacet facet normal 6.996809e-001 -7.144555e-001 0.000000e+000 outer loop vertex 2.950873e+000 2.661957e+001 2.000000e+001 vertex 2.950873e+000 2.661957e+001 6.938894e-015 vertex 3.836110e+000 2.745086e+001 6.938894e-015 endloop endfacet facet normal 6.691124e-001 -7.431613e-001 0.000000e+000 outer loop vertex 2.950873e+000 2.661957e+001 2.000000e+001 vertex 3.836110e+000 2.745086e+001 6.938894e-015 vertex 3.836110e+000 2.745086e+001 2.000000e+001 endloop endfacet facet normal 6.046186e-001 -7.965151e-001 0.000000e+000 outer loop vertex 3.836110e+000 2.745086e+001 2.000000e+001 vertex 3.836110e+000 2.745086e+001 6.938894e-015 vertex 4.818554e+000 2.816465e+001 6.938894e-015 endloop endfacet facet normal 5.706934e-001 -8.211632e-001 0.000000e+000 outer loop vertex 3.836110e+000 2.745086e+001 2.000000e+001 vertex 4.818554e+000 2.816465e+001 6.938894e-015 vertex 4.818554e+000 2.816465e+001 2.000000e+001 endloop endfacet facet normal 5.000212e-001 -8.660132e-001 0.000000e+000 outer loop vertex 4.818554e+000 2.816465e+001 2.000000e+001 vertex 4.818554e+000 2.816465e+001 6.938894e-015 vertex 5.882714e+000 2.874968e+001 6.938894e-015 endloop endfacet facet normal 4.632743e-001 -8.862149e-001 0.000000e+000 outer loop vertex 4.818554e+000 2.816465e+001 2.000000e+001 vertex 5.882714e+000 2.874968e+001 6.938894e-015 vertex 5.882714e+000 2.874968e+001 2.000000e+001 endloop endfacet facet normal 3.875382e-001 -9.218537e-001 0.000000e+000 outer loop vertex 5.882714e+000 2.874968e+001 2.000000e+001 vertex 5.882714e+000 2.874968e+001 6.938894e-015 vertex 7.011806e+000 2.919672e+001 6.938894e-015 endloop endfacet facet normal 3.485490e-001 -9.372905e-001 0.000000e+000 outer loop vertex 5.882714e+000 2.874968e+001 2.000000e+001 vertex 7.011806e+000 2.919672e+001 6.938894e-015 vertex 7.011806e+000 2.919672e+001 2.000000e+001 endloop endfacet facet normal 2.689435e-001 -9.631560e-001 0.000000e+000 outer loop vertex 7.011806e+000 2.919672e+001 2.000000e+001 vertex 7.011806e+000 2.919672e+001 6.938894e-015 vertex 8.188023e+000 2.949872e+001 6.938894e-015 endloop endfacet facet normal 2.283270e-001 -9.735845e-001 0.000000e+000 outer loop vertex 7.011806e+000 2.919672e+001 2.000000e+001 vertex 8.188023e+000 2.949872e+001 6.938894e-015 vertex 8.188023e+000 2.949872e+001 2.000000e+001 endloop endfacet facet normal 1.461073e-001 -9.892687e-001 0.000000e+000 outer loop vertex 8.188023e+000 2.949872e+001 2.000000e+001 vertex 8.188023e+000 2.949872e+001 6.938894e-015 vertex 9.392816e+000 2.965092e+001 6.938894e-015 endloop endfacet facet normal 1.045041e-001 -9.945245e-001 0.000000e+000 outer loop vertex 8.188023e+000 2.949872e+001 2.000000e+001 vertex 9.392816e+000 2.965092e+001 6.938894e-015 vertex 9.392816e+000 2.965092e+001 2.000000e+001 endloop endfacet facet normal 2.096695e-002 -9.997802e-001 0.000000e+000 outer loop vertex 9.392816e+000 2.965092e+001 2.000000e+001 vertex 9.392816e+000 2.965092e+001 6.938894e-015 vertex 1.060718e+001 2.965092e+001 6.938894e-015 endloop endfacet facet normal -2.096695e-002 -9.997802e-001 0.000000e+000 outer loop vertex 9.392816e+000 2.965092e+001 2.000000e+001 vertex 1.060718e+001 2.965092e+001 6.938894e-015 vertex 1.060718e+001 2.965092e+001 2.000000e+001 endloop endfacet facet normal -1.045041e-001 -9.945245e-001 0.000000e+000 outer loop vertex 1.060718e+001 2.965092e+001 2.000000e+001 vertex 1.060718e+001 2.965092e+001 6.938894e-015 vertex 1.181198e+001 2.949872e+001 6.938894e-015 endloop endfacet facet normal -1.461073e-001 -9.892687e-001 0.000000e+000 outer loop vertex 1.060718e+001 2.965092e+001 2.000000e+001 vertex 1.181198e+001 2.949872e+001 6.938894e-015 vertex 1.181198e+001 2.949872e+001 2.000000e+001 endloop endfacet facet normal -2.283270e-001 -9.735845e-001 0.000000e+000 outer loop vertex 1.181198e+001 2.949872e+001 2.000000e+001 vertex 1.181198e+001 2.949872e+001 6.938894e-015 vertex 1.298819e+001 2.919672e+001 6.938894e-015 endloop endfacet facet normal -2.689435e-001 -9.631560e-001 0.000000e+000 outer loop vertex 1.181198e+001 2.949872e+001 2.000000e+001 vertex 1.298819e+001 2.919672e+001 6.938894e-015 vertex 1.298819e+001 2.919672e+001 2.000000e+001 endloop endfacet facet normal -3.485490e-001 -9.372905e-001 0.000000e+000 outer loop vertex 1.298819e+001 2.919672e+001 2.000000e+001 vertex 1.298819e+001 2.919672e+001 6.938894e-015 vertex 1.411729e+001 2.874968e+001 6.938894e-015 endloop endfacet facet normal -3.875382e-001 -9.218537e-001 0.000000e+000 outer loop vertex 1.298819e+001 2.919672e+001 2.000000e+001 vertex 1.411729e+001 2.874968e+001 6.938894e-015 vertex 1.411729e+001 2.874968e+001 2.000000e+001 endloop endfacet facet normal -4.632743e-001 -8.862149e-001 0.000000e+000 outer loop vertex 1.411729e+001 2.874968e+001 2.000000e+001 vertex 1.411729e+001 2.874968e+001 6.938894e-015 vertex 1.518144e+001 2.816465e+001 6.938894e-015 endloop endfacet facet normal -5.000212e-001 -8.660132e-001 0.000000e+000 outer loop vertex 1.411729e+001 2.874968e+001 2.000000e+001 vertex 1.518144e+001 2.816465e+001 6.938894e-015 vertex 1.518144e+001 2.816465e+001 2.000000e+001 endloop endfacet facet normal -5.706934e-001 -8.211632e-001 0.000000e+000 outer loop vertex 1.518144e+001 2.816465e+001 2.000000e+001 vertex 1.518144e+001 2.816465e+001 6.938894e-015 vertex 1.616389e+001 2.745086e+001 6.938894e-015 endloop endfacet facet normal -6.046186e-001 -7.965151e-001 0.000000e+000 outer loop vertex 1.518144e+001 2.816465e+001 2.000000e+001 vertex 1.616389e+001 2.745086e+001 6.938894e-015 vertex 1.616389e+001 2.745086e+001 2.000000e+001 endloop endfacet facet normal -6.691124e-001 -7.431613e-001 0.000000e+000 outer loop vertex 1.616389e+001 2.745086e+001 2.000000e+001 vertex 1.616389e+001 2.745086e+001 6.938894e-015 vertex 1.704913e+001 2.661957e+001 6.938894e-015 endloop endfacet facet normal -6.996809e-001 -7.144555e-001 0.000000e+000 outer loop vertex 1.616389e+001 2.745086e+001 2.000000e+001 vertex 1.704913e+001 2.661957e+001 6.938894e-015 vertex 1.704913e+001 2.661957e+001 2.000000e+001 endloop endfacet facet normal -7.569790e-001 -6.534392e-001 0.000000e+000 outer loop vertex 1.704913e+001 2.661957e+001 2.000000e+001 vertex 1.704913e+001 2.661957e+001 6.938894e-015 vertex 1.782319e+001 2.568388e+001 6.938894e-015 endloop endfacet facet normal -7.837087e-001 -6.211286e-001 0.000000e+000 outer loop vertex 1.704913e+001 2.661957e+001 2.000000e+001 vertex 1.782319e+001 2.568388e+001 6.938894e-015 vertex 1.782319e+001 2.568388e+001 2.000000e+001 endloop endfacet facet normal -8.329077e-001 -5.534120e-001 0.000000e+000 outer loop vertex 1.782319e+001 2.568388e+001 2.000000e+001 vertex 1.782319e+001 2.568388e+001 6.938894e-015 vertex 1.847389e+001 2.465856e+001 6.938894e-015 endloop endfacet facet normal -8.553770e-001 -5.180060e-001 0.000000e+000 outer loop vertex 1.782319e+001 2.568388e+001 2.000000e+001 vertex 1.847389e+001 2.465856e+001 6.938894e-015 vertex 1.847389e+001 2.465856e+001 2.000000e+001 endloop endfacet facet normal -8.957008e-001 -4.446571e-001 0.000000e+000 outer loop vertex 1.847389e+001 2.465856e+001 2.000000e+001 vertex 1.847389e+001 2.465856e+001 6.938894e-015 vertex 1.899094e+001 2.355976e+001 6.938894e-015 endloop endfacet facet normal -9.135554e-001 -4.067142e-001 0.000000e+000 outer loop vertex 1.847389e+001 2.465856e+001 2.000000e+001 vertex 1.899094e+001 2.355976e+001 6.938894e-015 vertex 1.899094e+001 2.355976e+001 2.000000e+001 endloop endfacet facet normal -9.443683e-001 -3.288898e-001 0.000000e+000 outer loop vertex 1.899094e+001 2.355976e+001 2.000000e+001 vertex 1.899094e+001 2.355976e+001 6.938894e-015 vertex 1.936620e+001 2.240483e+001 6.938894e-015 endloop endfacet facet normal -9.573266e-001 -2.890083e-001 0.000000e+000 outer loop vertex 1.899094e+001 2.355976e+001 2.000000e+001 vertex 1.936620e+001 2.240483e+001 6.938894e-015 vertex 1.936620e+001 2.240483e+001 2.000000e+001 endloop endfacet facet normal -9.781425e-001 -2.079357e-001 0.000000e+000 outer loop vertex 1.936620e+001 2.240483e+001 2.000000e+001 vertex 1.936620e+001 2.240483e+001 6.938894e-015 vertex 1.959375e+001 2.121197e+001 6.938894e-015 endloop endfacet facet normal -9.860001e-001 -1.667446e-001 0.000000e+000 outer loop vertex 1.936620e+001 2.240483e+001 2.000000e+001 vertex 1.959375e+001 2.121197e+001 6.938894e-015 vertex 1.959375e+001 2.121197e+001 2.000000e+001 endloop endfacet facet normal -9.964908e-001 -8.370229e-002 0.000000e+000 outer loop vertex 1.959375e+001 2.121197e+001 2.000000e+001 vertex 1.959375e+001 2.121197e+001 6.938894e-015 vertex 1.967000e+001 2.000000e+001 6.938894e-015 endloop endfacet facet normal -9.991238e-001 -4.185114e-002 0.000000e+000 outer loop vertex 1.959375e+001 2.121197e+001 2.000000e+001 vertex 1.967000e+001 2.000000e+001 6.938894e-015 vertex 1.967000e+001 2.000000e+001 2.000000e+001 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 2.000000e+001 vertex 3.300002e-001 5.000000e+000 2.000000e+001 vertex 3.300002e-001 2.000000e+001 6.938894e-015 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.300002e-001 2.000000e+001 6.938894e-015 vertex 3.300002e-001 5.000000e+000 2.000000e+001 vertex 3.300002e-001 5.000000e+000 6.938894e-015 endloop endfacet facet normal 5.228807e-002 9.986320e-001 0.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 2.000000e+001 vertex 5.000000e+000 3.300002e-001 6.938894e-015 vertex 4.269451e+000 3.874954e-001 6.938894e-015 endloop endfacet facet normal 1.045761e-001 9.945168e-001 0.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 2.000000e+001 vertex 4.269451e+000 3.874954e-001 6.938894e-015 vertex 4.269451e+000 3.874954e-001 2.000000e+001 endloop endfacet facet normal 2.078648e-001 9.781576e-001 0.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 2.000000e+001 vertex 4.269451e+000 3.874954e-001 6.938894e-015 vertex 3.556890e+000 5.585663e-001 6.938894e-015 endloop endfacet facet normal 2.588654e-001 9.659134e-001 0.000000e+000 outer loop vertex 4.269451e+000 3.874954e-001 2.000000e+001 vertex 3.556890e+000 5.585663e-001 6.938894e-015 vertex 3.556890e+000 5.585663e-001 2.000000e+001 endloop endfacet facet normal 3.583232e-001 9.335976e-001 0.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 2.000000e+001 vertex 3.556890e+000 5.585663e-001 6.938894e-015 vertex 2.879864e+000 8.389996e-001 6.938894e-015 endloop endfacet facet normal 4.067805e-001 9.135259e-001 0.000000e+000 outer loop vertex 3.556890e+000 5.585663e-001 2.000000e+001 vertex 2.879864e+000 8.389996e-001 6.938894e-015 vertex 2.879864e+000 8.389996e-001 2.000000e+001 endloop endfacet facet normal 4.999585e-001 8.660493e-001 0.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 2.000000e+001 vertex 2.879864e+000 8.389996e-001 6.938894e-015 vertex 2.255043e+000 1.221891e+000 6.938894e-015 endloop endfacet facet normal 5.446792e-001 8.386444e-001 0.000000e+000 outer loop vertex 2.879864e+000 8.389996e-001 2.000000e+001 vertex 2.255043e+000 1.221891e+000 6.938894e-015 vertex 2.255043e+000 1.221891e+000 2.000000e+001 endloop endfacet facet normal 6.292831e-001 7.771761e-001 0.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 2.000000e+001 vertex 2.255043e+000 1.221891e+000 6.938894e-015 vertex 1.697811e+000 1.697811e+000 6.938894e-015 endloop endfacet facet normal 6.691663e-001 7.431127e-001 0.000000e+000 outer loop vertex 2.255043e+000 1.221891e+000 2.000000e+001 vertex 1.697811e+000 1.697811e+000 6.938894e-015 vertex 1.697811e+000 1.697811e+000 2.000000e+001 endloop endfacet facet normal 7.431127e-001 6.691663e-001 0.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 2.000000e+001 vertex 1.697811e+000 1.697811e+000 6.938894e-015 vertex 1.221891e+000 2.255043e+000 6.938894e-015 endloop endfacet facet normal 7.771761e-001 6.292831e-001 0.000000e+000 outer loop vertex 1.697811e+000 1.697811e+000 2.000000e+001 vertex 1.221891e+000 2.255043e+000 6.938894e-015 vertex 1.221891e+000 2.255043e+000 2.000000e+001 endloop endfacet facet normal 8.386444e-001 5.446792e-001 0.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 2.000000e+001 vertex 1.221891e+000 2.255043e+000 6.938894e-015 vertex 8.389996e-001 2.879864e+000 6.938894e-015 endloop endfacet facet normal 8.660493e-001 4.999585e-001 0.000000e+000 outer loop vertex 1.221891e+000 2.255043e+000 2.000000e+001 vertex 8.389996e-001 2.879864e+000 6.938894e-015 vertex 8.389996e-001 2.879864e+000 2.000000e+001 endloop endfacet facet normal 9.135259e-001 4.067805e-001 0.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 2.000000e+001 vertex 8.389996e-001 2.879864e+000 6.938894e-015 vertex 5.585663e-001 3.556890e+000 6.938894e-015 endloop endfacet facet normal 9.335976e-001 3.583232e-001 0.000000e+000 outer loop vertex 8.389996e-001 2.879864e+000 2.000000e+001 vertex 5.585663e-001 3.556890e+000 6.938894e-015 vertex 5.585663e-001 3.556890e+000 2.000000e+001 endloop endfacet facet normal 9.659134e-001 2.588654e-001 0.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 2.000000e+001 vertex 5.585663e-001 3.556890e+000 6.938894e-015 vertex 3.874954e-001 4.269451e+000 6.938894e-015 endloop endfacet facet normal 9.781576e-001 2.078648e-001 0.000000e+000 outer loop vertex 5.585663e-001 3.556890e+000 2.000000e+001 vertex 3.874954e-001 4.269451e+000 6.938894e-015 vertex 3.874954e-001 4.269451e+000 2.000000e+001 endloop endfacet facet normal 9.945168e-001 1.045761e-001 0.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 2.000000e+001 vertex 3.874954e-001 4.269451e+000 6.938894e-015 vertex 3.300002e-001 5.000000e+000 6.938894e-015 endloop endfacet facet normal 9.986320e-001 5.228807e-002 0.000000e+000 outer loop vertex 3.874954e-001 4.269451e+000 2.000000e+001 vertex 3.300002e-001 5.000000e+000 6.938894e-015 vertex 3.300002e-001 5.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 2.000000e+001 vertex 1.967000e+001 3.300002e-001 2.000000e+001 vertex 5.000000e+000 3.300002e-001 6.938894e-015 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 3.300002e-001 6.938894e-015 vertex 1.967000e+001 3.300002e-001 2.000000e+001 vertex 1.967000e+001 3.300002e-001 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 2.000000e+001 vertex 1.967000e+001 2.000000e+001 2.000000e+001 vertex 1.967000e+001 3.300002e-001 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.967000e+001 3.300002e-001 0.000000e+000 vertex 1.967000e+001 2.000000e+001 2.000000e+001 vertex 1.967000e+001 2.000000e+001 6.938894e-015 endloop endfacet endsolidsfact-2011.12.18/calibration/_40x10.STL000066400000000000000000002521571167321211700170120ustar00rootroot00000000000000solid _40x10 facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.286803e+001 2.957990e+001 1.200000e+001 vertex 1.173648e+001 2.984808e+001 1.200000e+001 vertex 1.115715e+001 2.953001e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.115715e+001 2.953001e+001 1.200000e+001 vertex 1.173648e+001 2.984808e+001 1.200000e+001 vertex 1.058145e+001 2.998308e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.115715e+001 2.953001e+001 1.200000e+001 vertex 1.058145e+001 2.998308e+001 1.200000e+001 vertex 1.000000e+001 2.960000e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.000000e+001 2.960000e+001 1.200000e+001 vertex 1.058145e+001 2.998308e+001 1.200000e+001 vertex 9.418551e+000 2.998308e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.000000e+001 2.960000e+001 1.200000e+001 vertex 9.418551e+000 2.998308e+001 1.200000e+001 vertex 8.842847e+000 2.953001e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.842847e+000 2.953001e+001 1.200000e+001 vertex 9.418551e+000 2.998308e+001 1.200000e+001 vertex 8.263518e+000 2.984808e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.842847e+000 2.953001e+001 1.200000e+001 vertex 8.263518e+000 2.984808e+001 1.200000e+001 vertex 7.702569e+000 2.932104e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.702569e+000 2.932104e+001 1.200000e+001 vertex 8.263518e+000 2.984808e+001 1.200000e+001 vertex 7.131968e+000 2.957990e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.702569e+000 2.932104e+001 1.200000e+001 vertex 7.131968e+000 2.957990e+001 1.200000e+001 vertex 6.595793e+000 2.897616e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.595793e+000 2.897616e+001 1.200000e+001 vertex 7.131968e+000 2.957990e+001 1.200000e+001 vertex 6.039202e+000 2.918216e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.595793e+000 2.897616e+001 1.200000e+001 vertex 6.039202e+000 2.918216e+001 1.200000e+001 vertex 5.538657e+000 2.850038e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.538657e+000 2.850038e+001 1.200000e+001 vertex 6.039202e+000 2.918216e+001 1.200000e+001 vertex 5.000000e+000 2.866026e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.538657e+000 2.850038e+001 1.200000e+001 vertex 5.000000e+000 2.866026e+001 1.200000e+001 vertex 4.546578e+000 2.790065e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.546578e+000 2.790065e+001 1.200000e+001 vertex 5.000000e+000 2.866026e+001 1.200000e+001 vertex 4.028414e+000 2.802123e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.546578e+000 2.790065e+001 1.200000e+001 vertex 4.028414e+000 2.802123e+001 1.200000e+001 vertex 3.634022e+000 2.718570e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.634022e+000 2.718570e+001 1.200000e+001 vertex 4.028414e+000 2.802123e+001 1.200000e+001 vertex 3.137583e+000 2.727374e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.634022e+000 2.718570e+001 1.200000e+001 vertex 3.137583e+000 2.727374e+001 1.200000e+001 vertex 2.814297e+000 2.636598e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.814297e+000 2.636598e+001 1.200000e+001 vertex 3.137583e+000 2.727374e+001 1.200000e+001 vertex 2.339556e+000 2.642788e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.814297e+000 2.636598e+001 1.200000e+001 vertex 2.339556e+000 2.642788e+001 1.200000e+001 vertex 2.099355e+000 2.545342e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.099355e+000 2.545342e+001 1.200000e+001 vertex 2.339556e+000 2.642788e+001 1.200000e+001 vertex 1.645122e+000 2.549509e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.099355e+000 2.545342e+001 1.200000e+001 vertex 1.645122e+000 2.549509e+001 1.200000e+001 vertex 1.499622e+000 2.446134e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.499622e+000 2.446134e+001 1.200000e+001 vertex 1.645122e+000 2.549509e+001 1.200000e+001 vertex 1.063674e+000 2.448799e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.499622e+000 2.446134e+001 1.200000e+001 vertex 1.063674e+000 2.448799e+001 1.200000e+001 vertex 1.023844e+000 2.340421e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.023844e+000 2.340421e+001 1.200000e+001 vertex 1.063674e+000 2.448799e+001 1.200000e+001 vertex 6.030733e-001 2.342020e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.023844e+000 2.340421e+001 1.200000e+001 vertex 6.030733e-001 2.342020e+001 1.200000e+001 vertex 6.789584e-001 2.229743e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.789584e-001 2.229743e+001 1.200000e+001 vertex 6.030733e-001 2.342020e+001 1.200000e+001 vertex 2.695508e-001 2.230616e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.789584e-001 2.229743e+001 1.200000e+001 vertex 2.695508e-001 2.230616e+001 1.200000e+001 vertex 4.699947e-001 2.115715e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.699947e-001 2.115715e+001 1.200000e+001 vertex 2.695508e-001 2.230616e+001 1.200000e+001 vertex 6.761588e-002 2.116093e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.699947e-001 2.115715e+001 1.200000e+001 vertex 6.761588e-002 2.116093e+001 1.200000e+001 vertex 3.999993e-001 2.000000e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 1.200000e+001 vertex 6.761588e-002 2.116093e+001 1.200000e+001 vertex 0.000000e+000 2.000000e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 1.200000e+001 vertex 0.000000e+000 2.000000e+001 1.200000e+001 vertex 3.999993e-001 5.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.999993e-001 5.000000e+000 1.200000e+001 vertex 0.000000e+000 2.000000e+001 1.200000e+001 vertex 0.000000e+000 5.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.999993e-001 5.000000e+000 1.200000e+001 vertex 0.000000e+000 5.000000e+000 1.200000e+001 vertex 4.566330e-001 4.280401e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 1.200000e+001 vertex 0.000000e+000 5.000000e+000 1.200000e+001 vertex 6.155763e-002 4.217827e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 1.200000e+001 vertex 6.155763e-002 4.217827e+000 1.200000e+001 vertex 6.251400e-001 3.578522e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 1.200000e+001 vertex 6.155763e-002 4.217827e+000 1.200000e+001 vertex 2.447171e-001 3.454915e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 1.200000e+001 vertex 2.447171e-001 3.454915e+000 1.200000e+001 vertex 9.013694e-001 2.911644e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 1.200000e+001 vertex 2.447171e-001 3.454915e+000 1.200000e+001 vertex 5.449671e-001 2.730047e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 1.200000e+001 vertex 5.449671e-001 2.730047e+000 1.200000e+001 vertex 1.278522e+000 2.296187e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 1.200000e+001 vertex 5.449671e-001 2.730047e+000 1.200000e+001 vertex 9.549148e-001 2.061074e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 1.200000e+001 vertex 9.549148e-001 2.061074e+000 1.200000e+001 vertex 1.747308e+000 1.747308e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 1.200000e+001 vertex 9.549148e-001 2.061074e+000 1.200000e+001 vertex 1.464466e+000 1.464466e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 1.200000e+001 vertex 1.464466e+000 1.464466e+000 1.200000e+001 vertex 2.296187e+000 1.278522e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 1.200000e+001 vertex 1.464466e+000 1.464466e+000 1.200000e+001 vertex 2.061074e+000 9.549148e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 1.200000e+001 vertex 2.061074e+000 9.549148e-001 1.200000e+001 vertex 2.911644e+000 9.013694e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 1.200000e+001 vertex 2.061074e+000 9.549148e-001 1.200000e+001 vertex 2.730047e+000 5.449671e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 1.200000e+001 vertex 2.730047e+000 5.449671e-001 1.200000e+001 vertex 3.578522e+000 6.251400e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 1.200000e+001 vertex 2.730047e+000 5.449671e-001 1.200000e+001 vertex 3.454915e+000 2.447171e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 1.200000e+001 vertex 3.454915e+000 2.447171e-001 1.200000e+001 vertex 4.280401e+000 4.566330e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 1.200000e+001 vertex 3.454915e+000 2.447171e-001 1.200000e+001 vertex 4.217827e+000 6.155763e-002 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 1.200000e+001 vertex 4.217827e+000 6.155763e-002 1.200000e+001 vertex 5.000000e+000 3.999993e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 1.200000e+001 vertex 4.217827e+000 6.155763e-002 1.200000e+001 vertex 5.000000e+000 0.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 1.200000e+001 vertex 5.000000e+000 0.000000e+000 1.200000e+001 vertex 1.960000e+001 3.999993e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 1.200000e+001 vertex 5.000000e+000 0.000000e+000 1.200000e+001 vertex 2.000000e+001 0.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 1.200000e+001 vertex 2.000000e+001 0.000000e+000 1.200000e+001 vertex 1.960000e+001 2.000000e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.960000e+001 2.000000e+001 1.200000e+001 vertex 2.000000e+001 0.000000e+000 1.200000e+001 vertex 2.000000e+001 2.000000e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.960000e+001 2.000000e+001 1.200000e+001 vertex 2.000000e+001 2.000000e+001 1.200000e+001 vertex 1.953001e+001 2.115715e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.953001e+001 2.115715e+001 1.200000e+001 vertex 2.000000e+001 2.000000e+001 1.200000e+001 vertex 1.993238e+001 2.116093e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.953001e+001 2.115715e+001 1.200000e+001 vertex 1.993238e+001 2.116093e+001 1.200000e+001 vertex 1.932104e+001 2.229743e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.932104e+001 2.229743e+001 1.200000e+001 vertex 1.993238e+001 2.116093e+001 1.200000e+001 vertex 1.973045e+001 2.230616e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.932104e+001 2.229743e+001 1.200000e+001 vertex 1.973045e+001 2.230616e+001 1.200000e+001 vertex 1.897616e+001 2.340421e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.897616e+001 2.340421e+001 1.200000e+001 vertex 1.973045e+001 2.230616e+001 1.200000e+001 vertex 1.939693e+001 2.342020e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.897616e+001 2.340421e+001 1.200000e+001 vertex 1.939693e+001 2.342020e+001 1.200000e+001 vertex 1.850038e+001 2.446134e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.850038e+001 2.446134e+001 1.200000e+001 vertex 1.939693e+001 2.342020e+001 1.200000e+001 vertex 1.893633e+001 2.448799e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.850038e+001 2.446134e+001 1.200000e+001 vertex 1.893633e+001 2.448799e+001 1.200000e+001 vertex 1.790065e+001 2.545342e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.790065e+001 2.545342e+001 1.200000e+001 vertex 1.893633e+001 2.448799e+001 1.200000e+001 vertex 1.835488e+001 2.549509e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.790065e+001 2.545342e+001 1.200000e+001 vertex 1.835488e+001 2.549509e+001 1.200000e+001 vertex 1.718570e+001 2.636598e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.718570e+001 2.636598e+001 1.200000e+001 vertex 1.835488e+001 2.549509e+001 1.200000e+001 vertex 1.766044e+001 2.642788e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.718570e+001 2.636598e+001 1.200000e+001 vertex 1.766044e+001 2.642788e+001 1.200000e+001 vertex 1.636598e+001 2.718570e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.636598e+001 2.718570e+001 1.200000e+001 vertex 1.766044e+001 2.642788e+001 1.200000e+001 vertex 1.686242e+001 2.727374e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.636598e+001 2.718570e+001 1.200000e+001 vertex 1.686242e+001 2.727374e+001 1.200000e+001 vertex 1.545342e+001 2.790065e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.545342e+001 2.790065e+001 1.200000e+001 vertex 1.686242e+001 2.727374e+001 1.200000e+001 vertex 1.597159e+001 2.802123e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.545342e+001 2.790065e+001 1.200000e+001 vertex 1.597159e+001 2.802123e+001 1.200000e+001 vertex 1.446134e+001 2.850038e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.446134e+001 2.850038e+001 1.200000e+001 vertex 1.597159e+001 2.802123e+001 1.200000e+001 vertex 1.500000e+001 2.866026e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.446134e+001 2.850038e+001 1.200000e+001 vertex 1.500000e+001 2.866026e+001 1.200000e+001 vertex 1.340421e+001 2.897616e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.340421e+001 2.897616e+001 1.200000e+001 vertex 1.500000e+001 2.866026e+001 1.200000e+001 vertex 1.396080e+001 2.918216e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.340421e+001 2.897616e+001 1.200000e+001 vertex 1.396080e+001 2.918216e+001 1.200000e+001 vertex 1.229743e+001 2.932104e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.229743e+001 2.932104e+001 1.200000e+001 vertex 1.396080e+001 2.918216e+001 1.200000e+001 vertex 1.286803e+001 2.957990e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.229743e+001 2.932104e+001 1.200000e+001 vertex 1.286803e+001 2.957990e+001 1.200000e+001 vertex 1.115715e+001 2.953001e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 8.842847e+000 2.953001e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.842847e+000 2.953001e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.842847e+000 2.953001e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 1.000000e+001 2.960000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.000000e+001 2.960000e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.000000e+001 2.960000e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 1.115715e+001 2.953001e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.115715e+001 2.953001e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.115715e+001 2.953001e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.229743e+001 2.932104e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.229743e+001 2.932104e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.229743e+001 2.932104e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.340421e+001 2.897616e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.340421e+001 2.897616e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.340421e+001 2.897616e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.446134e+001 2.850038e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.446134e+001 2.850038e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.446134e+001 2.850038e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.545342e+001 2.790065e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.545342e+001 2.790065e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.545342e+001 2.790065e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.636598e+001 2.718570e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.636598e+001 2.718570e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.636598e+001 2.718570e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.718570e+001 2.636598e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.718570e+001 2.636598e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.718570e+001 2.636598e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.790065e+001 2.545342e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.790065e+001 2.545342e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.790065e+001 2.545342e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.850038e+001 2.446134e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.850038e+001 2.446134e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.850038e+001 2.446134e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.897616e+001 2.340421e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.897616e+001 2.340421e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.897616e+001 2.340421e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.932104e+001 2.229743e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.932104e+001 2.229743e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.932104e+001 2.229743e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.953001e+001 2.115715e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.953001e+001 2.115715e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.953001e+001 2.115715e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 1.960000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.960000e+001 2.000000e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.960000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 1.960000e+001 3.999993e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 3.999993e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 4.280401e+000 4.566330e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 3.578522e+000 6.251400e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 2.911644e+000 9.013694e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.296187e+000 1.278522e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 1.747308e+000 1.747308e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 1.278522e+000 2.296187e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 9.013694e-001 2.911644e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 6.251400e-001 3.578522e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 4.566330e-001 4.280401e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 3.999993e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.999993e-001 5.000000e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.999993e-001 5.000000e+000 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 3.999993e-001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 4.699947e-001 2.115715e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.699947e-001 2.115715e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.699947e-001 2.115715e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 6.789584e-001 2.229743e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.789584e-001 2.229743e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.789584e-001 2.229743e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 1.023844e+000 2.340421e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.023844e+000 2.340421e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.023844e+000 2.340421e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 1.499622e+000 2.446134e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.499622e+000 2.446134e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.499622e+000 2.446134e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 2.099355e+000 2.545342e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.099355e+000 2.545342e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.099355e+000 2.545342e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 2.814297e+000 2.636598e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.814297e+000 2.636598e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.814297e+000 2.636598e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 3.634022e+000 2.718570e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.634022e+000 2.718570e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.634022e+000 2.718570e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 4.546578e+000 2.790065e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.546578e+000 2.790065e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.546578e+000 2.790065e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 5.538657e+000 2.850038e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.538657e+000 2.850038e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.538657e+000 2.850038e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 6.595793e+000 2.897616e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.595793e+000 2.897616e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.595793e+000 2.897616e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 7.702569e+000 2.932104e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.702569e+000 2.932104e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.702569e+000 2.932104e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 8.842847e+000 2.953001e+001 0.000000e+000 endloop endfacet facet normal 9.992487e-001 3.875592e-002 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 1.200000e+001 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 endloop endfacet facet normal 9.969914e-001 7.751183e-002 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 1.200000e+001 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 1.200000e+001 endloop endfacet facet normal 9.879928e-001 1.544996e-001 0.000000e+000 outer loop vertex 1.993238e+001 2.116093e+001 1.200000e+001 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 endloop endfacet facet normal 9.812515e-001 1.927314e-001 0.000000e+000 outer loop vertex 1.993238e+001 2.116093e+001 1.200000e+001 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 1.200000e+001 endloop endfacet facet normal 9.633761e-001 2.681538e-001 0.000000e+000 outer loop vertex 1.973045e+001 2.230616e+001 1.200000e+001 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 endloop endfacet facet normal 9.522419e-001 3.053445e-001 0.000000e+000 outer loop vertex 1.973045e+001 2.230616e+001 1.200000e+001 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 1.200000e+001 endloop endfacet facet normal 9.257313e-001 3.781818e-001 0.000000e+000 outer loop vertex 1.939693e+001 2.342020e+001 1.200000e+001 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 endloop endfacet facet normal 9.103549e-001 4.138285e-001 0.000000e+000 outer loop vertex 1.939693e+001 2.342020e+001 1.200000e+001 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 1.200000e+001 endloop endfacet facet normal 8.755676e-001 4.830956e-001 0.000000e+000 outer loop vertex 1.893633e+001 2.448799e+001 1.200000e+001 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 endloop endfacet facet normal 8.561568e-001 5.167161e-001 0.000000e+000 outer loop vertex 1.893633e+001 2.448799e+001 1.200000e+001 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 1.200000e+001 endloop endfacet facet normal 8.135634e-001 5.814762e-001 0.000000e+000 outer loop vertex 1.835488e+001 2.549509e+001 1.200000e+001 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 endloop endfacet facet normal 7.903807e-001 6.126159e-001 0.000000e+000 outer loop vertex 1.835488e+001 2.549509e+001 1.200000e+001 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 1.200000e+001 endloop endfacet facet normal 7.405571e-001 6.719934e-001 0.000000e+000 outer loop vertex 1.766044e+001 2.642788e+001 1.200000e+001 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 endloop endfacet facet normal 7.139161e-001 7.002313e-001 0.000000e+000 outer loop vertex 1.766044e+001 2.642788e+001 1.200000e+001 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 1.200000e+001 endloop endfacet facet normal 6.575360e-001 7.534231e-001 0.000000e+000 outer loop vertex 1.686242e+001 2.727374e+001 1.200000e+001 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 endloop endfacet facet normal 6.277969e-001 7.783771e-001 0.000000e+000 outer loop vertex 1.686242e+001 2.727374e+001 1.200000e+001 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 1.200000e+001 endloop endfacet facet normal 5.656230e-001 8.246640e-001 0.000000e+000 outer loop vertex 1.597159e+001 2.802123e+001 1.200000e+001 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 endloop endfacet facet normal 5.331879e-001 8.459968e-001 0.000000e+000 outer loop vertex 1.597159e+001 2.802123e+001 1.200000e+001 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 1.200000e+001 endloop endfacet facet normal 4.660608e-001 8.847528e-001 0.000000e+000 outer loop vertex 1.500000e+001 2.866026e+001 1.200000e+001 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 endloop endfacet facet normal 4.313685e-001 9.021758e-001 0.000000e+000 outer loop vertex 1.500000e+001 2.866026e+001 1.200000e+001 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 1.200000e+001 endloop endfacet facet normal 3.601959e-001 9.328767e-001 0.000000e+000 outer loop vertex 1.396080e+001 2.918216e+001 1.200000e+001 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 endloop endfacet facet normal 3.237155e-001 9.461545e-001 0.000000e+000 outer loop vertex 1.396080e+001 2.918216e+001 1.200000e+001 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 1.200000e+001 endloop endfacet facet normal 2.494600e-001 9.683850e-001 0.000000e+000 outer loop vertex 1.286803e+001 2.957990e+001 1.200000e+001 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 endloop endfacet facet normal 2.116849e-001 9.773380e-001 0.000000e+000 outer loop vertex 1.286803e+001 2.957990e+001 1.200000e+001 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 1.200000e+001 endloop endfacet facet normal 1.353506e-001 9.907978e-001 0.000000e+000 outer loop vertex 1.173648e+001 2.984808e+001 1.200000e+001 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 endloop endfacet facet normal 9.679149e-002 9.953047e-001 0.000000e+000 outer loop vertex 1.173648e+001 2.984808e+001 1.200000e+001 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 1.200000e+001 endloop endfacet facet normal 1.941080e-002 9.998116e-001 0.000000e+000 outer loop vertex 1.058145e+001 2.998308e+001 1.200000e+001 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 endloop endfacet facet normal -1.941080e-002 9.998116e-001 0.000000e+000 outer loop vertex 1.058145e+001 2.998308e+001 1.200000e+001 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 1.200000e+001 endloop endfacet facet normal -9.679149e-002 9.953047e-001 0.000000e+000 outer loop vertex 9.418551e+000 2.998308e+001 1.200000e+001 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 0.000000e+000 endloop endfacet facet normal -1.353506e-001 9.907978e-001 0.000000e+000 outer loop vertex 9.418551e+000 2.998308e+001 1.200000e+001 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 1.200000e+001 endloop endfacet facet normal -2.116849e-001 9.773380e-001 0.000000e+000 outer loop vertex 8.263518e+000 2.984808e+001 1.200000e+001 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 0.000000e+000 endloop endfacet facet normal -2.494600e-001 9.683850e-001 0.000000e+000 outer loop vertex 8.263518e+000 2.984808e+001 1.200000e+001 vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 1.200000e+001 endloop endfacet facet normal -3.237155e-001 9.461545e-001 0.000000e+000 outer loop vertex 7.131968e+000 2.957990e+001 1.200000e+001 vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 endloop endfacet facet normal -3.601959e-001 9.328767e-001 0.000000e+000 outer loop vertex 7.131968e+000 2.957990e+001 1.200000e+001 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 1.200000e+001 endloop endfacet facet normal -4.313685e-001 9.021758e-001 0.000000e+000 outer loop vertex 6.039202e+000 2.918216e+001 1.200000e+001 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 endloop endfacet facet normal -4.660608e-001 8.847528e-001 0.000000e+000 outer loop vertex 6.039202e+000 2.918216e+001 1.200000e+001 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 1.200000e+001 endloop endfacet facet normal -5.331879e-001 8.459968e-001 0.000000e+000 outer loop vertex 5.000000e+000 2.866026e+001 1.200000e+001 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 endloop endfacet facet normal -5.656230e-001 8.246640e-001 0.000000e+000 outer loop vertex 5.000000e+000 2.866026e+001 1.200000e+001 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 1.200000e+001 endloop endfacet facet normal -6.277969e-001 7.783771e-001 0.000000e+000 outer loop vertex 4.028414e+000 2.802123e+001 1.200000e+001 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 endloop endfacet facet normal -6.575360e-001 7.534231e-001 0.000000e+000 outer loop vertex 4.028414e+000 2.802123e+001 1.200000e+001 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 1.200000e+001 endloop endfacet facet normal -7.139161e-001 7.002313e-001 0.000000e+000 outer loop vertex 3.137583e+000 2.727374e+001 1.200000e+001 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 endloop endfacet facet normal -7.405571e-001 6.719934e-001 0.000000e+000 outer loop vertex 3.137583e+000 2.727374e+001 1.200000e+001 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 1.200000e+001 endloop endfacet facet normal -7.903807e-001 6.126159e-001 0.000000e+000 outer loop vertex 2.339556e+000 2.642788e+001 1.200000e+001 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 endloop endfacet facet normal -8.135634e-001 5.814762e-001 0.000000e+000 outer loop vertex 2.339556e+000 2.642788e+001 1.200000e+001 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 1.200000e+001 endloop endfacet facet normal -8.561568e-001 5.167161e-001 0.000000e+000 outer loop vertex 1.645122e+000 2.549509e+001 1.200000e+001 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 endloop endfacet facet normal -8.755676e-001 4.830956e-001 0.000000e+000 outer loop vertex 1.645122e+000 2.549509e+001 1.200000e+001 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 1.200000e+001 endloop endfacet facet normal -9.103549e-001 4.138285e-001 0.000000e+000 outer loop vertex 1.063674e+000 2.448799e+001 1.200000e+001 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 endloop endfacet facet normal -9.257313e-001 3.781818e-001 0.000000e+000 outer loop vertex 1.063674e+000 2.448799e+001 1.200000e+001 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 1.200000e+001 endloop endfacet facet normal -9.522419e-001 3.053445e-001 0.000000e+000 outer loop vertex 6.030733e-001 2.342020e+001 1.200000e+001 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 endloop endfacet facet normal -9.633761e-001 2.681538e-001 0.000000e+000 outer loop vertex 6.030733e-001 2.342020e+001 1.200000e+001 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 1.200000e+001 endloop endfacet facet normal -9.812515e-001 1.927314e-001 0.000000e+000 outer loop vertex 2.695508e-001 2.230616e+001 1.200000e+001 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 endloop endfacet facet normal -9.879928e-001 1.544996e-001 0.000000e+000 outer loop vertex 2.695508e-001 2.230616e+001 1.200000e+001 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 1.200000e+001 endloop endfacet facet normal -9.969914e-001 7.751183e-002 0.000000e+000 outer loop vertex 6.761588e-002 2.116093e+001 1.200000e+001 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal -9.992487e-001 3.875592e-002 0.000000e+000 outer loop vertex 6.761588e-002 2.116093e+001 1.200000e+001 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 1.200000e+001 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 1.200000e+001 vertex 0.000000e+000 2.000000e+001 1.200000e+001 vertex 0.000000e+000 5.000000e+000 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 0.000000e+000 2.000000e+001 1.200000e+001 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal -9.986320e-001 -5.228807e-002 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 1.200000e+001 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 endloop endfacet facet normal -9.945168e-001 -1.045761e-001 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 1.200000e+001 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 1.200000e+001 endloop endfacet facet normal -9.781576e-001 -2.078648e-001 0.000000e+000 outer loop vertex 6.155763e-002 4.217827e+000 1.200000e+001 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 endloop endfacet facet normal -9.659134e-001 -2.588654e-001 0.000000e+000 outer loop vertex 6.155763e-002 4.217827e+000 1.200000e+001 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 1.200000e+001 endloop endfacet facet normal -9.335976e-001 -3.583232e-001 0.000000e+000 outer loop vertex 2.447171e-001 3.454915e+000 1.200000e+001 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 endloop endfacet facet normal -9.135259e-001 -4.067805e-001 0.000000e+000 outer loop vertex 2.447171e-001 3.454915e+000 1.200000e+001 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 1.200000e+001 endloop endfacet facet normal -8.660493e-001 -4.999585e-001 0.000000e+000 outer loop vertex 5.449671e-001 2.730047e+000 1.200000e+001 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 endloop endfacet facet normal -8.386444e-001 -5.446792e-001 0.000000e+000 outer loop vertex 5.449671e-001 2.730047e+000 1.200000e+001 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 1.200000e+001 endloop endfacet facet normal -7.771761e-001 -6.292831e-001 0.000000e+000 outer loop vertex 9.549148e-001 2.061074e+000 1.200000e+001 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 endloop endfacet facet normal -7.431127e-001 -6.691663e-001 0.000000e+000 outer loop vertex 9.549148e-001 2.061074e+000 1.200000e+001 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 1.200000e+001 endloop endfacet facet normal -6.691663e-001 -7.431127e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 1.200000e+001 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 endloop endfacet facet normal -6.292831e-001 -7.771761e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 1.200000e+001 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 2.061074e+000 9.549148e-001 1.200000e+001 endloop endfacet facet normal -5.446792e-001 -8.386444e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549148e-001 1.200000e+001 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 endloop endfacet facet normal -4.999585e-001 -8.660493e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549148e-001 1.200000e+001 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 1.200000e+001 endloop endfacet facet normal -4.067805e-001 -9.135259e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449671e-001 1.200000e+001 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 endloop endfacet facet normal -3.583232e-001 -9.335976e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449671e-001 1.200000e+001 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 1.200000e+001 endloop endfacet facet normal -2.588654e-001 -9.659134e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447171e-001 1.200000e+001 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 endloop endfacet facet normal -2.078648e-001 -9.781576e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447171e-001 1.200000e+001 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 4.217827e+000 6.155763e-002 1.200000e+001 endloop endfacet facet normal -1.045761e-001 -9.945168e-001 0.000000e+000 outer loop vertex 4.217827e+000 6.155763e-002 1.200000e+001 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal -5.228807e-002 -9.986320e-001 0.000000e+000 outer loop vertex 4.217827e+000 6.155763e-002 1.200000e+001 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 0.000000e+000 1.200000e+001 vertex 5.000000e+000 0.000000e+000 1.200000e+001 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 1.200000e+001 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 1.200000e+001 vertex 2.000000e+001 0.000000e+000 1.200000e+001 vertex 2.000000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 1.200000e+001 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 9.991899e-001 -4.024415e-002 0.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 1.200000e+001 vertex 3.999993e-001 2.000000e+001 0.000000e+000 vertex 4.699947e-001 2.115715e+001 0.000000e+000 endloop endfacet facet normal 9.967556e-001 -8.048830e-002 0.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 1.200000e+001 vertex 4.699947e-001 2.115715e+001 0.000000e+000 vertex 4.699947e-001 2.115715e+001 1.200000e+001 endloop endfacet facet normal 9.870538e-001 -1.603898e-001 0.000000e+000 outer loop vertex 4.699947e-001 2.115715e+001 1.200000e+001 vertex 4.699947e-001 2.115715e+001 0.000000e+000 vertex 6.789584e-001 2.229743e+001 0.000000e+000 endloop endfacet facet normal 9.797863e-001 -2.000470e-001 0.000000e+000 outer loop vertex 4.699947e-001 2.115715e+001 1.200000e+001 vertex 6.789584e-001 2.229743e+001 0.000000e+000 vertex 6.789584e-001 2.229743e+001 1.200000e+001 endloop endfacet facet normal 9.605242e-001 -2.781965e-001 0.000000e+000 outer loop vertex 6.789584e-001 2.229743e+001 1.200000e+001 vertex 6.789584e-001 2.229743e+001 0.000000e+000 vertex 1.023844e+000 2.340421e+001 0.000000e+000 endloop endfacet facet normal 9.485295e-001 -3.166887e-001 0.000000e+000 outer loop vertex 6.789584e-001 2.229743e+001 1.200000e+001 vertex 1.023844e+000 2.340421e+001 0.000000e+000 vertex 1.023844e+000 2.340421e+001 1.200000e+001 endloop endfacet facet normal 9.199880e-001 -3.919466e-001 0.000000e+000 outer loop vertex 1.023844e+000 2.340421e+001 1.200000e+001 vertex 1.023844e+000 2.340421e+001 0.000000e+000 vertex 1.499622e+000 2.446134e+001 0.000000e+000 endloop endfacet facet normal 9.034411e-001 -4.287122e-001 0.000000e+000 outer loop vertex 1.023844e+000 2.340421e+001 1.200000e+001 vertex 1.499622e+000 2.446134e+001 0.000000e+000 vertex 1.499622e+000 2.446134e+001 1.200000e+001 endloop endfacet facet normal 8.660363e-001 -4.999811e-001 0.000000e+000 outer loop vertex 1.499622e+000 2.446134e+001 1.200000e+001 vertex 1.499622e+000 2.446134e+001 0.000000e+000 vertex 2.099355e+000 2.545342e+001 0.000000e+000 endloop endfacet facet normal 8.451784e-001 -5.344843e-001 0.000000e+000 outer loop vertex 1.499622e+000 2.446134e+001 1.200000e+001 vertex 2.099355e+000 2.545342e+001 0.000000e+000 vertex 2.099355e+000 2.545342e+001 1.200000e+001 endloop endfacet facet normal 7.994559e-001 -6.007248e-001 0.000000e+000 outer loop vertex 2.099355e+000 2.545342e+001 1.200000e+001 vertex 2.099355e+000 2.545342e+001 0.000000e+000 vertex 2.814297e+000 2.636598e+001 0.000000e+000 endloop endfacet facet normal 7.745912e-001 -6.324623e-001 0.000000e+000 outer loop vertex 2.099355e+000 2.545342e+001 1.200000e+001 vertex 2.814297e+000 2.636598e+001 0.000000e+000 vertex 2.814297e+000 2.636598e+001 1.200000e+001 endloop endfacet facet normal 7.212176e-001 -6.927086e-001 0.000000e+000 outer loop vertex 2.814297e+000 2.636598e+001 1.200000e+001 vertex 2.814297e+000 2.636598e+001 0.000000e+000 vertex 3.634022e+000 2.718570e+001 0.000000e+000 endloop endfacet facet normal 6.927086e-001 -7.212176e-001 0.000000e+000 outer loop vertex 2.814297e+000 2.636598e+001 1.200000e+001 vertex 3.634022e+000 2.718570e+001 0.000000e+000 vertex 3.634022e+000 2.718570e+001 1.200000e+001 endloop endfacet facet normal 6.324623e-001 -7.745912e-001 0.000000e+000 outer loop vertex 3.634022e+000 2.718570e+001 1.200000e+001 vertex 3.634022e+000 2.718570e+001 0.000000e+000 vertex 4.546578e+000 2.790065e+001 0.000000e+000 endloop endfacet facet normal 6.007248e-001 -7.994559e-001 0.000000e+000 outer loop vertex 3.634022e+000 2.718570e+001 1.200000e+001 vertex 4.546578e+000 2.790065e+001 0.000000e+000 vertex 4.546578e+000 2.790065e+001 1.200000e+001 endloop endfacet facet normal 5.344843e-001 -8.451784e-001 0.000000e+000 outer loop vertex 4.546578e+000 2.790065e+001 1.200000e+001 vertex 4.546578e+000 2.790065e+001 0.000000e+000 vertex 5.538657e+000 2.850038e+001 0.000000e+000 endloop endfacet facet normal 4.999811e-001 -8.660363e-001 0.000000e+000 outer loop vertex 4.546578e+000 2.790065e+001 1.200000e+001 vertex 5.538657e+000 2.850038e+001 0.000000e+000 vertex 5.538657e+000 2.850038e+001 1.200000e+001 endloop endfacet facet normal 4.287122e-001 -9.034411e-001 0.000000e+000 outer loop vertex 5.538657e+000 2.850038e+001 1.200000e+001 vertex 5.538657e+000 2.850038e+001 0.000000e+000 vertex 6.595793e+000 2.897616e+001 0.000000e+000 endloop endfacet facet normal 3.919466e-001 -9.199880e-001 0.000000e+000 outer loop vertex 5.538657e+000 2.850038e+001 1.200000e+001 vertex 6.595793e+000 2.897616e+001 0.000000e+000 vertex 6.595793e+000 2.897616e+001 1.200000e+001 endloop endfacet facet normal 3.166887e-001 -9.485295e-001 0.000000e+000 outer loop vertex 6.595793e+000 2.897616e+001 1.200000e+001 vertex 6.595793e+000 2.897616e+001 0.000000e+000 vertex 7.702569e+000 2.932104e+001 0.000000e+000 endloop endfacet facet normal 2.781965e-001 -9.605242e-001 0.000000e+000 outer loop vertex 6.595793e+000 2.897616e+001 1.200000e+001 vertex 7.702569e+000 2.932104e+001 0.000000e+000 vertex 7.702569e+000 2.932104e+001 1.200000e+001 endloop endfacet facet normal 2.000470e-001 -9.797863e-001 0.000000e+000 outer loop vertex 7.702569e+000 2.932104e+001 1.200000e+001 vertex 7.702569e+000 2.932104e+001 0.000000e+000 vertex 8.842847e+000 2.953001e+001 0.000000e+000 endloop endfacet facet normal 1.603898e-001 -9.870538e-001 0.000000e+000 outer loop vertex 7.702569e+000 2.932104e+001 1.200000e+001 vertex 8.842847e+000 2.953001e+001 0.000000e+000 vertex 8.842847e+000 2.953001e+001 1.200000e+001 endloop endfacet facet normal 8.048830e-002 -9.967556e-001 0.000000e+000 outer loop vertex 8.842847e+000 2.953001e+001 1.200000e+001 vertex 8.842847e+000 2.953001e+001 0.000000e+000 vertex 1.000000e+001 2.960000e+001 0.000000e+000 endloop endfacet facet normal 4.024415e-002 -9.991899e-001 0.000000e+000 outer loop vertex 8.842847e+000 2.953001e+001 1.200000e+001 vertex 1.000000e+001 2.960000e+001 0.000000e+000 vertex 1.000000e+001 2.960000e+001 1.200000e+001 endloop endfacet facet normal -4.024415e-002 -9.991899e-001 0.000000e+000 outer loop vertex 1.000000e+001 2.960000e+001 1.200000e+001 vertex 1.000000e+001 2.960000e+001 0.000000e+000 vertex 1.115715e+001 2.953001e+001 0.000000e+000 endloop endfacet facet normal -8.048830e-002 -9.967556e-001 0.000000e+000 outer loop vertex 1.000000e+001 2.960000e+001 1.200000e+001 vertex 1.115715e+001 2.953001e+001 0.000000e+000 vertex 1.115715e+001 2.953001e+001 1.200000e+001 endloop endfacet facet normal -1.603898e-001 -9.870538e-001 0.000000e+000 outer loop vertex 1.115715e+001 2.953001e+001 1.200000e+001 vertex 1.115715e+001 2.953001e+001 0.000000e+000 vertex 1.229743e+001 2.932104e+001 0.000000e+000 endloop endfacet facet normal -2.000470e-001 -9.797863e-001 0.000000e+000 outer loop vertex 1.115715e+001 2.953001e+001 1.200000e+001 vertex 1.229743e+001 2.932104e+001 0.000000e+000 vertex 1.229743e+001 2.932104e+001 1.200000e+001 endloop endfacet facet normal -2.781965e-001 -9.605242e-001 0.000000e+000 outer loop vertex 1.229743e+001 2.932104e+001 1.200000e+001 vertex 1.229743e+001 2.932104e+001 0.000000e+000 vertex 1.340421e+001 2.897616e+001 0.000000e+000 endloop endfacet facet normal -3.166887e-001 -9.485295e-001 0.000000e+000 outer loop vertex 1.229743e+001 2.932104e+001 1.200000e+001 vertex 1.340421e+001 2.897616e+001 0.000000e+000 vertex 1.340421e+001 2.897616e+001 1.200000e+001 endloop endfacet facet normal -3.919466e-001 -9.199880e-001 0.000000e+000 outer loop vertex 1.340421e+001 2.897616e+001 1.200000e+001 vertex 1.340421e+001 2.897616e+001 0.000000e+000 vertex 1.446134e+001 2.850038e+001 0.000000e+000 endloop endfacet facet normal -4.287122e-001 -9.034411e-001 0.000000e+000 outer loop vertex 1.340421e+001 2.897616e+001 1.200000e+001 vertex 1.446134e+001 2.850038e+001 0.000000e+000 vertex 1.446134e+001 2.850038e+001 1.200000e+001 endloop endfacet facet normal -4.999811e-001 -8.660363e-001 0.000000e+000 outer loop vertex 1.446134e+001 2.850038e+001 1.200000e+001 vertex 1.446134e+001 2.850038e+001 0.000000e+000 vertex 1.545342e+001 2.790065e+001 0.000000e+000 endloop endfacet facet normal -5.344843e-001 -8.451784e-001 0.000000e+000 outer loop vertex 1.446134e+001 2.850038e+001 1.200000e+001 vertex 1.545342e+001 2.790065e+001 0.000000e+000 vertex 1.545342e+001 2.790065e+001 1.200000e+001 endloop endfacet facet normal -6.007248e-001 -7.994559e-001 0.000000e+000 outer loop vertex 1.545342e+001 2.790065e+001 1.200000e+001 vertex 1.545342e+001 2.790065e+001 0.000000e+000 vertex 1.636598e+001 2.718570e+001 0.000000e+000 endloop endfacet facet normal -6.324623e-001 -7.745912e-001 0.000000e+000 outer loop vertex 1.545342e+001 2.790065e+001 1.200000e+001 vertex 1.636598e+001 2.718570e+001 0.000000e+000 vertex 1.636598e+001 2.718570e+001 1.200000e+001 endloop endfacet facet normal -6.927086e-001 -7.212176e-001 0.000000e+000 outer loop vertex 1.636598e+001 2.718570e+001 1.200000e+001 vertex 1.636598e+001 2.718570e+001 0.000000e+000 vertex 1.718570e+001 2.636598e+001 0.000000e+000 endloop endfacet facet normal -7.212176e-001 -6.927086e-001 0.000000e+000 outer loop vertex 1.636598e+001 2.718570e+001 1.200000e+001 vertex 1.718570e+001 2.636598e+001 0.000000e+000 vertex 1.718570e+001 2.636598e+001 1.200000e+001 endloop endfacet facet normal -7.745912e-001 -6.324623e-001 0.000000e+000 outer loop vertex 1.718570e+001 2.636598e+001 1.200000e+001 vertex 1.718570e+001 2.636598e+001 0.000000e+000 vertex 1.790065e+001 2.545342e+001 0.000000e+000 endloop endfacet facet normal -7.994559e-001 -6.007248e-001 0.000000e+000 outer loop vertex 1.718570e+001 2.636598e+001 1.200000e+001 vertex 1.790065e+001 2.545342e+001 0.000000e+000 vertex 1.790065e+001 2.545342e+001 1.200000e+001 endloop endfacet facet normal -8.451784e-001 -5.344843e-001 0.000000e+000 outer loop vertex 1.790065e+001 2.545342e+001 1.200000e+001 vertex 1.790065e+001 2.545342e+001 0.000000e+000 vertex 1.850038e+001 2.446134e+001 0.000000e+000 endloop endfacet facet normal -8.660363e-001 -4.999811e-001 0.000000e+000 outer loop vertex 1.790065e+001 2.545342e+001 1.200000e+001 vertex 1.850038e+001 2.446134e+001 0.000000e+000 vertex 1.850038e+001 2.446134e+001 1.200000e+001 endloop endfacet facet normal -9.034411e-001 -4.287122e-001 0.000000e+000 outer loop vertex 1.850038e+001 2.446134e+001 1.200000e+001 vertex 1.850038e+001 2.446134e+001 0.000000e+000 vertex 1.897616e+001 2.340421e+001 0.000000e+000 endloop endfacet facet normal -9.199880e-001 -3.919466e-001 0.000000e+000 outer loop vertex 1.850038e+001 2.446134e+001 1.200000e+001 vertex 1.897616e+001 2.340421e+001 0.000000e+000 vertex 1.897616e+001 2.340421e+001 1.200000e+001 endloop endfacet facet normal -9.485295e-001 -3.166887e-001 0.000000e+000 outer loop vertex 1.897616e+001 2.340421e+001 1.200000e+001 vertex 1.897616e+001 2.340421e+001 0.000000e+000 vertex 1.932104e+001 2.229743e+001 0.000000e+000 endloop endfacet facet normal -9.605242e-001 -2.781965e-001 0.000000e+000 outer loop vertex 1.897616e+001 2.340421e+001 1.200000e+001 vertex 1.932104e+001 2.229743e+001 0.000000e+000 vertex 1.932104e+001 2.229743e+001 1.200000e+001 endloop endfacet facet normal -9.797863e-001 -2.000470e-001 0.000000e+000 outer loop vertex 1.932104e+001 2.229743e+001 1.200000e+001 vertex 1.932104e+001 2.229743e+001 0.000000e+000 vertex 1.953001e+001 2.115715e+001 0.000000e+000 endloop endfacet facet normal -9.870538e-001 -1.603898e-001 0.000000e+000 outer loop vertex 1.932104e+001 2.229743e+001 1.200000e+001 vertex 1.953001e+001 2.115715e+001 0.000000e+000 vertex 1.953001e+001 2.115715e+001 1.200000e+001 endloop endfacet facet normal -9.967556e-001 -8.048830e-002 0.000000e+000 outer loop vertex 1.953001e+001 2.115715e+001 1.200000e+001 vertex 1.953001e+001 2.115715e+001 0.000000e+000 vertex 1.960000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal -9.991899e-001 -4.024415e-002 0.000000e+000 outer loop vertex 1.953001e+001 2.115715e+001 1.200000e+001 vertex 1.960000e+001 2.000000e+001 0.000000e+000 vertex 1.960000e+001 2.000000e+001 1.200000e+001 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 1.200000e+001 vertex 3.999993e-001 5.000000e+000 1.200000e+001 vertex 3.999993e-001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 0.000000e+000 vertex 3.999993e-001 5.000000e+000 1.200000e+001 vertex 3.999993e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 5.228807e-002 9.986320e-001 0.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 1.200000e+001 vertex 5.000000e+000 3.999993e-001 0.000000e+000 vertex 4.280401e+000 4.566330e-001 0.000000e+000 endloop endfacet facet normal 1.045761e-001 9.945168e-001 0.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 1.200000e+001 vertex 4.280401e+000 4.566330e-001 0.000000e+000 vertex 4.280401e+000 4.566330e-001 1.200000e+001 endloop endfacet facet normal 2.078648e-001 9.781576e-001 0.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 1.200000e+001 vertex 4.280401e+000 4.566330e-001 0.000000e+000 vertex 3.578522e+000 6.251400e-001 0.000000e+000 endloop endfacet facet normal 2.588654e-001 9.659134e-001 0.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 1.200000e+001 vertex 3.578522e+000 6.251400e-001 0.000000e+000 vertex 3.578522e+000 6.251400e-001 1.200000e+001 endloop endfacet facet normal 3.583232e-001 9.335976e-001 0.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 1.200000e+001 vertex 3.578522e+000 6.251400e-001 0.000000e+000 vertex 2.911644e+000 9.013694e-001 0.000000e+000 endloop endfacet facet normal 4.067805e-001 9.135259e-001 0.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 1.200000e+001 vertex 2.911644e+000 9.013694e-001 0.000000e+000 vertex 2.911644e+000 9.013694e-001 1.200000e+001 endloop endfacet facet normal 4.999585e-001 8.660493e-001 0.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 1.200000e+001 vertex 2.911644e+000 9.013694e-001 0.000000e+000 vertex 2.296187e+000 1.278522e+000 0.000000e+000 endloop endfacet facet normal 5.446792e-001 8.386444e-001 0.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 1.200000e+001 vertex 2.296187e+000 1.278522e+000 0.000000e+000 vertex 2.296187e+000 1.278522e+000 1.200000e+001 endloop endfacet facet normal 6.292831e-001 7.771761e-001 0.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 1.200000e+001 vertex 2.296187e+000 1.278522e+000 0.000000e+000 vertex 1.747308e+000 1.747308e+000 0.000000e+000 endloop endfacet facet normal 6.691663e-001 7.431127e-001 0.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 1.200000e+001 vertex 1.747308e+000 1.747308e+000 0.000000e+000 vertex 1.747308e+000 1.747308e+000 1.200000e+001 endloop endfacet facet normal 7.431127e-001 6.691663e-001 0.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 1.200000e+001 vertex 1.747308e+000 1.747308e+000 0.000000e+000 vertex 1.278522e+000 2.296187e+000 0.000000e+000 endloop endfacet facet normal 7.771761e-001 6.292831e-001 0.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 1.200000e+001 vertex 1.278522e+000 2.296187e+000 0.000000e+000 vertex 1.278522e+000 2.296187e+000 1.200000e+001 endloop endfacet facet normal 8.386444e-001 5.446792e-001 0.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 1.200000e+001 vertex 1.278522e+000 2.296187e+000 0.000000e+000 vertex 9.013694e-001 2.911644e+000 0.000000e+000 endloop endfacet facet normal 8.660493e-001 4.999585e-001 0.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 1.200000e+001 vertex 9.013694e-001 2.911644e+000 0.000000e+000 vertex 9.013694e-001 2.911644e+000 1.200000e+001 endloop endfacet facet normal 9.135259e-001 4.067805e-001 0.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 1.200000e+001 vertex 9.013694e-001 2.911644e+000 0.000000e+000 vertex 6.251400e-001 3.578522e+000 0.000000e+000 endloop endfacet facet normal 9.335976e-001 3.583232e-001 0.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 1.200000e+001 vertex 6.251400e-001 3.578522e+000 0.000000e+000 vertex 6.251400e-001 3.578522e+000 1.200000e+001 endloop endfacet facet normal 9.659134e-001 2.588654e-001 0.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 1.200000e+001 vertex 6.251400e-001 3.578522e+000 0.000000e+000 vertex 4.566330e-001 4.280401e+000 0.000000e+000 endloop endfacet facet normal 9.781576e-001 2.078648e-001 0.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 1.200000e+001 vertex 4.566330e-001 4.280401e+000 0.000000e+000 vertex 4.566330e-001 4.280401e+000 1.200000e+001 endloop endfacet facet normal 9.945168e-001 1.045761e-001 0.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 1.200000e+001 vertex 4.566330e-001 4.280401e+000 0.000000e+000 vertex 3.999993e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 9.986320e-001 5.228807e-002 0.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 1.200000e+001 vertex 3.999993e-001 5.000000e+000 0.000000e+000 vertex 3.999993e-001 5.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 1.200000e+001 vertex 1.960000e+001 3.999993e-001 1.200000e+001 vertex 5.000000e+000 3.999993e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 0.000000e+000 vertex 1.960000e+001 3.999993e-001 1.200000e+001 vertex 1.960000e+001 3.999993e-001 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 1.200000e+001 vertex 1.960000e+001 2.000000e+001 1.200000e+001 vertex 1.960000e+001 3.999993e-001 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 0.000000e+000 vertex 1.960000e+001 2.000000e+001 1.200000e+001 vertex 1.960000e+001 2.000000e+001 0.000000e+000 endloop endfacet endsolidsfact-2011.12.18/calibration/_40x20.STL000066400000000000000000002457211167321211700170120ustar00rootroot00000000000000solid _40x20 facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.239316e+001 2.970942e+001 2.000000e+001 vertex 1.120537e+001 2.992709e+001 2.000000e+001 vertex 1.060279e+001 2.958106e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.060279e+001 2.958106e+001 2.000000e+001 vertex 1.120537e+001 2.992709e+001 2.000000e+001 vertex 1.000000e+001 3.000000e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.060279e+001 2.958106e+001 2.000000e+001 vertex 1.000000e+001 3.000000e+001 2.000000e+001 vertex 9.397210e+000 2.958106e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.397210e+000 2.958106e+001 2.000000e+001 vertex 1.000000e+001 3.000000e+001 2.000000e+001 vertex 8.794633e+000 2.992709e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.397210e+000 2.958106e+001 2.000000e+001 vertex 8.794633e+000 2.992709e+001 2.000000e+001 vertex 8.201139e+000 2.942996e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.201139e+000 2.942996e+001 2.000000e+001 vertex 8.794633e+000 2.992709e+001 2.000000e+001 vertex 7.606843e+000 2.970942e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.201139e+000 2.942996e+001 2.000000e+001 vertex 7.606843e+000 2.970942e+001 2.000000e+001 vertex 7.033437e+000 2.913014e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.033437e+000 2.913014e+001 2.000000e+001 vertex 7.606843e+000 2.970942e+001 2.000000e+001 vertex 6.453951e+000 2.935016e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.033437e+000 2.913014e+001 2.000000e+001 vertex 6.453951e+000 2.935016e+001 2.000000e+001 vertex 5.912519e+000 2.868634e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.912519e+000 2.868634e+001 2.000000e+001 vertex 6.453951e+000 2.935016e+001 2.000000e+001 vertex 5.352768e+000 2.885456e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.912519e+000 2.868634e+001 2.000000e+001 vertex 5.352768e+000 2.885456e+001 2.000000e+001 vertex 4.856062e+000 2.810555e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.856062e+000 2.810555e+001 2.000000e+001 vertex 5.352768e+000 2.885456e+001 2.000000e+001 vertex 4.319352e+000 2.822984e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.856062e+000 2.810555e+001 2.000000e+001 vertex 4.319352e+000 2.822984e+001 2.000000e+001 vertex 3.880729e+000 2.739693e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.880729e+000 2.739693e+001 2.000000e+001 vertex 4.319352e+000 2.822984e+001 2.000000e+001 vertex 3.368773e+000 2.748511e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.880729e+000 2.739693e+001 2.000000e+001 vertex 3.368773e+000 2.748511e+001 2.000000e+001 vertex 3.001901e+000 2.657165e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.001901e+000 2.657165e+001 2.000000e+001 vertex 3.368773e+000 2.748511e+001 2.000000e+001 vertex 2.514892e+000 2.663123e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.001901e+000 2.657165e+001 2.000000e+001 vertex 2.514892e+000 2.663123e+001 2.000000e+001 vertex 2.233437e+000 2.564274e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.233437e+000 2.564274e+001 2.000000e+001 vertex 2.514892e+000 2.663123e+001 2.000000e+001 vertex 1.770161e+000 2.568065e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.233437e+000 2.564274e+001 2.000000e+001 vertex 1.770161e+000 2.568065e+001 2.000000e+001 vertex 1.587456e+000 2.462484e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.587456e+000 2.462484e+001 2.000000e+001 vertex 1.770161e+000 2.568065e+001 2.000000e+001 vertex 1.145439e+000 2.464723e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.587456e+000 2.462484e+001 2.000000e+001 vertex 1.145439e+000 2.464723e+001 2.000000e+001 vertex 1.074146e+000 2.353400e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.074146e+000 2.353400e+001 2.000000e+001 vertex 1.145439e+000 2.464723e+001 2.000000e+001 vertex 6.498378e-001 2.354605e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.074146e+000 2.353400e+001 2.000000e+001 vertex 6.498378e-001 2.354605e+001 2.000000e+001 vertex 7.016016e-001 2.238742e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.016016e-001 2.238742e+001 2.000000e+001 vertex 6.498378e-001 2.354605e+001 2.000000e+001 vertex 2.905819e-001 2.239316e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.016016e-001 2.238742e+001 2.000000e+001 vertex 2.905819e-001 2.239316e+001 2.000000e+001 vertex 4.756991e-001 2.120320e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.756991e-001 2.120320e+001 2.000000e+001 vertex 2.905819e-001 2.239316e+001 2.000000e+001 vertex 7.291138e-002 2.120537e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.756991e-001 2.120320e+001 2.000000e+001 vertex 7.291138e-002 2.120537e+001 2.000000e+001 vertex 3.999993e-001 2.000000e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 2.000000e+001 vertex 7.291138e-002 2.120537e+001 2.000000e+001 vertex 0.000000e+000 2.000000e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 2.000000e+001 vertex 0.000000e+000 2.000000e+001 2.000000e+001 vertex 3.999993e-001 5.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.999993e-001 5.000000e+000 2.000000e+001 vertex 0.000000e+000 2.000000e+001 2.000000e+001 vertex 0.000000e+000 5.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.999993e-001 5.000000e+000 2.000000e+001 vertex 0.000000e+000 5.000000e+000 2.000000e+001 vertex 4.566330e-001 4.280401e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 2.000000e+001 vertex 0.000000e+000 5.000000e+000 2.000000e+001 vertex 6.155763e-002 4.217827e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 2.000000e+001 vertex 6.155763e-002 4.217827e+000 2.000000e+001 vertex 6.251400e-001 3.578522e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 2.000000e+001 vertex 6.155763e-002 4.217827e+000 2.000000e+001 vertex 2.447171e-001 3.454915e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 2.000000e+001 vertex 2.447171e-001 3.454915e+000 2.000000e+001 vertex 9.013694e-001 2.911644e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 2.000000e+001 vertex 2.447171e-001 3.454915e+000 2.000000e+001 vertex 5.449671e-001 2.730047e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 2.000000e+001 vertex 5.449671e-001 2.730047e+000 2.000000e+001 vertex 1.278522e+000 2.296187e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 2.000000e+001 vertex 5.449671e-001 2.730047e+000 2.000000e+001 vertex 9.549148e-001 2.061074e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 2.000000e+001 vertex 9.549148e-001 2.061074e+000 2.000000e+001 vertex 1.747308e+000 1.747308e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 2.000000e+001 vertex 9.549148e-001 2.061074e+000 2.000000e+001 vertex 1.464466e+000 1.464466e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 2.000000e+001 vertex 1.464466e+000 1.464466e+000 2.000000e+001 vertex 2.296187e+000 1.278522e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 2.000000e+001 vertex 1.464466e+000 1.464466e+000 2.000000e+001 vertex 2.061074e+000 9.549148e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 2.000000e+001 vertex 2.061074e+000 9.549148e-001 2.000000e+001 vertex 2.911644e+000 9.013694e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 2.000000e+001 vertex 2.061074e+000 9.549148e-001 2.000000e+001 vertex 2.730047e+000 5.449671e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 2.000000e+001 vertex 2.730047e+000 5.449671e-001 2.000000e+001 vertex 3.578522e+000 6.251400e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 2.000000e+001 vertex 2.730047e+000 5.449671e-001 2.000000e+001 vertex 3.454915e+000 2.447171e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 2.000000e+001 vertex 3.454915e+000 2.447171e-001 2.000000e+001 vertex 4.280401e+000 4.566330e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 2.000000e+001 vertex 3.454915e+000 2.447171e-001 2.000000e+001 vertex 4.217827e+000 6.155763e-002 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 2.000000e+001 vertex 4.217827e+000 6.155763e-002 2.000000e+001 vertex 5.000000e+000 3.999993e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 2.000000e+001 vertex 4.217827e+000 6.155763e-002 2.000000e+001 vertex 5.000000e+000 0.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 2.000000e+001 vertex 5.000000e+000 0.000000e+000 2.000000e+001 vertex 1.960000e+001 3.999993e-001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 2.000000e+001 vertex 5.000000e+000 0.000000e+000 2.000000e+001 vertex 2.000000e+001 0.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 2.000000e+001 vertex 2.000000e+001 0.000000e+000 2.000000e+001 vertex 1.960000e+001 2.000000e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.960000e+001 2.000000e+001 2.000000e+001 vertex 2.000000e+001 0.000000e+000 2.000000e+001 vertex 2.000000e+001 2.000000e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.960000e+001 2.000000e+001 2.000000e+001 vertex 2.000000e+001 2.000000e+001 2.000000e+001 vertex 1.952430e+001 2.120320e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.952430e+001 2.120320e+001 2.000000e+001 vertex 2.000000e+001 2.000000e+001 2.000000e+001 vertex 1.992709e+001 2.120537e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.952430e+001 2.120320e+001 2.000000e+001 vertex 1.992709e+001 2.120537e+001 2.000000e+001 vertex 1.929840e+001 2.238742e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.929840e+001 2.238742e+001 2.000000e+001 vertex 1.992709e+001 2.120537e+001 2.000000e+001 vertex 1.970942e+001 2.239316e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.929840e+001 2.238742e+001 2.000000e+001 vertex 1.970942e+001 2.239316e+001 2.000000e+001 vertex 1.892585e+001 2.353400e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.892585e+001 2.353400e+001 2.000000e+001 vertex 1.970942e+001 2.239316e+001 2.000000e+001 vertex 1.935016e+001 2.354605e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.892585e+001 2.353400e+001 2.000000e+001 vertex 1.935016e+001 2.354605e+001 2.000000e+001 vertex 1.841254e+001 2.462484e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.841254e+001 2.462484e+001 2.000000e+001 vertex 1.935016e+001 2.354605e+001 2.000000e+001 vertex 1.885456e+001 2.464723e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.841254e+001 2.462484e+001 2.000000e+001 vertex 1.885456e+001 2.464723e+001 2.000000e+001 vertex 1.776656e+001 2.564274e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.776656e+001 2.564274e+001 2.000000e+001 vertex 1.885456e+001 2.464723e+001 2.000000e+001 vertex 1.822984e+001 2.568065e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.776656e+001 2.564274e+001 2.000000e+001 vertex 1.822984e+001 2.568065e+001 2.000000e+001 vertex 1.699810e+001 2.657165e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.699810e+001 2.657165e+001 2.000000e+001 vertex 1.822984e+001 2.568065e+001 2.000000e+001 vertex 1.748511e+001 2.663123e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.699810e+001 2.657165e+001 2.000000e+001 vertex 1.748511e+001 2.663123e+001 2.000000e+001 vertex 1.611927e+001 2.739693e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.611927e+001 2.739693e+001 2.000000e+001 vertex 1.748511e+001 2.663123e+001 2.000000e+001 vertex 1.663123e+001 2.748511e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.611927e+001 2.739693e+001 2.000000e+001 vertex 1.663123e+001 2.748511e+001 2.000000e+001 vertex 1.514394e+001 2.810555e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.514394e+001 2.810555e+001 2.000000e+001 vertex 1.663123e+001 2.748511e+001 2.000000e+001 vertex 1.568065e+001 2.822984e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.514394e+001 2.810555e+001 2.000000e+001 vertex 1.568065e+001 2.822984e+001 2.000000e+001 vertex 1.408748e+001 2.868634e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.408748e+001 2.868634e+001 2.000000e+001 vertex 1.568065e+001 2.822984e+001 2.000000e+001 vertex 1.464723e+001 2.885456e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.408748e+001 2.868634e+001 2.000000e+001 vertex 1.464723e+001 2.885456e+001 2.000000e+001 vertex 1.296656e+001 2.913014e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.296656e+001 2.913014e+001 2.000000e+001 vertex 1.464723e+001 2.885456e+001 2.000000e+001 vertex 1.354605e+001 2.935016e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.296656e+001 2.913014e+001 2.000000e+001 vertex 1.354605e+001 2.935016e+001 2.000000e+001 vertex 1.179886e+001 2.942996e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.179886e+001 2.942996e+001 2.000000e+001 vertex 1.354605e+001 2.935016e+001 2.000000e+001 vertex 1.239316e+001 2.970942e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.179886e+001 2.942996e+001 2.000000e+001 vertex 1.239316e+001 2.970942e+001 2.000000e+001 vertex 1.060279e+001 2.958106e+001 2.000000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.606843e+000 2.970942e+001 0.000000e+000 vertex 8.794633e+000 2.992709e+001 0.000000e+000 vertex 9.397210e+000 2.958106e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.397210e+000 2.958106e+001 0.000000e+000 vertex 8.794633e+000 2.992709e+001 0.000000e+000 vertex 1.000000e+001 3.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.397210e+000 2.958106e+001 0.000000e+000 vertex 1.000000e+001 3.000000e+001 0.000000e+000 vertex 1.060279e+001 2.958106e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.060279e+001 2.958106e+001 0.000000e+000 vertex 1.000000e+001 3.000000e+001 0.000000e+000 vertex 1.120537e+001 2.992709e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.060279e+001 2.958106e+001 0.000000e+000 vertex 1.120537e+001 2.992709e+001 0.000000e+000 vertex 1.179886e+001 2.942996e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.179886e+001 2.942996e+001 0.000000e+000 vertex 1.120537e+001 2.992709e+001 0.000000e+000 vertex 1.239316e+001 2.970942e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.179886e+001 2.942996e+001 0.000000e+000 vertex 1.239316e+001 2.970942e+001 0.000000e+000 vertex 1.296656e+001 2.913014e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.296656e+001 2.913014e+001 0.000000e+000 vertex 1.239316e+001 2.970942e+001 0.000000e+000 vertex 1.354605e+001 2.935016e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.296656e+001 2.913014e+001 0.000000e+000 vertex 1.354605e+001 2.935016e+001 0.000000e+000 vertex 1.408748e+001 2.868634e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.408748e+001 2.868634e+001 0.000000e+000 vertex 1.354605e+001 2.935016e+001 0.000000e+000 vertex 1.464723e+001 2.885456e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.408748e+001 2.868634e+001 0.000000e+000 vertex 1.464723e+001 2.885456e+001 0.000000e+000 vertex 1.514394e+001 2.810555e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.514394e+001 2.810555e+001 0.000000e+000 vertex 1.464723e+001 2.885456e+001 0.000000e+000 vertex 1.568065e+001 2.822984e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.514394e+001 2.810555e+001 0.000000e+000 vertex 1.568065e+001 2.822984e+001 0.000000e+000 vertex 1.611927e+001 2.739693e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.611927e+001 2.739693e+001 0.000000e+000 vertex 1.568065e+001 2.822984e+001 0.000000e+000 vertex 1.663123e+001 2.748511e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.611927e+001 2.739693e+001 0.000000e+000 vertex 1.663123e+001 2.748511e+001 0.000000e+000 vertex 1.699810e+001 2.657165e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.699810e+001 2.657165e+001 0.000000e+000 vertex 1.663123e+001 2.748511e+001 0.000000e+000 vertex 1.748511e+001 2.663123e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.699810e+001 2.657165e+001 0.000000e+000 vertex 1.748511e+001 2.663123e+001 0.000000e+000 vertex 1.776656e+001 2.564274e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.776656e+001 2.564274e+001 0.000000e+000 vertex 1.748511e+001 2.663123e+001 0.000000e+000 vertex 1.822984e+001 2.568065e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.776656e+001 2.564274e+001 0.000000e+000 vertex 1.822984e+001 2.568065e+001 0.000000e+000 vertex 1.841254e+001 2.462484e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.841254e+001 2.462484e+001 0.000000e+000 vertex 1.822984e+001 2.568065e+001 0.000000e+000 vertex 1.885456e+001 2.464723e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.841254e+001 2.462484e+001 0.000000e+000 vertex 1.885456e+001 2.464723e+001 0.000000e+000 vertex 1.892585e+001 2.353400e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.892585e+001 2.353400e+001 0.000000e+000 vertex 1.885456e+001 2.464723e+001 0.000000e+000 vertex 1.935016e+001 2.354605e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.892585e+001 2.353400e+001 0.000000e+000 vertex 1.935016e+001 2.354605e+001 0.000000e+000 vertex 1.929840e+001 2.238742e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.929840e+001 2.238742e+001 0.000000e+000 vertex 1.935016e+001 2.354605e+001 0.000000e+000 vertex 1.970942e+001 2.239316e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.929840e+001 2.238742e+001 0.000000e+000 vertex 1.970942e+001 2.239316e+001 0.000000e+000 vertex 1.952430e+001 2.120320e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.952430e+001 2.120320e+001 0.000000e+000 vertex 1.970942e+001 2.239316e+001 0.000000e+000 vertex 1.992709e+001 2.120537e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.952430e+001 2.120320e+001 0.000000e+000 vertex 1.992709e+001 2.120537e+001 0.000000e+000 vertex 1.960000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.960000e+001 2.000000e+001 0.000000e+000 vertex 1.992709e+001 2.120537e+001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.960000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 1.960000e+001 3.999993e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 3.999993e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 4.280401e+000 4.566330e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 3.578522e+000 6.251400e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 2.911644e+000 9.013694e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.296187e+000 1.278522e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 1.747308e+000 1.747308e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 1.278522e+000 2.296187e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 9.013694e-001 2.911644e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 6.251400e-001 3.578522e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 4.566330e-001 4.280401e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 3.999993e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.999993e-001 5.000000e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.999993e-001 5.000000e+000 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 3.999993e-001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 4.756991e-001 2.120320e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.756991e-001 2.120320e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 7.291138e-002 2.120537e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.756991e-001 2.120320e+001 0.000000e+000 vertex 7.291138e-002 2.120537e+001 0.000000e+000 vertex 7.016016e-001 2.238742e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.016016e-001 2.238742e+001 0.000000e+000 vertex 7.291138e-002 2.120537e+001 0.000000e+000 vertex 2.905819e-001 2.239316e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.016016e-001 2.238742e+001 0.000000e+000 vertex 2.905819e-001 2.239316e+001 0.000000e+000 vertex 1.074146e+000 2.353400e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.074146e+000 2.353400e+001 0.000000e+000 vertex 2.905819e-001 2.239316e+001 0.000000e+000 vertex 6.498378e-001 2.354605e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.074146e+000 2.353400e+001 0.000000e+000 vertex 6.498378e-001 2.354605e+001 0.000000e+000 vertex 1.587456e+000 2.462484e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.587456e+000 2.462484e+001 0.000000e+000 vertex 6.498378e-001 2.354605e+001 0.000000e+000 vertex 1.145439e+000 2.464723e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.587456e+000 2.462484e+001 0.000000e+000 vertex 1.145439e+000 2.464723e+001 0.000000e+000 vertex 2.233437e+000 2.564274e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.233437e+000 2.564274e+001 0.000000e+000 vertex 1.145439e+000 2.464723e+001 0.000000e+000 vertex 1.770161e+000 2.568065e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.233437e+000 2.564274e+001 0.000000e+000 vertex 1.770161e+000 2.568065e+001 0.000000e+000 vertex 3.001901e+000 2.657165e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.001901e+000 2.657165e+001 0.000000e+000 vertex 1.770161e+000 2.568065e+001 0.000000e+000 vertex 2.514892e+000 2.663123e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.001901e+000 2.657165e+001 0.000000e+000 vertex 2.514892e+000 2.663123e+001 0.000000e+000 vertex 3.880729e+000 2.739693e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.880729e+000 2.739693e+001 0.000000e+000 vertex 2.514892e+000 2.663123e+001 0.000000e+000 vertex 3.368773e+000 2.748511e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.880729e+000 2.739693e+001 0.000000e+000 vertex 3.368773e+000 2.748511e+001 0.000000e+000 vertex 4.856062e+000 2.810555e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.856062e+000 2.810555e+001 0.000000e+000 vertex 3.368773e+000 2.748511e+001 0.000000e+000 vertex 4.319352e+000 2.822984e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.856062e+000 2.810555e+001 0.000000e+000 vertex 4.319352e+000 2.822984e+001 0.000000e+000 vertex 5.912519e+000 2.868634e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.912519e+000 2.868634e+001 0.000000e+000 vertex 4.319352e+000 2.822984e+001 0.000000e+000 vertex 5.352768e+000 2.885456e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.912519e+000 2.868634e+001 0.000000e+000 vertex 5.352768e+000 2.885456e+001 0.000000e+000 vertex 7.033437e+000 2.913014e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.033437e+000 2.913014e+001 0.000000e+000 vertex 5.352768e+000 2.885456e+001 0.000000e+000 vertex 6.453951e+000 2.935016e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.033437e+000 2.913014e+001 0.000000e+000 vertex 6.453951e+000 2.935016e+001 0.000000e+000 vertex 8.201139e+000 2.942996e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.201139e+000 2.942996e+001 0.000000e+000 vertex 6.453951e+000 2.935016e+001 0.000000e+000 vertex 7.606843e+000 2.970942e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.201139e+000 2.942996e+001 0.000000e+000 vertex 7.606843e+000 2.970942e+001 0.000000e+000 vertex 9.397210e+000 2.958106e+001 0.000000e+000 endloop endfacet facet normal 9.991899e-001 4.024415e-002 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 2.000000e+001 vertex 2.000000e+001 2.000000e+001 6.938894e-015 vertex 1.992709e+001 2.120537e+001 6.938894e-015 endloop endfacet facet normal 9.967556e-001 8.048830e-002 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 2.000000e+001 vertex 1.992709e+001 2.120537e+001 6.938894e-015 vertex 1.992709e+001 2.120537e+001 2.000000e+001 endloop endfacet facet normal 9.870538e-001 1.603898e-001 0.000000e+000 outer loop vertex 1.992709e+001 2.120537e+001 2.000000e+001 vertex 1.992709e+001 2.120537e+001 6.938894e-015 vertex 1.970942e+001 2.239316e+001 6.938894e-015 endloop endfacet facet normal 9.797863e-001 2.000470e-001 0.000000e+000 outer loop vertex 1.992709e+001 2.120537e+001 2.000000e+001 vertex 1.970942e+001 2.239316e+001 6.938894e-015 vertex 1.970942e+001 2.239316e+001 2.000000e+001 endloop endfacet facet normal 9.605242e-001 2.781965e-001 0.000000e+000 outer loop vertex 1.970942e+001 2.239316e+001 2.000000e+001 vertex 1.970942e+001 2.239316e+001 6.938894e-015 vertex 1.935016e+001 2.354605e+001 6.938894e-015 endloop endfacet facet normal 9.485295e-001 3.166887e-001 0.000000e+000 outer loop vertex 1.970942e+001 2.239316e+001 2.000000e+001 vertex 1.935016e+001 2.354605e+001 6.938894e-015 vertex 1.935016e+001 2.354605e+001 2.000000e+001 endloop endfacet facet normal 9.199880e-001 3.919466e-001 0.000000e+000 outer loop vertex 1.935016e+001 2.354605e+001 2.000000e+001 vertex 1.935016e+001 2.354605e+001 6.938894e-015 vertex 1.885456e+001 2.464723e+001 6.938894e-015 endloop endfacet facet normal 9.034411e-001 4.287122e-001 0.000000e+000 outer loop vertex 1.935016e+001 2.354605e+001 2.000000e+001 vertex 1.885456e+001 2.464723e+001 6.938894e-015 vertex 1.885456e+001 2.464723e+001 2.000000e+001 endloop endfacet facet normal 8.660363e-001 4.999811e-001 0.000000e+000 outer loop vertex 1.885456e+001 2.464723e+001 2.000000e+001 vertex 1.885456e+001 2.464723e+001 6.938894e-015 vertex 1.822984e+001 2.568065e+001 6.938894e-015 endloop endfacet facet normal 8.451784e-001 5.344843e-001 0.000000e+000 outer loop vertex 1.885456e+001 2.464723e+001 2.000000e+001 vertex 1.822984e+001 2.568065e+001 6.938894e-015 vertex 1.822984e+001 2.568065e+001 2.000000e+001 endloop endfacet facet normal 7.994559e-001 6.007248e-001 0.000000e+000 outer loop vertex 1.822984e+001 2.568065e+001 2.000000e+001 vertex 1.822984e+001 2.568065e+001 6.938894e-015 vertex 1.748511e+001 2.663123e+001 6.938894e-015 endloop endfacet facet normal 7.745912e-001 6.324623e-001 0.000000e+000 outer loop vertex 1.822984e+001 2.568065e+001 2.000000e+001 vertex 1.748511e+001 2.663123e+001 6.938894e-015 vertex 1.748511e+001 2.663123e+001 2.000000e+001 endloop endfacet facet normal 7.212176e-001 6.927086e-001 0.000000e+000 outer loop vertex 1.748511e+001 2.663123e+001 2.000000e+001 vertex 1.748511e+001 2.663123e+001 6.938894e-015 vertex 1.663123e+001 2.748511e+001 6.938894e-015 endloop endfacet facet normal 6.927086e-001 7.212176e-001 0.000000e+000 outer loop vertex 1.748511e+001 2.663123e+001 2.000000e+001 vertex 1.663123e+001 2.748511e+001 6.938894e-015 vertex 1.663123e+001 2.748511e+001 2.000000e+001 endloop endfacet facet normal 6.324623e-001 7.745912e-001 0.000000e+000 outer loop vertex 1.663123e+001 2.748511e+001 2.000000e+001 vertex 1.663123e+001 2.748511e+001 6.938894e-015 vertex 1.568065e+001 2.822984e+001 6.938894e-015 endloop endfacet facet normal 6.007248e-001 7.994559e-001 0.000000e+000 outer loop vertex 1.663123e+001 2.748511e+001 2.000000e+001 vertex 1.568065e+001 2.822984e+001 6.938894e-015 vertex 1.568065e+001 2.822984e+001 2.000000e+001 endloop endfacet facet normal 5.344843e-001 8.451784e-001 0.000000e+000 outer loop vertex 1.568065e+001 2.822984e+001 2.000000e+001 vertex 1.568065e+001 2.822984e+001 6.938894e-015 vertex 1.464723e+001 2.885456e+001 6.938894e-015 endloop endfacet facet normal 4.999811e-001 8.660363e-001 0.000000e+000 outer loop vertex 1.568065e+001 2.822984e+001 2.000000e+001 vertex 1.464723e+001 2.885456e+001 6.938894e-015 vertex 1.464723e+001 2.885456e+001 2.000000e+001 endloop endfacet facet normal 4.287122e-001 9.034411e-001 0.000000e+000 outer loop vertex 1.464723e+001 2.885456e+001 2.000000e+001 vertex 1.464723e+001 2.885456e+001 6.938894e-015 vertex 1.354605e+001 2.935016e+001 6.938894e-015 endloop endfacet facet normal 3.919466e-001 9.199880e-001 0.000000e+000 outer loop vertex 1.464723e+001 2.885456e+001 2.000000e+001 vertex 1.354605e+001 2.935016e+001 6.938894e-015 vertex 1.354605e+001 2.935016e+001 2.000000e+001 endloop endfacet facet normal 3.166887e-001 9.485295e-001 0.000000e+000 outer loop vertex 1.354605e+001 2.935016e+001 2.000000e+001 vertex 1.354605e+001 2.935016e+001 6.938894e-015 vertex 1.239316e+001 2.970942e+001 6.938894e-015 endloop endfacet facet normal 2.781965e-001 9.605242e-001 0.000000e+000 outer loop vertex 1.354605e+001 2.935016e+001 2.000000e+001 vertex 1.239316e+001 2.970942e+001 6.938894e-015 vertex 1.239316e+001 2.970942e+001 2.000000e+001 endloop endfacet facet normal 2.000470e-001 9.797863e-001 0.000000e+000 outer loop vertex 1.239316e+001 2.970942e+001 2.000000e+001 vertex 1.239316e+001 2.970942e+001 6.938894e-015 vertex 1.120537e+001 2.992709e+001 6.938894e-015 endloop endfacet facet normal 1.603898e-001 9.870538e-001 0.000000e+000 outer loop vertex 1.239316e+001 2.970942e+001 2.000000e+001 vertex 1.120537e+001 2.992709e+001 6.938894e-015 vertex 1.120537e+001 2.992709e+001 2.000000e+001 endloop endfacet facet normal 8.048830e-002 9.967556e-001 0.000000e+000 outer loop vertex 1.120537e+001 2.992709e+001 2.000000e+001 vertex 1.120537e+001 2.992709e+001 6.938894e-015 vertex 1.000000e+001 3.000000e+001 6.938894e-015 endloop endfacet facet normal 4.024415e-002 9.991899e-001 0.000000e+000 outer loop vertex 1.120537e+001 2.992709e+001 2.000000e+001 vertex 1.000000e+001 3.000000e+001 6.938894e-015 vertex 1.000000e+001 3.000000e+001 2.000000e+001 endloop endfacet facet normal -4.024415e-002 9.991899e-001 0.000000e+000 outer loop vertex 1.000000e+001 3.000000e+001 2.000000e+001 vertex 1.000000e+001 3.000000e+001 6.938894e-015 vertex 8.794633e+000 2.992709e+001 6.938894e-015 endloop endfacet facet normal -8.048830e-002 9.967556e-001 0.000000e+000 outer loop vertex 1.000000e+001 3.000000e+001 2.000000e+001 vertex 8.794633e+000 2.992709e+001 6.938894e-015 vertex 8.794633e+000 2.992709e+001 2.000000e+001 endloop endfacet facet normal -1.603898e-001 9.870538e-001 0.000000e+000 outer loop vertex 8.794633e+000 2.992709e+001 2.000000e+001 vertex 8.794633e+000 2.992709e+001 6.938894e-015 vertex 7.606843e+000 2.970942e+001 6.938894e-015 endloop endfacet facet normal -2.000470e-001 9.797863e-001 0.000000e+000 outer loop vertex 8.794633e+000 2.992709e+001 2.000000e+001 vertex 7.606843e+000 2.970942e+001 6.938894e-015 vertex 7.606843e+000 2.970942e+001 2.000000e+001 endloop endfacet facet normal -2.781965e-001 9.605242e-001 0.000000e+000 outer loop vertex 7.606843e+000 2.970942e+001 2.000000e+001 vertex 7.606843e+000 2.970942e+001 6.938894e-015 vertex 6.453951e+000 2.935016e+001 6.938894e-015 endloop endfacet facet normal -3.166887e-001 9.485295e-001 0.000000e+000 outer loop vertex 7.606843e+000 2.970942e+001 2.000000e+001 vertex 6.453951e+000 2.935016e+001 6.938894e-015 vertex 6.453951e+000 2.935016e+001 2.000000e+001 endloop endfacet facet normal -3.919466e-001 9.199880e-001 0.000000e+000 outer loop vertex 6.453951e+000 2.935016e+001 2.000000e+001 vertex 6.453951e+000 2.935016e+001 6.938894e-015 vertex 5.352768e+000 2.885456e+001 6.938894e-015 endloop endfacet facet normal -4.287122e-001 9.034411e-001 0.000000e+000 outer loop vertex 6.453951e+000 2.935016e+001 2.000000e+001 vertex 5.352768e+000 2.885456e+001 6.938894e-015 vertex 5.352768e+000 2.885456e+001 2.000000e+001 endloop endfacet facet normal -4.999811e-001 8.660363e-001 0.000000e+000 outer loop vertex 5.352768e+000 2.885456e+001 2.000000e+001 vertex 5.352768e+000 2.885456e+001 6.938894e-015 vertex 4.319352e+000 2.822984e+001 6.938894e-015 endloop endfacet facet normal -5.344843e-001 8.451784e-001 0.000000e+000 outer loop vertex 5.352768e+000 2.885456e+001 2.000000e+001 vertex 4.319352e+000 2.822984e+001 6.938894e-015 vertex 4.319352e+000 2.822984e+001 2.000000e+001 endloop endfacet facet normal -6.007248e-001 7.994559e-001 0.000000e+000 outer loop vertex 4.319352e+000 2.822984e+001 2.000000e+001 vertex 4.319352e+000 2.822984e+001 6.938894e-015 vertex 3.368773e+000 2.748511e+001 6.938894e-015 endloop endfacet facet normal -6.324623e-001 7.745912e-001 0.000000e+000 outer loop vertex 4.319352e+000 2.822984e+001 2.000000e+001 vertex 3.368773e+000 2.748511e+001 6.938894e-015 vertex 3.368773e+000 2.748511e+001 2.000000e+001 endloop endfacet facet normal -6.927086e-001 7.212176e-001 0.000000e+000 outer loop vertex 3.368773e+000 2.748511e+001 2.000000e+001 vertex 3.368773e+000 2.748511e+001 6.938894e-015 vertex 2.514892e+000 2.663123e+001 6.938894e-015 endloop endfacet facet normal -7.212176e-001 6.927086e-001 0.000000e+000 outer loop vertex 3.368773e+000 2.748511e+001 2.000000e+001 vertex 2.514892e+000 2.663123e+001 6.938894e-015 vertex 2.514892e+000 2.663123e+001 2.000000e+001 endloop endfacet facet normal -7.745912e-001 6.324623e-001 0.000000e+000 outer loop vertex 2.514892e+000 2.663123e+001 2.000000e+001 vertex 2.514892e+000 2.663123e+001 6.938894e-015 vertex 1.770161e+000 2.568065e+001 6.938894e-015 endloop endfacet facet normal -7.994559e-001 6.007248e-001 0.000000e+000 outer loop vertex 2.514892e+000 2.663123e+001 2.000000e+001 vertex 1.770161e+000 2.568065e+001 6.938894e-015 vertex 1.770161e+000 2.568065e+001 2.000000e+001 endloop endfacet facet normal -8.451784e-001 5.344843e-001 0.000000e+000 outer loop vertex 1.770161e+000 2.568065e+001 2.000000e+001 vertex 1.770161e+000 2.568065e+001 6.938894e-015 vertex 1.145439e+000 2.464723e+001 6.938894e-015 endloop endfacet facet normal -8.660363e-001 4.999811e-001 0.000000e+000 outer loop vertex 1.770161e+000 2.568065e+001 2.000000e+001 vertex 1.145439e+000 2.464723e+001 6.938894e-015 vertex 1.145439e+000 2.464723e+001 2.000000e+001 endloop endfacet facet normal -9.034411e-001 4.287122e-001 0.000000e+000 outer loop vertex 1.145439e+000 2.464723e+001 2.000000e+001 vertex 1.145439e+000 2.464723e+001 6.938894e-015 vertex 6.498378e-001 2.354605e+001 6.938894e-015 endloop endfacet facet normal -9.199880e-001 3.919466e-001 0.000000e+000 outer loop vertex 1.145439e+000 2.464723e+001 2.000000e+001 vertex 6.498378e-001 2.354605e+001 6.938894e-015 vertex 6.498378e-001 2.354605e+001 2.000000e+001 endloop endfacet facet normal -9.485295e-001 3.166887e-001 0.000000e+000 outer loop vertex 6.498378e-001 2.354605e+001 2.000000e+001 vertex 6.498378e-001 2.354605e+001 6.938894e-015 vertex 2.905819e-001 2.239316e+001 6.938894e-015 endloop endfacet facet normal -9.605242e-001 2.781965e-001 0.000000e+000 outer loop vertex 6.498378e-001 2.354605e+001 2.000000e+001 vertex 2.905819e-001 2.239316e+001 6.938894e-015 vertex 2.905819e-001 2.239316e+001 2.000000e+001 endloop endfacet facet normal -9.797863e-001 2.000470e-001 0.000000e+000 outer loop vertex 2.905819e-001 2.239316e+001 2.000000e+001 vertex 2.905819e-001 2.239316e+001 6.938894e-015 vertex 7.291138e-002 2.120537e+001 6.938894e-015 endloop endfacet facet normal -9.870538e-001 1.603898e-001 0.000000e+000 outer loop vertex 2.905819e-001 2.239316e+001 2.000000e+001 vertex 7.291138e-002 2.120537e+001 6.938894e-015 vertex 7.291138e-002 2.120537e+001 2.000000e+001 endloop endfacet facet normal -9.967556e-001 8.048830e-002 0.000000e+000 outer loop vertex 7.291138e-002 2.120537e+001 2.000000e+001 vertex 7.291138e-002 2.120537e+001 6.938894e-015 vertex 0.000000e+000 2.000000e+001 6.938894e-015 endloop endfacet facet normal -9.991899e-001 4.024415e-002 0.000000e+000 outer loop vertex 7.291138e-002 2.120537e+001 2.000000e+001 vertex 0.000000e+000 2.000000e+001 6.938894e-015 vertex 0.000000e+000 2.000000e+001 2.000000e+001 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000000e+001 vertex 0.000000e+000 2.000000e+001 2.000000e+001 vertex 0.000000e+000 5.000000e+000 6.938894e-015 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 6.938894e-015 vertex 0.000000e+000 2.000000e+001 2.000000e+001 vertex 0.000000e+000 2.000000e+001 6.938894e-015 endloop endfacet facet normal -9.986320e-001 -5.228807e-002 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000000e+001 vertex 0.000000e+000 5.000000e+000 6.938894e-015 vertex 6.155763e-002 4.217827e+000 6.938894e-015 endloop endfacet facet normal -9.945168e-001 -1.045761e-001 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000000e+001 vertex 6.155763e-002 4.217827e+000 6.938894e-015 vertex 6.155763e-002 4.217827e+000 2.000000e+001 endloop endfacet facet normal -9.781576e-001 -2.078648e-001 0.000000e+000 outer loop vertex 6.155763e-002 4.217827e+000 2.000000e+001 vertex 6.155763e-002 4.217827e+000 6.938894e-015 vertex 2.447171e-001 3.454915e+000 6.938894e-015 endloop endfacet facet normal -9.659134e-001 -2.588654e-001 0.000000e+000 outer loop vertex 6.155763e-002 4.217827e+000 2.000000e+001 vertex 2.447171e-001 3.454915e+000 6.938894e-015 vertex 2.447171e-001 3.454915e+000 2.000000e+001 endloop endfacet facet normal -9.335976e-001 -3.583232e-001 0.000000e+000 outer loop vertex 2.447171e-001 3.454915e+000 2.000000e+001 vertex 2.447171e-001 3.454915e+000 6.938894e-015 vertex 5.449671e-001 2.730047e+000 6.938894e-015 endloop endfacet facet normal -9.135259e-001 -4.067805e-001 0.000000e+000 outer loop vertex 2.447171e-001 3.454915e+000 2.000000e+001 vertex 5.449671e-001 2.730047e+000 6.938894e-015 vertex 5.449671e-001 2.730047e+000 2.000000e+001 endloop endfacet facet normal -8.660493e-001 -4.999585e-001 0.000000e+000 outer loop vertex 5.449671e-001 2.730047e+000 2.000000e+001 vertex 5.449671e-001 2.730047e+000 6.938894e-015 vertex 9.549148e-001 2.061074e+000 6.938894e-015 endloop endfacet facet normal -8.386444e-001 -5.446792e-001 0.000000e+000 outer loop vertex 5.449671e-001 2.730047e+000 2.000000e+001 vertex 9.549148e-001 2.061074e+000 6.938894e-015 vertex 9.549148e-001 2.061074e+000 2.000000e+001 endloop endfacet facet normal -7.771761e-001 -6.292831e-001 0.000000e+000 outer loop vertex 9.549148e-001 2.061074e+000 2.000000e+001 vertex 9.549148e-001 2.061074e+000 6.938894e-015 vertex 1.464466e+000 1.464466e+000 6.938894e-015 endloop endfacet facet normal -7.431127e-001 -6.691663e-001 0.000000e+000 outer loop vertex 9.549148e-001 2.061074e+000 2.000000e+001 vertex 1.464466e+000 1.464466e+000 6.938894e-015 vertex 1.464466e+000 1.464466e+000 2.000000e+001 endloop endfacet facet normal -6.691663e-001 -7.431127e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 2.000000e+001 vertex 1.464466e+000 1.464466e+000 6.938894e-015 vertex 2.061074e+000 9.549148e-001 6.938894e-015 endloop endfacet facet normal -6.292831e-001 -7.771761e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 2.000000e+001 vertex 2.061074e+000 9.549148e-001 6.938894e-015 vertex 2.061074e+000 9.549148e-001 2.000000e+001 endloop endfacet facet normal -5.446792e-001 -8.386444e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549148e-001 2.000000e+001 vertex 2.061074e+000 9.549148e-001 6.938894e-015 vertex 2.730047e+000 5.449671e-001 6.938894e-015 endloop endfacet facet normal -4.999585e-001 -8.660493e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549148e-001 2.000000e+001 vertex 2.730047e+000 5.449671e-001 6.938894e-015 vertex 2.730047e+000 5.449671e-001 2.000000e+001 endloop endfacet facet normal -4.067805e-001 -9.135259e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449671e-001 2.000000e+001 vertex 2.730047e+000 5.449671e-001 6.938894e-015 vertex 3.454915e+000 2.447171e-001 6.938894e-015 endloop endfacet facet normal -3.583232e-001 -9.335976e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449671e-001 2.000000e+001 vertex 3.454915e+000 2.447171e-001 6.938894e-015 vertex 3.454915e+000 2.447171e-001 2.000000e+001 endloop endfacet facet normal -2.588654e-001 -9.659134e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447171e-001 2.000000e+001 vertex 3.454915e+000 2.447171e-001 6.938894e-015 vertex 4.217827e+000 6.155763e-002 6.938894e-015 endloop endfacet facet normal -2.078648e-001 -9.781576e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447171e-001 2.000000e+001 vertex 4.217827e+000 6.155763e-002 6.938894e-015 vertex 4.217827e+000 6.155763e-002 2.000000e+001 endloop endfacet facet normal -1.045761e-001 -9.945168e-001 0.000000e+000 outer loop vertex 4.217827e+000 6.155763e-002 2.000000e+001 vertex 4.217827e+000 6.155763e-002 6.938894e-015 vertex 5.000000e+000 0.000000e+000 6.938894e-015 endloop endfacet facet normal -5.228807e-002 -9.986320e-001 0.000000e+000 outer loop vertex 4.217827e+000 6.155763e-002 2.000000e+001 vertex 5.000000e+000 0.000000e+000 6.938894e-015 vertex 5.000000e+000 0.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 0.000000e+000 2.000000e+001 vertex 5.000000e+000 0.000000e+000 2.000000e+001 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 2.000000e+001 vertex 5.000000e+000 0.000000e+000 6.938894e-015 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 2.000000e+001 vertex 2.000000e+001 0.000000e+000 2.000000e+001 vertex 2.000000e+001 2.000000e+001 6.938894e-015 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 6.938894e-015 vertex 2.000000e+001 0.000000e+000 2.000000e+001 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 9.991238e-001 -4.185114e-002 0.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 2.000000e+001 vertex 3.999993e-001 2.000000e+001 6.938894e-015 vertex 4.756991e-001 2.120320e+001 6.938894e-015 endloop endfacet facet normal 9.964908e-001 -8.370229e-002 0.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 2.000000e+001 vertex 4.756991e-001 2.120320e+001 6.938894e-015 vertex 4.756991e-001 2.120320e+001 2.000000e+001 endloop endfacet facet normal 9.860001e-001 -1.667446e-001 0.000000e+000 outer loop vertex 4.756991e-001 2.120320e+001 2.000000e+001 vertex 4.756991e-001 2.120320e+001 6.938894e-015 vertex 7.016016e-001 2.238742e+001 6.938894e-015 endloop endfacet facet normal 9.781425e-001 -2.079357e-001 0.000000e+000 outer loop vertex 4.756991e-001 2.120320e+001 2.000000e+001 vertex 7.016016e-001 2.238742e+001 6.938894e-015 vertex 7.016016e-001 2.238742e+001 2.000000e+001 endloop endfacet facet normal 9.573266e-001 -2.890083e-001 0.000000e+000 outer loop vertex 7.016016e-001 2.238742e+001 2.000000e+001 vertex 7.016016e-001 2.238742e+001 6.938894e-015 vertex 1.074146e+000 2.353400e+001 6.938894e-015 endloop endfacet facet normal 9.443683e-001 -3.288898e-001 0.000000e+000 outer loop vertex 7.016016e-001 2.238742e+001 2.000000e+001 vertex 1.074146e+000 2.353400e+001 6.938894e-015 vertex 1.074146e+000 2.353400e+001 2.000000e+001 endloop endfacet facet normal 9.135554e-001 -4.067142e-001 0.000000e+000 outer loop vertex 1.074146e+000 2.353400e+001 2.000000e+001 vertex 1.074146e+000 2.353400e+001 6.938894e-015 vertex 1.587456e+000 2.462484e+001 6.938894e-015 endloop endfacet facet normal 8.957008e-001 -4.446571e-001 0.000000e+000 outer loop vertex 1.074146e+000 2.353400e+001 2.000000e+001 vertex 1.587456e+000 2.462484e+001 6.938894e-015 vertex 1.587456e+000 2.462484e+001 2.000000e+001 endloop endfacet facet normal 8.553770e-001 -5.180060e-001 0.000000e+000 outer loop vertex 1.587456e+000 2.462484e+001 2.000000e+001 vertex 1.587456e+000 2.462484e+001 6.938894e-015 vertex 2.233437e+000 2.564274e+001 6.938894e-015 endloop endfacet facet normal 8.329077e-001 -5.534120e-001 0.000000e+000 outer loop vertex 1.587456e+000 2.462484e+001 2.000000e+001 vertex 2.233437e+000 2.564274e+001 6.938894e-015 vertex 2.233437e+000 2.564274e+001 2.000000e+001 endloop endfacet facet normal 7.837087e-001 -6.211286e-001 0.000000e+000 outer loop vertex 2.233437e+000 2.564274e+001 2.000000e+001 vertex 2.233437e+000 2.564274e+001 6.938894e-015 vertex 3.001901e+000 2.657165e+001 6.938894e-015 endloop endfacet facet normal 7.569790e-001 -6.534392e-001 0.000000e+000 outer loop vertex 2.233437e+000 2.564274e+001 2.000000e+001 vertex 3.001901e+000 2.657165e+001 6.938894e-015 vertex 3.001901e+000 2.657165e+001 2.000000e+001 endloop endfacet facet normal 6.996809e-001 -7.144555e-001 0.000000e+000 outer loop vertex 3.001901e+000 2.657165e+001 2.000000e+001 vertex 3.001901e+000 2.657165e+001 6.938894e-015 vertex 3.880729e+000 2.739693e+001 6.938894e-015 endloop endfacet facet normal 6.691124e-001 -7.431613e-001 0.000000e+000 outer loop vertex 3.001901e+000 2.657165e+001 2.000000e+001 vertex 3.880729e+000 2.739693e+001 6.938894e-015 vertex 3.880729e+000 2.739693e+001 2.000000e+001 endloop endfacet facet normal 6.046186e-001 -7.965151e-001 0.000000e+000 outer loop vertex 3.880729e+000 2.739693e+001 2.000000e+001 vertex 3.880729e+000 2.739693e+001 6.938894e-015 vertex 4.856062e+000 2.810555e+001 6.938894e-015 endloop endfacet facet normal 5.706934e-001 -8.211632e-001 0.000000e+000 outer loop vertex 3.880729e+000 2.739693e+001 2.000000e+001 vertex 4.856062e+000 2.810555e+001 6.938894e-015 vertex 4.856062e+000 2.810555e+001 2.000000e+001 endloop endfacet facet normal 5.000212e-001 -8.660132e-001 0.000000e+000 outer loop vertex 4.856062e+000 2.810555e+001 2.000000e+001 vertex 4.856062e+000 2.810555e+001 6.938894e-015 vertex 5.912519e+000 2.868634e+001 6.938894e-015 endloop endfacet facet normal 4.632743e-001 -8.862149e-001 0.000000e+000 outer loop vertex 4.856062e+000 2.810555e+001 2.000000e+001 vertex 5.912519e+000 2.868634e+001 6.938894e-015 vertex 5.912519e+000 2.868634e+001 2.000000e+001 endloop endfacet facet normal 3.875382e-001 -9.218537e-001 0.000000e+000 outer loop vertex 5.912519e+000 2.868634e+001 2.000000e+001 vertex 5.912519e+000 2.868634e+001 6.938894e-015 vertex 7.033437e+000 2.913014e+001 6.938894e-015 endloop endfacet facet normal 3.485490e-001 -9.372905e-001 0.000000e+000 outer loop vertex 5.912519e+000 2.868634e+001 2.000000e+001 vertex 7.033437e+000 2.913014e+001 6.938894e-015 vertex 7.033437e+000 2.913014e+001 2.000000e+001 endloop endfacet facet normal 2.689435e-001 -9.631560e-001 0.000000e+000 outer loop vertex 7.033437e+000 2.913014e+001 2.000000e+001 vertex 7.033437e+000 2.913014e+001 6.938894e-015 vertex 8.201139e+000 2.942996e+001 6.938894e-015 endloop endfacet facet normal 2.283270e-001 -9.735845e-001 0.000000e+000 outer loop vertex 7.033437e+000 2.913014e+001 2.000000e+001 vertex 8.201139e+000 2.942996e+001 6.938894e-015 vertex 8.201139e+000 2.942996e+001 2.000000e+001 endloop endfacet facet normal 1.461073e-001 -9.892687e-001 0.000000e+000 outer loop vertex 8.201139e+000 2.942996e+001 2.000000e+001 vertex 8.201139e+000 2.942996e+001 6.938894e-015 vertex 9.397210e+000 2.958106e+001 6.938894e-015 endloop endfacet facet normal 1.045041e-001 -9.945245e-001 0.000000e+000 outer loop vertex 8.201139e+000 2.942996e+001 2.000000e+001 vertex 9.397210e+000 2.958106e+001 6.938894e-015 vertex 9.397210e+000 2.958106e+001 2.000000e+001 endloop endfacet facet normal 2.096695e-002 -9.997802e-001 0.000000e+000 outer loop vertex 9.397210e+000 2.958106e+001 2.000000e+001 vertex 9.397210e+000 2.958106e+001 6.938894e-015 vertex 1.060279e+001 2.958106e+001 6.938894e-015 endloop endfacet facet normal -2.096695e-002 -9.997802e-001 0.000000e+000 outer loop vertex 9.397210e+000 2.958106e+001 2.000000e+001 vertex 1.060279e+001 2.958106e+001 6.938894e-015 vertex 1.060279e+001 2.958106e+001 2.000000e+001 endloop endfacet facet normal -1.045041e-001 -9.945245e-001 0.000000e+000 outer loop vertex 1.060279e+001 2.958106e+001 2.000000e+001 vertex 1.060279e+001 2.958106e+001 6.938894e-015 vertex 1.179886e+001 2.942996e+001 6.938894e-015 endloop endfacet facet normal -1.461073e-001 -9.892687e-001 0.000000e+000 outer loop vertex 1.060279e+001 2.958106e+001 2.000000e+001 vertex 1.179886e+001 2.942996e+001 6.938894e-015 vertex 1.179886e+001 2.942996e+001 2.000000e+001 endloop endfacet facet normal -2.283270e-001 -9.735845e-001 0.000000e+000 outer loop vertex 1.179886e+001 2.942996e+001 2.000000e+001 vertex 1.179886e+001 2.942996e+001 6.938894e-015 vertex 1.296656e+001 2.913014e+001 6.938894e-015 endloop endfacet facet normal -2.689435e-001 -9.631560e-001 0.000000e+000 outer loop vertex 1.179886e+001 2.942996e+001 2.000000e+001 vertex 1.296656e+001 2.913014e+001 6.938894e-015 vertex 1.296656e+001 2.913014e+001 2.000000e+001 endloop endfacet facet normal -3.485490e-001 -9.372905e-001 0.000000e+000 outer loop vertex 1.296656e+001 2.913014e+001 2.000000e+001 vertex 1.296656e+001 2.913014e+001 6.938894e-015 vertex 1.408748e+001 2.868634e+001 6.938894e-015 endloop endfacet facet normal -3.875382e-001 -9.218537e-001 0.000000e+000 outer loop vertex 1.296656e+001 2.913014e+001 2.000000e+001 vertex 1.408748e+001 2.868634e+001 6.938894e-015 vertex 1.408748e+001 2.868634e+001 2.000000e+001 endloop endfacet facet normal -4.632743e-001 -8.862149e-001 0.000000e+000 outer loop vertex 1.408748e+001 2.868634e+001 2.000000e+001 vertex 1.408748e+001 2.868634e+001 6.938894e-015 vertex 1.514394e+001 2.810555e+001 6.938894e-015 endloop endfacet facet normal -5.000212e-001 -8.660132e-001 0.000000e+000 outer loop vertex 1.408748e+001 2.868634e+001 2.000000e+001 vertex 1.514394e+001 2.810555e+001 6.938894e-015 vertex 1.514394e+001 2.810555e+001 2.000000e+001 endloop endfacet facet normal -5.706934e-001 -8.211632e-001 0.000000e+000 outer loop vertex 1.514394e+001 2.810555e+001 2.000000e+001 vertex 1.514394e+001 2.810555e+001 6.938894e-015 vertex 1.611927e+001 2.739693e+001 6.938894e-015 endloop endfacet facet normal -6.046186e-001 -7.965151e-001 0.000000e+000 outer loop vertex 1.514394e+001 2.810555e+001 2.000000e+001 vertex 1.611927e+001 2.739693e+001 6.938894e-015 vertex 1.611927e+001 2.739693e+001 2.000000e+001 endloop endfacet facet normal -6.691124e-001 -7.431613e-001 0.000000e+000 outer loop vertex 1.611927e+001 2.739693e+001 2.000000e+001 vertex 1.611927e+001 2.739693e+001 6.938894e-015 vertex 1.699810e+001 2.657165e+001 6.938894e-015 endloop endfacet facet normal -6.996809e-001 -7.144555e-001 0.000000e+000 outer loop vertex 1.611927e+001 2.739693e+001 2.000000e+001 vertex 1.699810e+001 2.657165e+001 6.938894e-015 vertex 1.699810e+001 2.657165e+001 2.000000e+001 endloop endfacet facet normal -7.569790e-001 -6.534392e-001 0.000000e+000 outer loop vertex 1.699810e+001 2.657165e+001 2.000000e+001 vertex 1.699810e+001 2.657165e+001 6.938894e-015 vertex 1.776656e+001 2.564274e+001 6.938894e-015 endloop endfacet facet normal -7.837087e-001 -6.211286e-001 0.000000e+000 outer loop vertex 1.699810e+001 2.657165e+001 2.000000e+001 vertex 1.776656e+001 2.564274e+001 6.938894e-015 vertex 1.776656e+001 2.564274e+001 2.000000e+001 endloop endfacet facet normal -8.329077e-001 -5.534120e-001 0.000000e+000 outer loop vertex 1.776656e+001 2.564274e+001 2.000000e+001 vertex 1.776656e+001 2.564274e+001 6.938894e-015 vertex 1.841254e+001 2.462484e+001 6.938894e-015 endloop endfacet facet normal -8.553770e-001 -5.180060e-001 0.000000e+000 outer loop vertex 1.776656e+001 2.564274e+001 2.000000e+001 vertex 1.841254e+001 2.462484e+001 6.938894e-015 vertex 1.841254e+001 2.462484e+001 2.000000e+001 endloop endfacet facet normal -8.957008e-001 -4.446571e-001 0.000000e+000 outer loop vertex 1.841254e+001 2.462484e+001 2.000000e+001 vertex 1.841254e+001 2.462484e+001 6.938894e-015 vertex 1.892585e+001 2.353400e+001 6.938894e-015 endloop endfacet facet normal -9.135554e-001 -4.067142e-001 0.000000e+000 outer loop vertex 1.841254e+001 2.462484e+001 2.000000e+001 vertex 1.892585e+001 2.353400e+001 6.938894e-015 vertex 1.892585e+001 2.353400e+001 2.000000e+001 endloop endfacet facet normal -9.443683e-001 -3.288898e-001 0.000000e+000 outer loop vertex 1.892585e+001 2.353400e+001 2.000000e+001 vertex 1.892585e+001 2.353400e+001 6.938894e-015 vertex 1.929840e+001 2.238742e+001 6.938894e-015 endloop endfacet facet normal -9.573266e-001 -2.890083e-001 0.000000e+000 outer loop vertex 1.892585e+001 2.353400e+001 2.000000e+001 vertex 1.929840e+001 2.238742e+001 6.938894e-015 vertex 1.929840e+001 2.238742e+001 2.000000e+001 endloop endfacet facet normal -9.781425e-001 -2.079357e-001 0.000000e+000 outer loop vertex 1.929840e+001 2.238742e+001 2.000000e+001 vertex 1.929840e+001 2.238742e+001 6.938894e-015 vertex 1.952430e+001 2.120320e+001 6.938894e-015 endloop endfacet facet normal -9.860001e-001 -1.667446e-001 0.000000e+000 outer loop vertex 1.929840e+001 2.238742e+001 2.000000e+001 vertex 1.952430e+001 2.120320e+001 6.938894e-015 vertex 1.952430e+001 2.120320e+001 2.000000e+001 endloop endfacet facet normal -9.964908e-001 -8.370229e-002 0.000000e+000 outer loop vertex 1.952430e+001 2.120320e+001 2.000000e+001 vertex 1.952430e+001 2.120320e+001 6.938894e-015 vertex 1.960000e+001 2.000000e+001 6.938894e-015 endloop endfacet facet normal -9.991238e-001 -4.185114e-002 0.000000e+000 outer loop vertex 1.952430e+001 2.120320e+001 2.000000e+001 vertex 1.960000e+001 2.000000e+001 6.938894e-015 vertex 1.960000e+001 2.000000e+001 2.000000e+001 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 2.000000e+001 vertex 3.999993e-001 5.000000e+000 2.000000e+001 vertex 3.999993e-001 2.000000e+001 6.938894e-015 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.999993e-001 2.000000e+001 6.938894e-015 vertex 3.999993e-001 5.000000e+000 2.000000e+001 vertex 3.999993e-001 5.000000e+000 6.938894e-015 endloop endfacet facet normal 5.228807e-002 9.986320e-001 0.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 2.000000e+001 vertex 5.000000e+000 3.999993e-001 6.938894e-015 vertex 4.280401e+000 4.566330e-001 6.938894e-015 endloop endfacet facet normal 1.045761e-001 9.945168e-001 0.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 2.000000e+001 vertex 4.280401e+000 4.566330e-001 6.938894e-015 vertex 4.280401e+000 4.566330e-001 2.000000e+001 endloop endfacet facet normal 2.078648e-001 9.781576e-001 0.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 2.000000e+001 vertex 4.280401e+000 4.566330e-001 6.938894e-015 vertex 3.578522e+000 6.251400e-001 6.938894e-015 endloop endfacet facet normal 2.588654e-001 9.659134e-001 0.000000e+000 outer loop vertex 4.280401e+000 4.566330e-001 2.000000e+001 vertex 3.578522e+000 6.251400e-001 6.938894e-015 vertex 3.578522e+000 6.251400e-001 2.000000e+001 endloop endfacet facet normal 3.583232e-001 9.335976e-001 0.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 2.000000e+001 vertex 3.578522e+000 6.251400e-001 6.938894e-015 vertex 2.911644e+000 9.013694e-001 6.938894e-015 endloop endfacet facet normal 4.067805e-001 9.135259e-001 0.000000e+000 outer loop vertex 3.578522e+000 6.251400e-001 2.000000e+001 vertex 2.911644e+000 9.013694e-001 6.938894e-015 vertex 2.911644e+000 9.013694e-001 2.000000e+001 endloop endfacet facet normal 4.999585e-001 8.660493e-001 0.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 2.000000e+001 vertex 2.911644e+000 9.013694e-001 6.938894e-015 vertex 2.296187e+000 1.278522e+000 6.938894e-015 endloop endfacet facet normal 5.446792e-001 8.386444e-001 0.000000e+000 outer loop vertex 2.911644e+000 9.013694e-001 2.000000e+001 vertex 2.296187e+000 1.278522e+000 6.938894e-015 vertex 2.296187e+000 1.278522e+000 2.000000e+001 endloop endfacet facet normal 6.292831e-001 7.771761e-001 0.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 2.000000e+001 vertex 2.296187e+000 1.278522e+000 6.938894e-015 vertex 1.747308e+000 1.747308e+000 6.938894e-015 endloop endfacet facet normal 6.691663e-001 7.431127e-001 0.000000e+000 outer loop vertex 2.296187e+000 1.278522e+000 2.000000e+001 vertex 1.747308e+000 1.747308e+000 6.938894e-015 vertex 1.747308e+000 1.747308e+000 2.000000e+001 endloop endfacet facet normal 7.431127e-001 6.691663e-001 0.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 2.000000e+001 vertex 1.747308e+000 1.747308e+000 6.938894e-015 vertex 1.278522e+000 2.296187e+000 6.938894e-015 endloop endfacet facet normal 7.771761e-001 6.292831e-001 0.000000e+000 outer loop vertex 1.747308e+000 1.747308e+000 2.000000e+001 vertex 1.278522e+000 2.296187e+000 6.938894e-015 vertex 1.278522e+000 2.296187e+000 2.000000e+001 endloop endfacet facet normal 8.386444e-001 5.446792e-001 0.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 2.000000e+001 vertex 1.278522e+000 2.296187e+000 6.938894e-015 vertex 9.013694e-001 2.911644e+000 6.938894e-015 endloop endfacet facet normal 8.660493e-001 4.999585e-001 0.000000e+000 outer loop vertex 1.278522e+000 2.296187e+000 2.000000e+001 vertex 9.013694e-001 2.911644e+000 6.938894e-015 vertex 9.013694e-001 2.911644e+000 2.000000e+001 endloop endfacet facet normal 9.135259e-001 4.067805e-001 0.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 2.000000e+001 vertex 9.013694e-001 2.911644e+000 6.938894e-015 vertex 6.251400e-001 3.578522e+000 6.938894e-015 endloop endfacet facet normal 9.335976e-001 3.583232e-001 0.000000e+000 outer loop vertex 9.013694e-001 2.911644e+000 2.000000e+001 vertex 6.251400e-001 3.578522e+000 6.938894e-015 vertex 6.251400e-001 3.578522e+000 2.000000e+001 endloop endfacet facet normal 9.659134e-001 2.588654e-001 0.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 2.000000e+001 vertex 6.251400e-001 3.578522e+000 6.938894e-015 vertex 4.566330e-001 4.280401e+000 6.938894e-015 endloop endfacet facet normal 9.781576e-001 2.078648e-001 0.000000e+000 outer loop vertex 6.251400e-001 3.578522e+000 2.000000e+001 vertex 4.566330e-001 4.280401e+000 6.938894e-015 vertex 4.566330e-001 4.280401e+000 2.000000e+001 endloop endfacet facet normal 9.945168e-001 1.045761e-001 0.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 2.000000e+001 vertex 4.566330e-001 4.280401e+000 6.938894e-015 vertex 3.999993e-001 5.000000e+000 6.938894e-015 endloop endfacet facet normal 9.986320e-001 5.228807e-002 0.000000e+000 outer loop vertex 4.566330e-001 4.280401e+000 2.000000e+001 vertex 3.999993e-001 5.000000e+000 6.938894e-015 vertex 3.999993e-001 5.000000e+000 2.000000e+001 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 2.000000e+001 vertex 1.960000e+001 3.999993e-001 2.000000e+001 vertex 5.000000e+000 3.999993e-001 6.938894e-015 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 3.999993e-001 6.938894e-015 vertex 1.960000e+001 3.999993e-001 2.000000e+001 vertex 1.960000e+001 3.999993e-001 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 2.000000e+001 vertex 1.960000e+001 2.000000e+001 2.000000e+001 vertex 1.960000e+001 3.999993e-001 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.960000e+001 3.999993e-001 0.000000e+000 vertex 1.960000e+001 2.000000e+001 2.000000e+001 vertex 1.960000e+001 2.000000e+001 6.938894e-015 endloop endfacet endsolidsfact-2011.12.18/calibration/_75x10.STL000066400000000000000000002521571167321211700170220ustar00rootroot00000000000000solid _75x10 facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.286803e+001 2.957990e+001 1.200000e+001 vertex 1.173648e+001 2.984808e+001 1.200000e+001 vertex 1.111496e+001 2.918256e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.111496e+001 2.918256e+001 1.200000e+001 vertex 1.173648e+001 2.984808e+001 1.200000e+001 vertex 1.058145e+001 2.998308e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.111496e+001 2.918256e+001 1.200000e+001 vertex 1.058145e+001 2.998308e+001 1.200000e+001 vertex 1.000000e+001 2.925000e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.000000e+001 2.925000e+001 1.200000e+001 vertex 1.058145e+001 2.998308e+001 1.200000e+001 vertex 9.418551e+000 2.998308e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.000000e+001 2.925000e+001 1.200000e+001 vertex 9.418551e+000 2.998308e+001 1.200000e+001 vertex 8.885036e+000 2.918256e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.885036e+000 2.918256e+001 1.200000e+001 vertex 9.418551e+000 2.998308e+001 1.200000e+001 vertex 8.263518e+000 2.984808e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.885036e+000 2.918256e+001 1.200000e+001 vertex 8.263518e+000 2.984808e+001 1.200000e+001 vertex 7.786330e+000 2.898121e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.786330e+000 2.898121e+001 1.200000e+001 vertex 8.263518e+000 2.984808e+001 1.200000e+001 vertex 7.131968e+000 2.957990e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.786330e+000 2.898121e+001 1.200000e+001 vertex 7.131968e+000 2.957990e+001 1.200000e+001 vertex 6.719904e+000 2.864890e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.719904e+000 2.864890e+001 1.200000e+001 vertex 7.131968e+000 2.957990e+001 1.200000e+001 vertex 6.039202e+000 2.918216e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.719904e+000 2.864890e+001 1.200000e+001 vertex 6.039202e+000 2.918216e+001 1.200000e+001 vertex 5.701311e+000 2.819047e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.701311e+000 2.819047e+001 1.200000e+001 vertex 6.039202e+000 2.918216e+001 1.200000e+001 vertex 5.000000e+000 2.866026e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.701311e+000 2.819047e+001 1.200000e+001 vertex 5.000000e+000 2.866026e+001 1.200000e+001 vertex 4.745401e+000 2.761260e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.745401e+000 2.761260e+001 1.200000e+001 vertex 5.000000e+000 2.866026e+001 1.200000e+001 vertex 4.028414e+000 2.802123e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.745401e+000 2.761260e+001 1.200000e+001 vertex 4.028414e+000 2.802123e+001 1.200000e+001 vertex 3.866115e+000 2.692372e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.866115e+000 2.692372e+001 1.200000e+001 vertex 4.028414e+000 2.802123e+001 1.200000e+001 vertex 3.137583e+000 2.727374e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.866115e+000 2.692372e+001 1.200000e+001 vertex 3.137583e+000 2.727374e+001 1.200000e+001 vertex 3.076275e+000 2.613388e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.076275e+000 2.613388e+001 1.200000e+001 vertex 3.137583e+000 2.727374e+001 1.200000e+001 vertex 2.339556e+000 2.642788e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.076275e+000 2.613388e+001 1.200000e+001 vertex 2.339556e+000 2.642788e+001 1.200000e+001 vertex 2.387399e+000 2.525460e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.387399e+000 2.525460e+001 1.200000e+001 vertex 2.339556e+000 2.642788e+001 1.200000e+001 vertex 1.645122e+000 2.549509e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.387399e+000 2.525460e+001 1.200000e+001 vertex 1.645122e+000 2.549509e+001 1.200000e+001 vertex 1.809532e+000 2.429869e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.809532e+000 2.429869e+001 1.200000e+001 vertex 1.645122e+000 2.549509e+001 1.200000e+001 vertex 1.063674e+000 2.448799e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.809532e+000 2.429869e+001 1.200000e+001 vertex 1.063674e+000 2.448799e+001 1.200000e+001 vertex 1.351099e+000 2.328010e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.351099e+000 2.328010e+001 1.200000e+001 vertex 1.063674e+000 2.448799e+001 1.200000e+001 vertex 6.030733e-001 2.342020e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.351099e+000 2.328010e+001 1.200000e+001 vertex 6.030733e-001 2.342020e+001 1.200000e+001 vertex 1.018788e+000 2.221367e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.018788e+000 2.221367e+001 1.200000e+001 vertex 6.030733e-001 2.342020e+001 1.200000e+001 vertex 2.695508e-001 2.230616e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.018788e+000 2.221367e+001 1.200000e+001 vertex 2.695508e-001 2.230616e+001 1.200000e+001 vertex 8.174423e-001 2.111496e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.174423e-001 2.111496e+001 1.200000e+001 vertex 2.695508e-001 2.230616e+001 1.200000e+001 vertex 6.761588e-002 2.116093e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.174423e-001 2.111496e+001 1.200000e+001 vertex 6.761588e-002 2.116093e+001 1.200000e+001 vertex 7.499996e-001 2.000000e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.499996e-001 2.000000e+001 1.200000e+001 vertex 6.761588e-002 2.116093e+001 1.200000e+001 vertex 0.000000e+000 2.000000e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.499996e-001 2.000000e+001 1.200000e+001 vertex 0.000000e+000 2.000000e+001 1.200000e+001 vertex 7.499996e-001 5.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.499996e-001 5.000000e+000 1.200000e+001 vertex 0.000000e+000 2.000000e+001 1.200000e+001 vertex 0.000000e+000 5.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.499996e-001 5.000000e+000 1.200000e+001 vertex 0.000000e+000 5.000000e+000 1.200000e+001 vertex 8.023242e-001 4.335154e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.023242e-001 4.335154e+000 1.200000e+001 vertex 0.000000e+000 5.000000e+000 1.200000e+001 vertex 6.155763e-002 4.217827e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.023242e-001 4.335154e+000 1.200000e+001 vertex 6.155763e-002 4.217827e+000 1.200000e+001 vertex 9.580096e-001 3.686678e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.580096e-001 3.686678e+000 1.200000e+001 vertex 6.155763e-002 4.217827e+000 1.200000e+001 vertex 2.447171e-001 3.454915e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.580096e-001 3.686678e+000 1.200000e+001 vertex 2.447171e-001 3.454915e+000 1.200000e+001 vertex 1.213222e+000 3.070540e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.213222e+000 3.070540e+000 1.200000e+001 vertex 2.447171e-001 3.454915e+000 1.200000e+001 vertex 5.449671e-001 2.730047e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.213222e+000 3.070540e+000 1.200000e+001 vertex 5.449671e-001 2.730047e+000 1.200000e+001 vertex 1.561678e+000 2.501912e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.561678e+000 2.501912e+000 1.200000e+001 vertex 5.449671e-001 2.730047e+000 1.200000e+001 vertex 9.549148e-001 2.061074e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.561678e+000 2.501912e+000 1.200000e+001 vertex 9.549148e-001 2.061074e+000 1.200000e+001 vertex 1.994796e+000 1.994796e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.994796e+000 1.994796e+000 1.200000e+001 vertex 9.549148e-001 2.061074e+000 1.200000e+001 vertex 1.464466e+000 1.464466e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.994796e+000 1.994796e+000 1.200000e+001 vertex 1.464466e+000 1.464466e+000 1.200000e+001 vertex 2.501912e+000 1.561678e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.501912e+000 1.561678e+000 1.200000e+001 vertex 1.464466e+000 1.464466e+000 1.200000e+001 vertex 2.061074e+000 9.549148e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.501912e+000 1.561678e+000 1.200000e+001 vertex 2.061074e+000 9.549148e-001 1.200000e+001 vertex 3.070540e+000 1.213222e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.070540e+000 1.213222e+000 1.200000e+001 vertex 2.061074e+000 9.549148e-001 1.200000e+001 vertex 2.730047e+000 5.449671e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.070540e+000 1.213222e+000 1.200000e+001 vertex 2.730047e+000 5.449671e-001 1.200000e+001 vertex 3.686678e+000 9.580096e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.686678e+000 9.580096e-001 1.200000e+001 vertex 2.730047e+000 5.449671e-001 1.200000e+001 vertex 3.454915e+000 2.447171e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.686678e+000 9.580096e-001 1.200000e+001 vertex 3.454915e+000 2.447171e-001 1.200000e+001 vertex 4.335154e+000 8.023242e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.335154e+000 8.023242e-001 1.200000e+001 vertex 3.454915e+000 2.447171e-001 1.200000e+001 vertex 4.217827e+000 6.155763e-002 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.335154e+000 8.023242e-001 1.200000e+001 vertex 4.217827e+000 6.155763e-002 1.200000e+001 vertex 5.000000e+000 7.499996e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.000000e+000 7.499996e-001 1.200000e+001 vertex 4.217827e+000 6.155763e-002 1.200000e+001 vertex 5.000000e+000 0.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.000000e+000 7.499996e-001 1.200000e+001 vertex 5.000000e+000 0.000000e+000 1.200000e+001 vertex 1.925000e+001 7.499996e-001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.925000e+001 7.499996e-001 1.200000e+001 vertex 5.000000e+000 0.000000e+000 1.200000e+001 vertex 2.000000e+001 0.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.925000e+001 7.499996e-001 1.200000e+001 vertex 2.000000e+001 0.000000e+000 1.200000e+001 vertex 1.925000e+001 2.000000e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.925000e+001 2.000000e+001 1.200000e+001 vertex 2.000000e+001 0.000000e+000 1.200000e+001 vertex 2.000000e+001 2.000000e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.925000e+001 2.000000e+001 1.200000e+001 vertex 2.000000e+001 2.000000e+001 1.200000e+001 vertex 1.918256e+001 2.111496e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.918256e+001 2.111496e+001 1.200000e+001 vertex 2.000000e+001 2.000000e+001 1.200000e+001 vertex 1.993238e+001 2.116093e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.918256e+001 2.111496e+001 1.200000e+001 vertex 1.993238e+001 2.116093e+001 1.200000e+001 vertex 1.898121e+001 2.221367e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.898121e+001 2.221367e+001 1.200000e+001 vertex 1.993238e+001 2.116093e+001 1.200000e+001 vertex 1.973045e+001 2.230616e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.898121e+001 2.221367e+001 1.200000e+001 vertex 1.973045e+001 2.230616e+001 1.200000e+001 vertex 1.864890e+001 2.328010e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.864890e+001 2.328010e+001 1.200000e+001 vertex 1.973045e+001 2.230616e+001 1.200000e+001 vertex 1.939693e+001 2.342020e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.864890e+001 2.328010e+001 1.200000e+001 vertex 1.939693e+001 2.342020e+001 1.200000e+001 vertex 1.819047e+001 2.429869e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.819047e+001 2.429869e+001 1.200000e+001 vertex 1.939693e+001 2.342020e+001 1.200000e+001 vertex 1.893633e+001 2.448799e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.819047e+001 2.429869e+001 1.200000e+001 vertex 1.893633e+001 2.448799e+001 1.200000e+001 vertex 1.761260e+001 2.525460e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.761260e+001 2.525460e+001 1.200000e+001 vertex 1.893633e+001 2.448799e+001 1.200000e+001 vertex 1.835488e+001 2.549509e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.761260e+001 2.525460e+001 1.200000e+001 vertex 1.835488e+001 2.549509e+001 1.200000e+001 vertex 1.692372e+001 2.613388e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.692372e+001 2.613388e+001 1.200000e+001 vertex 1.835488e+001 2.549509e+001 1.200000e+001 vertex 1.766044e+001 2.642788e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.692372e+001 2.613388e+001 1.200000e+001 vertex 1.766044e+001 2.642788e+001 1.200000e+001 vertex 1.613388e+001 2.692372e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.613388e+001 2.692372e+001 1.200000e+001 vertex 1.766044e+001 2.642788e+001 1.200000e+001 vertex 1.686242e+001 2.727374e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.613388e+001 2.692372e+001 1.200000e+001 vertex 1.686242e+001 2.727374e+001 1.200000e+001 vertex 1.525460e+001 2.761260e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.525460e+001 2.761260e+001 1.200000e+001 vertex 1.686242e+001 2.727374e+001 1.200000e+001 vertex 1.597159e+001 2.802123e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.525460e+001 2.761260e+001 1.200000e+001 vertex 1.597159e+001 2.802123e+001 1.200000e+001 vertex 1.429869e+001 2.819047e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.429869e+001 2.819047e+001 1.200000e+001 vertex 1.597159e+001 2.802123e+001 1.200000e+001 vertex 1.500000e+001 2.866026e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.429869e+001 2.819047e+001 1.200000e+001 vertex 1.500000e+001 2.866026e+001 1.200000e+001 vertex 1.328010e+001 2.864890e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.328010e+001 2.864890e+001 1.200000e+001 vertex 1.500000e+001 2.866026e+001 1.200000e+001 vertex 1.396080e+001 2.918216e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.328010e+001 2.864890e+001 1.200000e+001 vertex 1.396080e+001 2.918216e+001 1.200000e+001 vertex 1.221367e+001 2.898121e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.221367e+001 2.898121e+001 1.200000e+001 vertex 1.396080e+001 2.918216e+001 1.200000e+001 vertex 1.286803e+001 2.957990e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.221367e+001 2.898121e+001 1.200000e+001 vertex 1.286803e+001 2.957990e+001 1.200000e+001 vertex 1.111496e+001 2.918256e+001 1.200000e+001 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 8.885036e+000 2.918256e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.885036e+000 2.918256e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.885036e+000 2.918256e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 1.000000e+001 2.925000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.000000e+001 2.925000e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.000000e+001 2.925000e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 1.111496e+001 2.918256e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.111496e+001 2.918256e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.111496e+001 2.918256e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.221367e+001 2.898121e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.221367e+001 2.898121e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.221367e+001 2.898121e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.328010e+001 2.864890e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.328010e+001 2.864890e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.328010e+001 2.864890e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.429869e+001 2.819047e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.429869e+001 2.819047e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.429869e+001 2.819047e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.525460e+001 2.761260e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.525460e+001 2.761260e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.525460e+001 2.761260e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.613388e+001 2.692372e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.613388e+001 2.692372e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.613388e+001 2.692372e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.692372e+001 2.613388e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.692372e+001 2.613388e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.692372e+001 2.613388e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.761260e+001 2.525460e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.761260e+001 2.525460e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.761260e+001 2.525460e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.819047e+001 2.429869e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.819047e+001 2.429869e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.819047e+001 2.429869e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.864890e+001 2.328010e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.864890e+001 2.328010e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.864890e+001 2.328010e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.898121e+001 2.221367e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.898121e+001 2.221367e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.898121e+001 2.221367e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.918256e+001 2.111496e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.918256e+001 2.111496e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.918256e+001 2.111496e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 1.925000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.925000e+001 2.000000e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.925000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 1.925000e+001 7.499996e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.925000e+001 7.499996e-001 0.000000e+000 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.925000e+001 7.499996e-001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 7.499996e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 7.499996e-001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 7.499996e-001 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 4.335154e+000 8.023242e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.335154e+000 8.023242e-001 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.335154e+000 8.023242e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 3.686678e+000 9.580096e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.686678e+000 9.580096e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.686678e+000 9.580096e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 3.070540e+000 1.213222e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.070540e+000 1.213222e+000 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.070540e+000 1.213222e+000 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.501912e+000 1.561678e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.501912e+000 1.561678e+000 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.501912e+000 1.561678e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 1.994796e+000 1.994796e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.994796e+000 1.994796e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.994796e+000 1.994796e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 1.561678e+000 2.501912e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.561678e+000 2.501912e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.561678e+000 2.501912e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 1.213222e+000 3.070540e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.213222e+000 3.070540e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.213222e+000 3.070540e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 9.580096e-001 3.686678e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.580096e-001 3.686678e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 9.580096e-001 3.686678e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 8.023242e-001 4.335154e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.023242e-001 4.335154e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.023242e-001 4.335154e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 7.499996e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.499996e-001 5.000000e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.499996e-001 5.000000e+000 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 7.499996e-001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.499996e-001 2.000000e+001 0.000000e+000 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.499996e-001 2.000000e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 8.174423e-001 2.111496e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.174423e-001 2.111496e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.174423e-001 2.111496e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 1.018788e+000 2.221367e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.018788e+000 2.221367e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.018788e+000 2.221367e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 1.351099e+000 2.328010e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.351099e+000 2.328010e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.351099e+000 2.328010e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 1.809532e+000 2.429869e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.809532e+000 2.429869e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.809532e+000 2.429869e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 2.387399e+000 2.525460e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.387399e+000 2.525460e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.387399e+000 2.525460e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 3.076275e+000 2.613388e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.076275e+000 2.613388e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.076275e+000 2.613388e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 3.866115e+000 2.692372e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.866115e+000 2.692372e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.866115e+000 2.692372e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 4.745401e+000 2.761260e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.745401e+000 2.761260e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.745401e+000 2.761260e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 5.701311e+000 2.819047e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.701311e+000 2.819047e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.701311e+000 2.819047e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 6.719904e+000 2.864890e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.719904e+000 2.864890e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.719904e+000 2.864890e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 7.786330e+000 2.898121e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.786330e+000 2.898121e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.786330e+000 2.898121e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 8.885036e+000 2.918256e+001 0.000000e+000 endloop endfacet facet normal 9.992487e-001 3.875592e-002 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 1.200000e+001 vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 0.000000e+000 endloop endfacet facet normal 9.969914e-001 7.751183e-002 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 1.200000e+001 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 1.993238e+001 2.116093e+001 1.200000e+001 endloop endfacet facet normal 9.879928e-001 1.544996e-001 0.000000e+000 outer loop vertex 1.993238e+001 2.116093e+001 1.200000e+001 vertex 1.993238e+001 2.116093e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 0.000000e+000 endloop endfacet facet normal 9.812515e-001 1.927314e-001 0.000000e+000 outer loop vertex 1.993238e+001 2.116093e+001 1.200000e+001 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.973045e+001 2.230616e+001 1.200000e+001 endloop endfacet facet normal 9.633761e-001 2.681538e-001 0.000000e+000 outer loop vertex 1.973045e+001 2.230616e+001 1.200000e+001 vertex 1.973045e+001 2.230616e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 0.000000e+000 endloop endfacet facet normal 9.522419e-001 3.053445e-001 0.000000e+000 outer loop vertex 1.973045e+001 2.230616e+001 1.200000e+001 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.939693e+001 2.342020e+001 1.200000e+001 endloop endfacet facet normal 9.257313e-001 3.781818e-001 0.000000e+000 outer loop vertex 1.939693e+001 2.342020e+001 1.200000e+001 vertex 1.939693e+001 2.342020e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 0.000000e+000 endloop endfacet facet normal 9.103549e-001 4.138285e-001 0.000000e+000 outer loop vertex 1.939693e+001 2.342020e+001 1.200000e+001 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.893633e+001 2.448799e+001 1.200000e+001 endloop endfacet facet normal 8.755676e-001 4.830956e-001 0.000000e+000 outer loop vertex 1.893633e+001 2.448799e+001 1.200000e+001 vertex 1.893633e+001 2.448799e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 0.000000e+000 endloop endfacet facet normal 8.561568e-001 5.167161e-001 0.000000e+000 outer loop vertex 1.893633e+001 2.448799e+001 1.200000e+001 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.835488e+001 2.549509e+001 1.200000e+001 endloop endfacet facet normal 8.135634e-001 5.814762e-001 0.000000e+000 outer loop vertex 1.835488e+001 2.549509e+001 1.200000e+001 vertex 1.835488e+001 2.549509e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 0.000000e+000 endloop endfacet facet normal 7.903807e-001 6.126159e-001 0.000000e+000 outer loop vertex 1.835488e+001 2.549509e+001 1.200000e+001 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.766044e+001 2.642788e+001 1.200000e+001 endloop endfacet facet normal 7.405571e-001 6.719934e-001 0.000000e+000 outer loop vertex 1.766044e+001 2.642788e+001 1.200000e+001 vertex 1.766044e+001 2.642788e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 0.000000e+000 endloop endfacet facet normal 7.139161e-001 7.002313e-001 0.000000e+000 outer loop vertex 1.766044e+001 2.642788e+001 1.200000e+001 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.686242e+001 2.727374e+001 1.200000e+001 endloop endfacet facet normal 6.575360e-001 7.534231e-001 0.000000e+000 outer loop vertex 1.686242e+001 2.727374e+001 1.200000e+001 vertex 1.686242e+001 2.727374e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 0.000000e+000 endloop endfacet facet normal 6.277969e-001 7.783771e-001 0.000000e+000 outer loop vertex 1.686242e+001 2.727374e+001 1.200000e+001 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.597159e+001 2.802123e+001 1.200000e+001 endloop endfacet facet normal 5.656230e-001 8.246640e-001 0.000000e+000 outer loop vertex 1.597159e+001 2.802123e+001 1.200000e+001 vertex 1.597159e+001 2.802123e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 0.000000e+000 endloop endfacet facet normal 5.331879e-001 8.459968e-001 0.000000e+000 outer loop vertex 1.597159e+001 2.802123e+001 1.200000e+001 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.500000e+001 2.866026e+001 1.200000e+001 endloop endfacet facet normal 4.660608e-001 8.847528e-001 0.000000e+000 outer loop vertex 1.500000e+001 2.866026e+001 1.200000e+001 vertex 1.500000e+001 2.866026e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 0.000000e+000 endloop endfacet facet normal 4.313685e-001 9.021758e-001 0.000000e+000 outer loop vertex 1.500000e+001 2.866026e+001 1.200000e+001 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.396080e+001 2.918216e+001 1.200000e+001 endloop endfacet facet normal 3.601959e-001 9.328767e-001 0.000000e+000 outer loop vertex 1.396080e+001 2.918216e+001 1.200000e+001 vertex 1.396080e+001 2.918216e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 0.000000e+000 endloop endfacet facet normal 3.237155e-001 9.461545e-001 0.000000e+000 outer loop vertex 1.396080e+001 2.918216e+001 1.200000e+001 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.286803e+001 2.957990e+001 1.200000e+001 endloop endfacet facet normal 2.494600e-001 9.683850e-001 0.000000e+000 outer loop vertex 1.286803e+001 2.957990e+001 1.200000e+001 vertex 1.286803e+001 2.957990e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 0.000000e+000 endloop endfacet facet normal 2.116849e-001 9.773380e-001 0.000000e+000 outer loop vertex 1.286803e+001 2.957990e+001 1.200000e+001 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.173648e+001 2.984808e+001 1.200000e+001 endloop endfacet facet normal 1.353506e-001 9.907978e-001 0.000000e+000 outer loop vertex 1.173648e+001 2.984808e+001 1.200000e+001 vertex 1.173648e+001 2.984808e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 0.000000e+000 endloop endfacet facet normal 9.679149e-002 9.953047e-001 0.000000e+000 outer loop vertex 1.173648e+001 2.984808e+001 1.200000e+001 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 1.058145e+001 2.998308e+001 1.200000e+001 endloop endfacet facet normal 1.941080e-002 9.998116e-001 0.000000e+000 outer loop vertex 1.058145e+001 2.998308e+001 1.200000e+001 vertex 1.058145e+001 2.998308e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 0.000000e+000 endloop endfacet facet normal -1.941080e-002 9.998116e-001 0.000000e+000 outer loop vertex 1.058145e+001 2.998308e+001 1.200000e+001 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 9.418551e+000 2.998308e+001 1.200000e+001 endloop endfacet facet normal -9.679149e-002 9.953047e-001 0.000000e+000 outer loop vertex 9.418551e+000 2.998308e+001 1.200000e+001 vertex 9.418551e+000 2.998308e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 0.000000e+000 endloop endfacet facet normal -1.353506e-001 9.907978e-001 0.000000e+000 outer loop vertex 9.418551e+000 2.998308e+001 1.200000e+001 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 8.263518e+000 2.984808e+001 1.200000e+001 endloop endfacet facet normal -2.116849e-001 9.773380e-001 0.000000e+000 outer loop vertex 8.263518e+000 2.984808e+001 1.200000e+001 vertex 8.263518e+000 2.984808e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 0.000000e+000 endloop endfacet facet normal -2.494600e-001 9.683850e-001 0.000000e+000 outer loop vertex 8.263518e+000 2.984808e+001 1.200000e+001 vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 7.131968e+000 2.957990e+001 1.200000e+001 endloop endfacet facet normal -3.237155e-001 9.461545e-001 0.000000e+000 outer loop vertex 7.131968e+000 2.957990e+001 1.200000e+001 vertex 7.131968e+000 2.957990e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 0.000000e+000 endloop endfacet facet normal -3.601959e-001 9.328767e-001 0.000000e+000 outer loop vertex 7.131968e+000 2.957990e+001 1.200000e+001 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 6.039202e+000 2.918216e+001 1.200000e+001 endloop endfacet facet normal -4.313685e-001 9.021758e-001 0.000000e+000 outer loop vertex 6.039202e+000 2.918216e+001 1.200000e+001 vertex 6.039202e+000 2.918216e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 0.000000e+000 endloop endfacet facet normal -4.660608e-001 8.847528e-001 0.000000e+000 outer loop vertex 6.039202e+000 2.918216e+001 1.200000e+001 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 5.000000e+000 2.866026e+001 1.200000e+001 endloop endfacet facet normal -5.331879e-001 8.459968e-001 0.000000e+000 outer loop vertex 5.000000e+000 2.866026e+001 1.200000e+001 vertex 5.000000e+000 2.866026e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 0.000000e+000 endloop endfacet facet normal -5.656230e-001 8.246640e-001 0.000000e+000 outer loop vertex 5.000000e+000 2.866026e+001 1.200000e+001 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 4.028414e+000 2.802123e+001 1.200000e+001 endloop endfacet facet normal -6.277969e-001 7.783771e-001 0.000000e+000 outer loop vertex 4.028414e+000 2.802123e+001 1.200000e+001 vertex 4.028414e+000 2.802123e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 0.000000e+000 endloop endfacet facet normal -6.575360e-001 7.534231e-001 0.000000e+000 outer loop vertex 4.028414e+000 2.802123e+001 1.200000e+001 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 3.137583e+000 2.727374e+001 1.200000e+001 endloop endfacet facet normal -7.139161e-001 7.002313e-001 0.000000e+000 outer loop vertex 3.137583e+000 2.727374e+001 1.200000e+001 vertex 3.137583e+000 2.727374e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 0.000000e+000 endloop endfacet facet normal -7.405571e-001 6.719934e-001 0.000000e+000 outer loop vertex 3.137583e+000 2.727374e+001 1.200000e+001 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 2.339556e+000 2.642788e+001 1.200000e+001 endloop endfacet facet normal -7.903807e-001 6.126159e-001 0.000000e+000 outer loop vertex 2.339556e+000 2.642788e+001 1.200000e+001 vertex 2.339556e+000 2.642788e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 0.000000e+000 endloop endfacet facet normal -8.135634e-001 5.814762e-001 0.000000e+000 outer loop vertex 2.339556e+000 2.642788e+001 1.200000e+001 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 1.645122e+000 2.549509e+001 1.200000e+001 endloop endfacet facet normal -8.561568e-001 5.167161e-001 0.000000e+000 outer loop vertex 1.645122e+000 2.549509e+001 1.200000e+001 vertex 1.645122e+000 2.549509e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 0.000000e+000 endloop endfacet facet normal -8.755676e-001 4.830956e-001 0.000000e+000 outer loop vertex 1.645122e+000 2.549509e+001 1.200000e+001 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 1.063674e+000 2.448799e+001 1.200000e+001 endloop endfacet facet normal -9.103549e-001 4.138285e-001 0.000000e+000 outer loop vertex 1.063674e+000 2.448799e+001 1.200000e+001 vertex 1.063674e+000 2.448799e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 0.000000e+000 endloop endfacet facet normal -9.257313e-001 3.781818e-001 0.000000e+000 outer loop vertex 1.063674e+000 2.448799e+001 1.200000e+001 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 6.030733e-001 2.342020e+001 1.200000e+001 endloop endfacet facet normal -9.522419e-001 3.053445e-001 0.000000e+000 outer loop vertex 6.030733e-001 2.342020e+001 1.200000e+001 vertex 6.030733e-001 2.342020e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 0.000000e+000 endloop endfacet facet normal -9.633761e-001 2.681538e-001 0.000000e+000 outer loop vertex 6.030733e-001 2.342020e+001 1.200000e+001 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 2.695508e-001 2.230616e+001 1.200000e+001 endloop endfacet facet normal -9.812515e-001 1.927314e-001 0.000000e+000 outer loop vertex 2.695508e-001 2.230616e+001 1.200000e+001 vertex 2.695508e-001 2.230616e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 0.000000e+000 endloop endfacet facet normal -9.879928e-001 1.544996e-001 0.000000e+000 outer loop vertex 2.695508e-001 2.230616e+001 1.200000e+001 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 6.761588e-002 2.116093e+001 1.200000e+001 endloop endfacet facet normal -9.969914e-001 7.751183e-002 0.000000e+000 outer loop vertex 6.761588e-002 2.116093e+001 1.200000e+001 vertex 6.761588e-002 2.116093e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal -9.992487e-001 3.875592e-002 0.000000e+000 outer loop vertex 6.761588e-002 2.116093e+001 1.200000e+001 vertex 0.000000e+000 2.000000e+001 0.000000e+000 vertex 0.000000e+000 2.000000e+001 1.200000e+001 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 1.200000e+001 vertex 0.000000e+000 2.000000e+001 1.200000e+001 vertex 0.000000e+000 5.000000e+000 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 0.000000e+000 2.000000e+001 1.200000e+001 vertex 0.000000e+000 2.000000e+001 0.000000e+000 endloop endfacet facet normal -9.986320e-001 -5.228807e-002 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 1.200000e+001 vertex 0.000000e+000 5.000000e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 0.000000e+000 endloop endfacet facet normal -9.945168e-001 -1.045761e-001 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 1.200000e+001 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 6.155763e-002 4.217827e+000 1.200000e+001 endloop endfacet facet normal -9.781576e-001 -2.078648e-001 0.000000e+000 outer loop vertex 6.155763e-002 4.217827e+000 1.200000e+001 vertex 6.155763e-002 4.217827e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 0.000000e+000 endloop endfacet facet normal -9.659134e-001 -2.588654e-001 0.000000e+000 outer loop vertex 6.155763e-002 4.217827e+000 1.200000e+001 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 2.447171e-001 3.454915e+000 1.200000e+001 endloop endfacet facet normal -9.335976e-001 -3.583232e-001 0.000000e+000 outer loop vertex 2.447171e-001 3.454915e+000 1.200000e+001 vertex 2.447171e-001 3.454915e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 0.000000e+000 endloop endfacet facet normal -9.135259e-001 -4.067805e-001 0.000000e+000 outer loop vertex 2.447171e-001 3.454915e+000 1.200000e+001 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 5.449671e-001 2.730047e+000 1.200000e+001 endloop endfacet facet normal -8.660493e-001 -4.999585e-001 0.000000e+000 outer loop vertex 5.449671e-001 2.730047e+000 1.200000e+001 vertex 5.449671e-001 2.730047e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 0.000000e+000 endloop endfacet facet normal -8.386444e-001 -5.446792e-001 0.000000e+000 outer loop vertex 5.449671e-001 2.730047e+000 1.200000e+001 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 9.549148e-001 2.061074e+000 1.200000e+001 endloop endfacet facet normal -7.771761e-001 -6.292831e-001 0.000000e+000 outer loop vertex 9.549148e-001 2.061074e+000 1.200000e+001 vertex 9.549148e-001 2.061074e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 0.000000e+000 endloop endfacet facet normal -7.431127e-001 -6.691663e-001 0.000000e+000 outer loop vertex 9.549148e-001 2.061074e+000 1.200000e+001 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 1.464466e+000 1.464466e+000 1.200000e+001 endloop endfacet facet normal -6.691663e-001 -7.431127e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 1.200000e+001 vertex 1.464466e+000 1.464466e+000 0.000000e+000 vertex 2.061074e+000 9.549148e-001 0.000000e+000 endloop endfacet facet normal -6.292831e-001 -7.771761e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 1.200000e+001 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 2.061074e+000 9.549148e-001 1.200000e+001 endloop endfacet facet normal -5.446792e-001 -8.386444e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549148e-001 1.200000e+001 vertex 2.061074e+000 9.549148e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 0.000000e+000 endloop endfacet facet normal -4.999585e-001 -8.660493e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549148e-001 1.200000e+001 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 2.730047e+000 5.449671e-001 1.200000e+001 endloop endfacet facet normal -4.067805e-001 -9.135259e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449671e-001 1.200000e+001 vertex 2.730047e+000 5.449671e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 0.000000e+000 endloop endfacet facet normal -3.583232e-001 -9.335976e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449671e-001 1.200000e+001 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 3.454915e+000 2.447171e-001 1.200000e+001 endloop endfacet facet normal -2.588654e-001 -9.659134e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447171e-001 1.200000e+001 vertex 3.454915e+000 2.447171e-001 0.000000e+000 vertex 4.217827e+000 6.155763e-002 0.000000e+000 endloop endfacet facet normal -2.078648e-001 -9.781576e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447171e-001 1.200000e+001 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 4.217827e+000 6.155763e-002 1.200000e+001 endloop endfacet facet normal -1.045761e-001 -9.945168e-001 0.000000e+000 outer loop vertex 4.217827e+000 6.155763e-002 1.200000e+001 vertex 4.217827e+000 6.155763e-002 0.000000e+000 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal -5.228807e-002 -9.986320e-001 0.000000e+000 outer loop vertex 4.217827e+000 6.155763e-002 1.200000e+001 vertex 5.000000e+000 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 0.000000e+000 1.200000e+001 vertex 5.000000e+000 0.000000e+000 1.200000e+001 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 0.000000e+000 0.000000e+000 vertex 5.000000e+000 0.000000e+000 1.200000e+001 vertex 5.000000e+000 0.000000e+000 0.000000e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 1.200000e+001 vertex 2.000000e+001 0.000000e+000 1.200000e+001 vertex 2.000000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 2.000000e+001 0.000000e+000 vertex 2.000000e+001 0.000000e+000 1.200000e+001 vertex 2.000000e+001 0.000000e+000 0.000000e+000 endloop endfacet facet normal 9.991899e-001 -4.024415e-002 0.000000e+000 outer loop vertex 7.499996e-001 2.000000e+001 1.200000e+001 vertex 7.499996e-001 2.000000e+001 0.000000e+000 vertex 8.174423e-001 2.111496e+001 0.000000e+000 endloop endfacet facet normal 9.967556e-001 -8.048830e-002 0.000000e+000 outer loop vertex 7.499996e-001 2.000000e+001 1.200000e+001 vertex 8.174423e-001 2.111496e+001 0.000000e+000 vertex 8.174423e-001 2.111496e+001 1.200000e+001 endloop endfacet facet normal 9.870538e-001 -1.603898e-001 0.000000e+000 outer loop vertex 8.174423e-001 2.111496e+001 1.200000e+001 vertex 8.174423e-001 2.111496e+001 0.000000e+000 vertex 1.018788e+000 2.221367e+001 0.000000e+000 endloop endfacet facet normal 9.797863e-001 -2.000470e-001 0.000000e+000 outer loop vertex 8.174423e-001 2.111496e+001 1.200000e+001 vertex 1.018788e+000 2.221367e+001 0.000000e+000 vertex 1.018788e+000 2.221367e+001 1.200000e+001 endloop endfacet facet normal 9.605242e-001 -2.781965e-001 0.000000e+000 outer loop vertex 1.018788e+000 2.221367e+001 1.200000e+001 vertex 1.018788e+000 2.221367e+001 0.000000e+000 vertex 1.351099e+000 2.328010e+001 0.000000e+000 endloop endfacet facet normal 9.485295e-001 -3.166887e-001 0.000000e+000 outer loop vertex 1.018788e+000 2.221367e+001 1.200000e+001 vertex 1.351099e+000 2.328010e+001 0.000000e+000 vertex 1.351099e+000 2.328010e+001 1.200000e+001 endloop endfacet facet normal 9.199880e-001 -3.919466e-001 0.000000e+000 outer loop vertex 1.351099e+000 2.328010e+001 1.200000e+001 vertex 1.351099e+000 2.328010e+001 0.000000e+000 vertex 1.809532e+000 2.429869e+001 0.000000e+000 endloop endfacet facet normal 9.034411e-001 -4.287122e-001 0.000000e+000 outer loop vertex 1.351099e+000 2.328010e+001 1.200000e+001 vertex 1.809532e+000 2.429869e+001 0.000000e+000 vertex 1.809532e+000 2.429869e+001 1.200000e+001 endloop endfacet facet normal 8.660363e-001 -4.999811e-001 0.000000e+000 outer loop vertex 1.809532e+000 2.429869e+001 1.200000e+001 vertex 1.809532e+000 2.429869e+001 0.000000e+000 vertex 2.387399e+000 2.525460e+001 0.000000e+000 endloop endfacet facet normal 8.451784e-001 -5.344843e-001 0.000000e+000 outer loop vertex 1.809532e+000 2.429869e+001 1.200000e+001 vertex 2.387399e+000 2.525460e+001 0.000000e+000 vertex 2.387399e+000 2.525460e+001 1.200000e+001 endloop endfacet facet normal 7.994559e-001 -6.007248e-001 0.000000e+000 outer loop vertex 2.387399e+000 2.525460e+001 1.200000e+001 vertex 2.387399e+000 2.525460e+001 0.000000e+000 vertex 3.076275e+000 2.613388e+001 0.000000e+000 endloop endfacet facet normal 7.745912e-001 -6.324623e-001 0.000000e+000 outer loop vertex 2.387399e+000 2.525460e+001 1.200000e+001 vertex 3.076275e+000 2.613388e+001 0.000000e+000 vertex 3.076275e+000 2.613388e+001 1.200000e+001 endloop endfacet facet normal 7.212176e-001 -6.927086e-001 0.000000e+000 outer loop vertex 3.076275e+000 2.613388e+001 1.200000e+001 vertex 3.076275e+000 2.613388e+001 0.000000e+000 vertex 3.866115e+000 2.692372e+001 0.000000e+000 endloop endfacet facet normal 6.927086e-001 -7.212176e-001 0.000000e+000 outer loop vertex 3.076275e+000 2.613388e+001 1.200000e+001 vertex 3.866115e+000 2.692372e+001 0.000000e+000 vertex 3.866115e+000 2.692372e+001 1.200000e+001 endloop endfacet facet normal 6.324623e-001 -7.745912e-001 0.000000e+000 outer loop vertex 3.866115e+000 2.692372e+001 1.200000e+001 vertex 3.866115e+000 2.692372e+001 0.000000e+000 vertex 4.745401e+000 2.761260e+001 0.000000e+000 endloop endfacet facet normal 6.007248e-001 -7.994559e-001 0.000000e+000 outer loop vertex 3.866115e+000 2.692372e+001 1.200000e+001 vertex 4.745401e+000 2.761260e+001 0.000000e+000 vertex 4.745401e+000 2.761260e+001 1.200000e+001 endloop endfacet facet normal 5.344843e-001 -8.451784e-001 0.000000e+000 outer loop vertex 4.745401e+000 2.761260e+001 1.200000e+001 vertex 4.745401e+000 2.761260e+001 0.000000e+000 vertex 5.701311e+000 2.819047e+001 0.000000e+000 endloop endfacet facet normal 4.999811e-001 -8.660363e-001 0.000000e+000 outer loop vertex 4.745401e+000 2.761260e+001 1.200000e+001 vertex 5.701311e+000 2.819047e+001 0.000000e+000 vertex 5.701311e+000 2.819047e+001 1.200000e+001 endloop endfacet facet normal 4.287122e-001 -9.034411e-001 0.000000e+000 outer loop vertex 5.701311e+000 2.819047e+001 1.200000e+001 vertex 5.701311e+000 2.819047e+001 0.000000e+000 vertex 6.719904e+000 2.864890e+001 0.000000e+000 endloop endfacet facet normal 3.919466e-001 -9.199880e-001 0.000000e+000 outer loop vertex 5.701311e+000 2.819047e+001 1.200000e+001 vertex 6.719904e+000 2.864890e+001 0.000000e+000 vertex 6.719904e+000 2.864890e+001 1.200000e+001 endloop endfacet facet normal 3.166887e-001 -9.485295e-001 0.000000e+000 outer loop vertex 6.719904e+000 2.864890e+001 1.200000e+001 vertex 6.719904e+000 2.864890e+001 0.000000e+000 vertex 7.786330e+000 2.898121e+001 0.000000e+000 endloop endfacet facet normal 2.781965e-001 -9.605242e-001 0.000000e+000 outer loop vertex 6.719904e+000 2.864890e+001 1.200000e+001 vertex 7.786330e+000 2.898121e+001 0.000000e+000 vertex 7.786330e+000 2.898121e+001 1.200000e+001 endloop endfacet facet normal 2.000470e-001 -9.797863e-001 0.000000e+000 outer loop vertex 7.786330e+000 2.898121e+001 1.200000e+001 vertex 7.786330e+000 2.898121e+001 0.000000e+000 vertex 8.885036e+000 2.918256e+001 0.000000e+000 endloop endfacet facet normal 1.603898e-001 -9.870538e-001 0.000000e+000 outer loop vertex 7.786330e+000 2.898121e+001 1.200000e+001 vertex 8.885036e+000 2.918256e+001 0.000000e+000 vertex 8.885036e+000 2.918256e+001 1.200000e+001 endloop endfacet facet normal 8.048830e-002 -9.967556e-001 0.000000e+000 outer loop vertex 8.885036e+000 2.918256e+001 1.200000e+001 vertex 8.885036e+000 2.918256e+001 0.000000e+000 vertex 1.000000e+001 2.925000e+001 0.000000e+000 endloop endfacet facet normal 4.024415e-002 -9.991899e-001 0.000000e+000 outer loop vertex 8.885036e+000 2.918256e+001 1.200000e+001 vertex 1.000000e+001 2.925000e+001 0.000000e+000 vertex 1.000000e+001 2.925000e+001 1.200000e+001 endloop endfacet facet normal -4.024415e-002 -9.991899e-001 0.000000e+000 outer loop vertex 1.000000e+001 2.925000e+001 1.200000e+001 vertex 1.000000e+001 2.925000e+001 0.000000e+000 vertex 1.111496e+001 2.918256e+001 0.000000e+000 endloop endfacet facet normal -8.048830e-002 -9.967556e-001 0.000000e+000 outer loop vertex 1.000000e+001 2.925000e+001 1.200000e+001 vertex 1.111496e+001 2.918256e+001 0.000000e+000 vertex 1.111496e+001 2.918256e+001 1.200000e+001 endloop endfacet facet normal -1.603898e-001 -9.870538e-001 0.000000e+000 outer loop vertex 1.111496e+001 2.918256e+001 1.200000e+001 vertex 1.111496e+001 2.918256e+001 0.000000e+000 vertex 1.221367e+001 2.898121e+001 0.000000e+000 endloop endfacet facet normal -2.000470e-001 -9.797863e-001 0.000000e+000 outer loop vertex 1.111496e+001 2.918256e+001 1.200000e+001 vertex 1.221367e+001 2.898121e+001 0.000000e+000 vertex 1.221367e+001 2.898121e+001 1.200000e+001 endloop endfacet facet normal -2.781965e-001 -9.605242e-001 0.000000e+000 outer loop vertex 1.221367e+001 2.898121e+001 1.200000e+001 vertex 1.221367e+001 2.898121e+001 0.000000e+000 vertex 1.328010e+001 2.864890e+001 0.000000e+000 endloop endfacet facet normal -3.166887e-001 -9.485295e-001 0.000000e+000 outer loop vertex 1.221367e+001 2.898121e+001 1.200000e+001 vertex 1.328010e+001 2.864890e+001 0.000000e+000 vertex 1.328010e+001 2.864890e+001 1.200000e+001 endloop endfacet facet normal -3.919466e-001 -9.199880e-001 0.000000e+000 outer loop vertex 1.328010e+001 2.864890e+001 1.200000e+001 vertex 1.328010e+001 2.864890e+001 0.000000e+000 vertex 1.429869e+001 2.819047e+001 0.000000e+000 endloop endfacet facet normal -4.287122e-001 -9.034411e-001 0.000000e+000 outer loop vertex 1.328010e+001 2.864890e+001 1.200000e+001 vertex 1.429869e+001 2.819047e+001 0.000000e+000 vertex 1.429869e+001 2.819047e+001 1.200000e+001 endloop endfacet facet normal -4.999811e-001 -8.660363e-001 0.000000e+000 outer loop vertex 1.429869e+001 2.819047e+001 1.200000e+001 vertex 1.429869e+001 2.819047e+001 0.000000e+000 vertex 1.525460e+001 2.761260e+001 0.000000e+000 endloop endfacet facet normal -5.344843e-001 -8.451784e-001 0.000000e+000 outer loop vertex 1.429869e+001 2.819047e+001 1.200000e+001 vertex 1.525460e+001 2.761260e+001 0.000000e+000 vertex 1.525460e+001 2.761260e+001 1.200000e+001 endloop endfacet facet normal -6.007248e-001 -7.994559e-001 0.000000e+000 outer loop vertex 1.525460e+001 2.761260e+001 1.200000e+001 vertex 1.525460e+001 2.761260e+001 0.000000e+000 vertex 1.613388e+001 2.692372e+001 0.000000e+000 endloop endfacet facet normal -6.324623e-001 -7.745912e-001 0.000000e+000 outer loop vertex 1.525460e+001 2.761260e+001 1.200000e+001 vertex 1.613388e+001 2.692372e+001 0.000000e+000 vertex 1.613388e+001 2.692372e+001 1.200000e+001 endloop endfacet facet normal -6.927086e-001 -7.212176e-001 0.000000e+000 outer loop vertex 1.613388e+001 2.692372e+001 1.200000e+001 vertex 1.613388e+001 2.692372e+001 0.000000e+000 vertex 1.692372e+001 2.613388e+001 0.000000e+000 endloop endfacet facet normal -7.212176e-001 -6.927086e-001 0.000000e+000 outer loop vertex 1.613388e+001 2.692372e+001 1.200000e+001 vertex 1.692372e+001 2.613388e+001 0.000000e+000 vertex 1.692372e+001 2.613388e+001 1.200000e+001 endloop endfacet facet normal -7.745912e-001 -6.324623e-001 0.000000e+000 outer loop vertex 1.692372e+001 2.613388e+001 1.200000e+001 vertex 1.692372e+001 2.613388e+001 0.000000e+000 vertex 1.761260e+001 2.525460e+001 0.000000e+000 endloop endfacet facet normal -7.994559e-001 -6.007248e-001 0.000000e+000 outer loop vertex 1.692372e+001 2.613388e+001 1.200000e+001 vertex 1.761260e+001 2.525460e+001 0.000000e+000 vertex 1.761260e+001 2.525460e+001 1.200000e+001 endloop endfacet facet normal -8.451784e-001 -5.344843e-001 0.000000e+000 outer loop vertex 1.761260e+001 2.525460e+001 1.200000e+001 vertex 1.761260e+001 2.525460e+001 0.000000e+000 vertex 1.819047e+001 2.429869e+001 0.000000e+000 endloop endfacet facet normal -8.660363e-001 -4.999811e-001 0.000000e+000 outer loop vertex 1.761260e+001 2.525460e+001 1.200000e+001 vertex 1.819047e+001 2.429869e+001 0.000000e+000 vertex 1.819047e+001 2.429869e+001 1.200000e+001 endloop endfacet facet normal -9.034411e-001 -4.287122e-001 0.000000e+000 outer loop vertex 1.819047e+001 2.429869e+001 1.200000e+001 vertex 1.819047e+001 2.429869e+001 0.000000e+000 vertex 1.864890e+001 2.328010e+001 0.000000e+000 endloop endfacet facet normal -9.199880e-001 -3.919466e-001 0.000000e+000 outer loop vertex 1.819047e+001 2.429869e+001 1.200000e+001 vertex 1.864890e+001 2.328010e+001 0.000000e+000 vertex 1.864890e+001 2.328010e+001 1.200000e+001 endloop endfacet facet normal -9.485295e-001 -3.166887e-001 0.000000e+000 outer loop vertex 1.864890e+001 2.328010e+001 1.200000e+001 vertex 1.864890e+001 2.328010e+001 0.000000e+000 vertex 1.898121e+001 2.221367e+001 0.000000e+000 endloop endfacet facet normal -9.605242e-001 -2.781965e-001 0.000000e+000 outer loop vertex 1.864890e+001 2.328010e+001 1.200000e+001 vertex 1.898121e+001 2.221367e+001 0.000000e+000 vertex 1.898121e+001 2.221367e+001 1.200000e+001 endloop endfacet facet normal -9.797863e-001 -2.000470e-001 0.000000e+000 outer loop vertex 1.898121e+001 2.221367e+001 1.200000e+001 vertex 1.898121e+001 2.221367e+001 0.000000e+000 vertex 1.918256e+001 2.111496e+001 0.000000e+000 endloop endfacet facet normal -9.870538e-001 -1.603898e-001 0.000000e+000 outer loop vertex 1.898121e+001 2.221367e+001 1.200000e+001 vertex 1.918256e+001 2.111496e+001 0.000000e+000 vertex 1.918256e+001 2.111496e+001 1.200000e+001 endloop endfacet facet normal -9.967556e-001 -8.048830e-002 0.000000e+000 outer loop vertex 1.918256e+001 2.111496e+001 1.200000e+001 vertex 1.918256e+001 2.111496e+001 0.000000e+000 vertex 1.925000e+001 2.000000e+001 0.000000e+000 endloop endfacet facet normal -9.991899e-001 -4.024415e-002 0.000000e+000 outer loop vertex 1.918256e+001 2.111496e+001 1.200000e+001 vertex 1.925000e+001 2.000000e+001 0.000000e+000 vertex 1.925000e+001 2.000000e+001 1.200000e+001 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 7.499996e-001 2.000000e+001 1.200000e+001 vertex 7.499996e-001 5.000000e+000 1.200000e+001 vertex 7.499996e-001 2.000000e+001 0.000000e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 7.499996e-001 2.000000e+001 0.000000e+000 vertex 7.499996e-001 5.000000e+000 1.200000e+001 vertex 7.499996e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 5.228807e-002 9.986320e-001 0.000000e+000 outer loop vertex 5.000000e+000 7.499996e-001 1.200000e+001 vertex 5.000000e+000 7.499996e-001 0.000000e+000 vertex 4.335154e+000 8.023242e-001 0.000000e+000 endloop endfacet facet normal 1.045761e-001 9.945168e-001 0.000000e+000 outer loop vertex 5.000000e+000 7.499996e-001 1.200000e+001 vertex 4.335154e+000 8.023242e-001 0.000000e+000 vertex 4.335154e+000 8.023242e-001 1.200000e+001 endloop endfacet facet normal 2.078648e-001 9.781576e-001 0.000000e+000 outer loop vertex 4.335154e+000 8.023242e-001 1.200000e+001 vertex 4.335154e+000 8.023242e-001 0.000000e+000 vertex 3.686678e+000 9.580096e-001 0.000000e+000 endloop endfacet facet normal 2.588654e-001 9.659134e-001 0.000000e+000 outer loop vertex 4.335154e+000 8.023242e-001 1.200000e+001 vertex 3.686678e+000 9.580096e-001 0.000000e+000 vertex 3.686678e+000 9.580096e-001 1.200000e+001 endloop endfacet facet normal 3.583232e-001 9.335976e-001 0.000000e+000 outer loop vertex 3.686678e+000 9.580096e-001 1.200000e+001 vertex 3.686678e+000 9.580096e-001 0.000000e+000 vertex 3.070540e+000 1.213222e+000 0.000000e+000 endloop endfacet facet normal 4.067805e-001 9.135259e-001 0.000000e+000 outer loop vertex 3.686678e+000 9.580096e-001 1.200000e+001 vertex 3.070540e+000 1.213222e+000 0.000000e+000 vertex 3.070540e+000 1.213222e+000 1.200000e+001 endloop endfacet facet normal 4.999585e-001 8.660493e-001 0.000000e+000 outer loop vertex 3.070540e+000 1.213222e+000 1.200000e+001 vertex 3.070540e+000 1.213222e+000 0.000000e+000 vertex 2.501912e+000 1.561678e+000 0.000000e+000 endloop endfacet facet normal 5.446792e-001 8.386444e-001 0.000000e+000 outer loop vertex 3.070540e+000 1.213222e+000 1.200000e+001 vertex 2.501912e+000 1.561678e+000 0.000000e+000 vertex 2.501912e+000 1.561678e+000 1.200000e+001 endloop endfacet facet normal 6.292831e-001 7.771761e-001 0.000000e+000 outer loop vertex 2.501912e+000 1.561678e+000 1.200000e+001 vertex 2.501912e+000 1.561678e+000 0.000000e+000 vertex 1.994796e+000 1.994796e+000 0.000000e+000 endloop endfacet facet normal 6.691663e-001 7.431127e-001 0.000000e+000 outer loop vertex 2.501912e+000 1.561678e+000 1.200000e+001 vertex 1.994796e+000 1.994796e+000 0.000000e+000 vertex 1.994796e+000 1.994796e+000 1.200000e+001 endloop endfacet facet normal 7.431127e-001 6.691663e-001 0.000000e+000 outer loop vertex 1.994796e+000 1.994796e+000 1.200000e+001 vertex 1.994796e+000 1.994796e+000 0.000000e+000 vertex 1.561678e+000 2.501912e+000 0.000000e+000 endloop endfacet facet normal 7.771761e-001 6.292831e-001 0.000000e+000 outer loop vertex 1.994796e+000 1.994796e+000 1.200000e+001 vertex 1.561678e+000 2.501912e+000 0.000000e+000 vertex 1.561678e+000 2.501912e+000 1.200000e+001 endloop endfacet facet normal 8.386444e-001 5.446792e-001 0.000000e+000 outer loop vertex 1.561678e+000 2.501912e+000 1.200000e+001 vertex 1.561678e+000 2.501912e+000 0.000000e+000 vertex 1.213222e+000 3.070540e+000 0.000000e+000 endloop endfacet facet normal 8.660493e-001 4.999585e-001 0.000000e+000 outer loop vertex 1.561678e+000 2.501912e+000 1.200000e+001 vertex 1.213222e+000 3.070540e+000 0.000000e+000 vertex 1.213222e+000 3.070540e+000 1.200000e+001 endloop endfacet facet normal 9.135259e-001 4.067805e-001 0.000000e+000 outer loop vertex 1.213222e+000 3.070540e+000 1.200000e+001 vertex 1.213222e+000 3.070540e+000 0.000000e+000 vertex 9.580096e-001 3.686678e+000 0.000000e+000 endloop endfacet facet normal 9.335976e-001 3.583232e-001 0.000000e+000 outer loop vertex 1.213222e+000 3.070540e+000 1.200000e+001 vertex 9.580096e-001 3.686678e+000 0.000000e+000 vertex 9.580096e-001 3.686678e+000 1.200000e+001 endloop endfacet facet normal 9.659134e-001 2.588654e-001 0.000000e+000 outer loop vertex 9.580096e-001 3.686678e+000 1.200000e+001 vertex 9.580096e-001 3.686678e+000 0.000000e+000 vertex 8.023242e-001 4.335154e+000 0.000000e+000 endloop endfacet facet normal 9.781576e-001 2.078648e-001 0.000000e+000 outer loop vertex 9.580096e-001 3.686678e+000 1.200000e+001 vertex 8.023242e-001 4.335154e+000 0.000000e+000 vertex 8.023242e-001 4.335154e+000 1.200000e+001 endloop endfacet facet normal 9.945168e-001 1.045761e-001 0.000000e+000 outer loop vertex 8.023242e-001 4.335154e+000 1.200000e+001 vertex 8.023242e-001 4.335154e+000 0.000000e+000 vertex 7.499996e-001 5.000000e+000 0.000000e+000 endloop endfacet facet normal 9.986320e-001 5.228807e-002 0.000000e+000 outer loop vertex 8.023242e-001 4.335154e+000 1.200000e+001 vertex 7.499996e-001 5.000000e+000 0.000000e+000 vertex 7.499996e-001 5.000000e+000 1.200000e+001 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 7.499996e-001 1.200000e+001 vertex 1.925000e+001 7.499996e-001 1.200000e+001 vertex 5.000000e+000 7.499996e-001 0.000000e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 7.499996e-001 0.000000e+000 vertex 1.925000e+001 7.499996e-001 1.200000e+001 vertex 1.925000e+001 7.499996e-001 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.925000e+001 7.499996e-001 1.200000e+001 vertex 1.925000e+001 2.000000e+001 1.200000e+001 vertex 1.925000e+001 7.499996e-001 0.000000e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.925000e+001 7.499996e-001 0.000000e+000 vertex 1.925000e+001 2.000000e+001 1.200000e+001 vertex 1.925000e+001 2.000000e+001 0.000000e+000 endloop endfacet endsolidsfact-2011.12.18/calibration/accuracy.stl000066400000000000000000000070001167321211700200120ustar00rootroot00000000000000C:\Users\Ahmet\STL\Calibration\fittest.stl____________________________COLOR=‘ÜPÿF‚LµhÐJ³€¿¼ ÜBhHÑBÀo5¸ ÜBhHÅB€e5¼ ´BsHÑB½œ„7r«‚LµhÐJ³€¿¼ ´BsHÑB½œ„7¸ ÜBhHÅB€e5¸ ´BsHÅB;ý†7r«€¿«ªª6¸ ´BsHÅB;ý†7¸ ´BsHÅBC@¼ ´BsHÑB½œ„7r«€¿¨ªª65Žc¬¼ ´BsHÑB½œ„7¸ ´BsHÅBC@¼ ´BtHÑB@Ar«€¿«ªª6ˆˆˆ¬¸ ´BtHÅB@A¼ ´BtHÑB@A¸ ´BsHÅBC@r«ÌÌŒ6€?ªª*µ¼ ´BtHÑB@A¼ ÜBiHÑB@A¼ ´BsHÑB½œ„7r«ÌÌŒ6€?ªª*µ¼ ÜBhHÑBÀo5¼ ´BsHÑB½œ„7¼ ÜBiHÑB@Ar«€?«ªª¶8Žc,¼ ÜBiHÑB@A¸ ÜBhHÅB€e5¼ ÜBhHÑBÀo5r«€?òªª¶óªª-¸ ÜBhHÅB€e5¼ ÜBiHÑB@A¸ ÜBiHÅB@r«€?«ªª¶¸ ÜBiHÅB@¼ ÜBiHÑB@A¸ ÜBiHÅB@Ar«óÿ¶€¿€6¸ ÜBiHÅB@¸ ÐBlHÅB@¸ ÜBhHÅB€e5r«óÿ6€?€¶´ ÜBhH±BP"²5´ ÐBlH±B@´ ÜBiH±B@r«‚L5rÒJ3€?¸ ÜBhHÅB€e5¸ ´BsHÅB;ý†7´ ÜBhH±BP"²5r«‚L5¥ÒJ3€?´ ÜBhH±BP"²5¸ ´BsHÅB;ý†7´ ´BsH±BeóŠ7r«•$IµIÊL³€¿¸ ÐBlHÅB@´ ´BsH±BE@¸ ´BsHÅBC@r«Ý¶Mµ¨Ç̲€¿´ ÐBlH±B@´ ´BsH±BE@¸ ÐBlHÅB@r«€?ÍÌL¶´ ´BsH±BE@´ ´BsH±BeóŠ7¸ ´BsHÅB;ý†7r«€?ÍÌL¶¸ ´BsHÅB;ý†7¸ ´BsHÅBC@´ ´BsH±BE@r«ÌÌŒ¶€¿«*5° ´BsH¥BãS7° ÜBhH¥B@*Ø5² ´BtH¥B@Ar«ÌÌŒ¶€¿«*5² ÜBiH¥B@A² ´BtH¥B@A° ÜBhH¥B@*Ø5r«‚Lµ½ÐJ³€¿´ ´BsH±BeóŠ7´ ÜBhH±BP"²5° ÜBhH¥B@*Ø5r«‚LµhÐJ³€¿° ÜBhH¥B@*Ø5° ´BsH¥BãS7´ ´BsH±BeóŠ7r«€?«ªª¶«ªª-´ ÜBhH±BP"²5´ ÜBiH±B@° ÜBhH¥B@*Ø5r«€?¼qœ¶ªªµ´ ÜBiH±B@² ÜBiH¥B@A° ÜBhH¥B@*Ø5r«€?«ª*¶´ ÜBiH±B@´ ÜBiH±B@A² ÜBiH¥B@Ar«€¿«ªª6Žªª5² ´BtH¥B@A´ ´BsH±BeóŠ7° ´BsH¥BãS7r«€¿¹ª*6² ´BtH¥B@A´ ´BsH±BE@´ ´BsH±BeóŠ7r«€¿«ª*6ˆˆ¬´ ´BtH±B@A´ ´BsH±BE@² ´BtH¥B@Ar«ÍÌL5‰ˆˆ¬€?¼ ÜBiHÑB@A¼ ´BtHÑB@A¸ ´BtHÅB@Ar««ª*59Žc¬€?¸ ÜBiHÅB@A¼ ÜBiHÑB@A¸ ÐBlHÅB@Ar«©m[5N C´€?¼ ÜBiHÑB@A¸ ´BtHÅB@A¸ ÐBlHÅB@Ar«ýÿ¶€¿ÌÌL5¸ ´BtHÅB@A¸ ´BsHÅBC@¸ ÐBlHÅB@r«%I’¶€¿€¸ ÐBlHÅB@¸ ÐBlHÅB@A¸ ´BtHÅB@Ar«·m[5%I¬€?² ´BtH¥B@A´ ÐBlH±B@A´ ´BtH±B@Ar«Çª*5Žã4€?´ ÜBiH±B@A´ ÐBlH±B@A² ´BtH¥B@Ar«ÍÌL5‰ˆ¬€?² ´BtH¥B@A² ÜBiH¥B@A´ ÜBiH±B@Ar«#I’6€?ÌÌLµ´ ´BsH±BE@´ ´BtH±B@A´ ÐBlH±B@Ar«€6€?´ ÐBlH±B@´ ´BsH±BE@´ ÐBlH±B@Ar«ÈÌŒ¶€¿3336¸ ´BsHÅB;ý†7¸ ÜBhHÅB€e5¸ ÐBlHÅB@r«€¶€¿¸ ´BsHÅBC@¸ ´BsHÅB;ý†7¸ ÐBlHÅB@r«€6€?´ ´BsH±BeóŠ7´ ´BsH±BE@´ ÐBlH±B@r«ÈÌŒ6€?433¶´ ´BsH±BeóŠ7´ ÐBlH±B@´ ÜBhH±BP"²5r«±è¡¾–û|5åÜr¿¸ ÐBlHÅB@¸ ÜBhHÅB€e5´ ÐBlH±B@r«°è¡¾!w5åÜr¿¸ ÜBhHÅB€e5´ ÜBhH±BP"²5´ ÐBlH±B@r«€?ÍÌL¶ÎÌL-¸ ÜBiHÅB@´ ÜBiH±B@¸ ÜBhHÅB€e5r«€?ÍÌL¶ÎÌL-¸ ÜBhHÅB€e5´ ÜBiH±B@´ ÜBhH±BP"²5r«üLµ÷ÐJ³€¿DöÛBŒ·ÖBŠý4Jö³B˜·êBv¢7JöÛBŒ·êBr«‚LµºÑJ³€¿Jö³B˜·êBv¢7DöÛBŒ·ÖBŠý4Dö³B—·ÖBgǃ7r«ÓÌL5…ËÌ3€?Fö³B—·ÖB AJöÛB·êB AJö³B—·êB Ar«ÓÌL5…ËÌ3€?JöÛB·êB AFö³B—·ÖB AFöÛB·ÖB Ar«€?š™™¶Âu,JöÛB·êB ADöÛBŒ·ÖBŠý4JöÛBŒ·êBr«€?ÍÌL¶¸Ì̵DöÛBŒ·ÖBŠý4JöÛB·êB AFöÛB·ÖB Ar«ÍÌŒ¶€¿­Gá,DöÛBŒ·ÖBŠý4Fö³B—·ÖB ADö³B—·ÖBgǃ7r«ýÿ¶€¿3ÍL5Fö³B—·ÖB ADöÛBŒ·ÖBŠý4FöÛB·ÖB Ar«€¿’™™6ÌÌÌ5Fö³B—·ÖB AJö³B˜·êBv¢7Dö³B—·ÖBgǃ7r«€¿ÍÌL6 ×#,Jö³B˜·êBv¢7Fö³B—·ÖB AJö³B—·êB Ar«€6€?ÍÌL5JöÛB·êB AJö³B˜·êBv¢7Jö³B—·êB Ar«˜™™6€?ÍÌLµJö³B˜·êBv¢7JöÛB·êB AJöÛBŒ·êBr«€?ÍÌL¶¸ ÜBiHÅB@¸ ÜBiHÅB@A´ ÜBiH±B@r«€?ÍÌL¶´ ÜBiH±B@A´ ÜBiH±B@¸ ÜBiHÅB@Ar«€¿ÍÌL6¸ ÐBlHÅB@´ ÐBlH±B@´ ÐBlH±B@Ar«€¿ÍÌL6´ ÐBlH±B@A¸ ÐBlHÅB@A¸ ÐBlHÅB@r«±ª*5¼ËÌ3€?¸ ÜBiHÅB@A¸ ÐBlHÅB@A´ ÐBlH±B@Ar«±ª*5¼ËÌ3€?´ ÜBiH±B@A¸ ÜBiHÅB@A´ ÐBlH±B@Ar«€6€?¸ ÐBlHÅB@¸ ÐBlHÅB@A¸ ÜBiHÅB@Ar«€6€?¸ ÜBiHÅB@¸ ÐBlHÅB@¸ ÜBiHÅB@Ar«WUUµwÇ̲€¿¸ ÐBlHÅB@¸ ÜBiHÅB@´ ÐBlH±B@r«®ªJµDÊL³€¿´ ÜBiH±B@´ ÐBlH±B@¸ ÜBiHÅB@r«€¶€¿´ ÐBlH±B@´ ÜBiH±B@´ ÐBlH±B@Ar«€¶€¿€´ ÐBlH±B@A´ ÜBiH±B@´ ÜBiH±B@Ar«sfact-2011.12.18/calibration/bridge.STL000066400000000000000000000275561167321211700173360ustar00rootroot00000000000000solid _bridge facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.000000e+001 5.000000e-005 2.000025e+000 vertex 4.000000e+001 1.178630e-001 2.000025e+000 vertex 3.727253e+001 1.178630e-001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.000000e+001 8.845481e+000 2.000025e+000 vertex 4.000000e+001 2.500005e+001 2.000025e+000 vertex 3.727253e+001 8.845481e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.727253e+001 8.845481e+000 2.000025e+000 vertex 4.000000e+001 2.500005e+001 2.000025e+000 vertex 0.000000e+000 2.500005e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.727253e+001 8.845481e+000 2.000025e+000 vertex 0.000000e+000 2.500005e+001 2.000025e+000 vertex 3.727253e+001 1.178630e-001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.727253e+001 1.178630e-001 2.000025e+000 vertex 0.000000e+000 2.500005e+001 2.000025e+000 vertex 6.946949e-017 5.000000e-005 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.727253e+001 1.178630e-001 2.000025e+000 vertex 6.946949e-017 5.000000e-005 2.000025e+000 vertex 4.000000e+001 5.000000e-005 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.000000e+001 5.000000e-005 1.000025e+000 vertex 1.000000e+001 5.000000e-005 1.000025e+000 vertex 3.000000e+001 2.500005e+001 1.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.000000e+001 2.500005e+001 1.000025e+000 vertex 1.000000e+001 5.000000e-005 1.000025e+000 vertex 1.000000e+001 2.500005e+001 1.000025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 6.946949e-017 5.000000e-005 2.000025e+000 vertex 0.000000e+000 2.500005e+001 2.000025e+000 vertex 6.946949e-017 5.000000e-005 2.500000e-005 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 6.946949e-017 5.000000e-005 2.500000e-005 vertex 0.000000e+000 2.500005e+001 2.000025e+000 vertex 6.946949e-017 2.500005e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 5.000000e-005 2.500000e-005 vertex 4.000000e+001 5.000000e-005 2.500000e-005 vertex 2.000000e+001 5.000000e-005 1.000025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 5.000000e-005 1.000025e+000 vertex 4.000000e+001 5.000000e-005 2.500000e-005 vertex 4.000000e+001 5.000000e-005 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 5.000000e-005 1.000025e+000 vertex 4.000000e+001 5.000000e-005 2.000025e+000 vertex 1.000000e+001 5.000000e-005 1.000025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 1.000000e+001 5.000000e-005 1.000025e+000 vertex 4.000000e+001 5.000000e-005 2.000025e+000 vertex 6.946949e-017 5.000000e-005 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 1.000000e+001 5.000000e-005 1.000025e+000 vertex 6.946949e-017 5.000000e-005 2.000025e+000 vertex 1.000000e+001 5.000000e-005 2.500000e-005 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 1.000000e+001 5.000000e-005 2.500000e-005 vertex 6.946949e-017 5.000000e-005 2.000025e+000 vertex 6.946949e-017 5.000000e-005 2.500000e-005 endloop endfacet facet normal 1.000000e+000 6.938894e-017 0.000000e+000 outer loop vertex 1.000000e+001 2.500005e+001 1.000025e+000 vertex 1.000000e+001 5.000000e-005 1.000025e+000 vertex 1.000000e+001 2.500005e+001 2.500000e-005 endloop endfacet facet normal 1.000000e+000 6.938894e-017 0.000000e+000 outer loop vertex 1.000000e+001 2.500005e+001 2.500000e-005 vertex 1.000000e+001 5.000000e-005 1.000025e+000 vertex 1.000000e+001 5.000000e-005 2.500000e-005 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 1.000000e+001 2.500005e+001 2.500000e-005 vertex 6.946949e-017 2.500005e+001 2.500000e-005 vertex 1.000000e+001 2.500005e+001 1.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 1.000000e+001 2.500005e+001 1.000025e+000 vertex 6.946949e-017 2.500005e+001 2.500000e-005 vertex 0.000000e+000 2.500005e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 1.000000e+001 2.500005e+001 1.000025e+000 vertex 0.000000e+000 2.500005e+001 2.000025e+000 vertex 3.000000e+001 2.500005e+001 1.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.000000e+001 2.500005e+001 1.000025e+000 vertex 0.000000e+000 2.500005e+001 2.000025e+000 vertex 4.000000e+001 2.500005e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.000000e+001 2.500005e+001 1.000025e+000 vertex 4.000000e+001 2.500005e+001 2.000025e+000 vertex 3.000000e+001 2.500005e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.000000e+001 2.500005e+001 2.500000e-005 vertex 4.000000e+001 2.500005e+001 2.000025e+000 vertex 4.000000e+001 2.500005e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.000000e+001 2.500005e+001 2.500000e-005 vertex 1.000000e+001 5.000000e-005 2.500000e-005 vertex 6.946949e-017 2.500005e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.946949e-017 2.500005e+001 2.500000e-005 vertex 1.000000e+001 5.000000e-005 2.500000e-005 vertex 6.946949e-017 5.000000e-005 2.500000e-005 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.000000e+001 2.500005e+001 2.500000e-005 vertex 4.000000e+001 2.500005e+001 2.000025e+000 vertex 4.000000e+001 5.000000e-005 2.500000e-005 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.000000e+001 5.000000e-005 2.500000e-005 vertex 4.000000e+001 2.500005e+001 2.000025e+000 vertex 4.000000e+001 8.845481e+000 2.000025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.000000e+001 5.000000e-005 2.000025e+000 vertex 4.000000e+001 5.000000e-005 2.500000e-005 vertex 4.000000e+001 1.178630e-001 2.000025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.000000e+001 1.178630e-001 2.000025e+000 vertex 4.000000e+001 5.000000e-005 2.500000e-005 vertex 4.000000e+001 8.845481e+000 2.000025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.000000e+001 1.178630e-001 2.000025e+000 vertex 4.000000e+001 8.845481e+000 2.000025e+000 vertex 4.000000e+001 1.178630e-001 6.000025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.000000e+001 1.178630e-001 6.000025e+000 vertex 4.000000e+001 8.845481e+000 2.000025e+000 vertex 4.000000e+001 8.845481e+000 6.000025e+000 endloop endfacet facet normal -9.284767e-001 3.713907e-001 0.000000e+000 outer loop vertex 2.000000e+001 5.000000e-005 1.000025e+000 vertex 3.000000e+001 2.500005e+001 1.000025e+000 vertex 2.000000e+001 5.000000e-005 2.500000e-005 endloop endfacet facet normal -9.284767e-001 3.713907e-001 0.000000e+000 outer loop vertex 2.000000e+001 5.000000e-005 2.500000e-005 vertex 3.000000e+001 2.500005e+001 1.000025e+000 vertex 3.000000e+001 2.500005e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.000000e+001 5.000000e-005 2.500000e-005 vertex 2.000000e+001 5.000000e-005 2.500000e-005 vertex 4.000000e+001 2.500005e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.000000e+001 2.500005e+001 2.500000e-005 vertex 2.000000e+001 5.000000e-005 2.500000e-005 vertex 3.000000e+001 2.500005e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.727253e+001 8.845481e+000 6.000025e+000 vertex 4.000000e+001 8.845481e+000 6.000025e+000 vertex 3.727253e+001 8.845481e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.727253e+001 8.845481e+000 2.000025e+000 vertex 4.000000e+001 8.845481e+000 6.000025e+000 vertex 4.000000e+001 8.845481e+000 2.000025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.727253e+001 1.178630e-001 6.000025e+000 vertex 3.727253e+001 8.845481e+000 6.000025e+000 vertex 3.727253e+001 1.178630e-001 2.000025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.727253e+001 1.178630e-001 2.000025e+000 vertex 3.727253e+001 8.845481e+000 6.000025e+000 vertex 3.727253e+001 8.845481e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 4.000000e+001 1.178630e-001 6.000025e+000 vertex 3.727253e+001 1.178630e-001 6.000025e+000 vertex 4.000000e+001 1.178630e-001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 4.000000e+001 1.178630e-001 2.000025e+000 vertex 3.727253e+001 1.178630e-001 6.000025e+000 vertex 3.727253e+001 1.178630e-001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.727253e+001 8.845481e+000 6.000025e+000 vertex 3.727253e+001 1.178630e-001 6.000025e+000 vertex 4.000000e+001 8.845481e+000 6.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.000000e+001 8.845481e+000 6.000025e+000 vertex 3.727253e+001 1.178630e-001 6.000025e+000 vertex 4.000000e+001 1.178630e-001 6.000025e+000 endloop endfacet endsolidsfact-2011.12.18/calibration/calibration parts.jpg000066400000000000000000004337211167321211700216140ustar00rootroot00000000000000ÿØÿàJFIFHHÿáExifMM*bj(1r2އi¤Ð ü€' ü€'Adobe Photoshop CS4 Windows2011:08:29 22:56:51  3 œ&(.àHHÿØÿàJFIFHHÿí Adobe_CMÿîAdobed€ÿÛ„            ÿÀƒ "ÿÝ ÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?õ@”*Ùìê6RÓíª‹IŸk €6?1­}~ÿë®;­»®âäÔÞ£÷šÜMÌsëǺ x¯"œsW£sy¿ôÑSÝBK¤ýeÅÎsqïiÄÌ ~‰ÿEóùÔ[ô-[)I.ë[ëïÏÊŦÓÓ±é³ÐÇ ·}®‹÷ûw_ú_Òú~êkôéÿ o¨¹¶×ê_`ͼÛÒ.{‰!¿BòïÝÙû‰Â*}v\¿Õ.¼ëCzncí²ç—;ëH~æ´nô½Oçö±¾§éWQà¥BP°zÞÖ.³' ¨ýŸ°ÛI9€ïþf§]enÿBÿ´zŸèÿÁ¥‡õ§¥WU4Ý–ì“°›s !»úÙ]^ï¥þó?IïJ”ï$‡‘NU,È¡Ûê°KHñ÷BÆúÑÖrzIÃx>ŽCÝNN^Ý—»oÙ]nÙEŽõ*²ÏOéúI)Ý%­Î0¤“  šZæ‡4îk„‚ ‚ 󺵽Hìϼ›_X¶»\^úÚâÝßg®ôîªÏg±ž“ÿÓ~üú_Rê½%Íû.EM¬±ö[„ç9ÌŽcÖTï¡nGªëÌ[}þ•G…O¦*™ÝW¦ôà>Û“]À–1Î÷8¤YXý#öîüÖ¨tN©û[¦×éz>¡{K$8Kê·5ãé5ÛW׺ñŸÑ\çÈÊ ú¸¯h&ߦÃÿm[ëz u:w^é=Mί >ÆÌÖàæ<ùí®ÐǽŸËj¾¼Ë¡à×Õ烶ìr Ú ?ÍÝ[‡¹¿Gû]ßG¾ïOì™6Ù[e–;W9¼{ÿyÌýôLt°§M1à§Lx)ªÿÐõ@‡“FU.£!‚ÊÞ!Íp¤ðâÂàבíqi-–îU=¬ ý²§{HƒI™÷éwæ~çþ¬IM,ª˜Ë/s²¨kƒ©¦Ý[\k숻óýÞõ´TmD=¥ùm,sE@Ñ?£Ýê;nïßVÒSõ“êíkOÑfV?A¸jé“þÎc—û‹œÃú›Ÿž ™eø7ÒðÖXðË Ú×>w¶¢Æ¹û/®ï ÿôK¸½¶º¢Ú,Y¦×–ï.öngÒo·é*⎨HÝ—XÚîE_I²×C¦Ïk½¯¯þ-ÿ鲦¯Kú³ÓzmÃ%7e€æ‹ì2àw[é´{+õßvÅ­à‡ŽË™K[}¢ëDî°7`2d{vÝ­ö¢ ¥"6GÕ>—û,³Õõ-sž^,pp.ýÓù»V¦K2\cZÚlw¹ž ù»7×ô¿¬£MY,°¾ìU¥°Xïo¹Îýä”–ªý65›‹¶€7;“7;ùJ98ÔeQf>Em¶›ZYeo×4s\ÔM?))á+ú“Ôð³íÇÂ~ü€ì{¬|:½Nü{¶Í¶ìöúV7ùÏð‹wêN¢˜NeœÃÄU?ñïÿ¯ºÕ Ì~®Ý›S†“ú˜ú_áÿ9Šr˜ý×ä Ahƒp{=Ïs;Û¹*NÖµ h kD5£@ì21©É¥ÔÜÐö<Að:"!ÞÛÜÐ1ímNK›¼M»ëüäðNèù_UzÕwÕºÞ›xuõ%ÿÍÕt~íͫѷÿF-¾‰_TÈê,Ì}fœV5À‡èçn!Ÿ›ýµ±ö~©"rêxï4Aôöþ—þÚÿÁ=Uk»+¯m¶ú¦I€Ý濺Äj”•1à§Lx)ªÿÑõ@ƒ‘‡#"öTZÝîp6vï#÷7{w%›’10²2ÈÜ1ê}¥¾;_ôW!к^/XDzìû ™Ý‘x0ò]¯±ÿ›]àjþiŒö"©ì¨È£"¿WÆÝ\Æö88HäKT×)Pè}g šòxÊ'÷>%ãkߎ÷6½­õ1ÜÏOÔú~‚êÒ"”¥Tõ~”/û?Û)õƒ‹ =FÈp_?Îl÷úk'ëPû6bÏOíÏ,~€‡ÖÖÍôo/«ÑõXïçwéEÍ6ŒsuX™.¦‹ò7ÚÜ[î}ØLkžû+}{«§'mWúUÙk,·þÑý*ªŸFMà¹ÿ©ÝEùXvãÙc­v9k˜ç®Ö謹oú=®[™"÷QcqœÖ^ZEOxÜÐèö¹Í–î@è¥ò21ñiuù66š˜%Ö<†´|\å[§õŽ™Ô·}‹!·9„‡3V¸F›½;_³_ç?›^e™û[ïÙ½Vû¬ qØm{ž üåõ?½ž¦ÏøÏÑlý"U››o¯Žç1ÁÎÛen5–û…ŸÎ0±ÿ¿·{“¸TúÊg9¬kžòÖ‰s‰€îJÃú¯Ôú¶mOoQ¨Ò]VXhc\ø?OéoüïQôö*ÿ_ÍŒè•ÜÓí«*‡XÙ 9®>ˆkÿy¾¥•¿úèV´§O#ëK {l7Ÿ †áÿn{jÿÁLO®].ëßFNì75Ð×Û²?•k ›S¿ãÏ\î6^ ´ ¯¦Û_ɬXYþÛëÖ~]Oê7½˜x ^æmcGîµöîs¿·ký*Ó¸BŸO È:‚oQëØx-Ãp}¹.¯ÕØÑ a%{Þí­÷¹Ûµ^Æ¥´c×C ©c@âBâ¾½5Ôõ o­ed‚Góo­Ñíÿà £u7óþµç¶«UUmi »u†GΕkê÷Ö¯Ú·ýŽê= ¿U0±ì/ÀºÜ6»_E„:±ýFX×9ŸÔkö-‹jeÕ:«±Â$Ū¨è½44°SítÝ»éý/{Ñ”¢abä·)îvFT]–Kd{ý&45ÜßÎúkEU¯¥àU´²¨Øw7ÜãCå²ïÞj´‚š}S¤àõ\a˜ÍÍi­í;^Ç[ÇÑr̯ꫫ ë Z ZçVÃ`iúLmÛw7rÙÊÂÆË  / ;šœÑ>{ÝßÚ@=¦—eÎNçÿä‘…3éÝ3¦ÒjÇ^wÙcŒ½î?ž÷+^8ØxØ¥æ†mu‘¼’\Nѱ’ç—}dæu¾‰Ö* ·Ùc~€Oy÷ 7!à}ZéxŽ{}g¶l<63è+·t¼ï9×6˜ÁÎ7Qô\[Ò:sXX)Oæ—8Žþ.üÝÞÔTÜÐ@9˜x¹ØÖbåÖÛ¨´m²·‰sÿEÞæ;ó¸Ñ$áSõ?£Tv´ÜkZ¤ˆýÝßÏà‹_¯K¶U[N­`Oò£ó¿¬‡oKÁºÃmµo{Œ—;·;óQhÅ£¸ÒÍ…ð_êG}Q²¤¾+ë'Õºzã(¬qò1 6FæÃöúµÛ\³sé³ó÷­—;kK¼¡¼>ƹº8k ýà$E¼Þ7ÔöhsòÃëh• ’?•kœ÷mþ§ý¸º < ,½,J[K9;F¤þóÝô¬wòž‚Þ“„Ã-Æo`½ÄDîÛóweÔÔÆÊÛ ‰Ð5›?ïªÓ&<ŠG‚š—ÿÓôN¿ÕÒzEùõ°Xú¶×½ì§{¶û¶×êz›?=sWõüÜ–2Ì1O°}ìý/þ·þ¶UêýXêmýÜk,Ûë7þ¡q7$» €t)ð¥$oXë>ë¯Ä½Á§ÝéÜKëqôª|¿ÜáôëôlþZô‘1¯=×›baäõºéǩִXÏYÍÖ3sM†Ë>ƒG»Ûôפ¡%9=Kë>gØY»$V-x'k×6½Ï‡ûŸé¿ÚÆ,L߬½YíxªÆÒC\@©› ÿ…õ¿óÚ§õä[õ‹,n®«ñ…> Òúßcý2eÿAV7ØXÚ)sÜlÿÂKžO‹YïµJvþ®}mËÍË£§æVÛ_vàÌšý¿EŽ·ôÕýw§ôêýeu~ “ú·õ¨ÓÔÔrØ(®¶½gï±h2ŒÌû}…)쾯u§uŒ[.}‡Óg¤ñ;šãµ–î­Ä1ßá?=ŠÖoTéØs2I"C}ä&±úGñù­Tþ­t¬Ž—€êr\×[m®µÛ$!¬k787w¶µÎŒ\Lº21zÞ37ÓMn£0 ¸YKÿÇzžÿð>§îoLÒÔÚÏúøñ•f/O¢· Ür-sœ×4€ÿQ”Ôç}/ô»ÕLo®[%ÿifÐH$1¾“› þhþ“wõmÿ·.N3nÅÖÒû\ÀúÑ.÷ýº}/jÓÆú³Ôº…›™WÙêÐz¶i ýÚ¾“¿è'P {|<Úóúss*k™]Ì.kl8 G»i{é u/¬3¦]V.M„åd £%ïOo·þ¹b±‰Š0ºmxÛ… ÷q;[·wö‘lÆÆ»iº¦X[ÆöƒÏÒMþ(êätÏ­Ý/?'쮜[Þâ(eÅ¿¤6µÕ:Æ6ßø»ú/Qm?è;àVÖ/«}# üƒSqìmns¬®¹ço¥ŸÏqôgÕ.©Ô·Œ3¿+akl:¶¡Å»/>ëþÒ{ßgÐôÿF•u {&}üsÁLϠ߀Nx(ÿÔõ2ÐæÁÔ.vΑõOû+®ilUP»Ò—£[Yúoú¾‚èÂI)¯‡n)k¨Æ¯Òe:ll}Õ¶vîVI%#ȯÊ\Ü–1õG½¶æÀýæ»Ú¨bftŠ„áãš‹šµ”:·H ke~í~ƒ–¢I)…V6Ú›c>‹Àp¾-üÕ$é$¦P«¦Ë31Ùs¾‹I¬Xæ·÷¾‹¬ôš–6vèꡎca‘YcA÷Gæ·fýªòI)e ©®úÝU­cÄ9§PAЂlü·áã;!˜öå–ÄÕ@i|ô¢×ÔݬüïrJrðq~®tÀ;\=9­¥Ì±äÝÜÇ{Y³jÕ§7ûM4’ç5¡çÚàØ'oóŽnÍÚ}OÖûm±ïn;Muv8'Õµ®Íÿ;·mwóUÿÅÛêWé-^•ÖkÏšÞÑUànkAÜ×3ó_Sỿ–‰ª‚æ8H }Èæ v·Ô­ÞíöÊs”’ Å„zh~ÖÇ<ÖÿúúQÚ­¨ýž­­l°hMÞݧùJÚIÆPé>h—Y_Ñfˆh#ÁN˜ðS?ÿÕôn±ÕYÒpNcé²ö4€á\{Aÿ iq*oç¿ó!›õ£ªdå³"™Ç®­¥˜âÇÓ¼ºßOÐõ}Vû66»Ç5¯ik„‚5 Šë¿WßÓžr1ksðœI±Œjþ[ßs¨ÿI[?™þr¿Ñ}Fº©ÝéZ0z‰m6²å»AS̵ÇþÝ7ÿSÙoüÙ\'@êçmuzUl¸þm?IßÛô×kÓ0ß……^+î~C«™¶Ã.2wGõ[ôX¢›I$’ RI&$48À’x%.’¤:¾­mL³~󵯖¢Ñtz~ïÍ÷+€‚$qâ’—Q±íƒ§Ÿ‚¡—׺~0?¤»ˆi³Ä:×–Õôïo\Ç\úÌìÇ[ÒØkžÉ}—ŸWÖN¡V;¬æ1í‚=7µß¦Ê³?;íýaŸõïÏ¿Ó5ö Ïs)eŒý+µ=îôÛs[þ§=ÿ¦­ŸðŸà½EŒ_•[,ËêÏnF;…Ý)®®Þ »wO¯uÍÅÈk=W'ô¾…öú‹kí]k­YYÀÀmXí;ê·/sX×£etWdúmÞÚÿš¯þ?@õ½3<æPM ¾³²ÖŽ$~{?õqft>•gNÇ"ë‘‘k—Üà¹ä5žÊ™ì¦ªëc+ª–}ë­5J’I$”¤Ç‚1धÿÖõ@©ÝwUi>ž%V·q &âÒDû\áè»gòýÏW ÒR s•¹âö±­™¯a$ƺ>9:I)I$’JR§ÕqY—v3ôe¬,q€ïðþUný#UÄÄ<Sç>žc3¬È£ß“{vå9ö:=PïO+ ¬öÔÌgb²ê~ÐïOôµz—«ê«?¶+êVâôÜ\Œ›[–Ë-u¶‡µ¬ôZ.¡÷²ÀÍîûCke¸ìý_ùÊìüűÔpzž.e—àÐ̺r ÝA³Ñ{lhôÛ‘MŽe•?Ô¥µ×}OÿC]µÿ„Uéè½s5î7=2›¾¼ =g÷ý?PsC¿öŒO±Jyî¨Öeg~Ÿ)ÍÈK¦ãTu77vÝ×_éÓK«}õ=ÿ­czöjôÞÔ,nÊΕŽH%˜Ç}æÚIÔnªýl¯Óî–~âézgÕÞ›Ó™ÔÒv®s¿¯k÷Zÿó–£ZÖˆhà2*pºgÔþ“ƒa¼R{Žâ÷—Xà|ZûfÞ?5n2¶0CD)$š¥$’I)I$’JRcÁN˜ðRSÿ×õAÂuòªI)ú©%òªI)ú©%òªI)ú©%òªI)ú¡ß/šqÂùY$”ýT’ùU$”ýT’ùU$”ýT’ùU$”ýT’ùU$”ýT˜ðWÊÉ$§ÿÙÿíèPhotoshop 3.08BIM%8BIMíHH8BIM&?€8BIM x8BIM8BIMó 8BIM' 8BIMõH/fflff/ff¡™š2Z5-8BIMøpÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè8BIM8BIM8BIM08BIM-8BIM@@8BIM8BIMIœ3 Untitled-13œnullboundsObjcRct1Top longLeftlongBtomlongœRghtlong3slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlongœRghtlong3urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM( ?ð8BIM8BIM ü ƒàõ àÿØÿàJFIFHHÿí Adobe_CMÿîAdobed€ÿÛ„            ÿÀƒ "ÿÝ ÿÄ?   3!1AQa"q2‘¡±B#$RÁb34r‚ÑC%’Sðáñcs5¢²ƒ&D“TdE£t6ÒUâeò³„ÃÓuãóF'”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷5!1AQaq"2‘¡±B#ÁRÑð3$bár‚’CScs4ñ%¢²ƒ&5ÂÒD“T£dEU6teâò³„ÃÓuãóF”¤…´•ÄÔäô¥µÅÕåõVfv†–¦¶ÆÖæö'7GWgw‡—§·ÇÿÚ ?õ@”*Ùìê6RÓíª‹IŸk €6?1­}~ÿë®;­»®âäÔÞ£÷šÜMÌsëǺ x¯"œsW£sy¿ôÑSÝBK¤ýeÅÎsqïiÄÌ ~‰ÿEóùÔ[ô-[)I.ë[ëïÏÊŦÓÓ±é³ÐÇ ·}®‹÷ûw_ú_Òú~êkôéÿ o¨¹¶×ê_`ͼÛÒ.{‰!¿BòïÝÙû‰Â*}v\¿Õ.¼ëCzncí²ç—;ëH~æ´nô½Oçö±¾§éWQà¥BP°zÞÖ.³' ¨ýŸ°ÛI9€ïþf§]enÿBÿ´zŸèÿÁ¥‡õ§¥WU4Ý–ì“°›s !»úÙ]^ï¥þó?IïJ”ï$‡‘NU,È¡Ûê°KHñ÷BÆúÑÖrzIÃx>ŽCÝNN^Ý—»oÙ]nÙEŽõ*²ÏOéúI)Ý%­Î0¤“  šZæ‡4îk„‚ ‚ 󺵽Hìϼ›_X¶»\^úÚâÝßg®ôîªÏg±ž“ÿÓ~üú_Rê½%Íû.EM¬±ö[„ç9ÌŽcÖTï¡nGªëÌ[}þ•G…O¦*™ÝW¦ôà>Û“]À–1Î÷8¤YXý#öîüÖ¨tN©û[¦×éz>¡{K$8Kê·5ãé5ÛW׺ñŸÑ\çÈÊ ú¸¯h&ߦÃÿm[ëz u:w^é=Mί >ÆÌÖàæ<ùí®ÐǽŸËj¾¼Ë¡à×Õ烶ìr Ú ?ÍÝ[‡¹¿Gû]ßG¾ïOì™6Ù[e–;W9¼{ÿyÌýôLt°§M1à§Lx)ªÿÐõ@‡“FU.£!‚ÊÞ!Íp¤ðâÂàבíqi-–îU=¬ ý²§{HƒI™÷éwæ~çþ¬IM,ª˜Ë/s²¨kƒ©¦Ý[\k숻óýÞõ´TmD=¥ùm,sE@Ñ?£Ýê;nïßVÒSõ“êíkOÑfV?A¸jé“þÎc—û‹œÃú›Ÿž ™eø7ÒðÖXðË Ú×>w¶¢Æ¹û/®ï ÿôK¸½¶º¢Ú,Y¦×–ï.öngÒo·é*⎨HÝ—XÚîE_I²×C¦Ïk½¯¯þ-ÿ鲦¯Kú³ÓzmÃ%7e€æ‹ì2àw[é´{+õßvÅ­à‡ŽË™K[}¢ëDî°7`2d{vÝ­ö¢ ¥"6GÕ>—û,³Õõ-sž^,pp.ýÓù»V¦K2\cZÚlw¹ž ù»7×ô¿¬£MY,°¾ìU¥°Xïo¹Îýä”–ªý65›‹¶€7;“7;ùJ98ÔeQf>Em¶›ZYeo×4s\ÔM?))á+ú“Ôð³íÇÂ~ü€ì{¬|:½Nü{¶Í¶ìöúV7ùÏð‹wêN¢˜NeœÃÄU?ñïÿ¯ºÕ Ì~®Ý›S†“ú˜ú_áÿ9Šr˜ý×ä Ahƒp{=Ïs;Û¹*NÖµ h kD5£@ì21©É¥ÔÜÐö<Að:"!ÞÛÜÐ1ímNK›¼M»ëüäðNèù_UzÕwÕºÞ›xuõ%ÿÍÕt~íͫѷÿF-¾‰_TÈê,Ì}fœV5À‡èçn!Ÿ›ýµ±ö~©"rêxï4Aôöþ—þÚÿÁ=Uk»+¯m¶ú¦I€Ý濺Äj”•1à§Lx)ªÿÑõ@ƒ‘‡#"öTZÝîp6vï#÷7{w%›’10²2ÈÜ1ê}¥¾;_ôW!к^/XDzìû ™Ý‘x0ò]¯±ÿ›]àjþiŒö"©ì¨È£"¿WÆÝ\Æö88HäKT×)Pè}g šòxÊ'÷>%ãkߎ÷6½­õ1ÜÏOÔú~‚êÒ"”¥Tõ~”/û?Û)õƒ‹ =FÈp_?Îl÷úk'ëPû6bÏOíÏ,~€‡ÖÖÍôo/«ÑõXïçwéEÍ6ŒsuX™.¦‹ò7ÚÜ[î}ØLkžû+}{«§'mWúUÙk,·þÑý*ªŸFMà¹ÿ©ÝEùXvãÙc­v9k˜ç®Ö謹oú=®[™"÷QcqœÖ^ZEOxÜÐèö¹Í–î@è¥ò21ñiuù66š˜%Ö<†´|\å[§õŽ™Ô·}‹!·9„‡3V¸F›½;_³_ç?›^e™û[ïÙ½Vû¬ qØm{ž üåõ?½ž¦ÏøÏÑlý"U››o¯Žç1ÁÎÛen5–û…ŸÎ0±ÿ¿·{“¸TúÊg9¬kžòÖ‰s‰€îJÃú¯Ôú¶mOoQ¨Ò]VXhc\ø?OéoüïQôö*ÿ_ÍŒè•ÜÓí«*‡XÙ 9®>ˆkÿy¾¥•¿úèV´§O#ëK {l7Ÿ †áÿn{jÿÁLO®].ëßFNì75Ð×Û²?•k ›S¿ãÏ\î6^ ´ ¯¦Û_ɬXYþÛëÖ~]Oê7½˜x ^æmcGîµöîs¿·ký*Ó¸BŸO È:‚oQëØx-Ãp}¹.¯ÕØÑ a%{Þí­÷¹Ûµ^Æ¥´c×C ©c@âBâ¾½5Ôõ o­ed‚Góo­Ñíÿà £u7óþµç¶«UUmi »u†GΕkê÷Ö¯Ú·ýŽê= ¿U0±ì/ÀºÜ6»_E„:±ýFX×9ŸÔkö-‹jeÕ:«±Â$Ū¨è½44°SítÝ»éý/{Ñ”¢abä·)îvFT]–Kd{ý&45ÜßÎúkEU¯¥àU´²¨Øw7ÜãCå²ïÞj´‚š}S¤àõ\a˜ÍÍi­í;^Ç[ÇÑr̯ꫫ ë Z ZçVÃ`iúLmÛw7rÙÊÂÆË  / ;šœÑ>{ÝßÚ@=¦—eÎNçÿä‘…3éÝ3¦ÒjÇ^wÙcŒ½î?ž÷+^8ØxØ¥æ†mu‘¼’\Nѱ’ç—}dæu¾‰Ö* ·Ùc~€Oy÷ 7!à}ZéxŽ{}g¶l<63è+·t¼ï9×6˜ÁÎ7Qô\[Ò:sXX)Oæ—8Žþ.üÝÞÔTÜÐ@9˜x¹ØÖbåÖÛ¨´m²·‰sÿEÞæ;ó¸Ñ$áSõ?£Tv´ÜkZ¤ˆýÝßÏà‹_¯K¶U[N­`Oò£ó¿¬‡oKÁºÃmµo{Œ—;·;óQhÅ£¸ÒÍ…ð_êG}Q²¤¾+ë'Õºzã(¬qò1 6FæÃöúµÛ\³sé³ó÷­—;kK¼¡¼>ƹº8k ýà$E¼Þ7ÔöhsòÃëh• ’?•kœ÷mþ§ý¸º < ,½,J[K9;F¤þóÝô¬wòž‚Þ“„Ã-Æo`½ÄDîÛóweÔÔÆÊÛ ‰Ð5›?ïªÓ&<ŠG‚š—ÿÓôN¿ÕÒzEùõ°Xú¶×½ì§{¶û¶×êz›?=sWõüÜ–2Ì1O°}ìý/þ·þ¶UêýXêmýÜk,Ûë7þ¡q7$» €t)ð¥$oXë>ë¯Ä½Á§ÝéÜKëqôª|¿ÜáôëôlþZô‘1¯=×›baäõºéǩִXÏYÍÖ3sM†Ë>ƒG»Ûôפ¡%9=Kë>gØY»$V-x'k×6½Ï‡ûŸé¿ÚÆ,L߬½YíxªÆÒC\@©› ÿ…õ¿óÚ§õä[õ‹,n®«ñ…> Òúßcý2eÿAV7ØXÚ)sÜlÿÂKžO‹YïµJvþ®}mËÍË£§æVÛ_vàÌšý¿EŽ·ôÕýw§ôêýeu~ “ú·õ¨ÓÔÔrØ(®¶½gï±h2ŒÌû}…)쾯u§uŒ[.}‡Óg¤ñ;šãµ–î­Ä1ßá?=ŠÖoTéØs2I"C}ä&±úGñù­Tþ­t¬Ž—€êr\×[m®µÛ$!¬k787w¶µÎŒ\Lº21zÞ37ÓMn£0 ¸YKÿÇzžÿð>§îoLÒÔÚÏúøñ•f/O¢· Ür-sœ×4€ÿQ”Ôç}/ô»ÕLo®[%ÿifÐH$1¾“› þhþ“wõmÿ·.N3nÅÖÒû\ÀúÑ.÷ýº}/jÓÆú³Ôº…›™WÙêÐz¶i ýÚ¾“¿è'P {|<Úóúss*k™]Ì.kl8 G»i{é u/¬3¦]V.M„åd £%ïOo·þ¹b±‰Š0ºmxÛ… ÷q;[·wö‘lÆÆ»iº¦X[ÆöƒÏÒMþ(êätÏ­Ý/?'쮜[Þâ(eÅ¿¤6µÕ:Æ6ßø»ú/Qm?è;àVÖ/«}# üƒSqìmns¬®¹ço¥ŸÏqôgÕ.©Ô·Œ3¿+akl:¶¡Å»/>ëþÒ{ßgÐôÿF•u {&}üsÁLϠ߀Nx(ÿÔõ2ÐæÁÔ.vΑõOû+®ilUP»Ò—£[Yúoú¾‚èÂI)¯‡n)k¨Æ¯Òe:ll}Õ¶vîVI%#ȯÊ\Ü–1õG½¶æÀýæ»Ú¨bftŠ„áãš‹šµ”:·H ke~í~ƒ–¢I)…V6Ú›c>‹Àp¾-üÕ$é$¦P«¦Ë31Ùs¾‹I¬Xæ·÷¾‹¬ôš–6vèꡎca‘YcA÷Gæ·fýªòI)e ©®úÝU­cÄ9§PAЂlü·áã;!˜öå–ÄÕ@i|ô¢×ÔݬüïrJrðq~®tÀ;\=9­¥Ì±äÝÜÇ{Y³jÕ§7ûM4’ç5¡çÚàØ'oóŽnÍÚ}OÖûm±ïn;Muv8'Õµ®Íÿ;·mwóUÿÅÛêWé-^•ÖkÏšÞÑUànkAÜ×3ó_Sỿ–‰ª‚æ8H }Èæ v·Ô­ÞíöÊs”’ Å„zh~ÖÇ<ÖÿúúQÚ­¨ýž­­l°hMÞݧùJÚIÆPé>h—Y_Ñfˆh#ÁN˜ðS?ÿÕôn±ÕYÒpNcé²ö4€á\{Aÿ iq*oç¿ó!›õ£ªdå³"™Ç®­¥˜âÇÓ¼ºßOÐõ}Vû66»Ç5¯ik„‚5 Šë¿WßÓžr1ksðœI±Œjþ[ßs¨ÿI[?™þr¿Ñ}Fº©ÝéZ0z‰m6²å»AS̵ÇþÝ7ÿSÙoüÙ\'@êçmuzUl¸þm?IßÛô×kÓ0ß……^+î~C«™¶Ã.2wGõ[ôX¢›I$’ RI&$48À’x%.’¤:¾­mL³~󵯖¢Ñtz~ïÍ÷+€‚$qâ’—Q±íƒ§Ÿ‚¡—׺~0?¤»ˆi³Ä:×–Õôïo\Ç\úÌìÇ[ÒØkžÉ}—ŸWÖN¡V;¬æ1í‚=7µß¦Ê³?;íýaŸõïÏ¿Ó5ö Ïs)eŒý+µ=îôÛs[þ§=ÿ¦­ŸðŸà½EŒ_•[,ËêÏnF;…Ý)®®Þ »wO¯uÍÅÈk=W'ô¾…öú‹kí]k­YYÀÀmXí;ê·/sX×£etWdúmÞÚÿš¯þ?@õ½3<æPM ¾³²ÖŽ$~{?õqft>•gNÇ"ë‘‘k—Üà¹ä5žÊ™ì¦ªëc+ª–}ë­5J’I$”¤Ç‚1धÿÖõ@©ÝwUi>ž%V·q &âÒDû\áè»gòýÏW ÒR s•¹âö±­™¯a$ƺ>9:I)I$’JR§ÕqY—v3ôe¬,q€ïðþUný#UÄÄ<Sç>žc3¬È£ß“{vå9ö:=PïO+ ¬öÔÌgb²ê~ÐïOôµz—«ê«?¶+êVâôÜ\Œ›[–Ë-u¶‡µ¬ôZ.¡÷²ÀÍîûCke¸ìý_ùÊìüűÔpzž.e—àÐ̺r ÝA³Ñ{lhôÛ‘MŽe•?Ô¥µ×}OÿC]µÿ„Uéè½s5î7=2›¾¼ =g÷ý?PsC¿öŒO±Jyî¨Öeg~Ÿ)ÍÈK¦ãTu77vÝ×_éÓK«}õ=ÿ­czöjôÞÔ,nÊΕŽH%˜Ç}æÚIÔnªýl¯Óî–~âézgÕÞ›Ó™ÔÒv®s¿¯k÷Zÿó–£ZÖˆhà2*pºgÔþ“ƒa¼R{Žâ÷—Xà|ZûfÞ?5n2¶0CD)$š¥$’I)I$’JRcÁN˜ðRSÿ×õAÂuòªI)ú©%òªI)ú©%òªI)ú©%òªI)ú¡ß/šqÂùY$”ýT’ùU$”ýT’ùU$”ýT’ùU$”ýT’ùU$”ýT˜ðWÊÉ$§ÿÙ8BIM!UAdobe PhotoshopAdobe Photoshop CS48BIMÿá-http://ns.adobe.com/xap/1.0/ ÿâ XICC_PROFILE HLinomntrRGB XYZ Î 1acspMSFTIEC sRGBöÖÓ-HP cprtP3desc„lwtptðbkptrXYZgXYZ,bXYZ@dmndTpdmddĈvuedL†viewÔ$lumiømeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ óQÌXYZ XYZ o¢8õXYZ b™·…ÚXYZ $ „¶ÏdescIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view¤þ_.ÏíÌ \žXYZ L VPWçmeassig CRT curv #(-27;@EJOTY^chmrw|†‹•šŸ¤©®²·¼ÁÆËÐÕÛàåëðöû %+28>ELRY`gnu|ƒ‹’š¡©±¹ÁÉÑÙáéòú &/8AKT]gqz„Ž˜¢¬¶ÁËÕàëõ !-8COZfr~Š–¢®ºÇÓàìù -;HUcq~Œš¨¶ÄÓáðþ +:IXgw†–¦µÅÕåö'7HYj{Œ¯ÀÑãõ+=Oat†™¬¿Òåø 2FZn‚–ª¾Òçû  % : O d y ¤ º Ï å û  ' = T j ˜ ® Å Ü ó " 9 Q i € ˜ ° È á ù  * C \ u Ž § À Ù ó & @ Z t Ž © Ã Þ ø.Id›¶Òî %A^z–³Ïì &Ca~›¹×õ1OmŒªÉè&Ed„£Ãã#Ccƒ¤Åå'Ij‹­Îð4Vx›½à&Il²ÖúAe‰®Ò÷@eНÕú Ek‘·Ý*QwžÅì;cвÚ*R{£ÌõGp™Ãì@j”¾é>i”¿ê  A l ˜ Ä ð!!H!u!¡!Î!û"'"U"‚"¯"Ý# #8#f#”#Â#ð$$M$|$«$Ú% %8%h%—%Ç%÷&'&W&‡&·&è''I'z'«'Ü( (?(q(¢(Ô))8)k))Ð**5*h*›*Ï++6+i++Ñ,,9,n,¢,×- -A-v-«-á..L.‚.·.î/$/Z/‘/Ç/þ050l0¤0Û11J1‚1º1ò2*2c2›2Ô3 3F33¸3ñ4+4e4ž4Ø55M5‡5Â5ý676r6®6é7$7`7œ7×88P8Œ8È99B99¼9ù:6:t:²:ï;-;k;ª;è<' >`> >à?!?a?¢?â@#@d@¦@çA)AjA¬AîB0BrBµB÷C:C}CÀDDGDŠDÎEEUEšEÞF"FgF«FðG5G{GÀHHKH‘H×IIcI©IðJ7J}JÄK KSKšKâL*LrLºMMJM“MÜN%NnN·OOIO“OÝP'PqP»QQPQ›QæR1R|RÇSS_SªSöTBTTÛU(UuUÂVV\V©V÷WDW’WàX/X}XËYYiY¸ZZVZ¦Zõ[E[•[å\5\†\Ö]']x]É^^l^½__a_³``W`ª`üaOa¢aõbIbœbðcCc—cëd@d”dée=e’eçf=f’fèg=g“géh?h–hìiCišiñjHjŸj÷kOk§kÿlWl¯mm`m¹nnknÄooxoÑp+p†pàq:q•qðrKr¦ss]s¸ttptÌu(u…uáv>v›vøwVw³xxnxÌy*y‰yçzFz¥{{c{Â|!||á}A}¡~~b~Â#„å€G€¨ kÍ‚0‚’‚ôƒWƒº„„€„ã…G…«††r†×‡;‡ŸˆˆiˆÎ‰3‰™‰þŠdŠÊ‹0‹–‹üŒcŒÊ1˜ÿŽfŽÎ6žnÖ‘?‘¨’’z’ã“M“¶” ”Š”ô•_•É–4–Ÿ— —u—à˜L˜¸™$™™üšhšÕ›B›¯œœ‰œ÷dÒž@ž®ŸŸ‹Ÿú i Ø¡G¡¶¢&¢–££v£æ¤V¤Ç¥8¥©¦¦‹¦ý§n§à¨R¨Ä©7©©ªª««u«é¬\¬Ð­D­¸®-®¡¯¯‹°°u°ê±`±Ö²K²Â³8³®´%´œµµŠ¶¶y¶ð·h·à¸Y¸Ñ¹J¹Âº;ºµ».»§¼!¼›½½¾ ¾„¾ÿ¿z¿õÀpÀìÁgÁãÂ_ÂÛÃXÃÔÄQÄÎÅKÅÈÆFÆÃÇAÇ¿È=ȼÉ:ɹÊ8Ê·Ë6˶Ì5̵Í5͵Î6ζÏ7ϸÐ9кÑ<ѾÒ?ÒÁÓDÓÆÔIÔËÕNÕÑÖUÖØ×\×àØdØèÙlÙñÚvÚûÛ€ÜÜŠÝÝ–ÞÞ¢ß)߯à6à½áDáÌâSâÛãcãëäsäü儿 æ–çç©è2è¼éFéÐê[êåëpëûì†ííœî(î´ï@ïÌðXðåñrñÿòŒóó§ô4ôÂõPõÞömöû÷Šøø¨ù8ùÇúWúçûwüü˜ý)ýºþKþÜÿmÿÿÿîAdobed@ÿÛ„      ÿÀœ3ÿÝgÿÄ¢  s!1AQa"q2‘¡±B#ÁRÑá3bð$r‚ñ%C4S’¢²csÂ5D'“£³6TdtÃÒâ&ƒ „”EF¤´VÓU(òãóÄÔäôeu…•¥µÅÕåõfv†–¦¶ÆÖæö7GWgw‡—§·Ç×ç÷8HXhxˆ˜¨¸ÈØèø)9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúm!1AQa"q‘2¡±ðÁÑá#BRbrñ3$4C‚’S%¢c²ÂsÒ5âDƒT“ &6E'dtU7ò£³Ã()Óã󄔤´ÄÔäôeu…•¥µÅÕåõFVfv†–¦¶ÆÖæöGWgw‡—§·Ç×ç÷8HXhxˆ˜¨¸ÈØèø9IYiy‰™©¹ÉÙéù*:JZjzŠšªºÊÚêúÿÚ ?ûëkþòÛÆ$ÿˆŒUUÝcRÌH°$Ôš †-ÒŸÖùdÿ‘oÿ4áà>_0Ž!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øQdPÊI‘¸ ÔŽ) Úì v*¦ò¤eCr% *³ W >8DIA -úÂ,Ÿò-ÿæœ<ËæÄ?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð Fæ%‘ T“Ðø<ðBñ…|ƒ'b®ÅTLñ«2üd©£qF` +Ôã’á,xƒ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð „ñ³*ü`±¢òFPM+Ôá ^ ­‘dìUت€¹‰€ HAFô#þ'À1ã ýa?–OùÿóNåó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ä•$,*!•”ÐÖ@ðÀbBAS]Š­wXÔ³ l 5&ƒa„ A4§õ„þY?ä[ÿÍ8x—Ì#ˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~TGY2’A$n5‡c€ŠH6»]Š»v*ìUØ«±Wb®ÅPññÿG_ö/Š¿ÿÐûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*£qöþ2Gÿ\”9üÜÆ\¾_z¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÑûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*£qöþ2Gÿ\”9üÜÆ\¾_z¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÒûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*£qöþ2Gÿ\”9üÜÆ\¾_z¶E“±Wb®ÅR­c]Ñ<»dÚ˜5‹ON\ïõ ˆíaQ¤jÉ+*Š"3úz Uó÷š¿ç."ü­#Û5·™/#fW¶Ðíä»PÔ…Á nÀ´|GIø•©ÀòÉŒr(´?åïüåÏäçŸîΚú¬þLÔÞc•¯˜–+T¸ž.I ÛêÅ Ô™c!môöV—b®Å]Š»v*ìUت¿ØoøÉ'üM²SçðsòùýêÙNÅ]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÓûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±U’Ë1É4Ò,PÄ¥å•ÈUUQRÌNÀÔâ¯óüåä•åXµÌÝ2ö“­½ÔÚ*\ëpÚ¹•à?\›K†ê;eI#e‘¦dT?l­Ed"OE{~™©éºÖŸg«hú…¶­¥j,öœ©=¼ñ8ª¼RÆY]HèA¦EQØ«±Wb®Å]Ѝ¯ûÑ/ücõ¾Hý#ÞCõÇz¶E“±U°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š¿:5¿ç4üóä¯6kžE³ü²³òï˜|½"-Ók·2Þ-Ä2•0ÝÛÇn-yÁ2¤žœ‚CS³’9"Öö‚_*ù›þr‡ó×Í(!¸óÕÖn/£¢¤zsWj·­n«-M?žƒµ*rÑŠ!ð›ë«ýRêKÝNöãQ¼šž­ÝÔ­4­M‡'rIûòt¨Q¶.ûb¯¤+¿ç'ÿ4ÿ,– =u/ñW—!WAÖå Ú–÷õb è*P.W,BI·é_å7üä—åÏæ¬6–pê1ùoÍ“ü2ySQ”,¬äÐ i™Q.+ÔøéÕcËŠmôV—b®Å]Š»v*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÔûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*§$±D I" I8«Í<ãùÇùsä4-æo4Øi’•VŠÒi•g“™`¢(jdrÜTÖ‡ÀážJù—Íóœ¾IÓýX|¥åýKÍ«²Gq"þ´<©2N ÀH@A¡?g‰k[òÇüçy]NFüÃòݾå餪k|ò\$cEYãtV˜ €^0Ÿ³ôÉKe·ßž^ón•æ:ÃSÓîã¼±Ô ŠêÂö ÐÌ¡ã‘HêH å e ‚* AïŠ·Š»v*ìUت¿ØoøÉ'üM²SçðsòùýêÙNÅT[ýè‹þ1ÉúÓ$>“雷ú‡ã¹["ÉØ«±T]ó7–ü¯l—žfó›åÛI ÝjwpÚFÅG&ætƒs¾*ù¿Îó™“>Xw¶Ó/5/:ßFæ9¡ÑmH†&⬬×7m¡å¹…¤"†¢»)[À¼Õÿ9ç¨ÍäÏ9Iåo$G¡yÒÓêÉm},š½ÒIyoÿÖ"läŠHížY"¡‘IZ±éÈà!mò}ŸüæçüåMç˜ç¸{ÍÎ3n=o/ÃeÓdhãXL°M4w7»Ì«Ié’á«ÅeAmâúv¡æk}FmÌwúe—Öe¾ó„\ý\I+&–X­ŸŒO$€¿4I5âÌEn†RŸšŸ™6zrXùcÏ^q”ÙÄÆÏËš»ªÅ³0•¨l¥6¼HgbÈìź)²¦=ßA~TÿÎkþaù2ò Ì—ƒÏúR3E®ÈÐj¾œ$£Ii©q‘®ÞGõ–f? ó‹*–yl¶ý;ü°üîü¾üÙ±†,ê¦ÛUd/uåmDǧ+^p¤’+€7-ºÿ•]²‰DÇ›'­äUØ«±UŸ÷žãþ1¿ê9(}CÞÆIVȲv*ìUF/·sÿüA2Rä=ߤ±3øè­‘dìUØ«‰®Ø«Ì?3ÿ7|—ùI¢&³æ«Çy._†™¢Y˜žþð‡E”ÛÃ,‘X„‹¢›òeQ‰‘ ©§1¼³ù“å­7Í^Z¹y4ýE+yÔGqm2m-¼è xÛcBTìÈÌ…X‰ g`ƒÓ| ìUØ«±Wb®Å]Š»Q—íÛÆCÿ|”ywé eÌ~:+dY;v*£mþóÛÿÆ4ýC%?¨ûØÃé ÙNÅ]а4þf~_y&h-<Õç'DÔ.éõ-&âê?®ÏûÈb&E&iµÄAŠ!ãÍI 8DIä¯óüå·—£µvò7’5ÿ6Ý˽ƥòý‰2áëµò›Ø€ ,›2ƒö 9ttó>H·Î>hÿœ½óþ§ucæ”< †[«=HŽ ýmaŠys5ô“Ç0+ÁO.`ñãhÓDs(·ÎÚÏæ”üËiç_8ë>~ô¤õce:†¥ r~æ¬Ñ›hHú¼d¢_ˆrûlÌ×Fãѱ¿6þ`y*+ê±C¯ZYÅl½A¬ãT&ÊgXÔЃ Ã9 V9ùqù¥ç_ËÛöÖ?+|÷6Ž%ušÿHŠE¿Ñ¯ ƒnt÷c2S$^œ¤tf4 $—éGå7üç“5Ø"Òÿ8¢¶ü³×”ñcõü·r Þ5ä‚¶µä·DF>³ÈÄL±›}Ëkum{mo{eqÝÜI5¥Ü.²E,R(dtu$2° ‚ ÊÒ¯Š»v*¢¿ïD¿ñŽ?Öù#ôyý GÔêÙNÅTn>ÂÿÆHÿâk’‡?û˜Ë—ËïVȲv*ùwþr“þqãMüôòr\éÐ-·æW“ãžçÈš¸“Ñ,òqi¬fzÝ\ˆÂԑŨkÚ¼£.¯Ãí?_–Òâ}̰Ia©XM5µÕĉÁVH WK…ØÃ"•`õA^ªO—Ûl!ö˸C튮ûb«„>تá¶*ú—ò—þrŸóòâ84YßÎþYFlµäk»t -®˜¹UP6F  l¡r©a–É·èçåç¯?5â1h7ï§ëh+7–õ ^RŒKD¡™fP’ccÄS˜ZŒÆž3l­ì™v*ìUت¿ØoøÉ'üM²SçðsòùýêÙNÅ]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÕûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕITš‹$›Uó‰¢ZÏ{ªêvö6–ËÊâæi#EéVv!@ùœUóšÿç0?(|¾d‹NÕ¤ó]Ò}ˆ´HÜoAVãuTµ¨èA›­GPi1ŽG¢-ó™ÿç8|ÝzÒÇå'Ùé•so{¬N÷2š‚Ôµµ0ª±n7êíe£Nz•¶[å?ÏCùÁåM{OÔR÷CÔ"·}3]’ÛÔ†2nHÌÖ *vR{˜Ûá«P3U8|U¬~GùçDŸU:·¦yºÒYlÚ5¦£z ФÓ)0ú¨(b¡XPìj2Øç¡ÉiäÐLÚþ™ö•<Ö@ÊO £J¨Y64'ƒux2±‹±³×ßóºOå»yg6™icuæ ä~» ¹¹z+FΓHî' t$§-Õ9 ãd”à ý:ò¾›¦‹hR Q *ªÀ¢”  ›m”%è Æ(¸ªüUØ«±Wb®ÅTmþÃÆI?âm’Ÿ?€û˜Ç—ÏïVȲv*¢ßïD_ñŽOÖ™!ôŸxý,OÔ?ÊÙO—ÿµö£e5Ù^A§·É ŒL¶Ö°‹+H$¤kF++/F&¤ƒGè¯.™u Z&§©êòÚ´FÆõ{s‹ûR^B±Æ¤ì×7ÜŠ*öæ¯ÓùÄÏÎO̯7yžóÈžyÕaÕ¬¬ô­SL¸¹C.¥[[«Kp$ºB¨ËÆâ¤8w$Œ ãæÄ"-/¾3.ÅTnÞ{øÆÿ¨ä¡õ{ý%["ÉØ«±U¾ÝÏüdñÉK÷~’Æ<Ï㢩!EOL‹$ Ú„0‚Z»b¯Î¿ùÊ/ùÈßÎÏÊÌK|¯Kù{s¥ÚÍoz–(áïdšh¥·’{”ôšJª0Uš2—ácÖÌq‰æ‚ùŽÛþr¯ó×]7Ú~kjñjÉft„=x€²éÜŠì@jh~#C—Œ1(·œù‡^×üÛ«ÜëÞgÕ®uÍfò‚ãPº`X…­B¤h*HDUQS@2ØÄDl†QäÏÌßÌËØ®müæY´kKÉD×–b iã’@¼CÒâJ?ŠíZÐ`ž1.i·§iÿó“¿ó×¾«æy…´|„—·ze…¼+Æ”nS[+:I ° ëÒ°ü¸ó[~Š~EyÏΞbò5­×æŸñwSE%ËZ/¬CðÉ‚2¨¤q~<•@jV€×1²DDÐH{´s$‚ ä«Š»v*ìUتŒ¿nÛþ2øƒä£Èû¿Hc.cñÑ["ÉØ«±Uo÷žßþ1§ê)ýGÞÆHxÇš?ç ?.ü·©è¶×Þkó‘+C}¢hvÆb’!ã,my;Ad¯Ù‘® Ó#% 2Ÿ ›x§™?ç#0u%1yCËZ?” w G]’]VïÒ1§líÚä^´¹•hïȪäÇFz”q£øïVȲv*£qöþ2Gÿ\”9üÜÆ\¾_z¶E“±Wb¯ÆOùÏ¿Écäï=Yþlh6 –0\[ùaRß^™ÊŽ!Eä)êl¦²¤ÎíÊE­¸ÏDÄ&½y¤*Añ^é±(Xìœã«Hd$PMÉ*©E|eHz¾Ÿwc©Û‹› ”¹† 1SBŒT7SFF…U€#¸ËA´#Äô¨¨ôù¤¥ÓTÒ G§!’áTöÛ˽?wøaVGgåùcx¥ˆ¼2Äë$3DÌŽŽ„2º:U”€A î2\óCôƒòGó¢çÍbÓÊ^r”¿›Lr5–¬!HbÔ|Ý—Œ_ Ì‘¯&UXT¨HÌ Øx7™ƒo¥³.Å]ЍÛý†ÿŒ’ÄÛ%>÷1/ŸÞ­‘dìUØ«±Wb®Å]Š»v*€ÿú:ÿ±|UÿÖûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûØn·u¨(e@G]ò,Ÿ“_Ÿ–_˜zGœu3j×Z‡Ÿü¯¯ê’Ï¢^ÊÏuq¢Ms!x´÷ÉX­ÃHRÞHè‹ö$âì­.N€lPC²ü üÅ¿%×B:e¨&—7¢DsHÖTT`$ µ¬düJYZ1d³D"šïä׿œžŒÃQ½±YN£åÙ‚Gâ±Z&óÐ+q È5hMG#_æ7M0Í÷Útwh¯}§^_Ìö¾’Qm®¡¸Š72$É1ONXÄl ƒÊ£ŠH­²á²‡¶ùóRoRïGó\2'Ôç0Yë²ÆÕVD~Q’’ÆV@U§J=[“eÅ{Å6¼÷ùAmuëkŸ–òÁÜL·WÞU’gM¹xd+ÙË&ÎP˱OÝ–¥Ui\Œ2ìVžmc¨=ƹyq¨ ­'Îð gÕ-gŽ+ ØM³¶–8íT)`É,*+PÕå™0á!°¿,?ç$õ/zzw¥—R³WE·×!JÏ AhD耙¨GÚQÎC·Z烬Tè?“?34o2XZÝÛ_Eyktµ‚ê& Sô‚ îÇ|Å"™=J)c™ÄáÔô#TÅ]Š»v*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Uÿz"ÿŒr~´É¤ûÇéb~¡øî|Ùÿ9Yùåäw嘿±Ôb±ó¯œõ¼»äNq%Ã-í´’ÜúB¸¶‚7sýÙ“ÓG |b,²~4è·6ÞešûÌìóÞO«Îo$ÔfyD·/+´…¯RI=I.Tš»Îž§-ù²æÄ “j6N´s¨ÉGã õ~$4àÎ>$ì9²Ž¾“µažhò„e¶{=½=AÓ»±yZ0ÂDé±CÊ’µ^¼.¡–¥ã%ÝÓDIñʰµØŒ¤ÈYÃn"XÙQH*}Að‘B~µO.jŸX^¯§…Ü , ŠâÝXrPœ?yhŨ«É‡bhTÆÜòJÎm¼¯ªÝQÿœ‡óÕÞ•uåŸ)Ùub÷“«Sbè~0 8daJ”qºíNYtH`o­_i>U¼ÔtÙRøÞYÔU2Md•$Wf=ò7AYWå·›¼·æ -4ï5My/š 1Yõ)Áµ£xÝZÞ8–Œìx©Ndr "©„ÁçÍKßÂÅoÃI I^F¡TTÔÐ ¹jRÉ_*júé-s\¸ô½OS½µáË•~«pöü«Aö½>TíZo˜ÒܲJaŽM2äêzTãO¸^OsKiÔžRzÈ(*œ|@ÐïJ`•’XkRkz5®¡5¬–wF¿YŠHÌcÔà¥Ê$ñ© ©¨èhÀŒ7a^_®jO£ë:~«³K´sª,ñ85_Š¢€Ñz©<…wE^Þ9£xfE–T¤±8 ¬¬(UØ‚:Œµ^µùoùÏù©ùJ¶ÖÞGó »òí±Qþ×ùÞi1±KSQqeÄ}…·Bí årÄ ÛôsòËþrÏòÃÏÒYéÕË~]ù²é–(´=vDH.fs@–Wàˆ',H „¤§ýö3P1eo¦×ýè—þ1ÇúßúG¼þ†#ê?Žõl‹'bª7aã$ñ5ÉCŸÀýÌeËå÷«dY;v*ñ¯ùÈËHÿ6ÿ(¼éä¤&Õo,×–ø©T³"{B$f^äAžCàfSð“„*þràz…4e¨¯XWÄ5>Ç2§V—6îÆU‚äq 嬊µ"9Ä¥IØ|;ä¥}+äÉl|Õ§}rÚ#Ì "Ô,[âhd¥vjhÃu`7@`Ê2aêzM¯–Îßá–¡‘Zùo¥SðÉR² o.OƒðÃJŸ[è§Áøa¥dlö7]ÚI%­Õ»‰-î"b’#®á•–„퉈"оáü½óªyÃL”\q‹[Ó8.«n‹Ái/#¨9¹âünAä­µ)]N|^«£0mèJ]ЍÛý†ÿŒ’ÄÛ%>÷1/ŸÞ­‘dìUØ«±Wb®Å]Š»v*€ÿú:ÿ±|Uÿ×ûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÔn¬ã¹Z0ß"ÉŽÉå{iš®‹¿ˆÅU£òž”’À¯^¢ƒbú÷’ìUííP!è@Üb¯ˆ:ÿç,ü×pþeÐ'_.ùâÒ>6Ú¡0^"R–úŒ*WÖŽ€ªšó޼ö3„ÌNËO‰ƒêv­såŸ3éÍ y¦ÉyK¦JÀ¥Ì@•úÕ”ŸîèX©€ªôuS™°È$À†[¢ëÚ¦€XY7­lÕ2iÒ»˜ÑÈàhÂ2]êÌ«SÞ»R91 {Ò !Õ´Ï,~fØñ¹Y­õ=,“ixµ‚þÆG ‘”î¿BQ¨iñ.Øž¨óyf«³äé½5"Ï£´‚;7À¼`aðõØÅ~®çßxÏÄj S2±ææ‚×”üݯùBúßQòþ§,z¢{‹zÚÝ¡O«CUŒ(‚‡,ž1>h·ß”ßóúf½õ-3P¹]3_”0m2RxJSsèÈÀ$\kÈ õ [0òb0÷2õ¾—æ; E’±èr¤²A ô8«±Wbª6ÿa¿ã$Ÿñ6ÉOŸÀ}ÌcËç÷«dY;BÏ"Ã*H抱ISþÉ2Cé>ñúXŸ¨~;ŸŠóôMnïWóßäæ‹òþˆ³ÒµYÚØ¨XKO4sÉYY؈"5áö—«TÁ“áËÿ*ùŠ÷V±±¦“±múCŒÐEü7hˆ³E42´¢åj °ZF]Pú'EüŸ—Ì•ÖüÉçy¿,eòåÝÅ…ÆŸ¨K$šäWªÉfñÝÈVExÝ Â#xÙêÇVØÂ÷´=G_´ü¹³Ó§´òÑÖuÍ}Úžd¾X¬m#DYDÒÉ'(˪™&Y¹q<~+!åú‡“4ï4Ý$o§½Î£o>µ½A çD•̓áD†„×Ä2&·ÿ8Ùùµù¡¯jú~²§Ébÿ húu×ÖÆê :võoÞ& ³) Ë,ÌjÜVÉå<‚ÓàÿN)ÓÓ™©é؃JT¸>ã|({Ÿå¿æuÆŸ¨išž5R|¹q*Â|Úðú’iñ‘@×1ÂxÖ€–U¨ìª5£)½iú§¡A7ž|¦•e¾°‰ŸQ·E&îÊ5$Zs‡˜4fuˆPc  óZ|»/štkVH’èêOš;+k©š6`øDSZžÀŸÙ4ºÐ‚¿“ÌZí½Í„¶Öš•r’E2Ü$w÷R-h¿»`Öêu $ð¦üƒD«ö—þq!$‹òòþ .îo¾­m{W“=ÄÞœZ¥òF†I bU©Ø;f6Q_?Ð9þ<ßIå,ÝŠ¨Ü}…ÿŒ‘ÿÄ×%÷1—/—Þ­‘d‡šæ(—=;b¬/Zó¤:r7Ží×|íç΋›3 Q½Û~/þfÃkkù‹æÑb‹•õóêvQ â¢+ãë‰SÅVxÔ ¾ €û"ø,N&É¡—yWÌw¾TÖ¬õÛõä¶;›"B­Í»²´° …åÄQ©ð°qPg p›Wé7–cÒüÉ£iºî(»ÓuHV{Y€¡¡Ø«©Ý]e;«¦„ϨX`Ì`Ðz|.N!Ñiða¥LKUýœ4ª†Ä(銦ž_ÖÂZÕŸ˜92ÛÙ†MI0W´r=z¨ 1P¼Ö¿´jæ>£|ÂA§Ù™§lv*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÐûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»ZÊ®¥XSÔU‚yÊñÝÆïQÜ~«ã¿ÍÏÉ]κ{YjöÒÇ=³4Í^Í„7ÖRš~òÚ~$£Pà ˜¶H䯃õÍ+Ì¿—š¤:žãG´ºÃ¡ùÚÌV‡NŠš[Ý:©<+Á·ôØýœÌǘKc͉ ³,6ÒÛ]›Ÿ¨]ÄÅ,ïUÄr+= U'f Ä„j|@Œ¶QPôß+ù£Hó¼šF©õ9æ¸g±.&µ½¨d’&W؇¶5ضáp§ˆÇÜÈ'æOÊ SGš’K­2t‘µ$<ÌŠCËôlÀ£Âìy7'“lj¥%1!æKu¤® ÚÍÖ•‹zæM7PŽÖÆþÔDà»:_$×0«DmÜŒ"¨Õ7\ˆPÞîÐ_N~]~wùŸÊeipÞaòàbH‘ËÞC|KèLZŽ¢¦‰%v +¢¨ špwŠ‚ûÿòÿó{Dó=ŒZv¢—8_ZeÔ|­æ \‹U¹ŸIÖ.´[›«X­.á6Ë=« zË4oéÌÂ&)Vè2Q Õù¨ùËó§ÊwçFó·™?0cºPÅ#—ÌZÕ¥Ó¢ž Iï–)Ò¦†Xœ%vUì2¢ z)‡œu]l7Ôÿ1¼Ùu*S[?˜õ”ž0zzÉt²%zŽJ*7é– p=jž‹UšI%žIžk‰äie‘Ü–y$’BÎîÌIfbKI$倰VÕf‰ÒK{‰í'ƒÃum,M)¨d–"®¤àƒ€€v*ŸÍ^dÓa{«ŸÌ?3Ø[ÅORæ_2jq"ÔÐUšèRh2;–Ù‡ùÇù½ ‹Dò·š|ϪK)f·I§ºÔn˜…œrú×%@í×"aÌ%ú?ÿ8Û掛ä@þnj—z—˜õ=fkë¯OóÃc%½²$L!¬q*HÁš9E€Ä™³ úJ9’A±È+Rý»oøÈâ’#îý!Œ¹ÇEl‹'b®ÅRÎE`ƒÀÆ”?ìFJQ÷±‡Òœ¿óšßó‰1þfÙj?›?—Ztù™¦Á×tKe úzÒÝV BÔ¥A ŽjdEQ›ÓâÆTÉø§xÜ«ŠX›qºº: ‚ùƒ–„=—Οœ~süÁü¸ò/åï™f:¿ü«íNK.ê²1k†³ž ³"Ÿ¦ULC­9"íéFì*¿¼Íæ-M.¡åo0]è3ê0}_Rú«$–×Öì¥L7–“¤¶×Q•4)4n¾Ù: MÏ—¼Ãë\O§[Y^Ã,ÎðYÇ#Û²+Õ•ÕõT?äìÜhI-ZË€­¢—H×âª>¨I:hò™$—VW³C£ªh%àš9ÞT¸ŽT¹¶Ž'p¬Q¤EjÁCfDr ’)ˆmÕtÉ,%¿Ö¢W—ZŠÚJæUÓŽic´$ƒj…AÞ”­s*1Pb÷¿Ê½fæç@k-sX›TÖí$c4WQ¢ËJ¨ G"ëÇʬ$#,”n¸Y`by2 çë_˜té-Ñ-uýP]*³ÛÈûU%]v#pGb2¤¾G×´³ùækí+UÒn<¿ ën|©¨K9šÂD%ŠB&`s0•bY¾Ó3;ÕópäQæÄ„Öß̳y6òß\²ÔæÒõC%¼–ÊòM"±^Qˆ\ʵ Ì¥Xlª-œA¡úUù+çß1y³ÊöÚÆ½ ÜynðÊbH&VŒ\ƈ„]G’É…Y¶äAÌ Ä±¶aô­– .y}¯‚£mþÃÆI?âm’Ÿ?€û˜Ç—ÏïVȲv*¢ßïD_ñŽOÖ™!ôŸxý,OÔ?ÌkÌZ Z„è•zJE“áÿÎÏÉ?Î60‰}#]ÑnÿÊÞh²&;Ý2úY"¸‚D*À«¢’ À «*²i_•™çóWó¶‰äïÌ'ÎP]Gbža¼šÚøj7 _´î zGˆg!G=W•c$äã¦4¥ç#ù«ò7óãÊozu2yzÙ&Ô.­"škv·•RJÊÆq$R#FÎUB«5WŽªhÀ«Ú<­æ­+Íp;Y±†öÙPßiïöã.ªšiZ€ÀvíÓ2#!$'úŽ“mªØÜé׈Ïmvœ% J·PA 7Éjðo4yZïËw?SGšeŽÊï•X ( âj¡Ûzž#páJ@´p,¤ÈèÅYMU•”†VRƒ¸ß"©üºÛÜÛ\-ý¬—z®asªÙy‚Ž9Ò+$CpPÄrŒ•' ¼C¹˜•«Þ)Ijúg˜§›W²‹NÒa´˜K{!´‚)'žîÙ”–õy=°¯)SðF¤žRñ„9¢že>ŸªGçAekwn5‡”\_j¶‹»W²ž“á-y”U‘C+7>#®C¸ŽÉ,âó_°¦†Ð>«wúRÁkFXäªÉ)"4+O‰Kr|;Šßh|}ùÕçÌ]Ìs~YùUî"½Ô–ÝltÚK‹Ë·‘’hɹX"rꊿÂy/&Ìl³#d€ý¯ÿœVü±›òŸò£ÈþC’Q5Æ…fÆþeåÅ®®æ’êä©frG«3S~ FO¹l–ÊPßMÿ9(}CÞÆIdYNÅ]ЍÅöîã ÿˆ&J\‡»ô–1æ²,Š»v*£,+*F*Àõû#;(튾güÄÒt­zÂm3[Ó-õk'<Ö „À!dŒ‘Tu©âëF^Äb +óæ]F±ó6»w¡ £ÒU¾¥§ÛK'ª¨avúÄ‘»|]ÀP›d AŸ„,JÆ©e ­m{ÛÀ¶¶¨eeaZ,Œ£„\ˆ!LŒ wØÒÔ%y«Nñê–÷:#²¿ˆ~+V¸†IaNG wRj+ƒ‰S‹«}R )ãs2E,wv’Ã(U‘iº‰ȼdŠòâÔ¯ *$XÙ_v~P'—lt{I<­§Áea~ªòM-,Œ„©1gwŒÕv%H+Û5Ò$Ù¾­Ñmå™–¦ dUÛZ¼`sjb¨©ØŇþ ù(ò>ïÒ˘ütWȲv*ìU ,–+tôÒ‡Ãa’ŸÔ}ìaô„¾HÚ6*ßAñȲ~fÿÎeÎÿŒF¥ù·ùQ¥ñz¹ó”mRŸ¥Ôn÷vˆ¿ñô:ºûî«ûí¦œeJü|Ž„4n»«£ ‚Z†c£ê‘À±Ã,N÷ 5~´“"°‰JÈõ­^½ä§©0Põ­*á\Dèêèà2:š‚à‚:ƒ–„=KDž€o–…z=ŒõQ¾I :§™t-’ «Å7r’°ØÅY'sǤkR+°© ©»ŒL‚°kÝs_Õ8þÓãÒ¬äàMÖ¢I¸àÕäËn• À@íß₦&D¥!‹AµYïRvÖu/I[˯‰*¡ªb†¦8ê]¾È­ *@TÂGÅRù®*Ï¿/ÿ(?1?4ÊKäý ÕÒ^¿ó³_»ZécåqÁÚ]ö"ŽàeS˦Ÿqþ]ÿÎù/AXo|ý}'õSŤÓU~­¥GB Œ4Ä™ž@®¬J ,Ò>I§ÚštZŵ´)mmmoVöñ(Dºªª­ 2éóú>£øïL²,ЍÜ}…ÿŒ‘ÿÄ×%÷1—/—Þ­‘dìU‰ùƒ@‡P†GDˆø—øŒUóœü–§Õ¬5šíý˜«à/ùÈÿ#¼S:¼Q¨]P·¹–»²òµø{YÁ5í^ô(sWÅ16^„Ê'é… Þ›¨^é—¶:ž›rÖz–™qæx»˜® q$Rß‹¨4;øA£jýµü·óæ/‘<·çK8„ ­Ú–ºµ¢¨] º„ö„sÆèzW6ЗA`Y<üVµÛ$„‚îáV´È¥‹^Þ]ð+¾Ô@å¾D•z§üãî»3ù³]ÑT)·¾Ò¾»3rÁìçŽ4ùqPEËT%¨(G\ `äYÅõÎ`2Q·û ÿ$ÿ‰¶J|þîc_?½["ÉØ«±Wb®Å]Š»v*ìUÿôuÿbø«ÿÒûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUتI©èðÞ£@$§NÇxǘ¼µÃÔ>)Zí¶*ø3óò?RЯ/<ËùibHÏ>¹äCð[ÜQGï4ÑUKyª¦©´rr©âÀv<Æ<ù ‡ŽY\éºõ¼ñ˜+%´’[jšEì\.-g^QËosŠÆëºFýª s4 Å?Ò|Õ}åMP6…#ê:Û>S…ZäßËÃáQmIJ ™dr¼°Œ·;‚ûjÛËÖ>ròŽ¿™<·þ…¯ØÁ.©åV(ähŒª²'O9ÄÛF¡ÌH¯ËÈoËÏ"Nn´/-$wÅÙ¡¿»’[¹aS#¼i œF"Áx€Ü@±ÜÈÌžjú6ÇC‰ãôäU˜Yéí;b©•¿ØoøÉ'üM²SçðsòùýêÙNÅT[ýè‹þ1ÉúÓ$>“雷ú‡ã¹XŠìw¨È²`þfòÜ7м± ›Šx⯃ç ? ô¯Ì[ µ6š‘ôMYEZÞI ¬*9G'kØFá•ùùÁæÿÍMWÏŸ˜ÜÛyÖÇF‡Ëúž¡l‘#j‹qq*ú_W‰‘L’„äA‘…Q‰¦dœœ[±§—iš½Ö‘¨é×–7 cª™V;(Ȭ$„ «†;2þ¢)}[åO>i>cµq"½ž«mÀ\iÁV9I@Ìè ø¶ªuj-²¡1&4É®!ºÔ"ž aKwø?|‘Ï+ä­•=9õ^Æ\Õó ÖW:]õý…Ì-½íÚØ}eY^K4º–;y0Ô¢Ïzw­só)Eéð5íÞµh¬®ü§­@®wÈÖŠ ûòqëîW£èšÝ·—¦Òô+ïoµ[!te•ÌN­1¹ºEy'¬e„¡h _ʹ`5² _ê/w÷r_HÒNÆÙ 3¨‰YútwqÈ’Ø 5{'”ÿ!¼Û¬ 6¿µO-hâ5ã«KƒeD¶p øÊÐRºeÎ-ÓO§?.ÿç¼µå}BëSÓ´Ã6«"ÉqªÝZâ¢á¤l‘)XÅU‚w"¹‹)™Ù>»ò÷”…œq–N4îr*Ï^†ÒuQþêmþƒ’‡Ô=ìgô”fE“±Wbª1}»ŸøÈ?â ’—!îý%ŒyŸÇEl‹'b®Å]Š´Æ€ÓHu vY_pF*ùÏó¶ÎóDò™µMŒ:Á†;M2áÉé\_M¬RˆÁRåPÁj9Jï†"È øsAÿœvóγ-­Cqebˆ;kÖk(BÅ£QUÔ€[‚â ft³B>lièð~FZh¤Jå"UH TX`N5$¤H6­zFcËQ#ËdÓ¾ÿœÒuI¦žÌÜèÓ3HÒZÀÎIb^ÙùGFcW(š§ã©®B9d:­<÷YÿœküÇÐZ}CËbYe¹Ñ\ZÝ;ŠY%Ó® Á)šQ¥þʆ Ë£œuÙõßùÅCÍmæÿ1yÌvDGi§6¯Êæ),¯mfŽhm„rÚȵýò¿"À¢†Œñã$C5!!ú7¤,–T ”%˜Å ‘A{â«eûvßñÿÄ%GÝúCsŽŠÙNÅ]ЍÛ¼öÿñ?PÉOê>ö0úBébYW‹le¼2,’—BŒU†ã~^ÿÎiÿÎ$>´o¿8¿*´pu”Ý~`yZÑO+ñ³BÒ%ÿwˆÌƒûß¶£ÕêÎ2¤?&ad‘;I˜ þºåªôMÌ2“ig{wgh°ºÆš¥óLˆRYOÖ'ÝÏêq$¨!·£e‚h{üöz¾…¨¾— ”zìÑæóL»¶¹³««8ŒÜ¤…ñPh{2²Á²èÊú!9Kmnæ8šûP:bì^ÊÅ!± 3šA444®Ou_k§iÚZºØZ¥°*¹Z’U+Ájjhµ4O¾5Jéß@Häš ’z ö Î=~f~cD·ÖšbùkC~&=o\[¬ÈÇv¶·f”q!ÕŠ¤nÃ/ZQ<ñ·M>Ûòüâ§å§“Ú×P×-[ÏZä ÖudV²I*Ix¬bëB¦_Q¨*ÀÔœi唓O§ÍKeiF%Ÿyýˆþ¸ª´j©<Š¢€Gû'ɤ{Ïèb>£øïDdY;Q¸û ÿ#ÿ‰®Jþîc._/½["ÉØ«±V#æ//à ȉñ´ ~¬Uò_æ¯å^™æÍUòþ¯nï§ê(¢_HðthÝdŠDmÀdtVTn¨Å_‘?™¿•úÿån¶4ýLÍ*ñ˜èÚâ!Hçs­[„ª:­w÷ |eh`Q?Lš(›¦*û÷þp»Ïb?ñåÝÔ”b©æ=If,¿»´¾쪇êÄÔ»µ®n–|âÆOµ/oÀ®ù–Jmþ¦/‹ J°}CV•™U‚j:Ⱦ,)e‘šóÊåòUªÛ%Ò_I¨C,îH6ÁtÛ¹D«îLb=û9ÌmNðL_¥ù®f£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÓûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±TºûO†õ2ŽDuñÅ^mªù]K³èjw¦*ùßóþqËÊþ{Õ,u§–÷ËzÄÿ¹MWEu¶ŸP¶ôý?BéÂ’ü@^~$§ÂiQ“ŒÌy-= ÈŸ”žNò-·Õü¯åë]-ÝxÝ_ªsºž§“gjÈõoŠ„Ò½DÈžjõko.ÆÄ0ŒãL ÊlôH⺖*žÇFETÅTmþÃÆI?âm’Ÿ?€û˜Ç—ÏïVȲv*¢ßïD_ñŽOÖ™!ôŸxý,OÔ?ÊÙM ŠƒÔb¯<óW—æ'’45Hö8«àßÏÏȽ?ó I’s¥kÚ940B)-¼‡z(J1¯ùBŒ +åÈ/-iž|üñüËòçç5•®‡æ6ØÝ^ÞY$)/}ê<×ëj´dÿI[†Ÿj†TåV¹‚Q‘7½±/,ò¾…þüèóW•ÅÂ\.‡gªÙ‰bbÑ¿£{f¡‘Žì< Ó¨`ã3!KÛ¥~¹{Ñúäç–¿7ÿ'¼¿c¬Æ,µ‹OÒ#Ëþf9\YÈ×óš0ª‰bb(ñ±¡©Wâë­‘©Ÿ{7Æ7‘?š^XüÉo&M婯®õ :{ jÙ'—Mxo¯,¡[¶ž(]’8Ô³È*¡Z¢”clr 'Éúȿ󇚵Þå-oκåÞ…æ{ >ÖÏUÓm 7”H hö˜†E›”óòjʇ÷d}—W‰Í¾ÝɧÚ>Oü¤òÇ•`Ht-8¦b Ú”£Õ»‘€"­3Õ©ñ(¢Šž*Ê¥3.i{—䧱Ѭìôã ãöˆÅSlUFçýç¸ÿŒoúŽJP÷±ŸÒU²,Š»Q‹íÜÿÆAÿL”¹wé,cÌþ:+dY;v*ìUتŒ‘†o£I®­µqV9>’$cðÖ¸ªšyR;µß½1VŸÉ‘|k-à*©o¢¤'ˆŒ(©Š§–ö ´ø U6ŠÕE6ÅQ©^˜ªÙ~Ý·üd?ñÉG‘÷~Æ\Ç㢶E“±Wbª6ßï=¿ücOÔ2Sú½Œ>­‘d¡<"UÛfdÿ U+ ©!…ê*ü°ÿœÂÿœ<36«ù»ùE¤“rÅï<ïä‹4©˜š´·ö(þó«KwAÏ’½‘•sCòÒ e`ÊÀ#pAËUö_’fäŸ(KÁc3h¶º ¢ò’ݨ=É'3#È1N¥“ `Kq,vöðÉsq1+´(ÒI#[Š"Ìh  ÀHÒúÉ?ó‹?˜¾jk;ÍtÛù+E”ó¯U¥ÔJ #³^!yn¤Ë"Ù¸8Û1§¨–é§Ú¾Cü„ü´ü½š ý'Cý#®À?Ä£›«ªƒ^hBÇ¡0Æ•ï˜ÒÉ)seOhŽ'}‘v@È*6;E2GÀtÅQaBŠ(x U¼UEÞ‰ã­òGéóú¨þ;Õ²,ЍÜ}…ÿŒ‘ÿÄ×%÷1—/—Þ­‘dìUØ«ˆ®ÇpzŒUˆëúW±;ªÔšÕiZW|¯ù™ùc¤ùŸI¿Ñµ›¼Óï’DAHÝ]n¬§ua¸8«òSó[ò“\ü«Õ’+†}KË×îWH×Bq à6ó²J ;:ŽKÑÑ/„í4‰úeˆz§åš”2|™®HÄ[G©GgyV è+Y<’±è‘ ýRj)Ƨ`rx¥Ã ¥úƒ¨ë rø©›X0 K[—Ç%^©ë¿kã®D”¼óS×¾×Ç%Y/äW™8~tù*³=Ôº‚GƆœtÛ·,Ûôøi_3<½,ƒõÇJÕLѨòð9€É=·û ÿ$ÿ‰¶J|þîc_?½["ÉØ«±Wb®Å]Š»v*ìUÿôuÿbø«ÿÔûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wbª2Â’Š0ßK$Ó#cöqUñi‘!©b©’D‘ý•§¾*©Š»v*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Uÿz"ÿŒr~´É¤ûÇéb~¡øîVȲv*±ÑdVGVØŒUåÞmòºÌŽèœ•«Cоüéü“Íâ c@»—Ë~zÐC·–üÓjͱ’¬¦ ]#‡e"†›fVtyFF&¿<ü«oæ}óvþ×Ï+u™[M½³¾7€z¯pdµ•7AÄ©Šeeø ÄîµËÅ.)[ú'LÒµ0Ý˧èlúÍü*K;n%“<}FvTŒ5( ²¯¾]9Æ<Ê)ú#ù9åmOË~HдV8ãÔ-Öy/-ãoP!¸¸’`¥€¡eR¢µ¡#s®‘²K7¼Úi¢DUd佪7M"Ð-Á”b©Ì6Öã÷q-|iŠ¢ñWb®ÅTnÞ{øÆÿ¨ä¡õ{ý%["ÉØ«±U¾ÝÏüdñÉK÷~’Æ<Ï㢶E“±Wb®Å]Š»SxÃb«Þ1¹ÅU€ ¦*ß\UE ·¦øªåŒ.*©Š»Q—íÛÆCÿ|”ywé eÌ~:+dY;v*£mþóÛÿÆ4ýC%?¨ûØÃé ÙNÅP× %üqT°Ôv5ðÅ_’ßó™_óŠZ]æµùÍùk¦úº5Ñkß>y^Ö0ÉÂWQ¶å мê$bÒîŒþ•—B‡Ž~WéZ¾»äï"XhÚeæ¯}>…¦,v¶p¼òmc5ã±I'`'a™âB1±}äŸùÄísRw¾{Õ—ËðIV¹ÐìŠOxÀ#N @Œw5_PtñډꚚ}‰ä¯ËO$~^Á$^TÐ Óçx]êmÊkÉ”Åd¸”´…y „€?eFbÊf\Ù3ä‰ä? Ôw=²*ŽÑw<χlU€PÃov*ìUEÞ‰ã­òGéóú¨þ;Õ²,ЍÜ}…ÿŒ‘ÿÄ×%÷1—/—Þ­‘dìUØ«±Wb¬K_Т»‰Ý¤ý¡Š¾aüÁü½Ó5í7PÒ5}:;ý6ý \ÚJ¨ Še `A Uù?ù¹ù;«þWêY‰äÔü©y' -Q–’[»,\v©ý—+¨¦€ß ÚBÁ¥‚h’VåFD  _qÔeˆ~ŒXyÐk¾^Ñ5ÁHÿLéö×Þš“EúÄK-hh9wÌñ+ʼnêž`û_D•`wZÝôßW³†[©Þ¼ …G?%PIÈJt–wåoÉí{Ì3E>¿+höA6éG¹eüR:žÅFbOQÜš}³ùgùkåß'[ˆô "+9§P//Ídºž‡ýÛ;ÕØÐAØ Æ2'›'ÒM”Š«·ÑY}¿ØoøÉ'üM²SçðsòùýêÙNÅ]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÕûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±WbªrÄ“!ÅAÅ^{¬yfY¦(|1WƒyËþqûÈþt×´/2kº)ŸZò÷¨–7°M-³¼2¬˜Y ‘†nJ­öO >‘^Q‘%zO—|…¦h¶Éc¥iVº]š³:ÚYÂDY‚FTž¦™z^ ,bûb¬š8R!EN*«Š»v*ìUتÏûÏqÿßõ”>¡ïc?¤«dY;v*£Û¹ÿŒƒþ ™)rïÒXÇ™ütVȲv*ìUØ«±Wb®Å]Š»v*ìUØ«±Wbª2ý»oøÈâ’#îý!Œ¹ÇEl‹'b®ÅTm¿Þ{øÆŸ¨d§õ{}!["ÉØ«±T4ІøÀßö±T)‹cÞ^ò‡–¼¥fÚ•¼¿§ùvÅ›‘³Ó­£¶o²8ƪ( ÑGE a&Õ?[vnƒéÀ¨¨íwsÌøvÅQ`(è1Wb®Å]Š»v*¢¿ïD¿ñŽ?Öù#ôyý GÔêÙNÅTn>ÂÿÆHÿâk’‡?û˜Ë—ËïVȲv*ìUØ«±W ŠƒÔb¬3Ì w1<ˆ•|C¾*ù«ÎþE´Õí/´Ûû¯¬/ch®íf@ÑÈŒ(U”ƒ\UùyùÇù¬þYJúÞœ%Ô¼›q(QsÄ™tçvâÜšžHÄ€’øÑÀÉt'|ÑI¿µ+ÛŸ(ysL¶ŽK¹íákhTÈæ+icP•,V4Qã¶û×3c*Žì^¿¥~Qù«Yh¦Õ¤ý g&òD IrTø Ñ µ<©Ýr‰êD€úÉ•F† Øián%^3^ÉWž@w!¤jš¿E ‹)sdú BòbŽºëÞ™zæ“å¨íUKŽ ‡|U–GD¡Qh*¶ßì7üd“þ&Ù)óø¹Œy|þõl‹'b®Å]Š»v*ìUØ«±Tü|Ñ×ý‹â¯ÿÖûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®ÅVJ<»ô†2æ?²,Š»Q¶ÿyíÿã~¡’ŸÔ}ìaô…l‹'b®Å]Ь(¾«B5î+Šªb®Å]Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*£qöþ2Gÿ\”9üÜÆ\¾_z¶E“±Wb®Å]Š»h€À‚*Qб=cBŠàTUæÚ¿“,u k«ë(ol¯bx.ìçE’)b‘J::0*ÊÊH ŠмÛÊ‘~Gò$"ßË_ŠÈ#LÑÜJÒ\L‚iFUšfw W"•éJ×$dO5zE¯”=/Ã"¬ÛKòŒqQŠÇfÖÖPZ¨¨¨ý£Š¢ñWbª6ÿa¿ã$Ÿñ6ÉOŸÀ}ÌcËç÷«dY;v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿ×ûëkþòÛÆ$ÿˆŒUUÑdR¬ ƒ± ÔÆiZŸÕÓù¤ÿ‘ÿ5aã>_ Žø%ßWOæ“þF?üÕòùá‚]õtþi?äcÿÍXñŸ/^ø%+°¸žòïW¶¸Ñu-.6å ²¿ºž‡P¡ŽC=°·ºšEEg1‘:Dü•ˆBœ]‘"b×gj±çÝ¿1½×0Ë(kžÀÝŸ=»ìuÚ·Nôiõtþi?äcÿÍXñŸ/^ø%ŠyïÍOå÷’|áçÝf+ëÉZ-þ»ªÛY7;™-´ëw¹•!Y% •Œ… ê+ÔŽ¹ æà«ê@ä9Ȉ´·é´§>Xã‰ÞDdÖì‚ÆK}BÊÎþ]a½‚;ˆ•äpÁdPÀ0 Ehwß/Ëcœ jâHåÝðpðN9±Ç$n¤}è¿«§óIÿ#þjÊøÏ—È6ðÁ+TfQ4…A"5•ªÄvœ Ÿs‘žB ]toå½™ Õ×Í£Í6§¥iú…yzîöšçBÔ'…î­ÅL35•Í͹t;®µèÄo–Lðšpý`1çÏ™ëçÏÜy޵̲]£ù—Ëzþ¯æ½HÔ¤»Õ|}›æ‹Z\Çõ[«›85£ç T“•½ÌoXËˉ<FFPp’G!Î&¥ò?±”ñðHDó1ÿ 2ˆ?8Hwíææ¯2ùoÉ:@׼ϩI¦iFûOÓEÕ.fÿJÕo!Óìãá‘ÿyqqV”ZòbÈÊqÆ+Šf†ÃsDýÀó_Ó)tŒe#¿(ÀHü'¿¹-òלô_4ùóË|„7ÿ–Ú­¦®MpÜa–{Í6ÓT­ŠLìÈ!¼E%ÕO0À(Å„Œñ ¢¨ÊQä.àxOÛÉ91ðHDó0æyN;Æ~¿t×êéüÒÈÇÿš°qŸ/cÂ?»êéüÒÈÇÿš±ã>_ ¼#ðJ¢"Æ¡T'rI©5;œÚ@¥ØìUMâI –ä ‚Ve44¯B<0‰‚[õtþi?äcÿÍXxÏ—È#„~ wÕÓù¤ÿ‘ÿ5cÆ|¾AxGà—}]?šOùÿóV^gØÖãzÞ±õtþi?äcÿÍX8Ï—È0á‚]õtþi?äcÿÍXñŸ/^ø%ßWOæ“þF?üÕòùá‚Z6Ñ0 ™"„„Áaã?€€+ä;v*¢`™›ã[‹²‚iN€ —cÂõtþi?äcÿÍXñŸ/^ø%ßWOæ“þF?üÕòùá‚]õtþi?äcÿÍXñŸ/^ø%ßWOæ“þF?üÕòùá‚]õtþi?äcÿÍXñŸ/^ø%Žyc̾[ó•ž¡¨yoR“Q´ÒõmKC¿š—0úwúMÔ–W°Ò`„úSÂéÈ­J©*AÂ$L#=ªq âyíÝ3ÇÃ3Î5{ÿ:"cçDük²?«§óIÿ#þjÁÆ|¾A#ðKÆæì7^t×¼¡åÏ˯9y¾×Ê·Ÿ¢¼Íç--ôÅÒìµceúiî·š­µëÈÑÏõcµkuiTI2”Æ#’RÆrµK‡—ï<2D„zDñFq!€2ꇧŽ0˜;ÔIÜúÎÆ_ ™â¦eÿ95Ãù±w®~H~dyKOü•Ó¯/üÿ¨jW>Wš;y-4¨õ•´‰tï2^I,³ZÌŒ…ÇVâò!‡ÄÉc„Ë„mÎ\cºY&…Vh1i¥“><z²Qì##(‰ùqBQÚåÖ«wÓv2[êVwðúë ìÜD¯#† "†€b+C¾ùfXËåWG.‚qÍŽ9#u ø‹ïEý]?šOùÿóVWÆ|¾A·„~ wÕÓù¤ÿ‘ÿ5cÆ|¾AxGà—}]?šOùÿóVÑÑ2ÇÃ#ÈÈGŸñ)þ–=ÛwÈþ®ŸÍ'üŒù«òùpÁ,r2ùnãͺ—‘aÔ¤5i:Mž¹¨it¹†¡=͵´Þ©&ç-œËÄ9aƬ*I„Œã) ¨ÈDì>¢8«å¿re„DŸââ­ùðpñ|¸ãï½¹~¯q>›h—6Z.¥æ šæÞ°Óç&Xç™#’ro.­£á±‘À~eTˆÑߊ0&@l<èPÛ™ëå°&Ï*²¢{…Õü‡K>dòO«§óIÿ#þjÇŒù|‚ðÁ.úº4Ÿò1ÿæ¬xÏ—È/üÂ?0¼ë£~\yj_2j¶º–©ÎòËKÒ4M1ƒÞê–§s•¿¯4«Ï<¨¦–8Ö¼¤‘3Ç#(Â"å"@tr;ШÂ2‘ß”M\¨pNF£I$ŸpøÊDF#¬ˆ#ó—üä£ä_,é~i×?ç3Å¥íí®™¨ÙEsåO¬i××úŒZe½Ç©æhã—ë2ÜDRKWš%Wýã£+ªHHË,1Çs:á47—ªã½Hð2$˜J@‚Žã)0Hÿ†2î"¯`x®2<¯£y[óËÌžjºò=ï•üÁå/5éþYÓ<Óªhú¼¶RkmVîúÎw›N¿½…¦WÓä.#v@¬”v%‚Ê>¨ÎQ ˆHDíÖQê:]1µŠ,LxD qñÖÿêf“¿ñx‘1ëWÅÂvzoÕÓù¤ÿ‘ÿ5d8Ï—È'„~ wÕÓù¤ÿ‘ÿ5cÆ|¾AxGà—}]?šOùÿóV8 ‰H*`K±U®‹"•`H$‰ Ôn0ƒH"Ôþ®ŸÍ'üŒù«òùpÁ.úº4Ÿò1ÿæ¬xÏ—È/üï«§óIÿ#þjÇŒù|‚ðÁ.úº4Ÿò1ÿæ¬xÏ—È/üï«§óIÿ#þjÇŒù|‚ðÁ+ZÕY‹KEŸÞ?oöY^mG…ŽS<¢ ä:n‘ 5úKüºóŽ‹ù›äO)~ah0jš/œ´»m_Kµ¿oNê8.£"Ì‘K*îØ{œÊÏ b— « yw€{¼ÖPáœáÖ”çœ$`kÊã·—s3úº4Ÿò1ÿ欧Œù|‚8Gà—}]?šOùÿóV_ ¼#ðK¾®ŸÍ'üŒù«3åò Â?ª",jAw$š“S¹ÀM¤ ].Å]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÐûëkþòÛÆ$ÿˆŒU_v*ìUòïüåg¯|ûä­ /òæ÷óOVÐu†Ôô(5——5] {¡esG_Ó|˨épÜÚ7KyÖáƒÆËFÊ% ±”DIá{ÀqîjçPôÎðŽ!(Î28ç~3"ø~­¯üÙGùЗ3ÂcÃ8Ç$8þ¯ÿ8÷ç6ùÔ7œ<‰§Þy?QüÝòÿ™µý.ÚîÜi’èÖ_—? îÀ·3$’Zþ‘V6ò%e޼âhY«ŸÄW(ƒª>¯Q>,ÁÆeÌH/èÈ^Ĉä˜Ó=3ð0B£°Œá¨9'÷ÀØ7Ë`IÙo’?çoü«þXùŸDü½²ÐüÇåOÍ7}w]·žÓëv¿—7qkñirMë3›Y¬½$Bx‘ bºü³8ô¾£ÏI8dêeðqsàˆ7QˆÌóÃÎ^üx§§ ¿wãp0-A”EFFR bù÷òsò_Ìþnü‚Ó/|‰ù;/“õ=oòÌ^^Ö¼åq¨é†_=êZîo‹É¡$í±GâÚ’B-XmÇ¢X®~²—ðÄŒŽùFqœ³_/L#0×”f&cŠ4æÃ4!Ú"s7Á«Ë#?æãÈ?ço# Áx‰’ ì·Ÿ“aò÷üä4ÿœ˜šoš$òö….‡«yoóJ¸ò z?–ô}7G‚ÛR²Õïuä‹ÌVÉ4W2ΚeÃA,S3õ`Î<ðÅ“,ÉáâžRe-£8ä¿é©Œc€Æ! Uèð2eÓiðÄD1G†;Èd„ø¥ÏÓGÓr‡®Qâ†àBÏç!?2?(¿9Wò7Nò±å¿ùÈ›-7óJ×üMäO(yƒHÔ$º‚o-y‰…­ÇútV¼n'•Ô±Ã:‡ŽCÀ¾QƒüÌf`e(åµÔ;ý'†Äˆçª ÈDÑ“‡O˜ pʱ‘¹ûü\«+ï"È¢/¿ç5uóWäž§æ¯ËK7ɾJ˜º®ä›¹¬o ò“ë:Ε}廆;‰á2ÛElîŸV2Cm"ñ‰Â¤Lkœf0e\yNš0ï•̘‚wýÞ9ǨÎ6}r Y g Æ#†Ï pìpΑÓSÊ|N÷‘`×,·ÿœJófµùo¨ØùÃòÒÓTó†ÿ8å ùWòð]ÞXLúžtÆ×%V²\˜íî­ÞæßÓ¼BsaÀFffËÃ9åÄj~6 DõáÇ ×p¸ž(ÿ .oºˆŒ»á9µF`ىǛ$ I[€mÅ þ’^óùyùuæ/ʯÌÿÏ/9èŸV:ž¿ù‹«ùoQ³ó­ŒÚš.­.­t‹-v®DÆôMÌwzŒ‘´”ì*²™¤ÁˆÂ0ð#è€Í?w‡.)c˜Æ‡Ã.DÈðƒ.¬ LažOVHé¸I;Ÿg€Ëý°xQâQˆŽ‡ˆyÃþq³Wó—ç.ü㎽¥^y¯Dón©ù»Mòky¯Ìw¶þiý!©ÛÁªZjsGuhtãœðz6O?WžÖHx«qø+hʱÊâ#„¥Å/,‰ßÕÇ;³¿¨o¿«ùÀð“ˆÂ<1ŽF¶$O,¸vÛÓÇé¸ôÓßò–NÅ]Š»v*ìUØ«±Wb¯•?ç ?,¿2<÷æ.÷òöÐ×q~WþbùnËÍŸ\Ÿ£µy4uÒ›”lnW“ZÈÞ¬(Æ>5Ù¸Öƒ ³ñGˆJ8‡ ׈!Ï$/§=6hz¹¹ºlЇ…Åü9ã3µÔF<±â®F¥8úzû­óüßóZÞ¹å8ižKüÈß,kÒ~^Zj–_è¶©]èžf¶Ô5kŽ…¨OgKôÄæu»ŸŠc‡žxá:ˆÊdKÌ&"FØâ!8Șý?½âÇb‡Äür_‹Žè“â>hJ`›É9ÇKiž ‘9ð‘âÿZõßùÇÝSËçCü“´ógät›w™ìÿ"4™´{=;VÑ$ò¥½•ȵÓon­4îk_émktðÆïL ¿§Ï½8|QÆaãÄ]9q╈£’s,~%Äz@GÄx ±ââ­¸¥’ŽÜ‰Ä1“!´Ä8$O‘ß󌿜ߒ_–Ÿ•ré^yüÈòGåTÚß|ó©ùwʺÿš4ÛyFKæN(º¸C< ÄѬ‰Tn'‹¾Z+QƒOŽÆY8Á«—âýRãŒCŠBW!d†¬áÏšB<1ãÀÃ8Ê;zb`}2„ Ž3è‰1 ü½ù¬~Xù_Ëšß’'¬†£å_Ïo1ùêóÉÞT…ö­åûÉ5í?Kkyfº²²&=NH縌¤JcXÈàÉ,#L'‡ á1üÙÎ?VÿVð„dFôA߆›u† êgŠ0ËùÜç¾ÿŲßc"e~«1-Cò/ó£^ò§™_Ëù4­[Ì>Yüÿ‚-mOK’XnüùªÛ^hÒKÓDZâ4nL®R2)#.Õ„!ááŽ;Çž;râŘÎuthGpH:^Î^›UÌÇ,½1üÆïÌCœâ$Õú„¨J Ë{á3ˆã={óßÉžtó÷‘¬ô ¿É ß:Üþ_ë6SyEcå]B×d¹×ô0j:\fÒ«™møEp.CÆ“Äê§%«ýî£Å‡9ãƒ(ðȑ댥q”"Lg‰sÖè1ŒZlx¦Hø¸vâÍœEDÈHðÈÊ<<3Æ2C›ÝÎ;yŠÃYüé}ò7EÒ5ÿ?yÃòçÍ^vòúhv–2YéwÞ[¸×tô‘®!¿R—6wed€G'Ûó¿ ÈÓäŒ2c‘ z‰È™sž9 øsôÝðqðjBR<Âä‹3€2ˆã:)âÛ”räò–(Ä‹0$G _¤9ŒÍØ«±Wb®Å]Š»v*ìUØ«±Wb¯’?ç#?.õ6ùÏòŸÌ^^ü®?™z×–.ž+A¯YywSò–™Õí‹Ü^ß[꺅–£owp¶ºÓRWŽŒ)XÚ:h©â'€JG˜ˆ22ðˆ¹G'8ç裓©õi¥¹©’— Dd‰¨Êì7‡¨‚#)C'žnçu½òûΖÚüã„»ù³¬kf¼ÐôŸËû»SË×W:¥î‰q¤[yŠIôðlL¶Öò BÙd†‘mccÅÖ£—O§Ç+$:m˜TIdcÉ/V?ßú`%Lj7çÊ<}FXîr [ÿ:"1ñ#ÓŠc$e 'XÉœ²q™ìgß”¿’Þ~ò5æçß3þXÁç<~[~CùkËÞHµÔ5=>K–óF”úßÖ¬-ïØº[I$7PÀnÄjœ%eSÇÔLØåÔožqú²äÇ}.<3ü`ÊQ»™ŒI2¨Éª±ÏÁÃ#ÃŽ93žB£O‚x"}0‰á€#`=[òßžîÿ;|·æO%~Wëþ@ÔåÕ¬ó7ó=oJ>Uó…‘[^éQjwuRÞ ßNI"1€·_V$ÇÓDcË-ÿwûˉå"lcž1¿ ̆9ÎW`' qžjÏ9dà ¼ôQñŽ!,™ÛŠ4rÆx‘ãœr)ð%æÏÊï=ê^WÿœâÓìt/^óó‚Öæ?˘>µj¿¤ZO%Xi*9<Áa­ä/ïÊtåölÇ#GŽ\£šS#ú>,f<¾‘|Ýž—wÿœ†šïK‘<Çäý\_­§—›ÒºmZu[k«[V´º¶KX…¹x¤c!éçŒôñÇ/D|)cÉ~,¤â½Ç÷œ:9Tâ`1ð’Eú¬äe–LfÏ)c?ê>‡Ä7åb!P±?Š\å@|Ñù ùÏæ¿Ê_=iz¥´­ç?-XéBò †÷NkÝ{ɺ«o{¨ÍëÞ-Õ’\ëö±,2Ãy¢Í%Âz.ã.Ëæ”så,¹#<Ñ^ˆÊ F3¸HC,ògˆ»0œ!) ãW‚1Ã#Fá’8IâôË(ÛpLêŽ,\Þ Ç&HØ”Iù_ÿ8à¶^iü—¸Ô?,µûO%~_ÃçkÔѼù’£}+WÔnt 2K=3ÉÌ4¨£2ÙÏ<>ŒA£™ZWá##9‘ÅšÌà³Å|y,.G‚| ƒÂ1Œ8¢Ó@â”7õg„¤ p˜G ñòãÅÁb^£;êcžDÿœpüÂü­òå¶¥ä?Ë=Ûó$¼ÍåÏ͵+‹K˜uo1ÈšKhÖZ»›–úôhÑ\Å .ÑCa,£,ÕÊññÕâÉ"€xIŽS?IÉáÎ{äôÎUÆdã8KQã꜒‰²?u?@GÕø€ £¼£.$£ò÷þqg̃Nòÿ•üÁùe}å¨üæµóe÷“<Éþµ ¡ÿƒ.´»³u¥yD[è뺃,r[ÛÆþ²7)„¥9f3,~%fœ«ŒÆXÇ«™ˆìa1qåË.P‹4üœ¶×u/ùÅÊß&ëß‘·_™~KoÊï'Ý­¥ž­§G}¨ÝÜ’f·´‹R¸±ϧ¤V÷qÜIs ,ÀÄë4B»Ž×êeÄ”'+iG†X ŽƒƒÒx‡Õ}<âLç '<ç{œLNM2ÄŽXJuÅ—*98¢zÿ—¿›ú÷äžVÖ4Ý^ëZ˜º­å/.ùV³ÔuÝ?Êúgš´ÝA ÕµE¹š «‹{[y\°¹Ù8#K<Ü™èÄxsi%2 Æo$€¡Ë ‰ªÈBXã:ˆÈ%!`ñÀí©ãɹ¹bૹm,¼R…ËÓ DáŒÛZO>ùOþr;Zó®™ùMæ?>ùKÍ~Dòç—W]Ðo|½X^iÚ¶±qqõ¸u}cNœ¢Å}ƒ rWp!L¯Hj9qËÓÇ’2?Mp’jå±þ.VÛª7‹Žæ-ǯ¯Â᫨ïáÈ}B¶½ŸO``ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÑûëkþòÛÆ$ÿˆŒU_v*ìUØ«±VˆEAê22ˆ ‹Rý#GÒ|¿¥Øhš—i¢hºT m¥éGmkmcŠE 1*¢"@ªd¤dl›*w$õ$“æI²O™&ÉêwLr*–ßèúF«6—s©éVzƇwõý{¨#™ìîý) úÅ»:“ž”Ò'5¡â̵£G¤ñ ~G˜÷£ªÞÆ= Xï¢$>D<À=,UØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*Å<åä?#~béËÿ˜>Lмõ ¬étº'˜tëmRÌO`’ˆ.ã–>j€Ô¨©ÈKdA 9ytÛàÊ3”AÐ;=ïˆÞ­#HÒt +Mд2ÓDÑ4{h¬´Âí­mm APA J©"€ªªP »&Id‘”‰$ó'rZã@PýiŽA“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¨SKÓu½7Pѵ:ÛWÑõkilõ]*ö¸¶¹¶ rÃ42IÕŠ²° ƒC€€yûþ#qò;²„å DG"9„\QGqà k 0¨H¢@UTP*°t)HÈ’M’׈Š_“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅX/ÿ+¿,ÿ3bÓ üÈüºòÇæ <’K¤Ãæ]"ËVKW”(‘ [È¥– +JÐW ƒ$v˜å!õ ïcÌn÷²â<&7±éÓk­¾'æYʪ¢ªª…U*@èÂMµÆ" (ð2v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅPññÿG_ö/Š¿ÿÒûëkþòÛÆ$ÿˆŒUUÝcRÌH°$Ôš †-ÒŸÖùdÿ‘oÿ4áà>_0Ž!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øQdPÊI‘¸ ÔŽ) Úì v*¦ò¤eCr% *³ W >8DIA -úÂ,Ÿò-ÿæœ<ËæÄ?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð Fæ%‘ T“Ðø<ðBñ…|ƒ'b®ÅTLñ«2üd©£qF` +Ôã’á,xƒ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð „ñ³*ü`±¢òFPM+Ôá ^ ­‘dìUت€¹‰€ HAFô#þ'À1ã ýa?–OùÿóNåó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ä•$,*!•”ÐÖ@ðÀbBAS]Š­wXÔ³ l 5&ƒa„ A4§õ„þY?ä[ÿÍ8x—Ì#ˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~wÖùdÿ‘oÿ4ãÀ|¾ax‡à}a?–OùÿóN<Ëæˆ~TGY2’A$n5‡c€ŠH6»]Š»v*ìUØ«±Wb®ÅPññÿG_ö/Š¿ÿÓûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*£qöþ2Gÿ\”9üÜÆ\¾_z¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÔûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*£qöþ2Gÿ\”9üÜÆ\¾_z¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÕûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*£qöþ2Gÿ\”9üÜÆ\¾_z¶E“±Wb®Å]Š õ GOÒlçÔu[ë}3Oµ^WW×r¤0ƤW‘ÈU4Üâ¯Öÿç$ÿ(4†x­<É/š§,c˶w»‘ØÐFÖ` zÓ³(Dz8§.AñÍþrÛZ•¦‡Éß–fÃ4k©yŸRŠÝÔƒA"YéË|%SMƒ\DÔëC¶[,=‘Äñ­góÇó£]ro¼ñ‹jj²ižZÓ¢°†D#`ó]=õÚ·~Q\G¿¶Ùtt±÷^'Î>yóÏž´ï5ùKQÓ¼õæ;Mf ]Bk}sô¥Ü÷j!–ÛŒ,÷J$‡÷îL2ަ¼qÉŽ"…(/¡?-¿ç7<÷åø­t¿Ìý?Ì+$`æ­ A§jâ1ûWMéÙ\¹'v‰­”´lsáîM¾ñü·üðü­ü×…?Á~m´½Õ8ºòÅÕlµ{p€r3i÷9ÕEvp…ª3.ùQsKÖ0+±Wbª6ÿa¿ã$Ÿñ6ÉOŸÀ}ÌcËç÷«dY;v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿÖûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±WŽyƒþròw˯qoqçÍ;VÔmQ^ãGЙµ‹ÈÄœ=?V =gx„ž¢•2R*Õâ¬D£.A^¯Îa4öÌ|‹ùq{<Œ¬©{櫨ô´£—„‘ÛÚ­ôÒ‘P2Iè¬HjŠ£¦‘ç²-ógægüä?ç¶¥å¿5_Áç¨< –ºmõÅŸ–´è )éÂ^ ÷7ß]˜•+»Fcåüª>·òÀh¶Oùaÿ9ÅæÝ[é_›ºøËKJ'øÓBŠ+mV5éÎóM¬v÷ÙÞÙ¢4Ù-œå2ÃÜ›}ýùuù»ùoù±cqùæËO0-“pÔ,@–ÚúÕ» ›¤Šæ õ¤kQ¸Û) „½»v*¢¿ïD¿ñŽ?Öù#ôyý GÔêÙNÅTn>ÂÿÆHÿâk’‡?û˜Ë—ËïVȲv*Á¼ùù—äoË-6ßUóǘ`Эo%ô,"d–âææABRÞÖÝ%žb©¡ ë„v ùŠ÷þrÞóZ2Gäo KkhæT‡\ó=ÊÛ°£OMX‘¸wÂqHtE½ÿÉœÿ–˜6¶wžTó}¥ìZ‹¤Ztw)5„×.ê]Voc‚I Q_…NDÂCrôüŠ»v*ìUتÏûÏqÿßõ”>¡ïc?¤«dY;v*£Û¹ÿŒƒþ ™)rïÒXÇ™ütVȲv*ìUØ«±W‰þv~|ù/òGÒõo8Eqúri-´›k•ùËæYdxã‰8bÌݧ&¢™F6Uð—æwüç§žgÐÝ?/ü™kåKدáiu«»¡ª»Ø˜¥¢Ú›X„rŒAX~_4w€G4[Ïÿ,?ç/ÿ:¢Öæ»–[=Ãtñɫ躌QÇ)+; -î¢Å ’¡ méÕx‰øB\‘oÕ#þeèÞnò—•<Í~`ò­×›ZHtýþî;\Å3ÂðDÁ€•¹&Ü+¶cÑ#¹“Ò2*ìUØ«±Wbª2ý»oøÈâ’#îý!Œ¹ÇEl‹'b®ÅTm¿Þ{øÆŸ¨d§õ{}!["ÉØ«óæWåÿåìQKço9iXk˜ÞK+[û¨â¸¸XéÏêöäú³q®â5c„ WŠjßó•SW·‹ÊžX×|Éë¿Å¨]Û>‹i\Z¯ ¿Tºº -‹VŒxÆÉ#]<Ï’-âºßüä7æþ½o46òhß—É2°ŒèÉúZöð•o5VÝøHÅ…l¾.+]‹&] êQÄñ-~]SÍ‹*ùßÌ:§ž–nFkmràÜY–r¬Ìšz„²Œ’µœ+Çp´]²øá„z"ÒĆÞÒ!¬Û@¥™a‰ .Ř…PìI>ù4!%~¸«ó%í½ž¨Ës'§Ä`V¡5’r"ŒlWp=»äeÉ/²„£m$¸²Ô-52öëGÖôóËOÖôéäµ¼€ÿÅsÂÊàâ´=Á5}}ùÿ9§ùå1gaç½Ìý‚çU³xtï0,{Q•…ÛŠRŒÖÕ­L•j%‡¹6ýü·üëü²üض2ù+ÍV×Ú„@ÿ.\†³ÕmI=…ÀŽt‹q~<Q™wÊH#š^©TWýè—þ1Çúß$~‘ï?¡ˆúã½["ÉØªÇØ_øÉüMrPçð?srù}êÙLó/Ï_–¾@óŸu v¼·ò®—q~¶ ]ZæX×÷6ᣎVS,…S—Ƶ"ƒ¯Á½3óÌŸ™þfÕ?0<á¨I¨ù‡Ì…wzí­Ð±‚ÎÞ5,±ÅrA;–bY™˜çbˆˆÙ‰}幫SÀfPbÍd“l’ %|U.•úàTºWÀ©l¯×¼[αJ¾dúÑZA6ooQ»Å5Ã0¥k°‘~ü£/4„…+J•Ö³¥éÄ-ö¡¬ŒX]À‘ j©öŽÈÇaÐØáµiuZõxéšÂFüW뺕l£Pã‘>“ƒ9⽌câ!j>2’”>åÿŸtùvkmoó·ÌÖñO<£B²µÕ’‚ÆíîíãBìáâêNÇc˜¹…d¨¹JTmþÃÆI?âm’Ÿ?€û˜Ç—ÏïVȲv*ìUØ«±Wb®Å]Š»@ÇÇýؾ*ÿÿÐûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*øïþrþróË“·—LòÕŠùÏó/ÒG“HV+c§ A(×ó.ሣSã ‚Å+F$«òû̾tüìüÍÕWYów›ä×£ýf/-]¬ƒJ‰· ´Ö8è 9q,GRNù•S_fþS~o~YᯖüÍäÆÐ|äèb²ŽEWµºzK{&Ÿ²êŒOÙo™±×OÒÅóæwZO8ª¥ŠEkÆfŽ#áÈ)JP×–Q”ú’•äò×›áúÔ1¬ò/‰ÀÞ»tà £âòÿæWäìžgü¤ó5î…m%^ûBV3é׬ÖRr…ÈÑŠòZž 0dÀ ‚ûŸþqóþr»DüÕxü¥çH-¼Ÿù”¤ˆ4õ,¶¢Õ+•™¹ªÊ<»¡pŽ ñ˜²õöV—b®Å]ЍÛý†ÿŒ’ÄÛ%>÷1/ŸÞ­‘dìUE¿Þˆ¿ãŸ­2Cé>ñúXŸ¨~;•²,Š»Y,±Ã“M"Å J^Y\…UU,ÄìN*øÎßóšz?™¼ñoùUù©iú…ÍÙ¹TüÖœ%æ™l–êV_ÑP,ˆ/eYU$'Ð CI—cvhüÿòÿ‘¼Áu£só&£ù§ç«[s Ö©«ß¾ Ö¨õ™]Œj¶Vñ#·‰tN•|Ξ,qÙx’máòV³eæ]=.5Ûv¶ŠÕ™­®L,ÔT»¶´™›ÈRŸµP0"&Õê¾tóßæŽ˜¯gabšÜåÌWR]ÊGÆH¿ÕR¤5Q‘ˆo¯Ã–Lñ„rb_”×hÒü©s7µUM;V³µ[;_Hîmµ(£TâׂH®@b»–U,zV™r l’ô_ËOùÉÿÍŸÊífÞÇR…<Ñå+‰â‡PòmÛ¤3ÚIq7¦'²œ»ˆƒ²ñX“•¹;DˆKÇÉ„IúÃäÌ?-~dh‹­yvyU¡+¯£^ †ûN¹(­î¡‚¸ ³+28£Æî…XâÊ&&‹&q‘Wb®ÅTnÞ{øÆÿ¨ä¡õ{ý%["ÉØ«±U¾ÝÏüdñÉK÷~’Æ<Ï㢶E’]©júN·Z¾©i¥[C×3\^O¤ÈdžVi@HÐv;(Ü튤ÞQó¿”¼ù¦_Êõ®½`’¦’Ý8œ8K’2iPEElAÂAÕ?¿¾³Òì®õ-Fæ;+ d¸½»™‚GQ)wwc°  ’p+òŸþs þrkDó¿—<³¤~OyçPm6ÒæëSóF£cêYZ][AG7¨ÐMq ¬¥‘WƒqçZ¬l/†27(·È¾vo5[~_þ^¶µæ Þ×RÕRHü«)å¬úŒ’²Aê³?©Ê ±Ð1äÅO\Èž0=J-ä™ òÏ’¼Çv4{ ]rÂàɦÚ^ÂÄ–ôx¹üi…Sö˜ý–|œ PÁ|ªuØ ¿³Ðu­VßX¼¶ŠÚæÎ >9má`%Kgg9EbÄò7 ñ'0¾Š­cuæ{ õÒo M}§ÞC§¤W°’ÞIŒonEÄb^hDÈÝ9-MYØn Ò_§ßóŠ¿›^g´¾Ö|«ù™ç¨u >=1oô8¯Ü3Ø¥´‘A:‹é™$–:ΟÞ/Ãð…ã¿*3ãªê_gùWó?òóÏ÷Ú_”<å¥y‹PÓ£ÜÚØÜ$¬a%G­ $Š®£ÔNKRk”BYÞv*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤5uumcms{{sœO=ÝÜî±ÅQ©gwv *¨’MȲ~h~eÎbk~mÖnôÊ-Lè~T¶2ZŸ4}^)/5 TÏheõ(XÝ“2/€‘Ç+ ܱ%ä^‚Õ.ï5C¯«êŽeÕu›†iïnä=^âæRÒÊÇÅØœÍŒ@1fÒI¶IRùdÅRédÀ©|¯Š¥Ò¿]ð+ ó»^h°«„)%´õ>\G)HJdgÉ/(³(ØÛ$¨ØÛH<ÕªI ÙÁæK=BmXÐëZ6½híÕ¤âœ#!Á-O„‹¥Bce~íþFùãXüÉü¤ò'ž<Ámii®y‡MYõX,Ka:;Äæ.Eˆ¥iÈÓ b78„Qdõÿz%ÿŒqþ·Â~‘ï?¡ˆúã½["ÉØªÇØ_øÉüMrPçð?srù}êÙOÿœŒÒ$×? ÿ9´ëhešýü™­O¤%»”_[YK=›FAÏ0bE"£4¯ç—òÛÌúvœ¶¶úœÐiKµ¬ŽLVôÚˆ$oÝ©$•Eçɂ׊ôÌÜr Kí¯+ܬ‘Bèá‘Ôe5Pj3(1zÉð–IP2Iò¾Kå~¸«×<ÛåÝ ½=WW·µ¸?fÏ‘’r8—¨†0ÒI$/A\‰ òínïÌžm»‰ô/,\ØZÅ Fºž»þ‚‚RjÕ¾+‚¼w¯Sðíñª@Èì—[ùõÝfÖüÅ<\Hºnš¢ÖUâÑ<§œ²-:PÔ– <#zÚyc èš ?¢´»{' †™z¬CHjäQNÁT €@®¹z+ŸqWè'üûóHô?.¿0<Á-¼°Ï­ùÂ[x'vªMiecié²/jK4ÊOz{fcêd{åIQ·û ÿ$ÿ‰¶J|þîc_?½["ÉØ«±Wb®Å]Š»v*ìUÿôuÿbø«ÿÑûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»|iÿ9ÿ9'äï–­¼Ÿå'füÍóͼƒE¸ TÒìƒzsjQBàÕa^ïñªiF6Uùaå(É,}|ò^_ßHÓß_NÆIf–CÉä‘Ú¥™˜’I;æ\ ľ†Ñ<®¼P‡Ý™Š´ÿ—vzÝ“Ú]Û ×á4©±g¡ò_æ_”õÿ(kÖƒWškÝ9İØj·´•‘£á Îwfªž,wmø·l|± ¤$zuýÆŸ4WVÒ§„‚Œ 2°i/­<“ù¡oæ)4Ë’³Íä†H^Ÿ¼·Qœ$±5QÖ¿ 3ZEfËp+±UŸ÷žãþ1¿ê9(}CÞÆIVȲv*ìUF/·sÿüA2Rä=ߤ±3øèÀ¿7'Õmÿ*¿2åÐuWÑ5øü©¬¶…¬DxÉkx,f6ó¡ßâŽJ0ۨȲ;Où…æO>ÝÉ}æ=zë]ó„ú4ž^¼¥äœµ­*Ud¶úÓ•e)q"•äC! 5æF‹{ù_ù¯æÿÉY|Åäýråtkb–ÚµÀ’ââÕ”ÔÙê–Š} IGƼ«Q°Ê"CìW´yûþrSówó/ËÚÞ“s¯&Žš–—r"Ót$X¡¿·‘Ó’+‡y¦!¹ n'ìÕB¿Ç€5·‘yÌ©&…tKK,ÞZÜÛëz·ôÈ{Ù]"k™X”˜2EV!.L|§É.ó޵}æ$yD].ïUÖ´Y-eóOâ‰aÓgµ» ü–8Í7±±5äž-HÌÜ@TG–ôk/3þQÛêö¨5Jk™Å½ÔÒ»(ŽÇWeN)#WHà ^!…&¥ª@¸*å–·og«y†I­oEµÔ66ÆëêÒ*G-³Ý™Q¹*µTȪB‚A;ÒŒCŒÕ©K|ÕrÇÎ×wv²é“~ŽÖþÂT–i]UR3ȯ/ú2òÔ¯Ù«dd}V•k½>O1Üi7úV§©]é†álä,å!{“ŸÔ–E) Z˜ä€YV=ÀÂG$2/^y¥/EÅŒÑ階—Æk/2ÚK5³Ç3òð$gÔWކ´˜q£GŠ¿`çÿ0µM[ò¾Îûó ÍvÚ®§fó‰5‰ŠBÉil¡+vÆYJ;vbP«;³TæXˆÈ€È=óAóW–<Õ ÍÏ•üÇ¥ù’ÞÎcowq¥ÞCx‘J½cvÜ+àï•ÒSìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤>"ÿŸ†kúþ‡ÿ8å©G¡´ÑA®kv˜n Mâ°ã5Ë¿1FÕ‚0xÁ£U9qóI~Tyà}^ÝTqPª€t¦gE‹éjª|²ð†fòl>XU$wÅPÉRÙ¦EãÉ‚úŽ‘¥M9<Œx–bɦi^å_ÉÌ8ÉZyz}N•doÓÀk(ACE7_]Ä”<"e#rÀ&™j"<ÓOoƒþqB¼Ò/l¼ÍæýDßÞB¢)4¨¡-Þ•p~°—¨åÐÑ6ì Ûz’y2§Åšÿó¾ü¤7Z–£lš÷“a«§œ´ðÞ„QÔõè[ãµcJ’Kź)cÄäióÔÞgÒ`¸’Æ ŸUÔâŸIÓÝ\¨ ÃãŽ*ðÜW ØøYhEF<ã¨òô¬m|µg"Q./_ëW °—Õ¢¤KA¶ò·ÄjV‹G˜‰(Kum?O¸¾Ô5+Ývö$ªÜ_H¼‚\˜à‰c…MwEû & @ß“ºiÑ¿(¿+4suõã¥yCC³7¼=/[а‚?SÓ«q寴©§ŽkÏ6oA_÷¢_øÇë|'éóú¨þ;Õ²,ЍÜ}…ÿŒ‘ÿÄ×%÷1—/—Þ­‘d•ëzM¶½¢êúãɦµeqau$$ ;˜Ú'(X0 T^Ø«ùaò[3ØÅo{áé]Úʽ 8º:‘ôFdÁí>]´“L•$е[ÿ/–nrCc5 bdYw·•d‡í-MV¬ÌÀäE‹Ú´-CÏò¥¤oçKå·­%ö’$áÂÓYíW’ « =×,]êÉ­ôÍ[  ó¿”Ò¾X¾?÷ÉT»ÇËö¡Çå¯7~èßù¯L$Mê‹="X ÊceSYu Š †+J8òk%Â{ÕŒê~CŽí¬äÖ<Ï®ê A.í »:}µÃy*ñÙZ•p¼yšªª¿?‹”L|Õf hzM¥ÛéêßÞIRC°¬’»š(bNÃÃUó?\U)™ºàT¢gë)üœmçmöCú°~©ÿÎiMÿœwò½ëEsǘµ-gS¹†äq§û‘žÚ&ˆqSé¼0#©5¯.@Ѐ5Ù>¢È>µÈ%Fßì7üd“þ&Ù)óø¹Œy|þõl‹'b®Å]Š»v*ìUØ«±Tü|Ñ×ý‹â¯ÿÒûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š¡o¯mtË+ÍJúame§Á%ÍåÃTˆâ‰K»h¶*þ|¼Çç;ÿοÍ_5~fjK"Ç®]•Ьå¥mtØ?wgÂUbµîYº“™â‚÷Ï+hê/‡Ã2¢½ï@ÑU‚‘‡°èþ]PðË€B;Ì”º4Ù´í^É&ŽT*­i\f#[«ãŸ4Îù—N–I<©¯™l™Ï£m~¦ã‚øä’›1ÌS§é)´Oå¿üã6­äi®¯u‹×¸žêw¹¹•¶ îK‹ÙG@<2xôü*K.󎀆9 •i÷däùžÃ͇äïæ?–¿1ô±)]ñN±g 9]鲟NòÞð’ñâHø_‹uPs4,2Üû+Ë]FÎÓP±¸K»+èc¸³ºˆòI"•C£©C)׳Dâ®ÅTmþÃÆI?âm’Ÿ?€û˜Ç—ÏïVȲv*¢ßïD_ñŽOÖ™!ôŸxý,OÔ?ÊÙNÅ^ÿ9)ù®ÿ““sóÅ“Æ5øm—Oòœr/0Ú­û {Vôø·¨"gõY)ñ*¨­pjü)ò÷—|ÍeÇY±Ô¯üÉ¥]Ãu¨Yj—òâà5Äw·QzÏ4« Ÿ“–ø³3Ôæ\ú1}™åï;7šô¸ ¶ªÅ¨L£÷…ÖžŠµPÅä¹…:ÐÇz.ÍLÎ0C@\yûMò,ÐùsLÓ[͆šAÖ®æ™l k‰[ÔœH¦¬„¹f '‡ Á•`gÁæšdŸ“ž`ü§óŸ›Âڷ寗|ç ´i|»CowúC¼©Á´¶"XãRÌ…*R¥Kn2Ã8ÌÕQA8ÿœ¡›]“ó—Kòèµ½½Ðüµ¢Ú^ZhðËl#{»—¸2^…–XèLt„r5ŽÎyW©‘2¤Åá>~›KÖ­/4ä“Hó/–å[›8®U}HK¡ƒFÅ$ŽE%_ƒ•`Z6ß’åF&Òûóe­|Åä/Ë/8Ý[Dš>¾,5/ª•Wáw¨Ùz–§ÕVd ¼{ÉÝ’i™™‡Ab ®X {i5ôˆ[ýIô¢/²؂=S"¶aJȆ…… .ÎÁ© úGþp§ÍþdòŸŸ/ü™©C+yó6kãåºò¥–»£¬¦E¡!xÞÚ[Êå‡OA7-˜Ùà~¦Aú£˜Év*£sþóÜÆ7ýG%¨{ØÏé*ÙNÅ]бÝ^þ[æxº´†§Â‘§õÉK÷~’Æ<Ïã£ò{þrÏ›6žzÕ¼·ç0]§“<Ë<ãÉ­dæßOº´–ŽM2í# ÎTFrRbâU<×ìðŽì<'˜Ý%ù¥¯yf÷Êwé¦\´³BªMÔ˜ÐΉOŒ0;:šrî B¤™G„¡›\߯Þg’çA»ŸN×.´ÍKH.äXê‚çF²¸x¥2QJï-œœXì¥Ë /}¼•:ÓÆ÷¯£X±†Âá¤ó?“%j\ÛN¦m=Ô ¡©# pÙ,H=ß%z?åøòì>A¹òÕ¾ òé—wßiº”x»@ðzv’Š’~å×í’xТp®C ò ͆}ç H¶—vfÖµ.©EûÔšÏP¾€MTðõD=EG¨iU㑆֥êzfµõ½?S»½ fî[Ù"˜ÖçŠÇ,|ƒ I1a±­}Ìí^.'Ðõ fx¤k E/õ–¶oƒëýji#õbo¶Œ¦ªÔ¨áa\¦È)fþbÑlt]zå­bšYî-,ßSÕ$j™YÞá#çj¡ª‰P,Ds!”Y\X¿•gÒô}NÒ×QšÞê(BN¢¼œ»xÊÞ£ò4¶N?J±X¾ý#¨ØÜHšLo"ÛØÃ0Y^Y"iVIc&ìv—gjÈ»ŒŒEP‘fÓ¯îît}]®-nŒQßÚ¬B[c4·0k—A¹i%ZÊ”ýÛ2² €EVwå>ë¾Uó¾«åë›Ï.ù³OEo¬Ù•‘¡™ÝDRÄÌîåZ’¤úd â@žÅ_±¿óÿ˜ÞaüÈü¹Ò<Çæû{ -nîI¡ bìÉ4ví虘2¯yêàÌ,‘á•3l—íÛÆCÿ|ä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤>;ÿœûÑ¥Õ?ç|ù{i˨ùfóEÖtþ4eF·Õ-’g‘΋o$…”ìGZ°DÑdüXò˜´ëhìíî¬X´p •™£j€,­^­·<ÿÖžgBA‹ëo.Ü«ªpà»mÜLÈ‹{Ì¿¥ÒLÉH7,îBª¨îXîrJô/þOþbù¡R[-ôûISœWú©6q¿øXˆ;°+"¿´¼¨–¢ëi§¸yþqoOŠQqæ¯4Üj ’NÓ![hÊñâieõÅjÕA­Hž4µR<¶O è*~Zy/ÉáËX³Óî5‡ô›)žñ£@B«ÞNdÀä~Óž¤õ&´JF\Ë%þvüÄü¼ü³³KÿÌ9é~WŠa[[{¹Õn.7¡ô-Ç)¦#©£PT8%_%yÃþsRÖ_¬YþVþ[ßkâKo5ù©›F³'‰+,v%$¿pM>c·=zS{£§‘ç²-òoœ?2?6<ý#·œ¿1µ/©³ò^òÓK i€X+%¬Ís*†; ®$ Z‘S‘)’?Y‘î¤XU– W™ª¢½2¼†‚‡ô[šæj+þôKÿãýo’?H÷ŸÐÄ}GñÞ­‘dìUFãì/üdþ&¹(sø¹Œ¹|¾õl‹'b¯åïÌöáÿÍoÍ?.úít<½çO0i‚é×”YêW 8òzsáZ=zåøÐYÖ‘/÷{ý“/fòíÇÙòØ«Øt¹ê£å–¡4ßÑ…XÆ£&D«™úäU*™úàT¦fë)LÍ×cZÌÞ…Óò HÎç"UûYÿ8Ý¥òò‚ÔÉ+¼þTÓoå¯ ïà[ÇŒ¯n 1]÷Û5²6Y½³¨Ûý†ÿŒ’ÄÛ%>÷1/ŸÞ­‘dìUØ«±Wb®Å]Š»v*€ÿú:ÿ±|UÿÓûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,оTÿœÐó›ùCþqßó ê²´z‡˜- Ð­xIé·Nâ;ièAhCA×å\#š¿!ÿ.í’( Z@6̸/®|­‘@í™1CèŸ,Û«z{xfDC»èv(Q6ßlœåÂéZrpˆÍf\ÆÙ€©w`Â28óRiæTâ™´Ç.(°/›<ãn€J)ã‚Jø¿ó.É$‚äP‚3a/ÒÿùÃï6·š <†·3™oü½Æ…8b¥–=2âKkaðÓþ=Ò:TWçÔë&*E°>È+±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E’ÇuK1 «áŸùÈŸ2h^iüèÿœü­Öï¸yzÝ[Î~`±ž¤ú]›A¥fZëÏ+Ð1Þ1UÝYr4ѹ¢\Ÿ+þd^yJÓóÌñh7k>™¦Ï»j±¡ŽD#15Xæ2Tš|lËJNdÏ©Š#ÉŸ˜ÞZºÕ-´K”½Óî/^8ô™îídŽ+—p(¡€>‘© „d“EÖŒ2iiòyšú oRÐõC-®§ýÌ>`ŽG1ÜzÕw™ÃÔ34¯ñzŠO%oQ[pÙ]oº½—òòþ7þoþZ\èJ¦«¢k–š¶¥ª[ÆHltùMÍÃ\J>?NBL{“ÊIT·\ˆH¿Q?7?"´ÍM>ÖX¦‡AóVž¾˜Å¸•ÞÜ,‡ê“Ы4\äæ7ª5JìÎNvVŸ Oÿ>þóv§æ]>óÍŸ˜ºmŸ—­âeÔ—HŠyoç¦4ÉK÷~’Æ<Ïã£åÍ¿Êí+ͺF£¡ëÖ^Óïï"5VGR%ŠE£G"0 ¬¤;Œˆ4Éù“ç¯ Oå«»%yåÿJÙjRH|«æR¾“\45+„#»D54øe^EE=D\Ìsy±!ó§¼µ¨è÷p¬öÍ>mge¦XjŒÙÚÅmËÄGSÊœ¨HÇ$HP»C»¹Öîì¬ä™ÓͨË•üʿ޻×à´¼bháÏÀ²0=„œ‡.lMûÕšY=ýÝô—ÙÅå¯;ΪºŸ—îYEޱ`™&ÕÍ£#8]èì…¦>EY÷åmþ‡¤Ë«Ûi°ÏgôóKC—‰º±¼¹žiâø¡wry ñ5©ûK˜ÈAYyohžAÔ¾§"Éjt[—Yáe`Å vw * ,Iùà?J¥žbÓ5 KÊ«a¥jwºÞ¿sv³h"[y¥ ´qÛÖ¢)Š‘×û8‘cÍS?0]?Ì7÷6·F£y¡Ï 6S4lH³ŽY ¤»¯[ŠHo†´ 8dU$òÙÔ Jƒê×66ß¾ï4–ÜXT¡Qûϵ·"’ç¦BòTšòÆ[{MCMgKɯ/æ$ʊ׷ŒØ?"D~¨, zÏ\‰¥j~°lŒ"F¸Énªµ’1 „"»0VøwOì×,’-5ý}SZ»„4‘à ­™TÙž%{‚ʵR·*7&»t¨Š½óòÇóGΖvð%”èth.nn.¼¿<‡Ð)$²HZ9O#9nlTäZªrÂ%¿"_§?’œzæþ™u¢Ití ]Åm¨-ÄY%†F¤rÐÇ(øHª1§zm˜¦&6wéSÓñÑï['b®ÅTm¿Þ{øÆŸ¨d§õ{}!â¿ó’Úó/üãïçFжò]ÜÜy7Y–ÂÖ#G’îÚÒK‹e9c]»ôȲ7žW–;‹EŽEYc•8ÉÊÊ„v æTX½gC†[9…Æ•ª_èÓH$6— £O²žŒœâkµ½Öà‡Òÿ—šßš~Lxnt=OÊzŽ¡l¥m5?0yi/.@(!î,îì&¯¥UýÛ¢’Y™IfåaãæJmô™ÿ9Iÿ9 !¯h¿—Whce‰ ‡Vµ>§ì»¹¸Û¹Zÿ²ï‘ü¯šñ2 /ùÈßλ­2ò\y?JÔ¤uú•îay)P†%¾»w"7:#†ËѹVqÒ¥xžoæÌÏÎ_1¼ªþnëº|-Ji^]ŽÏFµŽŠQ½9 ¯~1»sºz6éÃ`$4з®¥ÛßM« 4ŸY¹»×.K\ßÌ õ®æ/4”Nh6 °DJÜÍ× ¹›®¥s7\U*™ºàTëòÊÀk?“Ú9S‡›´»àa^mþãîò„)ôhDzÔöÊsJC÷Ž'"ƒ¨ðÌK×ýè—þ1Çúß$~‘ï?¡ˆúã½_"ÉØªÇØ_øÉüMrPçð?srù}êÙNÅ_Íÿüäæ˜þ_ÿœ¨üìÒåxÙν¢}x…Õl­µª|\nG*µ]ÏSv4‹H—dß2b‡°ùz}Ö§­2Ї±isü+O °!‘™~¾IXö¡']ûäJ±©Ÿ®K&~¸*™ºàJS3uÀ¬#Í÷B×BÔgo³.ÍòœŒŽÊþ†|¹¤ËÚ„×?]mNµ°7œ=?TÛD±zœ*Üyq­*iãšÖiÎ*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÔûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,š&€Ÿ Uù•ÿ? Õ®_òãK³F“ÑÿØ›€µãÀG=9Ó·.={Ó%jø/Éj‹nkµeÁ‹êß)ß-"Üv̈¡ô§•¯S÷g—†dD±} ^¡XÅFK$l(z}•ÚpŽ™©ËŒÛ`+ooSŒ8±A/*óòp“qß6Ð!|Óç Å"S_Œ•ñçæʘ® zƒ˜óKêÿùÀ}Fá/õ‹rî`e¾0«SˆSñ£¹W¨×jPn_©˜~ŒPV–ñU°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“×®Ì7…*üTÿœÙÖ%ÿ•ËäI­/å°¿ƒAœEunÁeE{—SÄz‚GÓã–b4PX/•c¶Öõ.Á{pηwòËper}YÒæei Œ‰=Z¿ Ô™°X—ªk^JÑnÊêÚ‹D·Ó¯//ž8äŒÀ#á(# 1†gU#™p¬€ðl´ã··CùCäÍ‹=Yó΄WͱØ@³ëZu̶+)ŠŽÚËéʳzkðøåƒ—5¶kù…æïËßùÃßÊkÿ1ù;Êo^¿ƒGòõ´²\ÜÏ}©O’Æ.ï&ygh †f*ÒD(…YÁÈæŒqÆÂß7ßó™ó”Rjv^dOÍ9ì®TúÑy~/L:JÂÎI·’ª³²6g•¥P¼­Fk$ ³~§ÿÎ7ÎGEÿ9ùmþ'»Ó мףÝ˦ù»D·gh"¸F%%€Éñúr¦ôj•péɉ?K¸c'Å_ó• ­ê¿™·ºã<6Ú ö¥yn?SŠÏg|°-Ãp%ÜÌA$ò‰NüC¨ÞJW•­.4/0iÌ—®°êþµ•ì ¼s"ÛÍpÔšU^*«Èn¢ŠïXãØ©`›71Gc~hnU;t>øÌ¨~Òþ[ë“iö?^1­é…>¸³4BR£˜BÁIZÖ•Ó5¬Þéó@Þ8ªÛŸ÷žãþ1¿ê9(}CÞÆIVȲv*ìUF/·sÿüA2Rä=ߤ±3øè“ëzDzŒE¥Þ9O‘ÿ5ÿ+tŸ5i:†‰­Ø­Ý…à×txÝ[”rÄëFI€ee ©i_~`òƯå­VëÈÞtOÒššKþó1Ž8ãÔbPY¡‘ŽîŠ…£(õ#WXó±dãy±"Ÿ4jþI¹ò÷™ü½¦ji$ú¥®ipEª…^)/"®ÀQ$T Hð†ÀÒ&Gr·å4Z\éöZW˜}yt6HäѯЮin@hÌM_ŠšPJ8ü 1—B¯Etºº¼ÓâÕ¯N款RóÅ·¡õ]F98˜Ö@Ò®6 W‰¨ ©Pgïæ„Ñ¯ou‹MoÊ×K‹æÝBÂ[ÑW´¸Æên­ˆ0ý¦e^]5þ𽺫Ñ縿ó­œR›íeòæ§Z9[»ñË‚4‘¸_Q„Wp>¯‚½'^Ñ!¹Ö.4ˆïnmoËú„Oq+™Br6ñ ª/b¡×¾ûää7V)£iúΙç°¹µ˜[¶tVæ%g¶•½[c 8€Á Bj-‚ ²è¼§1ÝI;Å©%Ô³=ÜGûÈd¹y„.­U4Fàœ—öH>Og[(ÖkNFýÛ½+È‚(µÜ± ÎI[Ñ4/0ù†â!å/-ð³Ô¦¼×o#{HCqÔ1”Y%j€¤,:Ž@S<±Šiï^Qÿœs°»ºŠïÎÒ?›U=)U ³‰ÇW#ñfž.G 6Ìiæ%4ý ü°Ð­|¿¦>ÆÆ6Æ&‰ml­¢XaŒ˜‘  Z» €äB1øèõœƒ'b®ÅT-ÿÞh?ã~¡’ŸÔ}ìaô„«ZÓm5­+Tѯƒ5–¯i5•â¡âÆ)ÐÆônÇ‹‹'ò­åhî¬ é÷е­õŒoylÿj9bbŽ­îs"dÒæûåñCÖ4)ÍW|´!ëeÇ™42E›lT¶öJƒ‰V;+ä ¥’¿\ K%~¸,•ñVôÝ[ó âéڮ߽ ÙiÖÒÝKİ^E!V` ØŠ¹ de!jûßþqÛþq{Wògšôÿ̯ÌŽÛ]Ò`”yoËÖÓú­k-Ô2[O%Ü‘·¥#*ª3¯ÅÈž@S.^-ƒ z¡éL¡*©ýüŸñŽ?Öù#ôyý GÔ茋'bª7aã$ñ5ÉCŸÀýÌeËå÷«dY;~ÿÎ{éM£ÎWk—MÁþ(òî‹«ÆêT™‘c“NõZŒH<¬Y> ¥(M˜Ð^£ËUO£2¢‡®hP¦ýrЇ°éS|+òË@›àä•#¾“®ýðcÓ?\Š¥s?\ Jæ|U+™ºàT…‡é¿6ù@Gó™ô}1d™yƦòúuý¥«î;Œ«!¨•è.9I7_Àf¯Š¨Ûý†ÿŒ’ÄÛ%>÷1/ŸÞ­‘dìUØ«±Wb®Å]Š»v*€ÿú:ÿ±|UÿÕûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,š" Uðçüåïåÿžÿ/üŤéèN ÑÇy¥ÿ•qi"ÏW·¨S‡Ó„Wä”õ -øÁp¯ð1Žhd]MXA æT ÓS×Á ȉCé,y…@ŒzžfDJùåÿ2  ñåÀ¡éöžf€ýçoJÚ•÷™Ó‰øÿcÅmå>aó !ǩㄕ|õæ­t0—ãñÊdRù'óZÀ^R9 Æ4˜ŸU’{3f’ý6ÿœOü·»ò4m"ùjnÒÞêò+sææF‘‡ ª@B º(ëÔë¤lÛ7ÙÃ`E[ÅTmþÃÆI?âm’Ÿ?€û˜Ç—ÏïVȲv*¢ßïD_ñŽOÖ™!ôŸxý,OÔ?ÊÙLCÍ03ÚÈENǦ*üpÿœäò…ùŸÉ˜VƒkåÉîôÍqÂ|b-DÃõiöøXJkñJ)Õ²P;«æŸ-jÝÛG“gÒït}^ÃÖ´žŽIŽX¥Œ†ŠhdB9#`He „WÁZ¿•õ êãÉþt†-L»;iz”‘¨‹Sµ‰ÃG)P,ñü>ª¨qÍ«(ز Š<Ø‘O”¼Õä[ÿ%\¤’]h,éš•+E]„3Óe‘G~Ž>%ý¥HJ*‹òÜš¥Õ‡‘o’+½ÌÍéÇ2³5œñ[Írf€«-úd:}’Z½ÜH`oÒU;ÕÞ+¯,þ[;ê­-ÏtÝ>äOÁÂÛ,“ ^<€tÌ’GšS$yz½[Wò̾dO8Ø9¹¸ú½…Æ™URñÚËq*4lÅW‘3C)ß±°Ç{C.}0\jöšÜ„¤°XËh¶än¢w†F© EA„ÿ<•*ÍOWÒt…P½Ž KÇl’wUûF8P4ŽSÅMIØ`&•<Ðü­ç_3ÍÕ´GдɗmBø¡š¥w"cJ8Ÿˆ7°ëLó€š{·’¿çt«i…ö®’y›Tt1µö ªê#&¥8(b W¥ÆžiI4ú¯Ë_–‘F¢Ú„HÔ*F¢Š  èT—±é~M²²U梣öFø«([xm²BÔ5§òQä}ߤ1—1øèȲv*ìU ¥µ¿üc_Ô2Sú½Œ>‡‘«Ðüò,ŸÌçæÿ’ïÿ-ÿ<ÿ4¼«{döPCæ]BóCW,ÂM2úáʼ« й4Ë vA_¦K²eñCÔt9÷Mòà‡¬i“ü+¾L!”Ç7Â7ÉAÝÉPqT‚WÛ R–Êýp*å/ ùËóêâÓÉú Ʋö›^N…#‚G ²Ï+$HÄnµO`r˜5§×þCÿœ8ÓÐZßþdkR_H y¼¹¥;EJ$×TYH¥y¸Ó‹Ðo=A<™Sì_/yWË~R²w–t+ ΋êCeEê^!¥e¤j Ù‰'¹Ê 'šY,P¼† Q˜ôÀ©ŠD©îqV—ýè—þ1Çúß$~‘ï?¡ˆúã½["ÉØªÇØ_øÉüMrPçð?srù}êÙJR’\Uøÿ?0Ò…§çGå—˜Œ2!Ö¼£.š·$Ÿ£/嘢(J}x¡¨æµ¥Egh/Žôy~©ðÛ2¢‡¬è3oûe¡_ÒføS|°!–$ß\’¥7²o×¾© Ï×¥s>¥“?\ •ÌøïŸóŽ”bóÇæg”|Ù6˜ÖþOòmêkW:µå»›{›‹V?W†Ñ™ rJ³„sñ~ì)jòâ>yФ‡ì$d f#$`銩[ý†ÿŒ’ÄÛ%>÷1/ŸÞ­‘dìUØ«±Wb®Å]Š»v*€ÿú:ÿ±|UÿÖûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,ФÚÞm­YÉm2ŽD Š¿/ÿç!ÿç5 ÝVO5ù" {MnI+«ZJÍhýà*I¶p~ÑrÈN‘O-¥Õü³~ún¹c>—}nÁ&·x•bªô®àü.§cÜf\& Ëåï5©ûßù|dÅíZœ8…¬¿Ž[+Ðí|éE_ÞíóÉñ!eßœª‡÷¿Ž%yîµæÐÁ©-Nýò&Ixæ­«ßêן£t«iµ-Be/²™%eé^# ®Üîr‰äš@} ù'ÿ8ߨþ˜‡ÍmŠ;A ¾`8í*.ÌviJ—·.¹ƒ“/Ó £Z.‘k¨@™JS¼Uت¿ØoøÉ'üM²SçðsòùýêÙNÅT[ýè‹þ1ÉúÓ$>“雷ú‡ã¹["É yl·P¯Ö‡îý/ï¸óû_³·L•ŽhY©yÉ]*G\L•åÚçšy+RŸNVd—“\Å­ùºý4½Ùï.d#Ô`h‘!4/#•GÞzMQ“(4€úÓòGòVÛÊ[ÙÔ5íO‰ÔuEÜC?eš’wc¹Ø*®çÄYÝž]Ò¬)U¥íK3‚ƒR¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅXo˜ôï"y#Jµ:S¾*ù#óKòËNóN—u¥êpÊ#.&´»½;‹[ˆ÷Žx$¡àèwPî,¤‚A°¯õK ý'U»ü¹ü˶†íõA!òþ¶±˜­5‹e`ß÷7íÉrSFCN,s±dX‘O"—È×¾LüÂòž£k ÷þ]{÷H.z’Â÷“Ûæ åäaÄÚ‘àá=i—?,õ‹ÍËöº±:XÒ<ËeæXÈ¡i#†ÑBÂÈÊX?Âá‚ÐÖ…€Üƾ+om{Ý:ÍÖÍî‘®A§ÕÔòrÜrUÜQBvÜã-°9¡>Ñÿ/üûæ‹ÈýQ–´5,¡¥¿š:’¿h(ˆ°ÙÔ¯%ê®OÙÆž L€}äÈI‘î"Óþµyq*Í5ýÒ¤“³-8’üEJÐPýóY%.i§Ó_ü·EÍN¦™½gMò­…Š­P3À b¬š8ã‰xÆv_ЍËöí¿ã!ÿˆ>J<»ô†2æ?²,Š»CÀ¡­`ýö¿¨d§õ{}!*²±}9O™ç#?ç<«ùý£ZË4‰ yïBB¾\ójGÌúD–k;´`bIò$ØÈ’J2¥~œµµµ±·†ÒÊÚ+KKu ok,q¢ŽŠ¨ €BQ±Á$þcŠ£cµ7?÷é÷b¨œUتŠÿ½ÿÆ8ÿ[äÒ=çô1Qüw«dY;Q¸û ÿ#ÿ‰®Jþîc._/½["É )¡5Å_“¿óô/+jwšG俞màyt¯-êzΩH‰ËÓ“YŠÒxØ5QOèçZ•+R ²’¡åjü×Ñeª&eE‹ÕtI·C^ùhC×t™þßl°+0Žj§\’ë¹*~œ “LýqJW3õÀ¯Jü½ü‘üÅüÏ0]h:?Ô|¿5üS©–¶±d;ÖâÒ\T…C.É×)žhÅ4ûŸÈ_󉿗>S¸P×̾yÔ¢âb]E;`XZ)`õ5ÚVu¥6¨©ÅžiKÉ4úŠÚÝ#H­í¡X¡"†5 ˆŠ(ª @2¤¦ÑÃÄF§ÃWÅTmþÃÆI?âm’Ÿ?€û˜Ç—ÏïVȲv*ìUØ«±Wb®Å]Š»@ÇÇýؾ*ÿÿ×ûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»AÞX[_Fb¸‰]OˆÅ^/ç_Èÿ*ù¾ÊâËQÓ ¼¶¸ûQH½fR7VC;ƒˆ4¯—5ïùÃM69®.<½©ßi ò<‘Ûrê\©#ŒƒÔ !Š •>ÈUÇ4‚)„ŸùÆ¿Ì}%‘mõk-J*·9Z9mYWâ*p<…wØR†áªòG ãù7ù§²Çm§ÌÃìrº™Pw¥³SñÉ~lw/ omùùƒxPOqoh 7>+$ôs²Ò¾–ÝÏÝï€êü—…œèŸó‹—­k—÷W`«  ‰¾­åÄ ½ZSjIÔŸ`*–¢gÉ4ú?Éß’>Tò¨wµÓ-mdÄ—?W…#2¸å!P9w;å$“Í/cµ³¶³ŒEmÄ€R€`TN*ìUت¿ØoøÉ'üM²SçðsòùýêÙNÅT[ýè‹þ1ÉúÓ$>“雷ú‡ã¹["ÉØª]¨i°_ÆVE©×xÿ˜¿/¡¹æV1¿¶*ùCÏ_óŒ^V׿¸¼]5´}Ng’Iu]3¼¯$‚$«Å£•Î߈Ç%˜òW‚ßÿÎ5ùãFvm[³ÕbEo{ ¶n)дÑ€Ä÷¤Kãí—ÇPG0ŠCEùuù¡¤¬BãAKÙš¥ÿG]¤‘¥ÀµÒÚ±'Ùiï– L|ј óh§ÊWÕñ}—ý”ä¿55áO­.0oæhîÒÂÒßÖ ±\M3˜¾*¹F·ŒÙ~Dn~-‡(Xè…šèÿóÒÝ›g×/®uŒƒ40«C!âäyçVIà§­iž¢RòM>†ò_äþ¢Ä¶úv• „/!–HàP<öøŠ³57c¹îr‚m/¢4?*[iÑ'4‡ìŒU˜"*ª(*»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅZ A¨ÅX™|¹Ôo$h7jtÅ_*þe~NhþxÒnôMrÕÞÚVÛ\Â};‹[„¯¥so- IÌ0*H$WÅ÷š'Ÿü•­¯‘µÍ÷Íz³ÀÓùgÌZ|`Õ-‘’6y”1K u3*‡¢ü`Es±çnć i¿‘þ{×&·—Í:²èÚ}=I4]GŽZÃÒ–éhä¡ ó”57A]«ž£¹@{Ç’¿'tÍí4Ý9`EÙž•cã¿@ ߊ€£°)™sdúËÿ—¨ EJu9zÆŸåë+%_݆aŠ§êª£Š€ v«x«±Wbª2ý»oøÈâ’#îý!Œ¹ÇEl‹'b®ÅTm¿Þ{øÆŸ¨d§õ{}!t‘‡ã¦E’ ÃLU wcoyoqiwwv—Q´7V³(’9#pUÑÑ ¬ ;мÌó‹‘ž`¸šòO!Ûèײ+úsè“Üi‘Ç#¨_Umm$ŽÙ˜åñÄÊZ¥äÕ˜œ‡"´Ân¿ç ?-¥¢ÏÌ^kÒ>®…d6·6f5¯9>³a5éðqÙ1¨š)9Ó?ç¿.tÿª}cVó®-¥L/.mWë 7§/Õ­ ¢8üZŸµ]ñ:‰÷­=3@ü‘ü«òÜ‘M§yOšâZÞj!õ9áp\ò†[çã?¼"¨FÔ^Š W)Ê\ÊiêœO†EU’Ýߨâ[üÐòO™<æÛf»Ð|ÏhÖ·«,L’ˆÕÕe‚TYbb§‹ªµ 1Wá¿æïüãæWäUååÍý„¾eò$¤µóæµ´p ©mB5ælŠŠTÊ}2H #š‘ ‚‚}¢ËºvÌ€Åë:Lÿ åYœ3|#å’Bþê(#’yåH`… “M#DEff4*IÅ^ÛäOùÇ?ÌO>A¤ö±ùcDž?RÛQÕ#ά*¦uF PC0U#u-Ó(žxÇÍ•>Îü¶ÿœròåûé\Ä|׿8À¦­¨F¾”M±&Ú×âHú qÙ€4ÌY攓O UÍK©(ØíY É×F*ªŠ(x U¼Uت¿ØoøÉ'üM²SçðsòùýêÙNÅ]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÐûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìU¢ê+Š©˜bn±©ú1U?ª[V¾Šýت¢Á ý˜Ô}ª tÅ[Å]Š»v*ìUFßì7üd“þ&Ù)óø¹Œy|þõl‹'bª-þôEÿäýi’I÷ÒÄýCñÜ­‘dìUتÆEqFPqT²}"ÚjÕøªIqå[Ykû°k튥2ù*ÙɬClU@yÐá_»L­ü“c+ýØ« ¶Ðl­éH×olU8Ž¢ü†*©Š»v*£sþóÜÆ7ýG%¨{ØÏé*ÙNÅ]ЍÅöîã ÿˆ&J\‡»ô–1æ²,Š»i”2•aPv#cŽ‹¤°@AÅXÄžYÛû±÷b¨«_)EPLbŸ,U”Ùè6V´>˜f1TíUTP€b­â®Å]Š»v*£/Û¶ÿŒ‡þ ù(ò>ïÒ˘ütVȲv*ìUFÛýç·ÿŒiú†JQ÷±‡Ò²,š ¸ªÓ8ª“EN˜ªŸ¢[¶Ø«b›oŠªˆG|UzÆ«Û_Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*£qöþ2Gÿ\”9üÜÆ\¾_z¶E“±T,Šì6ÅT X«æß6ÿÎ&~Cyªá¯[ÈvÞZÔé' ÿ,É&Œ ²¿7ž[[6ŽÖâRz¼ðÈ{d„Èä¯;›þpƒòìÎÓYùãÎÚld([H'Ò5â¡I}*Wøˆ,jÝI¥°g’)h¿ó‡ÿ—šSLnüÍæ¯0¬Š¡#Ô.4ôЂJýNÂØî6<‰Û¦ûãù‰­=ƒÊ“–^Gnü¹äûH/ãfh5[Ç›Q¼‹›‡eŠêúIæK*ž(À|+·Â)\¦eÌ¥êB7c@µÈª!-YûŠ£UE<*Þ*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Š»v*ìUØ«±Wb®ÅPññÿG_ö/Š¿ÿÑûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»h€E*³ÓN´ÅU)N˜«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*£qöþ2Gÿ\”9üÜÆ\¾_z¶E“±Wb«JƒŠ¬1ƒŠ©˜qVÄÅWˆ—T €¦*Þ*ìUØ«±Wb®ÅTmþÃÆI?âm’Ÿ?€û˜Ç—ÏïVȲv*ìUØ«±Wb®Å]Š»@ÇÇýؾ*ÿÿÒûëkþòÛÆ$ÿˆŒUUÑdR¬ ƒ± ÔÆiZŸÕÓù¤ÿ‘ÿ5aã>_ Žø%ßWOæ“þF?üÕòùá‚]õtþi?äcÿÍXñŸ/^ø%ßWOæ“þF?üÕòùá‚Xç–<Ëå¿9Yꇖõ)5M/VÔ´;ù©s§¤ÝIe{ &O¥<.œ€*Ôª’¤"DÂ3Ú§!°Þ'‘þÝÓ<|30<ãW¿ó¢&>q”OƹÛ#úº4Ÿò1ÿæ¬gËäÂ?°¯6ùÏEòn§ä-+SƒPžãóÌ#ËZ+Ú·$Šìé÷º—;‚ó!Xý+T1äTq¡$r92xb¯†Rä9B¯ã¾ÌŽ:Ç,#Ã{Ÿãœq¶bü¯ÜíOÎz.•çß)~]ÜA¨>·ç-+YÖ4»¨Ú¶±Á¢IcÊÌæ`áØêð Œ ¥h98¤r^ˆÆGaÊDÄWÄn³ÇÃ3ÈÌC™æc9ü«øÖÝÛÏþsÑ.<¸<Ï®A¨]X6«£èâç7¯­êVÚ]»RY¢^ 5Ò3žU€ÆŠXHÏ,1 ¹Ë„l*èË„WÃôÎ]! LîyB&f¼èmçÔ3_«§óIÿ#þjÁÆ|¾AüóÌ_Ì?òò/B<¿®yËÌ~oÔŽ•å?'h2Z‹ýBæ;i¯f .§{agÅmo,¬Ó\F(¼W”ŒˆÀNRŸEš2<¶ŒHFën)Â4,܆ÕdHÀFr4™ÞR;Dyó—”c#Ñæ~mÿœ€Ô|¡y䋯ùÇßÌýFoÌ ¨4Íê·>T‹ýËIgs}.2ÞyšÙ’X"´›œœL W÷SH J22ÊqÇ}Œ¡R€‘º"¸€1˜ŒÄ;#ìfg”yïÊçáŒH1±Ã I×VòžtŸ9kxÐmtÝWJÕ/µ /Ì6ÚƒÅAs}¥Ùêʱ=½Ìêá"½DsZs ’ÑÚ\áâ L§kŸá'p6<Åï\À;11á1@N¯”§4jÁÇ+«¨–{õtþi?äcÿÍY3åò á‚]õtþi?äcÿÍXñŸ/^ø%QcPª“¹$ÔšÎm Rì v*¦ñ$…KrA«2šW¡DˆA­úº4Ÿò1ÿæ¬_ ¼#ðK¾®ŸÍ'üŒù«3åò Â?»êéüÒÈÇÿš±ã>_ ¼#ðK¾®ŸÍ'üŒù«3åò Â?¥z½Äúm¢\Ùhº—˜&k›xÃOž™cždŽIɼº¶„ ÆGù•R#G~(È‘2` çB†ÜÏ_-6yUð '¸]YßÈt³æ@ï!Žyκ'Ÿô­gWÑàÔ-­´?0k~[»KÆíu ßϧ\ºæÚXÆI­ *…ysøzxç?L¡ÇÈ_ÿnÝõæÊx¸rË禽pŽAöL_ûÕ?.¼ã¢þfùÊ_˜Z …¦‹ç-.ÛWÒíoÛÓºŽ ¨Äˆ³$RÊÀ;…vç2³ÂX¥Âjè]àï4J3œ:ÂrÜó„Œ y\vòîfWOæ“þF?üÕ”ñŸ/Güï«§óIÿ#þjÇŒù|‚ðÁ.úº4Ÿò1ÿæ¬xÏ—È/üó:~jù'ÈÖߘ/ª]ß^j_–~O<ù—B²Išçô8ž›Âò´Vîòµ„ê©ê‚ ü\U1ñ}&Cp'†ÒWû l}û94’Ë“1±ÊH“^“.WUÇž×Eèv2[êVwðúë ìÜD¯#† "†€b+C¾ùvXËåWG.‚qÍŽ9#u ø‹ïEý]?šOùÿóVWÆ|¾A·„~ hÛDÀ‚d Šdzÿ‡Œþ^¯dìUت‰‚6foŒ5n.Ê ¥:<2\EwÕÓù¤ÿ‘ÿ5cÆ|¾AxGà—}]?šOùÿóV_ ÛÂ?»êéüÒÈÇÿš±ã>_ ¼#ðK„«+|d©ªòv` )Гã^­‘dìUت€¶‰@ÈHôþ 'Æ1à ý]?šOùÿóV3åò Â?»êéüÒÈÇÿš±ã>_ ¼#ðK¾®ŸÍ'üŒù«3åò Â?¨Ü*[ÛÏ8ŽâàÁH-áw2?OÀ,iAS×#<†1$ rgÈ]™Í”q‚@&¼÷Ûågä ¥þw^êæÍ$1lüûå4»ëŸËk‰ü¹úJïOÖ$¹ŠÚöÖò?0>’cçgpI|’)ŒN­9ñ8Ñfaé"1›«N ñoΨÔL8d¬\L¢w©Q”E]J6 áôEÛÑ.|ï¤~eùN×Íš^Ÿ«h©%Ýþ¨èz¸ôoì/ô«É´ûëK…†iâ/ żˆZ)6§$vR™žÆV”#0@þÄHmWtww²8jr„‰¢ ÷A‚%%ñ!çvŸóÞB»òÿæ·™JóV›cùI©A¤kšžq§ß_ÝÝÚZ]ÚGcctñ\VàÞÅBxá,ç§®k$qcÉ~,ø#¸ŒÌ„"7¡L‡ÔGùN9ãÉ(ÈÐŒC-Ìx#Æ'-®DGŸÓÆ8øÄ¢L×ȘÚ?žôo0jRiÇ“uO'êWOœü©¯IoúCJ»·†;® §]ßZ¸’Úx§F†y£®á¹*œùc‡Ìd *Fëù„Æ{ ÆQ;oW(˜’1ã”òø@/Mçq€bc¾àÝ_ó„¢w‰ AüðÔ<Õå§óg–"¿25­öÞÏQò„ñÏå»s¯i—¼š;û/­y†|$1_kŽ2-!,²*L¥¦‰9cÂbjqÚá±6kÓ-âb|32%Ve “Á.!½HÃ.í×{≠FQÐ ¼ÿ9¡ù×@ü²ó4ÿ—^uòv‘ù¿¬ÛhþA›[“Gv¼Z]æ­Û&™¬ß˜aôlH“Œ¼ÊOYo8ä2 F„¸e*®Qˆ‰î¯WÞãÅ[[(Œ¤ƒû¢#-ÿˆäLFÿÃ3¹å[ÄË“èÿ«§óIÿ#þjÊ8Ï—È/üï«§óIÿ#þjÇŒù|‚ðÁ.úº4Ÿò1ÿæ¬xÏ—È/üï«§óIÿ#þjÇŒù|‚ðÁ+’$Œ±^D°–fcAZu'Ç‘)L v*µÑdR¬ ƒ± ÔÆiZŸÕÓù¤ÿ‘ÿ5aã>_ Žø%ßWOæ“þF?üÕòùá‚]õtþi?äcÿÍXñŸ/^ø%ßWOæ“þF?üÕòùá‚XÏ›µ{ÿ-è³jšG“õï>ߤ‘Ç–t‹¯fæÔfY5ký:ÑU¬Þ¤ë°¢òbÆY#k³å¶Çs÷mfÈÚ¬‰ `ƒ½W¿Ç=ë—}‡êó‘úUaüË‹ò«óQò…‚êçÏ÷¶Ë¤¬ÞUmò[-Q5;iõˆ¦­¤·›—èä»ä±–NA£çlwž8ج£Œ«Óûêán!\CŽâ*úѤa”Œ "NH’8/Ôh G„ß ¼HqÔŽD‡Ð:­ìzn{¬Aa¨kFÖÙ®-ô½<—ºº`µHaY$9¹ ÝTV¬Êµ"¼³”?†ÍÕ çuÌÐò@ɦ82ÄHJ¢EÙ¾UwBävþ  ùÒOùÉß/­½Õ‚~XùúãóOÖ/4}Wò‚/Ðí¯Û5†­qtòþ™cÛ‹K¨$ëò2¤j µŒ fˆˆŽÎR¯îãŽ~Ì…qm3Œå!!(‚,‹ÇÀl`#giœ‚R ¶<–db"qÊ2©p‰tÝoócɺO律ù¡bú‡™´5G¤&Úi[ÝêóëòC—ml·RÛÄs%Äj òGW”¯«0»<2aÍàÜøŒhWðƒ)4*0Œ¥ÏqM’§ ŽLG)&1Œxƒœ$sãâ¨póã:ßýLÀwþ/&=jø¸NÏMúº4Ÿò1ÿ欇òùðÁ.úº4Ÿò1ÿæ¬xÏ—È/üï«§óIÿ#þjÇŒù|‚ðÁ.úº4Ÿò1ÿæ¬xÏ—È/ü¨ˆ±¨UIÜ’jMNç6)v»v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿÓûëkþòÛÆ$ÿˆŒU_v*ì(«ámCò+ó>þÃó;ÉZ?¡åÈúšm¿ç|Ê.Ò6MGÎJë7ú3<¶¡„²XÀÞa „§.58ò„Ž˜X¹Æ0àq`Å(’,ñDœØñàâOB@Ç–ŽV,Ž®¼g'.µ‚9¿®YòÈ}“a\“ù þqjY4ËÏ.j“þfÓü­où‹¦ùƒóÉžvòê-í¡òÖµa<ö¶>J[{[¤{‹‹x§70zÓ¯§É4~;>(K,I£Ç5X6 Æ>ü#‰”c ¡“Ž{HÆG‰yD‰ñ% 1°}2àÌ':‘¬„ðññK&ò w7¿XÿœZó åߘ<‹å_ÉfòÞ‡iùË©ù—ÍZ?•-üó•/.5gÒa²µÖ…Ö›p4±wlßVÕíáDny¤O˜XÉ0Óx–D!8Èlk.Àf£q"b<,ð1VL±ŒëóŸ[òüä]‡å°ü¦¸òßüä¶ùsçË]só3É>Pó.‡w!ÒeÑ5›1À—Q‚ÝÖâY–?ByV9ךIû¯PŠ1ã1ÏÓ8ø2FêÇ„xv;úó~¡ê e\b|3}qÎTFãÓ¾Ûбlßòóxù{G²ò–Š¿–R?’ÿ84ï)i©¨Áù:O6ßiÓùsMÙOq阣É6^¤VåJDÅ"Ñ”HÃ(ä>)ð°ÄîG‰Á”äž..~œD`—Ö"$Nå·M—2‰pðÃóPÚ1Ã4_Nyã3ëÇã ˆPœfx~›ËÅŽ>O†@xs´Jr'Š1#‘Ns‰™”ÿ›8ðÊÈx¦qÆ^™F!é??XùÌ~So/yÇþqçSóm§—u=1<´þCó™§jpÌšTR¾±£\]ê:$špµº’{%)v“”•Z)YDõ•—!œ ĉÉR¿XQ2—_™ŠÛ†q µhïĈD8£^‹³pˆÜz qÎ'`.ã1ù;ó¿ó¡.¿)¼ÇªyOó3ÍF«¢þbX^ùxéVÖÖþ\Ó4éšî b IJOi"‘›ÔP­AÊ4§üb—¤Æye¿"%.(Õ_>[DïBËv¬ÜñÎ>ªÅ9‚2e‘çB„rDìO^»>žÀÁØ«±Wb®Å]Š»v*ø_þrsCÓ<Ãùßùa­~PÏù奄|ú÷Ÿ—P˦*Ý~ÿ˪’Ko­^XØ\$NÊü'—á`²Æ¦XÓ(Ç)j@Ÿ ®Ç*=ñîã…Î7@T¤FQ‘Žš'‹‡÷ð¿1áfÛ¸ù‰THãÆõÿùÆ_Ìéõ¿É‹Ÿ;épóÎäï ùHÓŸÉ>J½»òϘtËÙ®.æ[=Fn"–è—ºdérÿVýèÚ682xz¹NRâ—?Þ‘QÈ#™ˆVH‰Î2É?îÅqF9ð£ýÕã…À_÷rÀÔ¤GPòÇüã–»åÿ7y?óOòE®“ù‚?:üó¬y£Î‰5£êÉšßø…¬ãy½bÒZ¼—6r‹E'„­ê˜–OQ†ž2LJ8ž ÒË¿á·Bÿœbb*[ÔG";9Z£ ÓË)*–¿Ñ0È"„pxÀ„¬š$Ä¥'ä·š"ü¨¹ò€ü†mó~Û_òEÇæç Ïå×>y“EóMþ£ªþ‘‹P}N`Ñ[Ëtþ]CzQ©`24ó„s`œ#ácŒâL9ðþîq&ʼnðÊUÆ}sâã"å:¯.òÏÄxÌñç—pÉ x÷£Œ!Â?w àŒIuçä§œ¡»Ñ.<áù(ß›ÞW‡Îß™ú’yjZB‹¿1ùƒëþ_óŠþò céZ‰WÔGk»oZ±D\Èã‘ÓÇ“òÑ„eÝ䌥Ä,o>()7jrFSœ¸™ã2âB8#*Upä‰È„ìHŸDKÏ­ÿç¿0 ò/åþƒç?Èáù›¬Ú~Mh^MòT­ªèì?/<Ýd×]ÔÍÕåäRÛú†{Gúî–..ÑiÃá‹–~¨ø¹²œRðòJXÌ3WÑÀ áúÇ1)Œc÷yLøg ¢9 3XÆLòž;âñI‰@ÜèJáÅÉRÕÊuÐ<åÿ8½®y‹RüÚóF¡åóžµ>þ_ÞyÎO{7¿¡´û?.ØùŽâÎSt­eõˆ-¯b¹U1Éq„a*úCg‰ˆðˆÄçÍ)ǘð²qðÂ_ÏÆD¨ãÞ;›ŽåÇ~Ç)J:QlÿŒ@åœ%±8å›UýUÄ/ÌùÆ/7&ç¯'ùÈÒiß“ßò¶´¯4YþVyQ|­z–€þW¶²¾M;JóWëºkkè£Ú6–>2úNqàIŽåÁ㎇‡Ž\x¥êæÎ>“Ç=¶.I0ˆqTe^Ò­4/2Em¬Ûµ‘I5šØÝZÝYÛm-ÌKÃÓ{F4‘™zc“Næx'wq‡âB&£*ŒàrDN'ûÏHÊÑeŒ3é'm‹.[Ûé„¥cYçÄL¤'’[T¤_¥Ú´Öz&iržÅ­¼3ÇPxºFªÂ hGc—êæ'šr#"GĺÍ9cÓã„…Æ ûÀ ¦c¹NÅ]Š»v*ìUØ«±WΟ™_•2yïóÃògÍz–¬õÏ,yAó[I|-æŠÃZº¹ÐæÒ'[Y›“Èg,‘º£ÝU_Ê£ÌÏŒ%Ý+—Vñ<2®.|&Qlå`Ž2,x±”£ÒPÊ ô#ŠQÛ¾mcÀš'üâ™ÇåǘôŸ8~Où“Îߘ\yoQó4šâ~[O yª÷Eó ­Ö¡y§ÜÙ­Ž©wwweõµŠmt¬ž”òÃ, Ë!l˜äÇ q‡¢305ÅðJ2°ðƒ(œ„pË †3ÂLDCšRž£12úñêd>ŸÞQÅÅ~»‰Œ8@¸b"\48Iô˜?"uãeÿ9æ=òKK“UüÂÔ|«¦ygDº³òÍþ¡“£Ñü¿g¬XiÖÚ”ÓiÍnÖrˆá¹oª¼ÐDî&‰#å^Aû¨ã™3âÏ’y¢eê3Å?Þsu-ýpŒ²J"9J# D œF;F ²ñGÑuû¹éôËÓ.#§•¿!¼ååÏ#~Wéyü“¿üáüºò¶­ç{ù}/”&ž¬ê‚ó@Õe°{3Ëõ;ešBD·7·Œ…4œä ¢r9 Qˆ–ç‚P‘ë±ppÆ9&#\G¦cà$e[8x@J5Ã~1ñ O¦r!”§™jÿó:•§™¿='òwäMއuùƒçoËß5hq°ËÖJÚf™¨yrçXÓex®ÖéeŽ{ «·OLÃ!ø’I&~&z9œRÅKlz‰JGzœeðLu"\1ƒ#Ã’r˜ÌX£ž!Êã22DCüèËA±)§žRü”óm‡æÍ¶³{ùUú?Ζ˜^bó/˜¿ç%Eî–N»å}@ß?C ÛjózpÜÚ[[«dµ„[ú‘HÆ8CàG¿(#Ag ÇŸ9 ¾[äáÔqΧˆH³[!’s#ÕÅ,FíBc}ň䇢ÄüN)Q2¢¯ÉßÈ_9~GØþNy»Ê_”¶§Îú/ä÷˜4¿Í}6ÛR°´¸×|ÉÒ'Ñtûûó,¢fçoq 3ŸR;tªHŠ©ÙäÌ#<чÑ(á¡ÈqÄ‘9XFr2'|‡™”¨²Í zŒÆS•©Èxè’0d9Ió1¿ˆs ¤õ}oË~{»üíòß™<•ù_¯ùS—V°ÌßÌXõ½(ùWÌVDMm{¥E¨=ÝÕüuKx'}9$ˆÆÝ}X“M,·ýßï.'”‰±ŽxÆü32ç9\ €œ%ÆxAÅÏ9dà ¼ôQñŽ!,™ÛŠ4rÆx‘ãœr)ð%æÏÊï=ê^WÿœâÓìt/^óó‚Öæ?˘>µj¿¤ZO%Xi*9<Áa­ä/ïÊtåölÇ#GŽ\£šS#ú>,f<¾‘|Ýž—G½’ã‚êêÚ[«›™›ÑšXžÝ®'Kû¹òü2µœ¨ˆÃeÂŒòÂŒ3B>žie¼ # ŒÇŽ'1ˆL‡$!qâžCõH@ÀŒ”‰2½\ˆ¹NQúòLÏ%3é|Ÿù¯çç#ÖoÉ0ùE¼×æÿ*ù÷ÈO­ê>Xk}Iü¡ÇLs§jú“A-ÜÚC„i"ô•YÝZ¨*ÓLâÆd\±e”̈Ç)<\'éâŒ$yÊ>¾•\…Ù¤%3ò–šXx¿„HøÔOñp~ö<¢eB^žB]òïNüËÐõŸ;yâëòÖk[¯Î¯>E}©ù_QÕtè®üµ¢Øyr 6 «ç³–úÞâYntÔ ¬ÒqYÕ¹NEÀb#§ŽR¡–g¸Îr2†=Àç#)É}QᑉŸ‹ÌÜD#Ž &e9ó¡^.C~¨ãðÊu¯Èß*ùÇAóšŸNüºóäßå΋ Ù~ZyVÒµ(b×ÞæG–}ßJÔuX´ûâð aŒ¹VŠÚ2$i)Ôc2ÑæÇ|FT1ƒõÄpJ2Œ¤vá?ºãÇ>€cc’R–xËk©q‘ôÎDÄÆQº<_Þœ’0„§Ç.)qpÁ-?/3ü›ù'ÿ8ue寧æÏ4~LêúUçž|›£_h©} PùoUÓ&0ͨê6VR˜ç»Œ·;Š•­3aŸ8üèÊ18¥ 9ÑçÉ»%N:±uâe2=ÇæFQÓk€½ë¸Ñ}©åýN÷YÑ´íSQòö¡å;ëØ„—>\Õ^ÊKÛF$NwÓîo-‹¿º×ü¬ÇœDNć+î帹—È‘»7Ï»¿ž×Ϙë\èìœdY;v*ìUØ«±Wb®Å]Š»h$Ч#)‚I ó_˜ÿ;ÿ(24M_Ê_–Þh‹óÛ\ž0Ú§’ÿ)|ñ£Yù’ÞÎ9Ix·I¯èòÛÅ…Þ;•j¸ZÄ`–9dˆŒŒl\ 9˜ñJ¹o}E[g÷21™–â¤7'‘}@YÞª‰ˆ†kŸ–Ÿ™·?“åŸüªÿ6^y®àk—^LÖ,5½Ó˾Y:¶¥q6•oæû«Ã¸Ú|/ ÞrÓµ™ÖFâWi$ȉýþ`C”«÷gƒ‡ÂƤ ÂD1pŒà÷tÆ8Ä2ƒ,s”êûÂ(ýYLÒ”¥>)ä±"3 Õë6Ô¼—ù½ä¿Ìß<~iy[òmüñbÑêùäuM"É óSÚZÃuæ¦K«è …5•W•d3@±™8Ô.ÂQŠgÆ"ŒÏ£`|G)3Æw#S@*ð¥(Aœ£Çáñž.=«ÅÉO‡%Ñ1à:}âO«‹†PÉ.ù[ó;Ë—ÞNüϲü—ó®»ç]$y£NóÞ›¯ßùBÛWÖ¯|Ó›qúfi®ÝØÅkm.• ªÀn’X­øˆÒoOãŽ\_¹ž F¡“Æ ‰&3Ë 7\²™ÇTèGaÂ"!9N#Åú†Hd•l c ˜ü<@ŒxãÂ&b nSË,†F]Hò/˜üù% ~HùŸòu¿8<±äÿ"ùfÇP—IÕ4è&ÕõXåxo¡Ó Ô§ÓÄ`ÐCw Ä·0“È™fˆW+]’ó À¦#zrX#†B@Dðž!fQ±³¡[^ϧ°0v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÔûëkþòÛÆ$ÿˆŒU_v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb©lÚ>‘sªXk—UœúÞ•Å®—¬ImumÙ‰®b†b¥Ñ%0F]T€Üµâ(ÇÓuµ€˜€{èî›y]üh‹÷Ñ"û‰S,UØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿÕûëkþòÛÆ$ÿˆŒUUÝcRÌH°$Ôš †-ÒŸÖùdÿ‘oÿ4áà>_0Ž!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øQdPÊI‘¸ ÔŽ) Úì v*¦ò¤eCr% *³ W >8DIA -úÂ,Ÿò-ÿæœ<ËæÄ?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð Fæ%‘ T“Ðø<ðBñ…|ƒ'b®ÅTLñ«2üd©£qF` +Ôã’á,xƒ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð „ñ³*ü`±¢òFPM+Ôá ^ ­‘dìUت€¹‰€ HAFô#þ'À1ã ýa?–OùÿóNåó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ¾°ŸË'ü‹ù§åó Ä?»ë ü²È·ÿšqà>_0¼Cð ä•$,*!•”ÐÖ@ðÀbBAS]Фaó ¯–ímn®­n¯~»t–vööh²JÒȬʳ-kÆ›o\ËÑè媑ŒH $š>}î.¯W4D¤ ³@ Í”‡üyÿ~gšîÿ_33ù'ý»úØâÿ)ÿµeÿKû]þ<ÿ¿3Í?÷ÿ¯˜ÿ$ÿ·bÿOûùOý«/ú_Úïñçýùžiÿ¸wý|Çù'ý»úØ¿ÊíYÒþ×?ïÌóOýÿëæ?É?íØ¿ÓþÅþSÿjËþ—ö»üyÿ~gšîÿ_1þIÿnÅþŸö/òŸûV_ô¿µßãÏûó<ÓÿpïúùòOûv/ôÿ±”ÿÚ²ÿ¥ý®ÿß™æŸû‡×Ì’Û±§ý‹ü§þÕ—ý/íwøóþüÏ4ÿÜ;þ¾cü“þÝ‹ý?ì_å?ö¬¿ék¿ÇŸ÷æy§þáßõóäŸöì_éÿbÿ)ÿµeÿKû]þ<ÿ¿3Í?÷ÿ¯˜ÿ$ÿ·bÿOûùOý«/ú_Úïñçýùžiÿ¸wý|Çù'ý»úØ¿ÊíYÒþ×?ïÌóOýÿëæ?É?íØ¿ÓþÅþSÿjËþ—ö»üyÿ~gšîÿ_1þIÿnÅþŸö/òŸûV_ô¿µßãÏûó<ÓÿpïúùòOûv/ôÿ±”ÿÚ²ÿ¥ý®ÿß™æŸû‡×Ì’Û±§ý‹ü§þÕ—ý/íO¼½æ_2ZÝ]ZÚÝY}Jéìî-ïc•eU˜VjS•7Þ¹‡¬ÑËK!l6(ü»œ­&®:˜™DFˆ; þb9NÅ]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÖûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*À¼ùÿLgþ:wüÌÍ¿dÿ–ÿ…Oô:¾Óÿ%ÿ ég¹¨vŽÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«òý6øê?ó/6ý­þGþÒêû3ü¯ü6_¡žæ¡Ú;v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿ×ûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUF_·mÿüAòQä}ߤ1—1øè­‘dìUت·ûÏoÿÓõ ”þ£ïc¤+dY;v*ìUØ«±Wb®Å]Š»v*ìUØ«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*À¼ùÿLgþ:wüÌÍ¿dÿ–ÿ…Oô:¾Óÿ%ÿ ég¹¨vŽÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«òý6øê?ó/6ý­þGþÒêû3ü¯ü6_¡žæ¡Ú;v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿÐûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìU y{g§[Iy¨]Ãci =[«‰(ב ¼È¤€*z⯠׿ç'&4B±Ûy¦O6Lü '•쮵¨ŠºÁ sue¶Ê=;…qÊQÌ É‘”YR<‚-äºïüå¾­,r(~XÉ BÜy£S‚у|4" 5uê~!¼ÈFÛš],=‘Äðý{ó³óÃÌI,wߘQyv )µò¦—ž¬¤H£”·ï©Ü)‘«Éñ­~ÃËc¥ˆçºñ>xó^µæÍYÑ|äþ`yÆ×Ì04Æß[›ÌZ¥ôèªë ‹ý6æá.Nß¹u1ïö1ÉŠ#P_AþZÿÎnùó˱Ûéšz _˜:tlù¿GiúÂÄæçOâ–w/]ËÂö›,$îq¥‡¹6ûÇò×óÓò³ójKóm¥Ö°"õo<§v~§¬ÚöŒútü'Ua SuGeß* ŽizÞv*ìUFßì7üd“þ&Ù)óø¹Œy|þõl‹'bª-þôEÿäýi’I÷ÒÄýCñÜ­‘dìUØ«±Wb®Å]Š»v*‚ƒRÓ®¯/´ëkûkCKô¿IØÅ*<Öþºó‹ÖIdæ¢«È Æ*Å]Š»v*£sþóÜÆ7ýG%¨{ØÏé*ÙNÅ]ЍÅöîã ÿˆ&J\‡»ô–1æ²,Š»v*ìUØ«±Wb®ÅPZv¥§jöpê:Mý¶©§Ürú½õ¤©Ïë228äJË,£W‘eL˜iIç³&¨þnþnêæq©yÚ=>ÚfÚÃ@ÓãÓãôê,ïytßi&S×2#¥€çº8žE©i~«©Ã­ki/˜u‹WZjºÌójw0¸ ç ×3ÆÔU©…QÑ— q‚-|¯’TºWÀ©t¯×¼»Ï²úZò€œ•îôèiôe9z$0dl­+¥¶·¹0¼¨DÖÍêZÝFÍпóÅ*xÛÝH8Õ«éËïùÊ¿Î/ËØ`²¿¾‹ó?ËÖhâ=3Ì3|ˆ®-4¹t»p’aw¬ýEdˆ² õ-Ä ‡V@ê²¶8'.ˆ·Šë?ó”:ϬšNƒåOËûW "v’ëÌW `¬×L‚6 ň1J´A5/Ž“¼£‰âš÷˜¼óæ{«›Ÿ5þdù«Ì püÆšÚ‹iöD‘ê:RÙ[?q2FÌ8Ö¼™ÙîŽ[çíKJ³òG›¬5ÿ"‡ò.·g§EŽ«åÖý41¬Ò±E6Á#’9Æá£z(u`)‘É|”>ªü±ÿœ×üÃò”k§~hiò³4H,:î•Zú*÷t.ñYݱn¦Üû1ÌiaîeoÐoÊÿÎïËÎ+Iæòšmõ+ûÒMcËs†µÕlž#ëV3„™°*¯ÄÆäÀW) „½_»Q¹ÿyî?ãþ£’‡Ô=ìgô•l‹'b®ÅTbûw?ñÄ%.CÝúKó?ŽŠÙNÅ]Š»v*òÿ:~u~Sþ^G;yÃÏú6ql\K¦}an/ëäál­ýK†*)P±šmã„DžJð?0ÿÎeh €?.¼ÉçY·xo/ÄZƒÇÊtV^“sW0©êßaÕ›Lº:y”[Å5¯ùÉÏï0FE¥÷–ÿ.¡"¨š]“j×c˜ßœ÷ì!ªV‚–ä9¾ º:^òŽ'„kv:‡™É>wóo™<ú€©Ž×Ì¥ÅÕª11 h¬–à3@ŒÃÓÜòèá„z"ÞEå9ùÃòÿQ¼Ö(¼á}ä{mZqvú\*%ÓgRA‰¥Óä>‘*€(¥(*)”JI}×ùsÿ9óem¦ùáå‰tžB9üí F×ZOÉ–xŒð…‹¹¤hFQ,DrM¿@<±æÏ-y×Hƒ_òž»eæ䕎þÆe™‹Nq?T‘ ££Êv`TE%b®ÅTeûvßñÿÄ%GÝúCsŽŠÙNÅ]ЍÛ¼öÿñ?PÉOê>ö0úB¶E“±Wb®Å]Š»yÏ›?7,|Ž·?â<é\öaÆõ…šôp- õ'c±MvêFHDžJù›Íÿó?—ZC<>Qòþ©ç°¦Ú°W* ¼«$ߎB°ˆ®õ `ÂO4[æ¯6ÿÎoþnkjðùj×IòT•¢¹·€_]€¬÷bHH PþäÎõ¥,B-„ù7þrËó³ÊW¦âãÌŸâÛ)¥I.ôÍu>°ŒdG*å‹á[/ˆ«Uƒb‰[}óùkÿ9‰ùW焵²óÃþ_yŠr¬5F2Y;É‹PDX¸…gz)¹D±›}]±ÍsC"Ë ª)P†VV ¤lAV•ø«±Uÿz%ÿŒqþ·É¤{Ïèb>£øïVȲv*À¼ùÿLgþ:wüÌÍ¿dÿ–ÿ…Oô:¾Óÿ%ÿ ég¹¨vŽÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«òý6øê?ó/6ý­þGþÒêû3ü¯ü6_¡žæ¡Ú;v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿÒûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,˜Wæ?-?.¼‰æ¿<^[5ô^ZÓf¼‹ORÊ×SªÒ pé¥LÒ•—µ"ƒUø'¦~dù“ócÌW_˜^oÔ—U×uú8ŒPZ“Ê5)`ìµÜÕÄNgá ˜Ò[ž±¦ý¶9Íä“lš %|U.•úàTºWëRé_®y'žds¨Ù©JF ªÉ^¤±¨§µß”eæÄãn™ZVÝj–:tfKË”T Ôµ ã^+S@zšPu;aW%ö§z’¥Ž‹s%£[­@ hÁê&R¥wN¤)¡åÂ@>àÿŸsùvâÏVüìÖïaŠy%}ÞÛTJ(õ¤K¦½…#äX-#·5a¾Â§‰Ì\Â2Ô\¥*6ÿa¿ã$Ÿñ6ÉOŸÀ}ÌcËç÷«dY;Qo÷¢/øÇ'ëLúO¼~–'êŽål‹'b¯üÉüûü³ü¬¹ƒIó´÷Þg»¬üŸ£Â×ú£¡¡õ$‚- ‰$<í¬NÙ(ÀË’¾wóüåæV¬<‰ä½ÊöÒqkm[ÍWÒ©f¨›KÓͬA‚…Ù5’+ðÕ²c¤‘æXñ¡ïc?¤«dY;v*£Û¹ÿŒƒþ ™)rïÒXÇ™ütVȲv*ù«ÏŸó•–¾O¹»Ò´eÔ?0õëZ¤¶>\‰g¶Šb*‰=ó²@Aé´Œ”!“—k#ŠRäoÕ?ç%?8üÄÑCÐ.tïSý'ëõÍA–9"qèÈ’Û[ •9«Š²g̘é;Ê8ž-®MçO8¢Ì?Ì}Î GúN–&f—#àØXc$ª­Ce Íù]<-'²Ð´='è­ÏNhâôVKx7ôþ„²€H§«õ%z´ãËÓyR¦•§Žc²LclUåÛ½ÉwçWü¼ó.£ä=U‚ eÒfxmçXÛš¥Å²²Ç*rܩֹUöÏåïüçV¿¡Ãc¦þqùHêÐHeó¿—Þj0â¯sg)y¡oOŠ*ôäß ¢X{“oÑ¿-yŸËþqѬüÁå}^Û\ѯ—•µý«‡Z´Œ:£©Ù‘€e;0S*"’›Ëöí¿ã!ÿˆ>ò>ïÒ˘ütVȲv*ìUFÛýç·ÿŒiú†JQ÷±‡Ò²,Š»|ëùÓÿ9-äŸÉ-SMòþ½¥k:¯˜uÛ½Ðí,íÒ;i‚³¡SypñÆJ¬‹©"!W1Ñ—”ã.JøïÍŸó˜Z¡h|¡åmÊV¬¯Ü]¼š­Ýy7 bzZç£Å(üF¢— ?yE¾dówçæ×¤½ÿyóXÕ,/V³èÑ\}RÍŠ˜Ê§Ôí½vÄ¥K-CUªK1ËF8Žˆ·›YÂo]-ôè%¼P-¢y1COQPøH«PWn»dÀ´2‹#y’ä~öm%I(^êA,‹ðÔ:Åep †U'~›!¬¢/!hñ4†òkA$VVµvXâ¡ ‚a^  ¹§n”—[x~›§ëvZu€k¡©\¥´BúÖé¾?T õ=;…ŸŠ»85þe@$%3¶»¶¹‘­þ+{Ä^rXμ&UÁOÚPM9©(OF9 mhü¿üïüÔü°Ãå4I—ž£ywPAy§IÔ”h\‡Xš±ãsO¶2Æ$›~ƒ~[Îj~_ùŠÞ ?Ìdò¸$—…dºÒçrBòI£V’ îÄL¡mê±ß1å„4Ûì]?QÓõk+mKJ¾·ÔôëØÄ¶z…¤©4ÆÝ9•`|AÊ’¬¿ïD¿ñŽ?Öù#ôyý GÔêÙNÅXŸ?éŒÿÀ§Nÿ™™·ìŸòßð©þ‡WÚä¿á±ý,÷5ÑØ«±Wb®Å^QæÿÏ/Ê?"I%¿™üû¥ÙßB$i´»yúõ,Èü­lÖi…7MئHDžJòÝþs+ò?Vóèw:½÷—måBmüͬ[-®–ÎØ{QŒ? [œê‘ÐSŸ"Èâ·Ôv×6÷–ð]ÚOÕ­Ôk-µÌ,9#p]I ‚:åiVÅ]Š»v*ìUØ«±Vä?úlÿð)Ôæ^mû[üü*¥Õögù_øl¿C=ÍC´v*ìUØ«±Wb®Å]Š»@ÇÇýؾ*ÿÿÓûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,ž1ÿ9¤I®~AþsiÖÐË5ûù3ZŸHKv)(¾¶²–{6Œ‚>%ž4`ÄŠEFi_Ïå×™¬le´¶½C§ÅvÀZHjaûˆƒšÐuáɉâµjW7ÃûoÊ÷+$Pº8‘AGAÔfHbô&“á,š d“ßKä| —ÊýqV;©kZ^œ¥ïõk@‡ïeU<¸— Ö¼G*xoÓ"J¼·_mo̺Œ-£h’®Ÿh£RÔyØ©rîÓ#C,bpàËÌA§Z¤ ŠT­¼™vD«ëN͉M®žž‚5MZ)drï"² ˆÉ‘ZqF5´â×HÒ´°>¡c¡ÔONRñ‘¹²™®A lM6%@*•ËÑ\øŠ¿A?çßšG¡ùuùæ må†}oÎÛÁ;µRkK+OM‘{RY¦R{ÓÛ03S ûß*J¿ØoøÉ'üM²SçðsòùýêÙNÅT[ýè‹þ1ÉúÓ$>“雷ú‡ã¹["ÉðüæüäÝç‘\þS~^ê‹§ùÓT…™|Ç +O¤ÚNœÄVÀÂêHÙX;Ý£+ f`ÑÝå¾òLöˆÒ!yn¯¥kFþwinn§‘‹<ÓÌ伎ÌI%‰9&/w°–°ë¶\¾I1T’{â©|Rù_¥Ò¿\ ñ2ßÅwæRÕÕô׊ÚrÀP»Aà­ ¨ã(Ózå;¥-²)GFØU u®éV-èÜ^'ÖÄBÖ:Ë/2 éÆ·ä´ÛrTuaP¯¤çÞðêןŸ>vÖÚÂêÏK%\År—b1Í&£`mÃ@X±fX¥«qq¦à©4e±—?ï=ÇücÔr¨}CÞ‰ý%["ÉØ«±U¾ÝÏüdñÉK÷~’Æ<Ï㢶E“ñÛþr—þrnÿó7^›òÛÉZĺ_åì—S»²¬šârx‹´ÈJ5¬œHHêC%]ÁgŒC“RÄ– å7Ž(¢H‘bOµÁQV<‰ÛÄšælX½z +ß,UdÀ¨ _®*—Jø/•ð*]+⯚ôkÉï´½6öêOVêòÖîe ^RH˜Ñ@¤öŒ $ö6¨őTÌ$Óv4é&˜«ó¥mua&Ÿlí<—–fŽ&˜Åe0 2:|B…‚H©×¯Ôßù÷¤Œ’Z÷×"¹ŠÑ¼ßsŠ×s¤òÉmm¦i¶ÌíÁŸ3Ã-A=jÛò®båú’tKöí¿ã!ÿˆ>F<»ô„K˜ütVȲv*ìUFÛýç·ÿŒiú†JQ÷±‡Ò²,˜Gšÿ2|…äh¥“ÍžmÓ4W‰yýJiÔÝ8ø»µNSINjO4½0ˆ“É^ç1&».õv²‘Š¿™E‰úŒtäe..hxŠRö‡½,ðeH·Çÿóñ‚5MOòÒõP]h¦É&‘ªEV‚á®d2Hc˜U¢Ã ©CQÈÚ\8ù/Ïí'Ì—6Ìrñ£“rMZL ¡N+ŹY…¥•ÝÍÅ»šÐBѲ¹¡(^oN0Bž[¿J^KY Õïóºßæ6‰ù™äm3Ëa¼Ñ´ísÌ:bëþ\²™ZÞæÙ®SëÆhî ·bmù©aª>“‰8¯,R öÍÞ‰ã­óý#ÞB¨þ;Õ²,а/>ÓÿNÿ33oÙ?å¿áSý¯´ÿÉÃcúYîj¢ÖtAW`£Äšb¯™?3?ç.%ÿ-¬3y…<Ù¨^Ëè%Ÿ—å·¼X%n"5»ŸÕXàæXq yø©ÉÆKo–üÝÿ9Íç{¸å_)ùOLòÜ!ø‰îÚmVé”4€ÕÝCÈ tONJÊ9–R·?ycoÖ<ßùùù¨†]wQ×õ éÌ‹óÛiÖg—¦µ:zÉãÊ~Ó-}Fg¾@‹x¦µm¨ùl±Ö´k« hA3Ýò·™#P:²Á4’SÄ…4êh*p‘\Õ’Xù3^ÔlVÊÊ@%Í㛋0 &NJµ4p€š ïQ.¯kü˜üè¼ü•‚ô[þaA®ywN¼¸´Ö<¥y"ZiÉuqufõç·GîÜ£ÈÆæ™TðÆ]wM¿Rÿ-?6<—ù«åË1ùOZ´Ô!º†6»¶‚e’KYC4º:ˆ``‘Lž•]Š»v*ìUØ«òý6øê?ó/6ý­þGþÒêû3ü¯ü6_¡žæ¡Ú;v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿÔûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,’½oI¶×´]_B¼y#´Ö¬®,.¤„"ÇsDå €cJ‚+Û,>Kf{­ïaâü=+»YW¡§GR>‚̘ ½‡FÒÅ»‡Ò5mOËÏ)a¦]< àVŠc<’€± “ã—€Åí:=Ïæ%ÊYÇþ=†u¶““Éw¤[¼— QDœÀöëÐP˜Ñ:ž›RÑÅÞ¬¾ßHüÕºŸ;ùM+áå‹ãÿwü•K¼|¿jè|¯ç4s_ùÃNš!jñÉki£¼ Ó•øfKéØqökºÕkÊŽ%Â{Õ%›Ê¤ñj~jÖuFT¥÷"²Iä©<«g2F@ ’E¹åâcæªVÚV™¥ó66QÁ,›MsBóI°’g%ÜÑ@«1; j•Ng능37\ ”Lýp%"¿“¼í¾ÈV¯Õ?ùÂ- i¿óŽþW½h®`¸ó¥¬êw0ÜŽ4ÿr3ÛDÑ*}7†u&µåÈ»'ÔYÖ¹¨Ûý†ÿŒ’ÄÛ%>÷1/ŸÞ­‘dìUE¿Þˆ¿ãŸ­2Cé>ñúXŸ¨~;•²,ŸÏWüå5‹éßó–Ÿša.^þKk«(¯ßÓâÑ »85H¨ä§ÿAX€?rFÕQ™XNÌK$òÅb‹zôÌ ‡¹é²ÖòËB2I×  $“¥òIïPISï.yÎ>s*|³åë½Vy"úò ŽÔI«£\ÈRaàZµÛ®W,‘2šxççg凙ÿ'5–Õüåo®™æÓÕ†¥o2ÜÄf†Ö¦¶*Š$I"µª•jþíßâ Gˆ$vM<ºÙuíHÆ4½¡¶–6c©ê<­ã^ÈV&Y+JÒ‹µ7Úb$ªd<«ypí&³­K,ÆéVu·‰XzÊD®´ÜŠîvˆ˜‡z-3¶Ó4Ý-e}”6ž±¬ï€òIÛí5 Tä€_mÿϾ´[ÌŸœÞešÎ¢t]/KÔ=OçkÙ¯"ôÓreöSö³Pwd¦w?ï=ÇücÔr˜}CÞ‰ý%["ÉØ«±U¾ÝÏüdñÉK÷~’Æ<Ïã¢]æ 2MoAÖôhoN›W°¹²‹PE,Ð5ÄM•T2Pµ@ä>c"ÉüÌi·I}©i^jµ™“æ‹[©À¢ŸUžKjàUeâHPÝš›)9œ îÅõ'•'¬pÐö|PöKIkËP¶I0*I=ð*_$˜,wÅSŸ,ù7Í>v™SËZ5Æ¥8I5 ¼,ã'‰nW/Æ*ª°b¡‹R”SQZ¥–1æSO”nä“N½›M¹õ¼²Á$04wòÁýêA<.ðÜ;~áÞ¤5¡¥@ÚS8t¯0\–Ej­Ñ†ýA#·\¨‚‹Óî®ôÉšãM”Dd<®-¦ÞcЗAJ1¶´=+È8A¥zn­Yk…OÕµ“•Ξçã ¡ õ¤Q‡ˆ ª¢Ñ+B}èûaTDw7v¶’Y@‘Ïi"¤”¢ƒ#1ܲƒA—±} þgù2qmo>²šeíÅØß«[J97ä+Û|º3¦kq¯è±[É5‹(í´fé®#óF(Ë̵*H"½E2VGIÕ4Ï1_ŦhºÆ¨^Ï$Q,QÞ[ÑZv+7i bˆ„²Ds)§©ÛyÉúMn¿1ÿ6ü©å ønôX5{íQe` ÆÐÄä-ÖRÊd¢nB‚Yi– ÿM&Q~jÎ;yFÝ'ü¾ò&¹ù¿¬,qÍa¬ê0]=åj¥çÔãn\(mX‰u–~K°ažjüúüåól3i£WÓÿ/t0­­—•Å祩ï®d¨?r‘’¢›TŒ”tÀs[xiÓ 'P¼’}cXvõ.5ÝJW»¾–B¥^GžbÏWäŨ@%˜Óâ5¾1ä…9›®J¦n¸ªQpôW=€'ðÀ¯Ñù÷ÞŽ-¿,¼õ¯ËgèÜë¾qž(.½N^µ•¢Gð!8LóÀcÔÔqÌ ÇÔÈ>ï¹ÿyî?ãþ£‡Ô=èŸÒU²,Š»Q‹íÜÿÆAÿL”¹wé,cÌþ:+dY?—O0YOåOÌßÍ?*Å%¼°èžq×4ÉíÙÚÈÖZ„öâDZ6F+£+­ô¨9ÎÈ/UòמL[xî¬'Š)Étß³5¼Í(D½kÌô̘͋ÜtÍ'Ý´ViªRòjúVˆ†á舮åÅ¿ª#â[‰æTÔTP›DÂ)>—Î>YKx.nuÛ=>;®~‚ßJ,änû»Mö÷¡ÉqCÃæ/_‹§kÚn¡-´Fg¶¶¼·’B¡•>TîÃõªr&`*q&±ùe¥Î‘y“óÝnT¤“i=¤×3ˆ%BѳÏuõ;hØj‚Gp?cíztË)è>i¤×þVž‰d-ãü¸ü¡B^ &ó?ŸƒOr+#1 §|E"„dŒ8©Rµf‡‡9}E6/™µß>yêY.¼óç;ûõžC$š¤¢=9w!U`©UŒ˜Ã¢#X±,ye‘âØä:}ŽžYÚÇ:ªK(’@•âdÕœüDÕ‰5$÷Ë9*f능s7\ Åõé„ZmÓžÈz|°~ã~@háÏÈÿÊM¬þ¡soå-&MFÓÔõx^Oi×_'³;Ÿ„ñþ_†™­—6oW—íÛÆCÿ|1ä}ߤ1—1øè­‘dìUØ«ñ»þ~ƒ K­ù)渹˜ïtÝSKº|",ä´¸¶*Ã~Oõ‰O·L·ø‹ý!ñ§åWèzä¡uul¯ZŠ.ÀdöÔ~×QÜ ¨Nö*C×ý,µ úX«~—¶*—jZŽ­Çyg@D7V0ÅKr ¸Šøà1^Gªè—Úª·`=¼¯éÚÞ©ej3q RÁ¸©4?A4'(”HJ"Kéòä&ç ¨ÌG$u!”БPk^‘åMCXÕï?CÌöóH–ír5Y*®R9#FW†5 ÍI*2òE*m%DO.Ù£½ž]L©ä°ÍÅaRyW÷Hª|@':qíU”¬7ÌË_‹m6Í Æ§ÂZÎ$XËBÒH°Ç’ª8úrSAR7QS’¤ö·1MêØò…¸M®@Ü]XRC*:z‚Sx›¦Cè ]Úà}‹÷žúÜGy3ÜFü ²iµk¹ë–G’lÎÙ ÿ4üÁ~ÒÄRÇË–Î…¤2MyiIQéEà¨Ê{ž~Ì}I؇ê"ÿ½ÿÆ8ÿ[æ1úG¼þ…Qüw«dY;`^|ÿ¦3ÿ;þff߲˧ú_iÿ’ÿ†Çô³ÜÔ;F1­èQßÄ̃âî´Å^æïÊÌÚ}ö®iêzf žÝœëÉXT0> ©•†à€Aм÷Dü„°Ñ4Ë-"Õ§žÓMˆ[X,†ž´1ü4¯ÀZÍ*ró¨W$RrŸV’³Ë°Yd<¤n?h€$÷ØS)$žiCê6RÛI Õ”sÄâ’A"V×pEã¾iÕ?çl|½æÁæ.JºlIk-³hrÚ¬öñ—xälCÆÑqdØ|@UBŠRØf1E>]ó§ä‡æ6‹æî<¶«u÷22jåÖX™]ÄW"AËHIÓ—EPHeëÕi%°ÖntÝn 1[Ïå5AHàpïoÚ3QB2HÊêZ”GfRÛ)fVã‘ ‚H!‡þbyvïQ×lõÖ´M@JÐFUæX$k„N¼e1»!f1®ÅA‚A¡ Æö¯Fü­ü×üÊüˆüÄÓõ+%ÔüѰ°ÍPŠIE´¶ïC 0[[ÜQâT%£™€P9$¬õäÇ{uP_´ß•Ÿž>IüÕÓ!¸Ñ¯M®¬¶ñÍ©hjb»¶ç±äŒ%å°tªŸÆ” y²{(!€ Ô„dU¼UØ«òý6øê?ó/6ý­þGþÒêû3ü¯ü6_¡žæ¡Ú;v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿÖûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š¿›ÿùÉÍ1ü¿ÿ9QùÙ¥Êñ³z=Dú ñ ªÙ[j7Tø¸ÜŽTj»ž¦ìh)‘.ɾdÅaòôû­OZe¡bÒçøVž`C#2ü|’±íBN»÷È•cS?\ –Lýp*U3uÀ”¦fëXG›î…®…¨Îßf(]›ä9•ý ùsI:—´- ®~ºÚ.k`o8z~©¶‰bõ8U¸òãZTÓÇ5¬ÓœUFßì7üd“þ&Ù)óø¹Œy|þõl‹'bª-þôEÿäýi’I÷ÒÄýCñÜ­‘düeÿŸ¡ébÓÏÿ’žaý1£ë:oZH?G\ZÍVnàýwá¾/œ9 ¾Ñ%øcß2‚©£È®8Ž(ÈÛ‚Pk–„=IòÏ•%Tõ|³¤Ë¶Ü¬ ?­2b!Y½¿“¼”È+å Ÿ}>Ûþ©äøGr»]/HÒRa¥iVz`Ÿ®- Ž|+Ç—¦¢´©¥|pÐ ”^¿ÆwÀU%•úï‘T²Wë)\Í×¥S7\U$¿“Œ7‚œ ýbÿœ+ÓNÿ8óäÙ&µ÷zåÖ­ª^0“Ôõ}mFá-åÙ™W•´q|"”îrÍ~Cr,Ãêë‚Úr?ßoúŽ}CÞÆIDdY;v*£Û¹ÿŒƒþ ™)rïÒXÇ™ütVȲ7Ÿó”º`òÿüåoçNš7ë6ú—(—‚ÿ¹; kúS¹½÷jœ»Acš<».þôý2+KèÖÞöÖÈ Ã:,ˆHèx°#l´!èúg•|£ S'•´yrÖ6çõ¦LDw!–Cäï%Š2ùGD 7 4ûjÿɼˆîTØ[ÚX[Giak •¬<½+hcyÇŠ¨T’M\*Çnâmûà*”Ìýr*–Lýp%+™ºàTªfëXgšc¼ºÓd²Ó£jÄ[ØDYP<Ò‘©g!G& T|ŒBúVš^›§épý^ÃK¶ŠÒÆ Ìü!F¼œ–4U¤“ãšæi¼¿nÛþ2øƒä£Èû¿Hc.cñÑ_"ÉØ«±WæÏüü¿ËãPüŠòN¿ !®ü¹æÛEšà±ªÙÞX]Ç*­)–ZTqØÐšØ~¢Æ?H~!DÛ©©RYIj#pAÜ“Ké˯ÌÖ:»0]aGÖ [°Ù=„ uµÔw#ïb‚Çé{e¨oÒ®ô±T5är[Ko}éýVéL2$¤pà‚»‘ÔWWk~^“IXoì’y4K©!žäÝ$$²Æ@®ëįMÀܱÜÓ(ÖéOÿ.K?˜®Ý%µÓ\û&y£ô«þ·¢ôù8ù©{¯×.C¸‚ÎçR»¹†wEixÀ’G¦dB: ë·ŽD…Ku/[êX¼¶—QÿslBL”®Õ!•—zñpË]éP0Ú±û¹.´in5° µ´2OsªÛE!c‹vg@dh軚’)ûY))…·èí:ÃOõ=o¨ÛEoêÓ/Ir¥M+JÒ¹`Ù¿ÿçÞM3þV&¤âàÛê²iV‹ÍH·-h.ݽ6è_ý s‡ÄÔà ý†E–W‘~ËÅ{å'éóú>£øïEdY;`^|ÿ¦3ÿ;þff߲˧ú_iÿ’ÿ†Çô³ÜÔ;Gb¨9¬â”׈©ëŠ­ŽÂ5à1TZ¢¨¢€1Vž$Q”U#Ô|½gCxÓ®*ñ4ù*IKqÞ„®*ùCó'ò‹Gó%”ö:®š“¥МêBÄS”lA¦ÛÑ…URA Ò¾Õb¿ò>·ªùOQ”ù‹H°1Á*NµœE4 )¥y P£V¿²Ê)eãÉcv$&ѾŸ ¥(M˜Ð^£ËUO£2¢‡®hP¦ýrЇ°éS|+òË@›àä•#¾“®ýðcÓ?\Š¥s?\ Jæ|U+™ºàT¾ÂÃôß›<‹  #‰¼Áæ}LY&^q©¼¾†.¿´µ}Çq•d5¡ýC?0uñÌhœUFßì7üd“þ&Ù)óø¹Œy|þõl‹'bª-þôEÿäýi’I÷ÒÄýCñܽڃ"Éù_ÿ?FѽO þSù§…¹ýæ¹ôŸU—ý ~’±–~1·ýB®9 ›m(sWæ…5cę̀±z®5(rØ¡ìZ$ÿ Tå^ƒi?À7É¡,µSò¬ríþ#òÀU&•úäU-•úàJY+õÀ©d­×¬²òǘüá?è_+èךާtDiogÊW™§9 ÁGRÇ`79 Hº¿lÿ+üž<ù{ä¯%ó†Y¼³£YØ^Ü[«,S\Å‹‰‘[p%—“ïã˜Ùfôgÿyî?ãþ£†P÷±ŸÒQÙNÅ]ЍÅöîã ÿˆ&J\‡»ô–1æ÷S ²,ŸóŸZ_èùÊ;«îéþ)ò¾‘ªò€Q߃O§òœñZ¿ú©øŠöcAxV/Ÿ,Éz¦‡=(rЇ°i3ü+¾ù`C4†o„o“U—Õq*ÆnâožDªU+äR–Jýp*Y+õÀ©dÍ×½ò—ò³Ì™˜Mi2¿–4^×Ró«</«YL³ÉlÒœá=5­Mz”嘒´–ÍJW0Ù' Ü·üd?ñÉG‘÷~Æ\Çã¢7"ÉØ«±WÈó—~RÕ¿2#<ñä] mfâÓO¿Òmš¥›M¹·¿ÆI^a ‰I U¾"¹9}GÞÆH;/ ö—Ú]A%­Õ¤¯Õ¬Èc’)cb£U•Pv90”dLj¤1VR]I ¬ An" Œ*úwòßó u‘¯ÌXQÆÆù¨«x }“ØJQû]Gp2qÎö,H{°¯ÂÅöŒVI!ø£F êqi6PH¦Ä×qØ×-TÅ4 ç(÷w±Ú(¯©mj¾£Àýô  2•$z@‚äzá¤#ãÓtûI °Û/¬YÜO!i$^d’ä,Ê»š(4¦4¯9üÒ÷gÿmÿäÔ¹^^I /ò¹ÿÜÏš¿æJÿ“—Ù }R^¹#ûå¨I’=>Àê²Ý,^»FŸÔeÚc P¤h¬¨´]É'n b¨iõ9\”°´!Gõ» Q'âá÷„­Ú :PœU1Ò?/<ÇææIšÞ[ûX”–ê‘Z¡, 8ŒƒBÁØn9W*žHÇžé§Ñ¾Lÿœ|ÓžU—Ì‚Mt–-ªÖöê¨ä‘¿'ð`ÌTØÌiç2å²i÷'“ü³ú:ÖÚÒÊÒ;;H$°"Ç/‚¢€ù ¥/j³ŒÅHÛí$1ƒ÷¾Hý#ÞCõÇz;"ÉØ«óçý1Ÿøéßó36ý“þ[þ?ÐêûOü—ü6?¥žæ¡Ú;v*ìUØ«±Wb¨[«Hnã1ʵ¨ nãy?š<™‹#ª‚¤о4üÚüšÐ<ÓI}Yj¶ÊVÇ[¶¢ÜB*OH+"MQÁÅŒ dG%|Ok¡yŸÈºõ¯•µX£—G¹õSL¼X§t[jüJ©&ì7ø³1dâÙ‰Ðt™<³ªM:¼ö·W·z’Ï/!¥ÍÃÌSÓ›S%6QÜ b(¡9ÕôÖÕµ» æ§èëxf3Bãûã4~˜ãaÓ‹kÞ‚i9 *ú[ò{óŸWòf£•æ Nk¿*J8BeGÓÍGI†þˆ:"žŸ¼[&Ì$év‹®­äh²5XÐß1%^Cÿ¦ÏÿGþeæßµ¿Èÿ¡ú]_f•ÿ†Ëô3ÜÔ;Gb®Å]Š»v*ìUØ«±Tü|Ñ×ý‹â¯ÿÐûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,”¥$¸«ñþ~a¥}Só£òËÌFë^Q—M[’ŽOÑ—òÌÈ„ŠŸ_¨j9­iQYÚ ã½_…*|6̨¡ë: ÛǾÙhC×ô™¾ß,e‰7Á×$©Mì›õC3õÀ©\Ï)dÏ×¥s>{Ïüã—嘼ïù—å5ͦ5¿”ÚüCãR$c*düî…Ãe ©t#-BeÄvån& EnD®Är Œò­NÔÂúy+æ{¶W능ҿ\ ò¯Í)) Ù“^#Qˆ3P+ Tö© oÜÔåYy$1OË('Kï2^²RÚâßO†)*7’»g­E‹ÔwùäqõIz”Ò…f ¤ÓrhÒrÒ„ûË¿”>`ÔõûãkõÕ&BúíC¼$[Çn8ƒÝAâ7;×­ÍòÝ4ú_Ê’}¡¶š[Sz„1ºš¿j”ª¥x¾ÝýÉÌi唓O¥<»ùj Áøei{&“äÛ+%S*GìŒU˜Ão º…Š0€xb®_÷¢_øÇë|‘úG¼þ†#ê?Žõl‹'b¬ ÏŸôÆàS§ÌÌÛöOùoøTÿC«í?ò_ðØþ–{š‡hìUØ«±Wb®Å]Š­gTcLU ÔïT£ PA5ðÅ_~xùò+ÝC¢éö°Þy‚þu\±X¡·ghýR©ñHC!j¿ëe¸ñq š|=­y’þÿUœêQMªê6p,ìbX ·†)ݪ°Fò§ÀhO"h¤$m™ b˜’ÄLGÌ0ɬ[ZJÚt0~ˆÔ- ¸kY¡“ƒ¨…ç‚3ÈŽE½RvR¼YVª Oºÿ \j1j¦+H®¶‘åËYžî~!äQ"DX#aÄ‘«uaö™‰=U“ù?Nóo懘í4-M:~‘ݹ×õW¶µYRI„Ò(xcy"ª¤D±zìÀ"rP! ?\ü³$ñËn¯_¶½~b¹‚Éšùþ›?ü uù—›~Öÿ#ÿ ‡éu}™þWþ/ÐÏsP튻v*ìUØ«±Wb®ÅPññÿG_ö/Š¿ÿÑûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,S9â¯Éïùú•õ;Í#ò_Ïð<ºW–õ-cFÔ¤DåéɬÅi< 쨧ôs­J•©PYIPò5~lè²Õ2¢Åêº$Û¡¯|´!ëºLÿ o¶X˜G5S®I uÜ•?NI¦~¸¥+™úàW¥~^þHþbþg˜.´ê>_šþ)ÔË[X²ëqi.*ÂŒ¡‡dë”Ï4bš}Ïä/ùÄßËŸ)ÜG¨kæ_<êQq1.¢‹Š0¬-°zší+:Ò›TTâÏ4¥äš}Col‘¤p[B±E ,qE…DEUPÀeIM¢ƒ€O†*ˆÅTmþÃÆI?âm’Ÿ?€û˜Ç—ÏïVȲv*¢ßïD_ñŽOÖ™!ôŸxý,OÔ?ÊW(@.:wLg]Ðô3èÚ¯—¼Á§Ã«hšÝ¬¶Z®›p¼¢ž ”¤‘°ð â¯ÂÏïùÅÿ3~Aù†âëL‚ï_ü²Ôei43,M!³W`ÏQdb• W4I… Q¹Æ—Âv‚ò-.Zß2"‡¬h“ü)¾Xô[)þ¾X„ÐÍ·\*”ÜIñг_$~SyïóçÓòöŒé`…EƹzÞÆ>B¿Þ•<ȱ†`%hk•O,cÍ4úûÈŸó‰UÒâ·¼óíìžgÔÕħZÉ%½‚Pl„¯ ¥£oRP…)ZâÏPO-™Së >ÃK³·ÓôË(4ë Eákckà Kü©ª=€Ê ´¦QÛÈý¸Š££·Ž=éɼN*¯Š¨Üÿ¼÷ñÿQÉCêö3úJ¶E“±Wbª}»ŸøÈ?â ’—!îý%ŒyŸÇD“T„ÇñŠ”l‹'þuþNùcóÃÈ×ÞMó6³rú×—õØãM§_"‘ÄjHä(JºTsBVªhÀƒJüAóŸå—?(üÇsåo:iRY\Àì,u4WkøV”žÎબ¨CGÚJñuVªæD$ N‘57ï—Å[Ò'–ûäY? ç&!“o®|óå?ÒòÕËÓº\ ÒÊyž´H.HGØnŸ¢Y!ñü±}fÖâØ?¦n"xÄ”¯jEiQÒ¹5~–éÚ˜Õt­7SúQ´†èCËŸYñåAZV•¦gƒl•úâ©|×d~MÐm<Ѩßè÷ö©}gqa(¹µ•y#¡xÔ‚?Ùf>§éø² £ÊßóŒí¥ê÷Ñ[êò+]æ·‰¾;èÞ„<Ùx2Ž«!«Pñe$sj#œÄ&ŸDùoò;BÒDkaëÝG^:•È\U€ G â…{uÊå3.i§µh?—)NPƒïL‚½gMòµ•’¯$Ù«'Ž8âP± E€ÅWâ®ÅTWýè—þ1Çúß$~‘ï?¡ˆúã½["ÉØ«óçý1Ÿøéßó36ý“þ[þ?ÐêûOü—ü6?¥žæ¡Ú;v*ìUØ«±Wb¨[”fRWlU‰ß—£-7Å_ÎS~Iù·ÎÒhþ{ò]ü¯®yVÞH¦ÐÐ,Ðò2 ­Z†²%X4NJ†ƒqÂ[1Ï„ ¾‹^ÒµèßCó¦—s»§¬•²…§€Ü*Ü•Z/M”°’n8’j4>lY—¼¿ç9´Ú_•4$²ÒÕ™ Ø)Dˆ1%Ì—l#D.·Pàî¬N dZ}äÏùŽ&Ù_4Ü˨\É žêÊÖI!†I)BÓOUžf$X²–¥0­qe˜ž[2§×^UòŽƒgk¦é:}¾§ÚŽ6ÖV±,0ƤֈˆÉ; ¥/aÒ4³Ê&áöH5¦*«ä?úlÿð)Ôæ^mû[üü*¥Õögù_øl¿C=ÍC´v*ìUØ«±Wb®Å]Š»@ÇÇýؾ*ÿÿÒûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,·1RËÔu«Íÿ0ü…åßÍ%yÈ>m¶k½ÌÖ†Öõcâ%‰ƒ !¸…]VX%U–&*xº«SlUø}ù¹ÿ8Ãù“ùywsa/™|‰i-|ù§@ím*[Py›"»TÊ}2H #š‘ ‚‚¢ËºvÌ€Åë:Lÿ åYœ3|#å’Bþê(#’yåH`… “M#DEff4*IÅ^ÙäOùÇOÌ?>A¤öÑùcDž?RÛQÕ#ά*¦uB †`ªFêOL¢yã6Tû?òÛþqËÈ—ï¥só_˜ãš¶¡úQ6Ä›k_‰#è,]ÇfÓ1gšRM>Tg4U,r¤£c´d5ÿ$\Uªª( à1VñWbª6ÿa¿ã$Ÿñ6ÉOŸÀ}ÌcËç÷«dY;Qo÷¢/øÇ'ëLúO¼~–'êŽåb*=\‹$º[~,Jý“Š .ì ¼¶¸³¼·ŠîÎî7†êÖdG,r®ŽŒe`H ŠоEóÏüá7äïš'ŸQòåµßåæ§)/éè®§NgâUA°˜çà'úb¨èàŽ=ÀäßÌqUlUØ«±UŸ÷žãþ1¿ê9(}CÞÆIVȲv*ìUF/·sÿüA2Rä=ߤ±3øèºX’d1¸ªœ‹&-u§˜ñcа¿4ù3˾qÒ¥Ðü× Øù‹I•„aN‹"‚TZž.´e;‚ Ò¾>ó?üà×’.¥–ãÉcÔüžò Gav¿¥ìâ§*Yd†äÔ‘^w ° ã×-ŽbL2ùÃï?éÿZ7™4-Mb‘½k«#,f¼ÚQ^™PõñhÔù"‘šwüâïæ°®£{åkxB²[êÓ±Ù_N„{ž[xŸæ‡rð½'BÿœSR¥üÓç ʉ[=&ØFao‹Ô¥ÍÁI_‡‰0­(j»@ê@¼/|òWåüˆÒÜhš2Ë©M)•µ{æ7W*MB¬O%DJªBÒ0µ¥[“UÉ)s)§¨G ²°Xб9¦öúIÙ§m¿‘®*œE PŽ1 Q튪â®Å]ЍËöí¿ã!ÿˆ>J<»ô†2æ?²,Š»Q¶ÿyíÿã~¡’ŸÔ}ìaô†1æ!."i+Q¸È²|Ùç?)ÛÞAwiwkÕµÔoÍ´¨9#pU‘Ñ "„b¯ÆïÏïÉ ÿʽoô¶› Ëä½ræA§H¨Ì~?ªJƵ©Œ“RªCnµkc+CÝ|‡t÷>BòEÄ­ÊIô 6I€UšÖ2MÝó>'Ò²xmîõ + Yo¥FT‘!^\YÅT9û)Q݈%G™Zz•)îµGç¯LöêÅLV–„rµ>¤Œ¤n6!FݘöÆž¤ôM>¯ò¯åæ‘¥DF™¥[؉¸™Ú(¼…ÈßiˆU‰9)sdõÝ+Êj8‘ùàV{g¢Û[…䡈튧*Š‚ˆ¡G€ÅWb®Å]Š»Q_÷¢_øÇë|‘úG¼þ†#ê?Žõl‹'b¬ ÏŸôÆàS§ÌÌÛöOùoøTÿC«í?ò_ðØþ–{š‡hìUØ«±Wb®Å]Š»Kîì’e%GÅŠ±+Í=ªT¦*ðo4ÿÎ;~\ù·Í–~tÕü¼­­ZÅ$Sµ¼oߨѿ+¤ˆ¨•‰w=GÂü”(#’½*ÃÊÖ:m¼6V60ÙÚ[/ {X#XãEðTP!‘Tæ/z¤qŽŸF*Êì<½ih}»â¬’8£ˆqE ÅX7ÿé³ÿÀ§Qÿ™y·íoò?ð¨~—WÙŸåá²ý ÷5ÑØ«±Wb®Å]Š»v*ìUÿôuÿbø«ÿÓûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š ¦·,£Cz'¶*ùÃÍŸó‰þj¸7Íä;o,êt­ÿ–d“GY_›Ï-­›Gkq)=^xd=²BdrWžMÿ8Aùvgim<óçm62-¤éñP¤ƒ6•+üD5n¤Ò‚€X3ÉŸh¿óˆ?—ºSLo<Íæ¯0¬ª¡#Ô.4ôЂJ}NÂØÔ"vé¾øþbkO_òäÏå—‘ç[¿.ù>Ò øÙš VñæÔo"æÁÙbº¾’y£RÊ§Š° íðŠW)™s)z’ÆîhªNEQqÚw×ü‘Š£UUE<*Þ*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Ѝ·ûÑüc“õ¦H}'Þ?KõÇr¶E“D±ÅTŒ@â« 4ÅTÚ*öÅTŒ>Ûâ®ú¹=±UUµñÅQ)'A¿Ž*©Š»v*ìUتÏûÏqÿßõ”>¡ïc?¤«dY;v*£Û¹ÿŒƒþ ™)rïÒXÇ™ütVȲXñ¬‚Œ1T ة銡^ÀÙÅT •?gkê$þÏ\UQtâz/ÓŠ¢ãÓc¾þتb‘¤bˆ¡G¶*¿v*ìUØ«±U~Ý·üd?ñÉG‘÷~Æ\Ç㢶E“±Wbª6ßï=¿ücOÔ2Sú½Œ>¨ÊJ°¨=FE“×<½¼˜GPÝñWŒùÃò×Gó^‹ªù{[ÓÒ÷JÕà{kÛgUÇÚSÕYMXn¬#x'‘?ç´'i6šEöµ{æ8tùgjè¶±ú/3Ë•c,ìè+0uV¥x(ö0úB¶E’ÉH¥N*’Ï¥£“ð×QM2wQ°iöðnŠ£©M†Ãv*ìUØ«±Wb®Å]Š»Q_÷¢_øÇë|‘úG¼þ†#ê?Žõl‹'b¬ ÏŸôÆàS§ÌÌÛöOùoøTÿC«í?ò_ðØþ–{š‡hìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]а/!ÿÓgÿN£ÿ2óoÚßäáPý.¯³?ÊÿÃeúîj£±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÕûëkþòÛÆ$ÿˆŒUUÑdR¬ ƒ± ÔÆiZŸÕÓù¤ÿ‘ÿ5aã>_ Žø%ßWOæ“þF?üÕòùá‚]õtþi?äcÿÍXñŸ/^ø%ßWOæ“þF?üÕòùá‚R_1júG•tcÌšÍĶúV‡g5íü¡äfÂ…Ø*ò«1¥ É V}Oƒ2/Èd„GœæYãÄ$jès$“Qs#Ý‹$ô—ΓÿÎVy?*ù'ÎVÞVó~¡¢y«Ê–þzפ·K!'•ü·q$qþ’Ö–]F:"j¥¡¹”ˆåe• ̳ŽCPpXØã_ÃÅšÆ(òâ¹EððÇœåMf$Džqng/l¼5µÄ˜ÔoŠf@@HñW¤u{´Òô‹íVCZk;wž /Mc-ÕÓTŠòF…¤4»ª Õ™V¬1òd”ѳʨsºë@y’@É–(Ã%/M]Ù"ªïk'nB ™rˆ$€ùÎOùÉß/­½Õ‚~XùúãóOÖ/4}Wò‚/Ðí¯Û5†­qtòþ™cÛ‹K¨$ëò2¤j µŒ2Í;3œ¥_ÝÇü)™ âÚf4!ÊBBQYO°I€¦r J<$\FØòY‘ˆ‰Ç(Ê¥Â%Óu¿Í&é?–ú/æ…‹êfÐ<Õ|›i¥ow«Ï¯É :]µ²ÝKo=Ì—¨3Éi^R¼j¬Âìðɇ7€csâ1¡_ ¤lШÂ2—=Ä}6Hœ&91¤˜Æ1â±§__ê1i–6÷§™£Ž_¬ËqI-^h•_÷ŽŒ®©#,°ÇÌë„ÐÞ^«Žõ cÀlÈba) `Çq”¿˜$NÿÉ™wW°_ ¼#ðK¾®ŸÍ'üŒù«3åò Â?»êéüÒÈÇÿš±ã>_ ¼#ðJ¢"Æ¡T'rI©5;œÚ@¥ØìUMâI –ä ‚Ve44¯B<0‰‚[õtþi?äcÿÍXxÏ—È#„~ wÕÓù¤ÿ‘ÿ5cÆ|¾AxGà—}]?šOùÿóVÿ!rë\"R‰”8qÏ&ç‚&TäF&r¯tc#f£`FøåÊ?æ/Ï?*yoÏñyëCó å´ú>‘æO=ZýXèš6©æ)¤Øß4·±Ý™nœÆ Ám*!–/Uã\iò"47”FÃÕ8@eœ^ñÆx®\1?LdgéFhŒQâ6j"d ± Lã=8x„¸¨“ÆS¢N0?3í¼‘­h~VÒ¼“æÌŸ7ëöWº­·•¼³.œ—1iº{ÁÍì²ë:–™l%º†0‹1•‹ü²«²ˆd2”‡ðÀ)Uˆñ_Àž. !Aêb%#ŒÄ“\RሽÉååQÛˆ’â{ Ö?>/ôŸÌMòà~D~dê:‡š ¼¾òîµϕⱺ°ÓžÑ//8Ýù’Þê$„ßCÉ&&5 ÈõTdðØú¨‚z¯‘|ç¢þ`éšÆ«£A¨[[è¾aÖ¼µt—­ÁÚïBÔ'Ón]sH m, c$‚V…•NÂ1‘8ñäÚ²DHl9ÿ6̘ø2KçÜÿ#}“ç~ökõtþi?äcÿÍX8Ï—È1á‚]õtþi?äcÿÍXñŸ/^ø%ßWOæ“þF?üÕòùá‚Z6Ñ0 ™"„„Áaã?€€+ä;v*¢`™›ã[‹²‚iN€ —cÂõtþi?äcÿÍXñŸ/^ø%ßWOæ“þF?üÕòùá‚]õtþi?äcÿÍXñŸ/^ø%ßWOæ“þF?üÕòùá‚^ ¨~uÍ£~bh_—úïä÷Ÿ4tó=î§iåï9ËuåÙô«¨ô«Yo&ºÚkóêÂÑÅ𴶈C:+ª3S*üÈœ¥é0Ç,„/†15V/Špúó«©Ï !)Æ‹ú¦ «z>‘¯I«ÚÏ¿'3ÿåqy^ÇÎvß—~lò7—u» -SÊ÷þe¸Ò Õ,¯âõ¢žô_R’0©e¸X˜r ø¸æfÅ<$Æt$ =EWZáùÈù][qÊ"ȉ"ïk‰1#¿˜î¤\ÿš^[ƒócKüžm/ÌCÌ:®¨kpk2Y\A£ú:kY ¢Žöá£[‰)}ÿGªQ–Vè­Fø£!0 °3[u¡üí¢yDÈÆB3É1–äJB;D‰È_Mü9ì.Bœ £ÿ—Ÿž~TüÇó,¾\Ót?0è©{ay«ù'^Õ¾¬–>eÓ4ëÁay}¥›kÛ‰ÄQM$UQ@ì²ÆèŽ„°8IË‹Äm QÄ2ƒ,Rî©Æ$ÕñF«$`HeˆÇ>gÕ8Þô'Œ8o^ n¶©ðÎP2Œm7aºó¦½å.~]yËÍö¾U¼ýæo9io¦.—e«(ïÓOu¼Õm¯^FŽx««[«J¢I$¦8Ç$¥Œäj—/Þxd‰ô‰âŒâ_ ¼#ðK¾®ŸÍ'üŒù«3åò Â?®H’2ÅyÀY™iÔŸD¤0%تAæ/Zù’ÖÖÖêêêËêWIyoqfë«,jʤ3+Rœ«¶õ̽²ZYD`‚±GåÜâêô‘ÔÄFDŠ6ØØHÀ÷ùù§þâ?õï3?•¿Úq¤ý®/ògûn_ôß±ßà?ûüüÓÿqú÷ò·ûN/ôŸµ“?Ûrÿ¦ýŒcÎ>\ºò÷—5bËÍþd–æÏÑô’}Aš3êL‘š…U=÷ÌîÍÖÇS¨Ž9aľQß`O{‡ÚIiðK$rä±\忯´íoÍÚÒÙÁæmE%hå4—·i m+tbz)¦Ýs¦Í¥ÒâÅÛøGS_¥ç°êu9f 2JÏôŠüWæú™5OúLŸþkË“ôßêpÿJ?S_çµê’ÿL[¿Å~hÿ©“Tÿ¤Éÿ漓ôßêpÿJ?Rþ{Qþ©/ôÇõ¢o5ÿ8Ø]Oewæ R+›g)4]•¸°ê*²~ƒ•ãÒi2DJ8àAþˆýLòjµ8Ï § ¬Z&ÿXóf‹ÏæËö–ú¹©{rdŽ9hÌ„Ñ>55X‘Þ™ Zm.S 1F¢jøcDŽu×o0<™äÔjaÈå—¨]q¯>›ûýêºf£ç-UY­üÑ~n­m©{p>;¶eC±;¦¿Ç#Ÿ“ÕŠ<‰úcü<×}N@HÉ-«øSKlõO7]Ï{y²úÖ9ï¯f¼º1F¡Ä`Ò>nj좞¾Ó–‰ð¢L¹ÙÚúÐåæÊ9u'$¡âÈpÝž)PkïçC—TÂÒçÌ—‚õ“óXFÓOÊïR?¹VU° —}¯å9!§‡ éþ­‡¦û¹ù{»‹f9ç™ gä/œùUß/³Ÿ’Uy¬ù¶Ê +–óV¡4:‚ÊöÏåÎë­$9R*V£Û­:fF-6–r”|(ƒ¿Lz‹ý-95ˆDKÅ‘š©K§¾ží¢yB]KFÒ5üãædžþÊÞæeP!Ë» ¥NÕ9Éê»HbÍ8 8ª2#éî5ÞôºmÉŠ39rYý]ãÜš€ÿïóóOýÄëÞQü­þÓ‹ý'ínþLÿmËþ›ö;üÿŸšî#ÿ^ñþVÿiÅþ“ö¯ògûn_ôß±>ò÷—­|·kukkuu{õÛ§¼¸¸¼u’V–EUbYUk^5ßzæ³Y-T„¤ P¡óïr´šHé¢cM›$îl§ùˆå;v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿÖûëkþòÛÆ$ÿˆŒU_v*ìUØ«D€ &€u9HDM¯–<áç/#ÎBÛé~LüŽÿœŠü·¾óg–µ›/4jš5¼ö¾nK›]"^qÇu§ézÖr±ÇzÖò—䊎\©§>™1œQ®„ä„¡W hÈÆÁõT†ñl™Ž1<9Œ¥QçÂAŒ„¥æD£BqÚá)µ‡Í>]üˆüùòßäý’5(Ûù‹Ì¿™¿’6_”Þa½ÓæÓ¬m<§si. °\j+q©M%Ì)¯'«%‹ÌÏ$ ­¸Y ŽyC6S´ ðä2ÿ…ˆŒ±¯«‹†ð¬J&F\SÇÍŸšžãQ&qåÔN1úxÎYÂxÎö ±“;¡v9æ1Ïj–C騲ÈäÇÎ<|RÔЯ S„a‚8 MÇ`%µx³„'Á“ФcÁ>àŸW ¡‡•ùwÊß™Þ\¾òwæ}—ä¿uß:é#ÍwžôÝ~ÿÊÚ¾µ{æ˜ôÛÓ0MvîÆ+[it¨mVt’ÅoÄF“zyq~æx1†Lg2$˜HHÌO,€Üd9rÊgeS¡Q‡‰„å8ê!’U°1Œ2cðñv1㙈1¹O,²t #Ⱦcòwä–ù#æÉÖüàòÇ“ü‹å›B]'TÓ ›WÕc•ᾇNƒRŸO=ƒA Ü7ÜÂO beš!\­vHgÌf€˜ŒaéÉ`Ž Âx…™FÆÌñJFòHÄO)Ë9ÄïÇ!#Œìxã1<‘Þ<2àb1Éq#ËßÍý{òO+kn¯u­Ì]Vò——|Ç«Yê:îŸå}3ÍZn jÚ¢ÜÍÕŽ­¼®X\Î윥žnLãáͤ”È'¼’‡,‚&ª7! cŒê K ”…ƒÄjÛR"3Ç’0srÅÁWrÚYx¥ —¦ˆ<5ö´ž}òŸüävµç]3ò›Ì~}ò—šü‰åÏ.®» Þùz$°¼ÓµmbâãëpêúÆ9EŠú'ä®àB™^Ôrã—§$d$~šà$ÕËcý\­·To#Ì<[__…ÃWQßÃú…m{>žÀÁØ«±Wb®Å]Š»v*ìUØ«±T‡Ìþjò¿’t;ï3ùÏÌš_”|µ¥„:—˜u«È,,mIJ,Q™®n8Ó“º¨ä¬@êr2œcV@³CÌ÷2„%3QìNÝÃr~rø{ó·Êþ`ÿœ†ËÏÿóŽœ^BüÀÑ´¿.诣YÛÅæm.-<Í¥ëzÔz—˜,mãa ­´³A$O#ÇHž6š¹n–Á©Ç–cÑ)ÆW\£äŽßÎS•ðÖü7| žHO±¨cÌ*þ¯vé-¥L؉=«ŠÌ‡å/Ÿ$×´ï'kŸ—O¯ùÉ?˜¾oü̺ó¯¤=—™­üÅc«úz%µŒ÷k:\nH¤‘¤”UúÃs ¸ôT8¼<Â!c×Å AúD|(úÉàÊ}0”nl¥–fr©rœ71`cc‹ˆ‘¼¸ŽL#„GŒ râ2ã6›òÃó«Êß•zŸ“¦ü™×0¼ç¬y§É:Ô>iÒuŸ/I·—ü½©éº·—åŸZÖ4û†:<ÓYÄÊŒ—/þ–ì²Ý\pÍŒs`2&gIË$èdãÞÇ$eðšáÌ~‘*ä"NiDpÇ&,ÇÂŽA”G¦ãP2&$âxpâŽ0õ4þ\~cù“ÌþkÑ-<‡}cå¯Î?9yóWóuÝîËÃË¢[PÒo †òK‰.YtHÖµ[ˆ ÌyJŠœš½-bÉŽ2"°dÉ0EÖA8ž¯‹Å‘âãŒ?t”ýgÍ)ÀÈGyàðhó²qN]8F<·HÊqáŒ}l‹ó£OóÏt8'OÈo4?Ÿô{Ï1[~[yÛÉÞgÑ,u H§6úv¡qyw¨iÌ-5(’‰­U.”…ô®m¥à¡± 2b#Sîw€6I†P¼HDˆÈŽ YááœAr8±Æã1âc±qN^€o˜ˆÎ&Y1ñqã#j&'Ã;“ɾ|¹üÚüˆón· ¶¦<§äO3é>|×ìÞ8­†±©¶€ÉèÁ#,Å&{+†^(B…£q%kŸÅˆj52€1„ãyМ¥GŸ(‘Ïæ\L~'äñcÈAÈ2BR®F±eŒ¤9mÅ8íÏ~T þC§Ÿ|¡ço#y›ò›ÌzFç¿:y‹MüÃ{ß/M¢ÜYêúåÞ¡eÂ;}b]I^Hg]žÉxµC×(ÀoM†ôË8ăԃÈUŽ·¹Ö»VoQ)ÇÔ'Á˧@Ý×ñ@¯˜<¬O``ìUØ«±Wb®Å]Š»v*ìUØ«óÏæ¿åwå‚é¯ù—ù“å_ËÅÖL£Go3k:H»0põ„òh½OOÔ^\kNB½FGŽ<\6.®º×{! ñQ júYº?"ó=6ËRóoæ¶±ù¾š\>gò—ü‡›ù;s¥_i÷©¯þ›a¨ê×Voõ•Ru¶²‚&™Ñ[‹·/M¹bqË=@ÉÇ9?»ÇŠ…Îyf%FØ HGË,1„ª1â‘•šñ$x€ ¼Q„ÿßJ X•ù±"<Õyæ-çåŸä’Î=Xù¶ëÊ~^ùmdòümå¯1éWs]ùîM;F¾¹Ó‘¢‚x¡ô-æ’[цåR «(äðÄê\r”e¹ð qpKâÇŽD¡P¸ããoŒÈFRÉHÊP¿ÝÎ2åye)—úŒ¿{âJ¦ —&øå¾PÐ?24?ÌùÇðŸógÐü½äO)ùËžr×àÖ<±yfºŸ˜nt™fÔ„’k‹¨]ÆòØÏq<Ò[ ‰ Šæ&•V잦z‡.(Âÿcr¨ñÁ1ƽÇBõï?8-ncü¹ƒëV«úE¤òU†’£“ÌÞBñþü§N_`†Ìy4xàÊ9¥2?£âÆcËéÍÙésÂìdj0†0OqŽ\²>{Fq;w÷ÛÝ,<Áæ=sËÐÁæOË?1þZ]èðÛY­Ÿ˜®4;‡»á , ¡êºªS÷¬à´ß3õ3ŽIË ?T¤k¨ÅôÞúÈßKÒèñË(búc} uÚºÌy×IÌg)Ø«±Wb®Å]Š»v*ìUتɸó›E®„mõe”‘’‡ˆr +Öƒ*Îf1Ëã*5|®¶¿+æÏã¾Þ¹×Zó~Wùþqóó¦ÇDüâ¼—÷^O½óæ‘å+¿5y*)<¡¡éúþ£¥ë7WÞdÒ´Èü­é¤vÚ…œ­iΧ+ÜÈ’º˜*’.„pãà B&xc–2•qx|Š"°Üd!9b…bÈ dDˆ‹9Jy¥0D2J9£Æ.£)pø2ã¯B7:œ‡áÈúûG™ÿ+l¯¬?+nl¿çëò‡@`ƒÌó‹«oä»q«~öÏa¯¶œ5q \ˆ– „£]ú¨n=ENA¸Çoæ8ý@óðˆ™2J«Äøáf5ÃË.JŒ»1‡ ø‚Réâǀƽ7u#S x/œ1ñyûòëóIµ¯ÌÏ.y_ò—PÔ´/Ìß>~\yÇMó%¾¡¡ZiºE‡—dòüZ…•Ôê)uëÃ‘2²…——×é&Fl^$¿ºÏ’f{ž8ä‰ ¸¯ŽD!QâÜ‘eð½®-,±ì8d|}¥Ð É!Å@ðÆç÷™çüÈ¿—þiÒÇäõ—˜oÿ17¼Í­~bKecäý_ÌùzMSX¾ÐnlÿÅ¿XÒHG¸„”¸Wxb–J%É'ŸO„£ÿ7979o.(™â¼‚±Â?»99òƒ—6A¹#cwôF†HÄm¿6ŒÌ`MÌ›â3òOäל<¾ÿ‘ÇóoòRÏ ?Ë_—ÞZòö™§OsåíU¼‘æ-&âC}©o’|¹æÎ˜ºv‰å{_9hóƒ[“òcËñÞGhoõŸ3Û V=0ÜJ¾…£iö÷Æ'"‰Àå]óM) "uê:qÐxXÌx¦?œ c‚2<üm>xŠ!¿,!“R1ÈðÂräk‹†sâ}ßÔf”ypåÃÁ@müÕü€óæšÿ>¢²ü±ÔÿåhùX‚óÏ>w±ò½ì‘ë_¢m Ò,¼»«Û_ɪEl—P£¼7öb4–343GEI*ð†(™âþ @ãã”gÇ ClWi5©ÓeÈ9ñ‹â„!ÀDøAÜJÏAaJr”¥“¸þIþ]ê¾XüÀ—Ì6ÿ–òª¼›/åo–<¹¦ù[ýÃÅõ-KNÕµÛ›Ûo«h×wVéðÞG7(Ø£zŸk˜u]–L øûßXÊ<þŒD.¢¹z}7.·O>šT¡âñZg«ÏÄ0œ¯êþx4ú³1—b®Å]Š»v*ìUØ«±VùŸÿ(6¹ÿFßõmû üv÷%ÕöÏø¤þîƒÄ­¼Ác Ю.uq$Ö6óD, úÌ–¯Ôž(ËA¨›á®\U!çӜê„F3)}$l/†€;˜‘\]æ6ûu([yŠ ÒÆk­]àוqhuÉD­%¼ÆèÉiZMáª@H N'=¢d# ‡<"¨Ž;¾­èÕÓz°DLåëC‹Mý;óï®­eÏ™– }`éú´«ªNºt¤áE%Ë@²‰åEa^@U¨Ì7=Hà ¡ÇÀ8ý&ˆ×®_+ä²Ö‰Tý|1Bìwߟ-¬Ñ4†ó ¶­æ}bóUÒc¾ó ”¬SÁÌ¢ö„ Z1Ä­kE¨ßc“ÑϓǓ‡‡Bb/ú\úùîת5Sã‡Å@ž¹rï³¶Û¢çó:ËÛßjòzw_‹OW^¼‰ м¼”+¿ÄÑJ©©ßß+ŽŒâÂÆC*.;Ü9¥°ê„¥ÎGè1Þý27ñî‹o=².¢&ŽÚMÖ)B°° .@hµÚ¢§°ÊΓ4¢O 2ícøë‡ªN£G•Ôb9bVzrù|öcv’ÛÃ|÷–~`‚Æ[´œÜ¥Õ¼¯” бÍêJ= Øî37$e(pËTEòæ7QÛ´ÇÅ3ŽJ³.`×>»Ð÷º«_èÑ_y¨Ù•õƒA§ G ò™afà§‘UbŒT7A@wÈŒ9¥ \[Ê2³Ë•}çquÕ'6!–f;6¸«z•ÕòÈ{¶°¼ÐtU]ZÚ½.Þá&ÓäKQ™î$‘B2ÂÑî¬:¸Éã†yú #}«ïcY0žŽ x¶7½ÕU>d>¯ò§ü¢þ[ÿ¶]Ÿü˜LóîÐÿÉýy}åî4?âøÿ«¸'ùˆå;v*ìUØ«±Wb®Å]Š»v*ìUÿôuÿbø«ÿ×ûëkþòÛÆ$ÿˆŒU_v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»vU!òß•|±äÝ*= Ê\Òü©¡Ã,ÓÅ£höpXÚ,·4³H°[¢ i$bìiVbIÜä¬ÐH€îÀt w”¤yÈÙ=Iï'©ó)öv*ìUØ«±Wb®Å]Š»v*ìUuik}ÚÞÛEym-=[yÑd¸ÂªÀƒBÉãÉ,râ‰ Ž£bÆpŒÇ €#¸¥áO+ÿÔ·¥ÿÒóFd(jÕ'þ˜þ·ò:õ8ÿ¥©ßáO+ÿÔ·¥ÿÒóF?ÊŸõIÿ¦?­#§ÿSúQúþò¿ýKz_ý!Áÿ4cü¡©ÿTŸúcú×ò:õ8ÿ¥©ßáO+ÿÔ·¥ÿÒóF?ÊŸõIÿ¦?­#§ÿSúQúþò¿ýKz_ý!Áÿ4cü¡©ÿTŸúcú×ò:õ8ÿ¥©ßáO+ÿÔ·¥ÿÒóF?ÊŸõIÿ¦?­#§ÿSúQúþò¿ýKz_ý!Áÿ4cü¡©ÿTŸúcú×ò:õ8ÿ¥©ßáO+ÿÔ·¥ÿÒóF?ÊŸõIÿ¦?­#§ÿSúQúþò¿ýKz_ý!Áÿ4cü¡©ÿTŸúcú×ò:õ8ÿ¥©;Š( Š( ‰!‚Xá†5 ˆŠ(ªª6 €‹)I²\˜ÄDPØL v*ìUØ«±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÐûëkþòÛÆ$ÿˆŒUUÝcRÌH°$Ôš †-ÒŸÖùdÿ‘oÿ4áà>_0Ž!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øßXOå“þE¿üÓòù…â€]õ„þY?ä[ÿÍ8ð/˜^!øQdPÊI‘¸ ÔŽ) Úì v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¨;MCO¿kı¾·½}:á­5‚TÁpª®ÐÊžÔ•;ЃßFb®ÅZ¨ñ«x«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Tü|Ñ×ý‹â¯ÿÑûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»b~oóç’|a§çŸ7hþP°¹Áiu¬^Áf³ÍÄ·¥¬ëêH@Ù¬{ UòÖµÿ9ƒüÑÁùgùo«y†Éædo6yŽAåý4 ~úÞÞDŸQ”’~’Öp õ@*Æøiå/$[ç­kÍß›^u–;;þgêŸW4ãʾU¯—´„䈋Z±Ô.#¥ÅÜ‘¹'”t¢®D4ñ÷E¤~N’ãò{Ì–¾zü²Ð,­omm—˜¼£gVúö–IÍ“0UŽ)’iZkyM8ÈYXúrËS—Ûš~–ù'óGÊ?˜~UÓ<ßå[ÿ®iz’º´RÅ¥Ì,b¹³»†¤Ãqo*´RÆß:•=3^E3yw™?ç)?)ôkûNó"yÏÌ–ë1“Ë~W_Ò“Ç$,Êa¹žõ[7,¥WësB Wl”`eÉ^1ü滦jv:·Ÿ¿.í<™ùq4Þ†¯® iooôxån0ßjP‹h­Ò$ Fy}}NO¹[%‚Q‹}ŧê¶÷qE43$ðNŠðÍVVVR6 ƒPFR”èEA¨=ñVñWb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÒûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅX¿¼ÊþMòwš|Ûªùªo-iWz”XЭžóSÔd¶…¥KK+xÁi&™”"æ"¤ ñWâýÏüç¯üå'ç &ÿÈ”Z‡’|¯Üö÷vš6¡ 6¬9Z&·¹¾Ö¦uãAY#K¥I>Qz›±â½êÐKέ¿2õ¿-ê3k~mÿœoüÁºÖV6Y|ãŇ›µyD¬­(–ì_KrÊIŠ3Ê‚”Q"ÂX½GÉ?žß•Þ}½mGóÓüÇþUÖ ›JÔ³*õkĉž¬êµ©¥k–Ç$eÕiìíLšS¶yž|·ua%Ϙl®5‹Ï*\oÌË» BòÚÃQŠAK¨µ•´±Çsq 1€ñȯëF¼™<ªxã|Ui·¢èK¢þ…қˉk-¤RèÉb‰·Õ¤@ñUP…H"‚”ËtBfð¤¨ñJ«$r)Y#` ²‘B;Fe¿”ßš7?”·Zo’<Ó}=ßåæ«{’uɪçAšá‚[é7,¢Íœ„µ‘î‹-»ž•0sááÜrf ôIÖ£Uª|ÆK'5¡Å[Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Tü|Ñ×ý‹â¯ÿÓûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U°ßñ’Oø›d§Ïà>æ1åóûÕ²,Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅV<ˆ‚¬Àb¯œ?7¿#üùu'˜á‹üù†°ú1þaèÖö«¨OFɵÿ«­åºŽ]×ýÔñ±-’ŒÌM…|æû2~U^.—ù ––Ú\Ó%®“ùŸl"³Ðu)åþê ·wØÎÕ Šv(Çh¦•ªn<â[‹Kù“äo(yûJ}#Î_³×ìjƹOÞBͱx&R²DÄ r”Ó¾[8‰ Ðò/+~cù“ò/RµÒ<÷æ9üÛù?q$vZg˜.â_ÒX^A-Òîdø®íMB™_ãM«UÊÄŒ9òû—›îxÚ9Q%ŠE’)4r)YH¨ ˆ#/Bþ8Uåôü¯¾ý%oùWzÕãfÝT°Ðï¯&äoTD²–GcpI¤.}]¢2”…ðû’õp dÐ…¿ÓìõKÍ7P¶KË B -¯­%£–”¤ˆàõ ¤‚0U«5ü–üÇÔ<}§~XùÂþk!ŠZþ[ùÆúâK‰î–„/Qšj“s) ŒÄϬÈÍ&¿6c“0_hzÊ\Ʊ»V½P–SŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÔûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUØ«óOü›ä{X¯|åæ½#ʶ·þ­6«y  ˜ÆeˆJêdaÈlµ;@µCy3óÉ?˜v3ê>Jó5˜­­_Ò½²V[w%‚¬ð·",•£’üKU á ŽjÌp+±Wb®Å]Š»v*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUJBÀm÷â©%Ù’‡|U†j2¸ ×y_™¢µÔ¬o´ÝJÒCNÔ ’ÚþÂæ5–á•JI±¸*êêHe ‚68«ñ‹R»óoä'›5˯:ê^còf™ ÏårX${”Ò¸ª$ÑIñ=ÌpéÜ!2KÜš7s/]¨±! ç…Ó5Ýâ)= SHÕíMx‘$3Á2lU”ÊÊj?,º[„=sþqÍמdüª›AÔ¿ü¶Öï|ª.ç(e–ÎÔG5‹7¼m§Ž*‘RPÖ¦¤Ë¸û”¾¨ 2Ô)OmouÖ·PGsmsEqo*‡ŽHÜqduj‚4 õÆ•åZ]Ã~\kZw“¯Ù‡’5–[o"jó8áasEXô9™˜±kWmˆy¬^¬>“]?%ë!IÉ¡+Öô-+ÌZ]æ­Y­ö›|.-Ø•û,dte ޤ2° ¤0(«Ö?"¿4µ«[˜¿-0µ'¿ón™?—¼Û2E yŽÁ "P‘ÑVòÝ(·1¨'UÇ·.#äÌ}Ë£jÑÝF¨Ì+MŽT–CŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Tü|Ñ×ý‹â¯ÿÕûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUøÿù©ùÝùëæ?ÏÌÊý+óO-ùDºÔ?D~Sc-µ­œ°ÁVšÛ„÷Í:P e`Æ$Ä—œ[~Yi‚E¼×ukQ‘Ô%ÛÅ;%64g˜pE ˜Š{l3 ÛëÏùĽ7KÑ05‹]2Ö+ŸË2,üqmuj±œÕ¥($j3’~&ßâ5ÅÕ€)”_¡y†ÉØ«±Wb®Å]Š»Q·û ÿ$ÿ‰¶J|þîc_?½["ÉØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ÑÅP‚#劰ýRÄ•j Uäºõ©Pûb¯ÿ=.,ÿ1<»6œÒG§ëº{ýkË:ùÔ{;¥#°*Z9@á*WâSâ‚ Wå”vÚ¿–çÖt{˜CÙi²ÌžbòÍÛýzªÒZHUC[N˜  Á„©NNTecnL_qÿÎ3ù^çË¿”ÚL×ö†ÇPó=íö½sïgcjdåO‹êËE6û;Ò§+ HŠ è?ÛËÝ1¥Ajº>®i×zN¯gþ}§uk'ÙaÔA@*À‚Fº°*júž‰«¿åÿ›n$¹Ôaæòo˜¥äߦtØBƒëËÅSëÐIÐ}µã2lΑD zgš¤^aòý§˜´ÿ¨ÝMse42Çu¦jÖ2˜/,nànPÝZÌá$m¸¨ Š««#2˜ÊBнçò;óƒR×^çÉÞwú–›ùåøýkË;GoCSÓ¹úpêÖjà†‹,ucŸ­’k2c04Yƒo³4­N;¸•KTØåiN±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»@ÇÇýؾ*ÿÿÖûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Ѝ\ÜÛY[\^^\GiiiÍuu3ˆãŠ8Ágwv *¨’MÅ^æßùÉÉŸ(z‘\ù rýÚ=;CFÔÌe'­6èß ’U­•*Ô°b‘è‹|ÓæßùΉ?oäO#¨!‡Õõ]vrÀ€Æ¡¬í¸Ö„_c]7¶:~ò¶øGüE©Ý~jyƒó?THnn¼Éi|/¬ [«Ë›yË!%éXx€w-]²1Ä@ìĦŸœõÍE^(ä]>JÛÕ^‡þ,5`}ÔŒ°È•Ht­[XеXuÍT»Òu˜%3EªZLðÎ…™†@SHüÖ´UûŸ5ØFÄ8ÜZ¢’)¹çß§¦)ÈãOs+}ï¡ù‡Eó&ŸmªhZ¥¶«§Þ';[ÛYRh¤ZÒ¨èJ°¨êc¥9Å]Š»v*ìUFßì7üd“þ&Ù)óø¹Œy|þõl‹'b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U¬¼‡êÅR«›oP§yö» ´ªÍÆ€ö«Ã|ÅåÔ_P”©ñ8«ó·\ò?‘??<÷/˜tÈ–çÉ^[’óËÞkÖ-îO1\XÎcm<Àµ&ÚÞ_P4ÍŤ¬\à“Ô9Z|F[žLI}?ÀøfÁŠà„b®á튷Ǧ*ÇüÑå«?4éé—RIk2H—ZV©×W°v÷P7gÀ45VG ŒÊA!òg˜µÓqåŸ6C—´Ôjkúvú”Šš¥Š—r ˜õBÅ¡zÄŨ®ñ‰<5g¼ŽIR sCŸQ—úV¢ú™ôWk,ù’IgpËCÊ:¨–Ã,LBÈ»,!“˜¢_IþIþpmu 3U¶ýç)I §œ´P²RiP´WVRJšÒä+42{2?Õus‰¢Íõ¦~—‘.ã>üЦx«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅPññÿG_ö/Š¿ÿ×ûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÖOw¸¬ô ‹'æ÷üä·üåwæåßælHòý凖t»(_LÕä±]Ïs"þñšK“$X">¢¸f=Ø¡Íñß™<ÏæŸ8ɾló¥æV·‘f¶Ô·K ¢zjÑ,¬Â: ý7,z³—ò Xÿ¥í’Vý,U¿KÛoÑöÅZô‡†*×¥^…äÌÏ:~[jQ_ykW–n@ÞèòŸRÒå©W«Äš}´âãp„ƒ ãæ›~~QÿÎQùSÏb×H×ÀòÏ™dtm.d_BæW$/Õ¦$rå°âá[‘⼺œIâ1M¾¨ŽXæ@ñ°un„ei_Š»v*£oöþ2Iÿl”ùüÜÆ<¾z¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb©^ ±²0jtÅ^#渢A!Ú›â¯çoòoóëò&ëFó¤Vìÿ–þ{µÓ[ó/A‰ÙÆŸw2"®µl8Ò©Ì­Ày­‚Ê)™Ž^[»õ®ÒêÓP´µ¿°¹†úÆú¸²½·u–)¡•C¤‘º’¬¬¤A¡šÅÀøaWzgÃw§Š»€qVùƒä»Ï5i¶÷^]Õ—<óåæ’ëɾgô’o«\:qxgGVõ-®xÇU£)"2ÆQ¾\Õòv‹ÿ9ç¯Ë?2iú/禣cªéwižk×­´õÒ_ˤü>®—)õ‰’{9ƒ*@âÊÄQ” †'Õý‰§Ý(ÑËK ‹$R¨xäRYXTFÄ™cšÆ•ªÇ©ižoòÔzoü¶“ êg‘m.á˜6Ÿ¨,u/m1E'bѺ¬¨9 ¬¸„ÇšA§Ø¿”_™Ö}òíž½aÖz²ÙêÚ5×ua}læ;‹[…F`7A£/RU”a,ßFZÜ­Äaø©¾Eb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿÐûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÒ-nÊI!y"'a¸Oˆ?ç!)tÍ?/K£ëVÆ;ë#$š¸ˆk)˜H­9ÆôHÉ£ teFR +òÎ+Ý{òÛÌry ó&·x¨4½H—H†¡9âš)(J9! @VeãË|ØõEuWŒ‡G•”ÔzF^…þ–oÒöÅ]é{b®ô½°+^—¶*ץЭh«+(e`C) Œ úKò³þrKÎß—ò[éÚ¬Íæo,F‹²œÿ¥[ª/ó“özU\0Øq)½ižyl_£_—Ÿ›¾LüÉÓã¼Ðu53þ•§L W08’Éo±jrZ¡?eˆß1elž¢" Ô‡"®ÅTmþÃÆI?âm’Ÿ?€û˜Ç—ÏïVȲv*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ƒ¸¼Š5`Xb¬ Z×Â+…jо5ü×üîÐí›Yò–ßœ|ûõy"O-hfžÎYˆÞúä²[ØŠÀÏ"1a\í’„ ¹-¿$çò®£å(¢ò—˜,RÞ÷J´†ÎöÒâ`±*ü;Q‘‡NÄfo lX½þq³ó:_ËNü“óUÄ×>Oó5ãÊmzf l®dI4IÚ ð$¶b;˜ê~§øO åÑú%Çç™HwUrÄîhªNLí´k™È¨*0€†KiåôŽ…—“d„UùÛÿ9uå5ó¾—¦ÙùZÿT¼°Òx~rëinGµòõÒÊ-ôÌG)â˜óP€”…åg!x‘‡©”D€ëÕL?ç59Eš|¨Ü?™üäÁj¾Qó|ó.mVâ5‘t[†+ûÖ·ˆ¬ˆÁ‰Xž0Ô Ç<º/°JŽÙzü­½—Ë_œZ¶i 1韘ZÞa¾âÒ ©¡Kc¦É;)c3ÚÝÛFHn ò¨ãƒª{ÙE÷ž‡~J¦ýi˜Œ™ÄnCýqUø«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Tü|Ñ×ý‹â¯ÿÑûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕHEAê2,žyæŸ-GsH‰U5Ú˜«äŸÌËÌ·6zÖ‘o©[ËÄVhÁeY'ƒìÈj ÕH €Fàa…~tù—ÊÚïä½é·Ô Æ·ä ‰øØëyO§úðÅ*­K ú€ßÄÂ!“‹7BĆI †â®-åIàH&ƒ#£ «+ ˆ Ô™HUô¼*ߥлÑÅZô½±V½/l ץлÒöÅQšuÞÛêZMýΙ¨Z7;këY^P‘CGB $ЂAØà оÙü®ÿœ³¹¶+¥~c[©„uæ+DcZ8ÍlŠiMÏ8Îûr8³ÁÜÈÝ:˜´o2X[êZ.£o©XÝ/;{»iRh¤ZÒ©"¬6ìs)­¿ØoøÉ'üM²SçðsòùýêÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±UŽá¾*’Ýß2‚+LUòOüå?üä]§üã¿å¹óåÞÚãÝj¶º=¥¡’Xâî–Iæv‚ ‰=+x¢y_„eŠ©za_4kOªyÛA}wóSó!OâÒÕ¢q²T©OšµÍÉ>Xó›µÉ-ÊÚ]Þ¯«H€3­µŒ/q1PÅEB!êF2<"ÕùŸ£yþÓ\Šâ}.û@óWæ—æF©iwé¨Cåÿ£o#LÑÉ#µ¦™hˆŒûr†ŒÊ¹£7–~öÎO¦¿.¼…£þZù7Aòn‹µ¾i7WÞšÇ%åÊÆ«-ÔÁ6ç+/"Ãì­6p€ˆ¦ Û¶yoå/›$ó¿üäïžtí:ÑEü–òªè—úÌS3,º§™î,路e%S”ij>üK0fBxæªw*îeè·+›æ+'¦XKUž½F*šb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅPññÿG_ö/Š¿ÿÒûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,–º+©F•¶#yÇ™ü´“Fò"SZb¯–¼÷ä[MFÒöÆþÊ;Ë;´h®måPÈèÀ†R¤o\UùÕæ¿$ë¿’×Ïykëk_–÷wÔŒs{-¥m˜2r5 äMsâdÉÅš¶(!’Y\Zj6°ÞØ\Gwip¼ ¸‰ƒ# ÐÐ(}ó,nÅéaWz8«½, ץ튵éb®ô±V½/l –ßj{,w¨¸u/¢|R²ƒJ„Ò¤Ç`zœUéŸó~}ó}¯æï”t=ïôv•®^Õ´·Ÿ’ÝÛ¢4Ó…”ÆD:ò~¨TžTf­!û/oöþ2IÿlÅŸ?€û–<¾z¶E“±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìU.¾ž–qZtÅ_9þe~zþ]~_Κn¿ækXüÁvŒÚg”lù_kW”¥~­¦[ .e«,|TX¾ 4ñgçm¯š¿ç#t.hèëù{åMIu{ûdÅy®;%½Å¯Õã±µ’[8„‘Ü1õ$¸”Ž;Œ¼zY]˜™$—¿ó—?—šV¥ÚÙÝù©¼¿C¢jg¸:¤¶Q3™8ZG"ˆ-…[ýÑTPÐf\qF>lm çÏ- ˺n¡ªYýBÛF³‘­ãó¿™oÓGÐ'IWŠÒ~Wެ?ãÞÙ£;TŒ²´ñ«/Ì]#ówò×ókZÑ|Û?æv¿ä=?ô¤žL¹°Ô|³¡°ki.m”Z ŽöêÞå!‘B]M"ÈËö#R2¾>8î¾ bß”>E×?34Ìɼũé×Úæ™6—kå3O·ÒtËâ¶yŵ½¿6ôÌ£”ŒÇ¡20‰6¥âÚìžeü½ó.‹ù‰åë¾üª½–îÛK˜² Ë~&-CLœ-I[ˆy(¦á¸•÷¸›Â_ºCó'–|ýäÏ,yëÊ×b÷˾mÓ-µ]"zæ˜Äв('‹¥xº“U`Tî3g GV žY €²´Â„†óZ‚0hõü KçOÎ_0&º¾Kò F)Gœ|ÅhÚ¤,ÇèíºµÇ%gPRWµŠÝ‡¨–…x’ëNCt;Òâ­9ŽÞidXã‰KÉ#ªª¢¤’v UðŸç·üæw–¼·gªù[òzêßξqô&†óÍ̲èÚКYÊ´W2 ’‘FXUO2¡ÆÉœ £¹H¡ç?)5_ËŸÊüÁæo^_7~kj¯æ­^âêI᡹Eú°š7HøHÔ®(Ç”†¬EuÅ›ôŸG€M°+ÑlA 8ªyŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»@ÇÇýؾ*ÿÿÓûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š­tWRŽ9+lAÅ^oæ,$ñ¼‘©e>qWÌ~qòl70]ÚÝZ¥ÅµÂwò±ù5©\yƒËqKªyúQúkD‘É{)„Icr +ÑjjeÉ^<ŒYkb‚‘©iú柧¦Î.-n¡•†Ìާue;zfh6Å3ô½±WzX«^–*ץ튤ºŽ±§i¬"•Þ{’Á~©n†W…G:|1‚7ʃ〕c­uæ nî+-1 •ÿB²ŒËpÿ³¼¤l´$’¨¤mñ€ a)Í^«äïÈMWR˜]ùŽ— ­Y¬íŠKw7±šsÍEzíÌz«f<³÷2§Ý_–BÐü¨m!д[}1C –tJÏ ä?½™ë$‡a»1è<3Èži}uoöþ2Iÿl3çðsòùýêÙNÅ]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅZ,£©h:ž†¸ªìUØ«±Wb®Å]Š»v*ìU¢BбxœU+½Öll!–yçHâ…啨*"¨©fc@“о\ógüåO–U~¥ùi§]þkê·–ÖãC!t$+JµÆ½ 6|Pš:ÀÓL G¢H#,†)OE¼gVó_æ÷/'—Ìžl‹ÉÞ^š&‰|›å&a#¬‹F7:äñGvÌèÖ‰hW¹l̆«v&I–ü¯åŸ+ÛÝYysN·±ÎeÕ%Bd¹¸¹e e¼žBòÍ+ yYœÖ¤æTb"(>üçüú$iža›E…á³òö©e Ï®EÄú޵yNºFlüb–hã§šWÀ &‘$*É–’å¯ÌïùÈO)ê•:̺~‹ù°?4u‹Xm$Òµ ÍcN´ãpËÓO%±‹JXd‡šÿ£Â¼‰ýߦÄJ´Ï(áë‚iŠh·?óŽß˜?™¾lüÐüæóìVÚúvŽ<‘ä[ë¦Òu Kx"K‹¦[­Ãé²ÕX#«3“+2²DpJDȪiÿ8·ù…£\ÿÎPù«MÑ£Õcòæ6‡s£yY<É Búm(.ÑådŒXgº 5 ¨LŠjpÈx‡¸©äûÿòÿBÕ?)ü®þY¸·½òþ˜ú†‰¤jV¬’Ewo¢ßÜi‘ܬ‘Å ¸™mCò +ZïÔäâ Çf%‰~zþX fÚO9èvÌúÅ”j5{8’­s¢›—‰EÆ«þ¨Á’º†'ÿ83ù—s ZþcþEêSÀ–ÞL¿ÿù $eWý¯Ï<÷ëß­ç:“þý^ÔÇM:¸÷,ŸhêžnTäL xï™$¡æ:Ïžâ‹—ï¹Sµr³4¼‡FóÆŠÞ|óGœ¼Ó®éÚ–?/ü·—ékëˆa….5˦žê9$yAFHôÛr/Åê'¨5ñ ³È+̼ßÿ9¡¥^Ãqiù%å ÏÌ ª‡Íú¢¾“åôb YZp—w<P¬q=¤¦ù\³ÿ4ZiòϘuo̟͇mó/Î:¯Ÿ®.‹M埕­¥¶² ~>?RÓWëWI*ᘻS®Q9_ÔRúÛòþpÕ“WÑüÏù—¤Yé:^…þmùòãL][Íþb³Ðlæ“ѲúÖžêsºÁioi®%oÙŽ$g=Ä WÍ~jÿœƒóï˜. å—”¢Ò´éaõÏ~qŽXá«¡1ý_C†X/¥*Ôæ·RY°í˨Ɇ–rç²8ž=uåGÍîãó?Íÿ™Sê*«w£ê4‡Ëñ…nj–údÚQuyÄÓóËǧŒz[YdpÇi1ˆâ‰BGUElz&ÎR~nÿʲÐïï&Šö÷FдdÔuÝ'KÔ®tkËËGSµ°Ó­SQµS%ºÉ¿•™^°©N@0ÊsO„$çOÕ<“ùeªéÏ—`‡KÐÿ2|&­§ÚÂÒÞI{¥Ë ñH#Xžêòââ-YšI9´Œ‘U…7º„<¶O$é?œ¿’>jFžæóòòîÓT×<µ¢ÝÃ{zA_KVŽ3¬muÅÍǧÑ5›)ð‰À䦾`Ñ¿#uMÐõoÌÒ¾]Ò“Ö¸ÓtÈf{Ø¢*Í^4jÿSD(¤¸T@æU[ #š¾4üÉüüÑWRò·–<·å›6[Ýjðhÿ_°¿·†îæÝgeú¡Ö­c»¶·2±R>©4üAçêÆ~¢y šFMùæï9´vV–^U†ágy7Éó}våîkê%æ½vòêüˆt.‘Ó°ðû?Z¿R?#¼ƒsùaùOä"]ú[òýŽðBIEši^yZ´iØÓÃlÌǀĽ_…}²jüû󥎗ùEÿ9Sä­GËz•¹·óÿ–uÝ?Ì:L{…¡Ô ‘¡RJDÒÆDnÊ¢¤ c°ÌcèÈ+ªz3½ó.È–Š:14×&f¯Ö<ûyv]`f þѪ£¾Vf¯‹È‰ù‘æõ-Ê:—æf«=Ò Šk­&Òæ(„'Ô–f]>Ù -ê8 ì2‰Ê ïº_cù#þqUÕm#—óÌO§–ddò畜ıÆ:Ã>¡4~¤‡x#—ö\õÊ¥”žI§Û@ü¦ò¯‘´ÔÒ<¥åëMÀ°’hí££Ï%(ežV¬“H{¼ŒÌ{œ©/uѼ½ÇÁн;LѸøzwÅY•µ’Ä~ìU0A°«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÕûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*§,I2qPqW›y‹ËÕJ‚6 b¯üéùq§ù†Æ÷IÖ,#¿Ó¯W…ͤ«U``|AV‚#~l~a~Tù¿òKÌðkšM}å‹é–¾1³BÜ«ß׌d^€AMËF2qdù±!•i>]ógž{8íÆ³cÒA ‚Æ0ÊƒÉ $‚ ÏŠ¨Ì‰LG™E=Ë¿—!ãm~ád…Ó¬y,eFÀ4¥U¨GeU§óf4ó“ËfTú_˾@·´†(-lÒÞ,Q U@®PMóKÙ4O$€S÷@ýê—-mK ,; U‘"$j*ŽÃ]ЍÛý†ÿŒ’ÄÛ%>÷1/ŸÞ­‘dìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb«DAV`1TªëVŽ`ò ¹¸¾·¼Ó$‘f¾[Yæ+Ôj[q@Ò~í¾ ZóiâEÄn ¾ÞÑ<ͧë:~›¬i7±j^­m æ›} Š{yÐIˆÝÕ•Ã5ÌÞ¦jA¸ü]qVX¬C‡]Š»q “A㊠gÔ- “‚Gaоqó—üåå> ]\þay¥,þWòŠÃ¨\[‚hZòᦊÎÌlHúÌñ–§À퓆9LìÞ!®þaþrùÚKØŸV³ü¬òüê”R×È*~)ï¯a{8 åFŽ+YJ‘T¹#®\4Î,Lžqm ~^ù s­_Mce­ênE×›õûÁ>«}%>/[Q¾‘ç”ÑKÑFÊí™q„aËf7júïæåç–ukm[óv›c¬Ý_Zéߣ}_Rhno¸ýU.V0ÆÜL]B4ÜU‹(¤a3ˆ<Ö™ø%hy7›¿:<…å]7S½ƒWµó5Ö“ ³ê~•yfßUŠ =%½¸šx­ícI>ÓH¿*¡˜qÊåÓóãó›ÏYüæòÎèiw>oÖ¿5µTÖô='NÕ.ìô =Ê+>—MNöâÂÞêxþîâA´IÉèVDeå.6I Žûý ƒ9ó¡¤þrÎ1þGZ^Y‡¥o2ÛyRëòê×W¾ˆ^>YôAf‚IŒ—ˆ“-¼ÄÌÌU,ü¹r‘©ãwØŽ«´oùÇÝ{È÷z‹heóOäÅÕÔH·^Tº·‡J¼û,’MlÑOnó"©NiFÔ‘Ô f<¬- /? 5ÿ<]G˜õ:~m#4E™µeÓc’7i‚Z­ šSEøGz¾—;+oe°ÿœ1òž±uå}OÎ÷ò <¡yo èº![{h¤ÕøJÏsF∨GUpzX0Ímõ®‘å¿-ùVÖEÒ4»=ݵÌñ¢¡*µ%¥”üMO;eàW$>|óçüåŸåŸ–Lšg’Zãó‹Í”"= Éå/májñ÷RBֶʀܜ²ÿ&U,ÀrÜù&Ÿ3ùÓóó¯ó*ÚX<Íæø?(ü³tÍ_(ù5Ú]YájR+½rZ1a¸o«C õ=锥.f½ß­^s¤ØùKÈv-i~_¶TfÔ5™È7‚C;Ü\ÊKµH©.Ç"*<’̼¹ä¯ÌÌGI<£å{›Û9TùŸW-§ij®¼Ä±K*nŽk©]‹.W, rZ}SäïùÄ/‘muùƒ«ÝùÖèk!õ šÖ£êѳO*šüK<îAð.ã(–BSO²ü½ä‹*ÊÓNÓ4ë}7N²b³°µ‰a†(×¢Gª`A/HÓ|±N?»ü1V¦ùgìþï犳»-(,§lU-ñeé°ÆbËY®‰åË‘\C h¶:,w’z×¢Îá3Ë@¾¬Ì€»1$÷9°ŒDy/üÄÿœŒòŸ’üÃ7‘<·£ê?™˜ÐÆ^çÊzƨ3©^Üɪü…*Y÷…2¹æ47+O=ó–Ï–.#»üÙüœ¾ò”þ°c¼óe†¯¿œ%O îm­`I– >š?Ö½Œ8™Žä½?Ë_‘ß›>t¹ˆ®’žJѧT’O1kÃÔ¹tq_Üi‘ȳs¹h ŸÙn™D³w&Ÿ\ùþqoòÿAº±Õu; üç¯Y0’×U×X\$2 Qà³EŽÖ6R Wz‚¿lå2‘<Òú§MòÇÙýßá‘V{¦ù`|?»ü1Vy§yg§îÿ U™Zh°@ °ÅS”#E 1Uø«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»@ÇÇýؾ*ÿÿ×ûëkþòÛÆ$ÿˆŒU»°¿ñ’?øšä¡Ïà~æ2åòûÕ²,Š»v*ìUت×EqFÅRù,Qš¼zâ«ã°‰hHÅQªª¢Š)Š®Å]Š»v*ìUFßì7üd“þ&Ù)óø¹Œy|þõl‹'b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š¥7Õ½ñV¨KNB¸«ò³þrf×Sü¡ÿœ¡ü¬üéÓáàoÎHm?,ÿ2¢‰B¬Z¨–GÑu ›¡bÑæ~Ìq‘ûC/Ód៽>…{æÕ­øÙù¤þbÞù«ÌZ=åƒéþ}ŽömOó[RÖC;i×wÎòF÷1,‹$Ï-?suäŠIu§WÆaÏ›e>‹ó¿’ç›EMëóPÖ¼Õæcú3FÐeÓl$±¿º¹"?Ilà†;•€s«µÑEÉÞJ@G$äk½i÷'ü®žMòO”<¥‹åÇL"E­`H™–Š›1RkÄWÀfÎ"€ ^dòÄZüVsÛÝÉ£yƒGÜywÌVÀìç"‡fÚH¤ ±7Âë±Þ„ ˜Äض‰ùáç¯Ó7þKÿ•dÚïœ4oDj:æ«[7•á“ÄÝßOÂòÚ`«Íí–Îi:õc>®k¿->* í›[ù—óúsk<þuò–€>6¸Ò´ýîô§/±×nu8ýN|bÞ>[ü µ/.òŽ$ù5ÿ7¼½÷>cÒt_>Ø!‰ä“ËpÜéÐD zü,nîuº!d q1øŽBz9F׉‹/æçæ'æ¶‹¤êß—ŸRò'•u¨ZI<Ǫ˜u-q8»FñC§Û¼–PH¥H-5Ä¥’Û zS-ÉÙLŸ*þWèÎ4þs^~TÉ©\ÜþZþt¤º÷åþ£¨´\­¼Ëljz{£†%7Qðš%UQððQZæN8øRáèy{Ðw}¸»ôæK1æŸ8ù{ɶö’ë—’-Æ¥#C¤ipMy}*ŽF;[Kt’iX ÛŠ£v o‘”€Kò‡þróž3~mygó'òªöãIó‡å匚V«4ÉvútYΩõHæÒÚ^D’xò2î})#aeÉr±Ì~=Ì€{ÿŸ7ô=Î(ëßœ˜T_(yßÈ÷7ZFŸ9+>°—[4zmÅ=Y,ïªU§Â¢@KD¹l²qcâ#pŠÝò·™<¿ç?É ~x~Uh²ê×úÇåÿ’|ä.‡qp¶÷w6Þb´Ó/î´øc)2 ÈîPKÁT¶âAËaAÇÈ}éæ÷,ÿ?4¼Ûù%­ëZ"þSÚywVóÌöÖ÷s\ùŠÂöÕ漣éC tmÙK]e‘kʹ`ýäŒ{‚93ˆÿç¬-žÎ/.ùBòΤG ï0*Â}.tæñYè@Ø  NKÀî o´-¿-ü»ù]å{+ùv&ô­u¨ÞÊ{ww"ªÉ<”Ø@` Ù‘ŠAþe~nþ[þQik«~`ù®ËËñNÔ,]Œ··l6ákiy¦5ÛàSNôÆY#eiñÿœ¿ç*¿1üÕ¤\Íùaå+Ë ŠÉçÏÌ©xPršÛH…¤U*jTÜ̪E*›ÐQ,¤òïMD¹“Pòï—=bá=;~òY¯¯Ù(*‚êéå‘õôÑ•+Ñr¢Iæ—Ð:w–~Ícü0+<Ó¼³N?»ü1Vu§ùh JS¹ÅYu¶•oPÄb©šª¨¢€¶*Þ*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»@ÇÇýؾ*ÿÿÐûëkþòÛÆ$ÿˆŒUUÑdR¬ ƒ± ÔÆiZŸÕÓù¤ÿ‘ÿ5aã>_ Žø%ßWOæ“þF?üÕòùá‚]õtþi?äcÿÍXñŸ/^ø%ßWOæ“þF?üÕòùá‚XW‘|ç¢þ`éšÆ«£A¨[[è¾aÖ¼µt—­ÁÚïBÔ'Ón]sH m, c$‚V…•NÀÆDãÇ“jÉ!°ä{üÙdÇÁ’XÏ8ðÞçø¡ƒì˜¿;÷²®'‹W±ÓSEÔ®,®í®'¸ó sÀ,íd…£ È÷Kr^`ìPÇ  ÜÝâ2&ù  Þúw3t7Ø“`DÀ;5Ìíµß»¦Ölò«,z×Îz-ßæ&µùi‚뺗´ß2ÝݳRÑ­5K«ëHR72+ØHX´bI qÈä„ä*¡!°æcÅ·•}¬²cà'øøësþO‚ïþVF¾<¶¹¯ÕÓù¤ÿ‘ÿ5`ã>_ Ç„~ a˜^uÑ¿.<µ/™5[]KTçye¥é&˜Áïu KS¹ŽÎÆÊßךUçžT@ÓKk^RHˆ€ã‘”ar‘ º9èTaHïÊ&®T ¸ §#Q€$’O¸|e"#ÖD‘ùËþrQò/–t¿4ëŸó¿™âÒöö×LÔl¢¹ò§Ö4ëëýF-2ÆÞãÔó4qËõ™n")%«Í«þñÑ•Õ$$e–ã¹pšËÕqÞ¤ x ™ L% A@Çq”¿˜$NÿÉ™wW°_ ¼#ðK¾®ŸÍ'üŒù«3åò Â?»êéüÒÈÇÿš±ã>_ ¼#ðJ¢"Æ¡T'rI©5;œÚ@¥ØìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±T òrŒ‘м×Xªr8«å?ùÉ˸¿8?(<ÿùvÜRÿ]Ó$>_ºr[ê¶Ô¸ÓææA*â4,FükB1WΟó™wÿš¿”Ú&³¯ÄÖ¾sòüÓùo϶2PK³¥‘Ǫ£ì4ƒŒ¥ONt;œq¬Šz'™?,|“æÍB_YÑykGèÇ­Y\Üé×¾Ÿ@†êÊX%emƒ03VSÇó o*×üÛùÿ8éuè`¾vó r<6“mu¯y£TU¤œdô‹¶JÄÏ"Æ)@™]Ãw,4Îdh–k5ߘ?%¿34":?éI4Ë+&µ’x`¾y“ˆ¡!Qé½vÁãŽâ´öwüÛòß›ÿ/4ï6~Vë–þer¼‡DòŽ¡ºª_]?¤dž9ag‹ê«ÎyXÁâ…iVÛÆ n=QOCò—”´_%h6^]Ðm~¯ciÍÞF£Mqq3'º¸’€É4Ò3I#Ù‰'%€(+%àrH^¾xòošm,ç#?6¿--Ävñ\yCó}½œ23'Ögyí5 Œ~ŸžN6Ň?‹ûÊrg9TO¬ŠY7ç¿å[~l~_ÞhÚmçè9hw6úÿåߘ×i4íwMq5œêNÀ ü,M*K,8‡ŸEùù’ßšß–Ú™¯mFù–ÔˤyãD#‹Økšs˜/íÝ?f’©eöpâŸmKæ¿6~sywÉÿž^WüÅò?˜üâjÚVg¥ù§C²¸¾¸ƒN»Óc[*–¥'‚3I:ÈŸîד“‚"™d™&Ÿ ¬ôëß%þ\ùÏZ—“bÎÞÏÍ^R…ì§õc•nï^[‹¹ÇŒ°L~×$?cùkä”ëFüšó÷ç_š|«åï3^G¨èž^ÚÛèZT2[yËZlŒ‹tmc–I$’Yïg•¦•ºµjAÌÍì[§Û¿ó’”©«Zù{]òÕæ¹ j¶ ÷”§¿Ð.fŠúïK¹{i£±¸œ $x‹[ž§™c³nÕÈË åî@(ÿùÄ¿ÈoùS^TÕï/´èô½gͲÃ!ÓvvVüýd$ŸŒ®ïßpâ]Ž|²Ì?ùÊÊ? ½Æ™k­¿æ›ág‰|äõƤ%JòK…ŒvÜi¹Ò‚´­2RÍæ|–Ÿ%y÷ó÷ó£ÎšbÇu«XÎ>èZ”« f”ߦüÓv¬0GuÅ"†Gܨ·†INUÑ<²#sÂ>ÔÒEäOÈß0ÜJºÇ—ü®<µ©_Ÿ÷#ù…çV}GÌWëÀȱz1,ªI¦ƒŽß»4#1ŽP>‘¿{*}IåùÇÿ*ÙOg¨ëq\ùÏ[µ1É©®8XëÆHl”%¤,9FJËàƒÀxv7"f\£ÃbÌ ì’rLcá7õ.þôs xŒ  ùG¬þbèœz??-/¼«ä}ó»HŸÍ_’z$¾R¸º“K³òm…¤º|6šÈÔ<³#Ú^Í ÃZJín†2"MdSŒ^<¦xãzŽU.fcëðpOª”/ÑÅú¯”Äg’8q£ü¬òLT6É qç‰ e£— ÀÑüµ«é“~Vj¿^ió×´.é¢×B×5o)Ãæ+‰ßS¹§Åm¦ÝYé²iqEmso%½Ô1¢X&€.OU/BR¾(˜(™qmŒ~÷ŽDOŒpÎ\\FFY"d9Ñ¥‡¤‰Ãê<$DJ&#<‚1áá1†A2bNÿ—¿›ú÷äžVÖ4Ý^ëZ˜º­å/.ùV³ÔuÝ?Êúgš´ÝA ÕµE¹š «‹{[y\°¹Ù8#K<Ü™åˆðæÒJdŒÞIC–AU„±Æu%JBÁâ"mHˆÏHÀÍË]Ëieâ”.^˜J ð× fÚÒy÷Êó‘Ú×tÏÊo1ù÷Ê^kò'—<ººîƒ{åè’ÂóNÕµ‹‹­Ã«ëtå+èœc’»€9 ezCQËŽ^ž<‘‘úk€D“W-ôyr¶ÝQ¼XŒw0ñn=}~ ]GCêµìú{b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±U’'4eñ«Íuûvè1Wêv¬ÌÕÅ_œw+yù!ÿ9¢KÕÿ.¿ç'¬Ž«£ÉUK{_6é¼A²…k¸P;T“$Ž€t ËÒd©p÷±{¯çŸâü©ü¯óÏæÚ­ôžUÒg¼³²v“]P%´nÕZ+ÌÊé^ šŸ’\1%ˆ~U~GØù¿RÔõk'N“Î}ÖŠê>yó†§(Š5šá™•ïïÈÁA °Ã»m²"ë¼N{:}Syäÿ<ÝóŽãÎ: ¢þð-²èw3¥¾RR"ÅTnB¨5;t¤1%§‹èWž¿'ßó·ó ,b¸B·òÏœßÊÚ}á“EÔ%{ë«[ûïIâŠX®OŠn”ÕL*…&ÜS4d:R õ#Ê~iÐ|ñå½ÍÞVÔaÕô ~Õ.ôÍB¯ÁâM U”î¬ ÁÍ„H"ÃF÷¬KÏž|òå—•µ?9yã[·Ð|¿¤Æ^æòv¡v¡+ (>)%zQf;‘”„E”¿* ÿ5õ:ÎcÚþdêÖ·:Z~jE¨h6šEÏÇ%†“‘¹°·DD¡½K$,J¶ï½OǘX¦N[ïdFÏØÀ¾3Ø>4ó7_ó‘ZwœmÔGùWÿ9wm¡ùÓjG¥y²ÙtÛδU¿Rbr €ÎvA˜çÑ;é/½—0úÍß•Zšõ«O2éZõ¼ÒãQ·Š2×PÊ8î œDÄ”ø¾OüÛ[(m–ÚþJydÈ%Õînµ`öܽ˜•éüsŒ„Þ‡¯–|•¡Ëé‹-yK§º¸•ÒÞÞ¼²Ë!{³™Ë(D+å6Îdy-໳ü™ÐµÎmv ^Ù®l´ý ÞT­Lú½â$.;«‰yt¨¨ÊNqü;­>Vó§¿5?4ˆòßæ'žoãQOùT?–Ik°¥õÛ.ä‰ÿm¤–k]À¥(Éרü äoÈ2&——wåG—y#6¡,wº¤ÈPWÖº‘=ebBÜò‰æ9Í[DRiôÿ“?&ü£åi"ºÒt(K,^Œž`»åw©Ê†•Y/g2NÊiöKñ)$ži{^寳û¿Ã³½;Ë=>Ãgzw–~Ïîÿ UiÞZû?»ÅY½——Ò0 ¨Qв(m!„¨*;œUŠ»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÒûëkþòÛÆ$ÿˆŒU_v*ìUØ«±Wb®ÅRO1ùgË~qÑ/üµæï/é¾jò檂=S@Ö-!¾²¹E`áf·¸GÀeS¸!ÐÅ^CªZñw¨Å_Îcþ]ê¾yü–Õõ(Z,ߘ¿–·Ö^vü¼¸ãÊXµu¹aÙ¤eW¡b¾A£aXß—¯<™ÿ9Où¥Þêv²?•34tÅ„NRH'Š^0¤”$40²†öj3pË"×Éäþ@ò5çä?”Èú¦¬ëm&¥xþxÑtÛ­Yuv‘ÐA5͵„sÜ[J¶â8J¼~˜Qd~§]“O8žVÌÁ|Ûæ«©í|ä½r[¸¤Ž9o¼Á§^ù~ÂV§Õ’MJ%•ˆ[E+TN¥c <äyRØ{—•¿'tý/Èþnòǘ.có©ù‰Ô~xÕÄM Wî×êBbõ G0 zý©ú’;Ž<"áï`KòÃò†ÓÎÿ—Óê‹ù}ç;ÏË3èËcç}!í¢Ôt«½CN–KK“q§ÎôY£/(eO›lsÇ‘¦Eôý¿æWüåuý…½¤žvü¾Ó©Å>¹kåûɯ*â‚oJ[án]àpUþ`ze¾&NðŠ óï’µmwT“Í_˜~rÕÿ2<Án Ó›U1ǧØo¨éÐ*AOp ”Næ¹D“dÚPó^^“Tÿœ‰ò1X"š&KíBå¥Hä¬VS„p²~רȯĤ†f¸â0§“ö|)¦Ã3Ø<ÿóWòãIüØü½óGu¢cµó ™ŽÞñkÎÖî6ÚÝFEhfDPöÈÎb’ù;ÿ9¡é–:Í¿çÇš4ï'ùëòsQ(þb\jW 5íå’ ü @’¯D¾ªˆÔ–n|)•cËQõlFÅHa~dÿœ½ó/›tùSò7òöha™ óÿŸ´Ý7… Yí4øZKË•aöKˆEiZŠäNb~‘óM>q×4}GÏ¥ïçuoÍ­IY$K»o©y~ÝЦ ÐÇkP Ȯǩ5ÊÈ¿¨Ú½'ò¿òò̹¼Çoªj7:_–¼§©E¦ØùGFNŠkw°µ¹Vžæ*JWÔ–E D(´n]ñòä ÐäÈÚVü¾Ñ¼»§[é:k£é–ßÜXÙÂĤõ¸·E©f"Ð Ÿ´*Kf>L{ØH/"Ò$•ÛÜFðÌ›IŠU”øhFV•÷ÞP×|ØßQд©õ+‰¦=5¢+OÇ#Q`wf𒯥ÿ#?!tÏʈ¯5»×Pó®µ ƒQ¿ŒŸJÞØºÉõh*AdVf"¬@èËñâ÷ —Ñ*‡å–!瘟›_–Ÿ”Ú|Z—æ/œôß+ApÙÁs!{«ž¤[ZDy´hÆ»uÈÎq2š~aù÷^òÇæ÷çÌÿšþ_ü¿¹Ó´_,¦‰¹æ=>+k­CP‚è´WÖÖÒ»O‹v1‡’4fZ›fˆ”ø€d‹›Rš÷S‹D°·¼ó˜®œ\Òâ7We  wEøbŽ»z’²F;°Á,€sZ{‡–çüùæXí§óN±‘ldâ×V—ÂÿTd`IFº‘~­nÀÐÎìºò‰f'’iö?åÿå?—ü‹¤.‰å» -¬Úf¹¹’y¥¹žyÝU^i§ÞGvIè ¤›KØôï-}ŸÝþiþ[û?»ÅYΟ徕ðÅY}®‘Øb©²F‘Š"…تüUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUÿôuÿbø«ÿÔûëkþòÛÆ$ÿˆŒU_v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®;ìzU„kÖnƒ¯LUäz­µ mŠ¿>ÿç44]GËz’ÿç!<­b·^mü€ÖÓY¸…P™o<½|>¥¬Ù©(hdm•QÈÜäñÏ‚@©}!åHó—t?5hk¡ùŽÂ GI¼N’[ÜÆ$©ØÑ·ŽÙºa©t¯¾]B{b«Âxâ¨iôë+¦Wº´‚åQXÕȰ8Ò¢¢‚8QcŠ5Š4HÔP=€Ûx/æüäßäÿåEëè:ט$×¼éÀµ¯<¹jšÄ¬)ðaø $ƒq$kNùTóF;uM>Eóüä/üäæ÷£åX­?"ü ¬i;-®µæK´©nk-•¨eÞŠ$u?µ˜òË9rØ}©§y[òþ?2ù–}kÉÞ]Ôÿ4¼íz@Ô|ûª]ËzˆÊJ¸Ö/ኄc·«ŽÑPeœbo™Kë¯-Î-^ê“Åsùæ‰.¬J«?”ô-ŒÚKCŸÖgQØÄ-ëûJFÙT²’š}yå/˽Ëe®åÍÏCÒmú>ŸcA ש€ “¹=IÜåIzŽŸå¯³û¿Ãg:–þÏîÿ UœXyp JßeVúdSá F*˜€Q@Àb­â®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š ?ããþŽ¿ì_ÿÕûëkþòÛÆ$ÿˆŒU_v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅRÍNÜM 4­*ò]jÄ©rŽ*ñï4èÖz¶Ÿ¨é:•¤wÚv§o-¦¡e0åÐL†9#uA«òŸògó‰?ç<ÕæoùÇoÎY'°ü¼Ñ5{™,¼òRK‘e¦ßÍ5ŤZ‰›eR J©Æ9}Xä!S’çi³ˆŠ—&$?N4SKÖôëmWDÔ­u.õKÙêv3%Å¼Ê RÑËeaPEAÌû¶ àp«R†9&šE†”¼²¹ ªª*I'`늾Dó§üæw妫]y_òçOÔ9¼Õjx]Åå¯KôE¤•—šÄÌ-ÓjÿuꚊ2‰j" Êiò§ž<ýùÛù‡s%ÿææT•þL†Oô&y"öm<:²ßëRz72’*¬‘ðCØ ¢S”¹š_­(ËŸÊbþSmùqùw—t‹“ÊÿÎzÄ2iðή$ÔCy~O.JÔ°é8ÊHÇ“*}]å?ùů-¬–·þ|½›óPˆ#6Ÿu¶ÐÒe5瘭 qÐu,åNêFS,†I§Öz_•Ò(âŠ((¢P‘ÆŠUTPÀVy§ùoìþïðÅYÆŸåϳû¿ÃfÖ>^T Y@ø«%‚Æ¢‚GsŠ£)M†Ãv*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb¨øøÿ£¯ûÅ_ÿÖûëkþòÛÆ$ÿˆŒU_v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅV²òR§¾*µ‹\öñÅ^_«i\¹|8«ä/ùÈùÇ=ó{N·ºŠEÑüç¡E2èé^qI£ã²¾Š‡Õ¶€HûH~$#âW1•~cj–~wüˆ»ÕA×|ÙùJñÝkžZ¿œyFæU¤YCÏÔ€*õã…ê( 2!1ÐÓg¶˜?ŸwÐDÿÎW\¶žÐ˜˜®ƒå§•€*·"Ó#Çv¯zåüsþw܆«è^]ó…üv?˜šžhüëÕ~¾%µò}þ©6©ܱv LP›r$D€dÊäGñKè_$þG~ajímecùaäí9Ì1Åss^Í´±´‘a·CÕ^Y ñ€Œ®Y«’iôÇÿç|—å+øµ¶µºóG™âb`ó>¼éuw.ÖȑŶÛB$åûUÊe#.i}§ùoìþï"¬ãOòßÙýÞ*Íôÿ.}ŸÝþ«4³ÐcŒà U?ŠÖ@à‚£¹ÅQ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUÿôuÿbø«ÿ×ûëkþòÛÆ$ÿˆŒU_v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š¥÷° šb¬&þÀ5~U‡^é!‹|«¹ÐÁ'àÅ^o}ù-ùu –ûòûË—’¬ßXYgÒ­$a0$‰*Ñʤï×dÚ’tí2´Ó4Û}:Õ)ÂÖÖ$†1@QPÐòÅSÛ,ŠŠGв[?-týÞ*Ì,<¹öwøb¬ÂÓDŠ QÛN£†8…@÷b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®ÅPññÿG_ö/Š¿ÿÐûëkþòÛÆ$ÿˆŒU_v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š­e 8ªSskÊ»b©úxjü8ªW&”¤ýœUKô:“ö? Uˆ§ö1TÚßD]¾ U;ƒM†*T}±TÁUTQT–*»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÑûëkþòÛÆ$ÿˆŒU_v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»ZÊP⪠nJbª_SSØb«–ÑGQAŠ«,(½«Š«b®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUتþ>?èëþÅñWÿÒûëkþòÛÆ$ÿˆŒU_v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Wb®Å]Š»v*ìUØ«±Tü|Ñ×ý‹â¯ÿÙsfact-2011.12.18/calibration/long_full.stl000066400000000000000000002167401167321211700202160ustar00rootroot00000000000000"Boolean_1"; Produced by Art of Illusion 2.6.1, Mon Aug 10 08:35:15 BST 2009 ¶€€¿€ðAwÖ@0AàAwÖ@0AðAwÖ@À@ €¿ðAwÖ@À@àAwÖ@0AlòØAwÖ@À@ _|¿•Ð1>àA F|@0AlòØA F|@À@àAwÖ@0A _|¿•Ð1>àAwÖ@0AlòØA F|@À@lòØAwÖ@À@ €?ðAwÖ@À@lòØAwÖ@À@ðAÀ@ €?ðAÀ@lòØAwÖ@À@žª¤Aͯf;À@ €?fIžAÜ×<À@½{ŸA3ÜÐ>À@‚Ö˜A{ å>À@ €?lòØAwÖ@À@lòØA F|@À@ðçÈA F|@À@ €?ðçÈA F|@À@ðçÈA#¾@À@¸A#¾@À@ €?¸A#¾@À@¸A#þ@À@Ï·šA#þ@À@ €?ŒBàA€AŒBàA€'ŒBXB€A €?šoAˆ?AÀ@7ÿ@WAÀ@0‰@v² AÀ@ €?šoAˆ?AÀ@º‚b@¯kAÀ@7ÿ@WAÀ@ €?šoAˆ?AÀ@zTQ@+^"AÀ@º‚b@¯kAÀ@ €?šoAˆ?AÀ@ðAˆ?AÀ@Ã$²APAÀ@ €?Ã$²APAÀ@ðAˆ?AÀ@=ÛÍAPAÀ@ €?=ÛÍAPAÀ@ðAˆ?AÀ@z¶ÛA€AÀ@ €?ÑÚAɦAÀ@z¶ÛA€AÀ@ ÞAalªAÀ@ €?=ÛÍA˜AÀ@MrÕAh¤AÀ@¦¾ÏA¤Ç¤AÀ@ €?‘ËAå ¨AÀ@=ÛÍA˜AÀ@¦¾ÏA¤Ç¤AÀ@ €?‘ËAå ¨AÀ@Ã$²A˜AÀ@=ÛÍA˜AÀ@ €?‘ËAå ¨AÀ@FYÈAÔ ­AÀ@Ã$²A˜AÀ@ €?Á¨A¤AÀ@†I¤A€AÀ@Ã$²A˜AÀ@ €?Á¨A¤AÀ@ÝÁ‡A¤AÀ@†I¤A€AÀ@ €?ðA(BÀ@àAàAÀ@ðAˆ?AÀ@ €?ðA(BÀ@àABÀ@àAàAÀ@ €?ðA(BÀ@oÞA¼ñBÀ@àABÀ@ €?ðA(BÀ@yãÙA‘gBÀ@oÞA¼ñBÀ@ €?ðA(BÀ@"ÏÒA¼ñBÀ@yãÙA‘gBÀ@ €?ðA(BÀ@yãÉAˆ7BÀ@"ÏÒA¼ñBÀ@ €?ðA(BÀ@ÀA BÀ@yãÉAˆ7BÀ@ €?ðA(BÀ@‡¶Aˆ7BÀ@ÀA BÀ@ €?+µ\A BÀ@((BÀ@Ó<É@ BÀ@ €?Ó<É@ BÀ@((BÀ@'L"@BÀ@ €?'L"@BÀ@((BÀ@(¤AÀ@ €?(¤AÀ@ù Í>|ç¢AÀ@'L"@BÀ@ »qè¾îd?yãÉAxÈB€'yãÉAxÈBÀ@"ÏÒADB€' îd?»q辇¦A‘gB€'‡¦A‘gBÀ@ð¡A¼ñB€' €?'L"@BÀ@ù Í>|ç¢AÀ@Ó<É@ØAÀ@ €?Ó<É@ØAÀ@ù Í>|ç¢AÀ@Š#Ò>5ÒžAÀ@ €?µ§è>R-˜AÀ@Š#Ò>5ÒžAÀ@ÏN=Ö ™AÀ@ ød?’qè>\BÞxŠBEžeAhBÞxŠBEžeA\BÄ›‹BñÆSA €?Š#Ò>5ÒžAÀ@Éߥ<“AÀ@ÏN=Ö ™AÀ@ €?Š#Ò>5ÒžAÀ@µ§è>R-˜AÀ@Ó<É@ØAÀ@ €?»?¨€AÀ@P.ÿ>»”AÀ@<ì?>|'ŽAÀ@ €?hBŒB@AhBû²‹B±\5AhBŒB A ó5?ó5?hB\{‡BLkAtBÉa‰BäÚ[AhBÉa‰BäÚ[A €?P.ÿ>»”AÀ@âÿó=v²’AÀ@<ì?>|'ŽAÀ@ €?€BäBmÊ|A€B¾jxBÄktA€B€BÜFfA |­b?Jïí¾‘ËAõ·A€'‘ËAõ·AÀ@FYÈA,ß²AÀ@ Êh?kaØ>€BÜȈB A†ByŠBúªA€ByŠBúªA €?’“?ÇqAÀ@o¯?¤GzAÀ@˜];?¯kqAÀ@ €?’“?ÇqAÀ@ªçp?¬â}AÀ@o¯?¤GzAÀ@ Üö=+"~?¦¾ÏA¤Ç¤A€'MrÕAh¤AÀ@MrÕAh¤A€' ì”y?¼Ûc¾ÀAàA€' •ÁA1ñæAÀ@ÀAàAÀ@ €?³Ý?ÎßTAÀ@žÓ´?žŒPAÀ@CpÐ?+HAÀ@ øÂX?,3?hBÉa‰BäÚ[AtBÉa‰BäÚ[AtBÇÏŠB§IA €?‘í@òŒHAÀ@³Ý?ÎßTAÀ@CpÐ?+HAÀ@ €?Ñú?ÈoîFw?€BÊUpBB}A†BÊUpBB}A†B¾jxBÄktA €? ”'@À!5AÀ@_A@áAAÀ@² @164AÀ@ €?hBÞx†B Þ|AhB„B€AhBä4…B3~vA |­b?Jïí¾‘ËAõ·A€'FYÈA,ß²AÀ@FYÈA,ß²A€' €?º‚b@¯kAÀ@¢ëQ@ü)AÀ@H1f@ŒAÀ@ ,©>^¢q?tBäBmÊ|A€BäBmÊ|AtB0ñ‚BòRsA €?7ÿ@WAÀ@º‚b@¯kAÀ@H1f@ŒAÀ@ Ÿ?¿¦Á)¿ ÞAŸ“µA€'ÑÚA7à¹AÀ@ÑÚA7à¹A€' €?tBÇÏŠB§IAtB^jŠB‰7AtBû²‹B±\5A €?ƒ¯™@NEþ@À@³ ¤@Ó¤ñ@À@šoAˆAÀ@ €?šoAˆAÀ@³ ¤@Ó¤ñ@À@Ÿœµ@¹¥Ý@À@ €?™ËÀ@½Ñ@À@šoAˆAÀ@Ÿœµ@¹¥Ý@À@ €?™ËÀ@½Ñ@À@§Ó@íõ¾@À@šoAˆAÀ@ Üö=+"~?¦¾ÏA¤Ç¤A€'¦¾ÏA¤Ç¤AÀ@MrÕAh¤AÀ@ êFw?탄>€ByŠBúªA†ByŠBúªA†B©¢‹BO®Â@ -Ù|?}/ >ð¡AD B€' ABÀ@ð¡AD BÀ@ €?³ ¤@Ó¤ñ@À@ú9@½æ@À@˜L©@t^Ø@À@ €?Ÿœµ@¹¥Ý@À@³ ¤@Ó¤ñ@À@˜L©@t^Ø@À@ €?§Ó@íõ¾@À@›ß@„Ó³@À@šoAˆAÀ@ €?šoAˆAÀ@›ß@„Ó³@À@Ÿ¬ó@¸X¢@À@ €?,AÙ˜@À@šoAˆAÀ@Ÿ¬ó@¸X¢@À@ €?,AÙ˜@À@WÄ Aáî‡@À@šoAˆAÀ@ €?,AÙ˜@À@–AAfN€@À@WÄ Aáî‡@À@ €?,AÙ˜@À@éòû@š_‹@À@–AAfN€@À@ €?pÌA°fÐA€'pÌA°fÐAÀ@qÓA°fÐA€' €?t`Ú@,}§@À@¤+è@)y›@À@›ß@„Ó³@À@ êFw?탄>€B©¢‹BO®Â@€ByŠBúªA†B©¢‹BO®Â@ €?Ÿ¬ó@¸X¢@À@›ß@„Ó³@À@¤+è@)y›@À@ €?WÄ Aáî‡@À@}nA­ú|@À@šoAˆAÀ@ €?šoAˆAÀ@}nA­ú|@À@PŠAï¬_@À@ ó5¿ó5¿"ÏÒA¼ñB€'yãÙA‘gBÀ@"ÏÒA¼ñBÀ@ €?qÓA°fÐA€'pÌA°fÐAÀ@qÓA°fÐAÀ@ €?}nA­ú|@À@A©A6c@À@™KAUûN@À@ ¼&Þ¾¹¥f¿qÓAP™ïA€'ÑùÙA`‚ìAÀ@qÓAP™ïAÀ@ €?PŠAï¬_@À@}nA­ú|@À@™KAUûN@À@ €?\BɳˆBñÆsA\BŒB€A\BÞx†B Þ|A €?€B^jŠB‰7A€BÜȈB A€BN™‹B{A }/ >-Ù|?ÀAB€'‡¶AxÈBÀ@ÀABÀ@ €?LBA¦ @À@òj5Ah– @À@§=AÜcõ?À@ €?LBA¦ @À@ßO6AØ*%@À@òj5Ah– @À@ €?€B^jŠB‰7A€B”b†BKj;A€BÜȈB A ì”y?¼Ûc¾ •ÁA1ñæA€' •ÁA1ñæAÀ@ÀAàA€' €?Ï·šA#þ@À@~ojAþ}¢?À@GrAÇF?À@ €?ï,Al?À@GrAÇF?À@Œ•{A•`?À@ €?GrAÇF?À@˹rAóq5?À@Œ•{A•`?À@ €?GrAÇF?À@ï,Al?À@Ï·šA#þ@À@ €?Ï·šA#þ@À@ï,Al?À@´“ƒAHP?À@ €?¾ŠAt{)?À@´“ƒAHP?À@æ„A?WË>À@ €?g„ˆAI–>À@¾ŠAt{)?À@æ„A?WË>À@ €?€BxB€A€B¾jxBÄktA€BäBmÊ|A €?´“ƒAHP?À@¾ŠAt{)?À@Ï·šA#þ@À@ ðÂX?:3?tB^jŠB‰7A€Bb‚ˆB…ÎOA€B^jŠB‰7A »qè>îd¿Þ0­A¼ñB€'‡¶Aˆ7BÀ@Þ0­A¼ñBÀ@ €?‚Ö˜A{ å>À@$¹™A·(3=À@fIžAÜ×<À@ I3?æÂX?tBÐù…B dA€B0ñ‚BòRsA€BÐù…B dA €?àA°AÀ@ðAˆ?AÀ@àAàAÀ@ €?`jÞAÏÙAÀ@àA°AÀ@àAàAÀ@ €?`jÞAÏÙAÀ@ ÞAŸ“µAÀ@àA°AÀ@ €?ÑÚA7à¹AÀ@ÑùÙA }ÓAÀ@MrÕA˜é»AÀ@ €?MrÕA˜é»AÀ@ÑùÙA }ÓAÀ@qÓA°fÐAÀ@ €?¦¾ÏA\8»AÀ@qÓA°fÐAÀ@pÌA°fÐAÀ@ €?‘ËAõ·AÀ@pÌA°fÐAÀ@/ÆA }ÓAÀ@ €?0A¸AÀAÀ@/ÆA }ÓAÀ@ •ÁAÏÙAÀ@ €?Á¨AÜAÀ@ •ÁAÏÙAÀ@ÀAàAÀ@ €? •ÁA1ñæAÀ@Á¨AÜAÀ@ÀAàAÀ@ €?qÓAP™ïAÀ@yãÉAxÈBÀ@pÌAP™ïAÀ@ €?qÓAP™ïAÀ@"ÏÒADBÀ@yãÉAxÈBÀ@ €?qÓAP™ïAÀ@ÑùÙA`‚ìAÀ@"ÏÒADBÀ@ €?"ÏÒADBÀ@ÑùÙA`‚ìAÀ@yãÙAo˜BÀ@ €?yãÙAo˜BÀ@ÑùÙA`‚ìAÀ@`jÞA1ñæAÀ@ €?àABÀ@oÞAD BÀ@àAàAÀ@ €?0A¸AÀAÀ@FYÈA,ß²AÀ@‘ËAõ·AÀ@ €?/ÆA }ÓAÀ@0A¸AÀAÀ@‘ËAõ·AÀ@ €?‘ËAõ·AÀ@¦¾ÏA\8»AÀ@pÌA°fÐAÀ@ €?¦¾ÏA\8»AÀ@MrÕA˜é»AÀ@qÓA°fÐAÀ@ €?0A¸AÀAÀ@ •ÁAÏÙAÀ@Á¨AÜAÀ@ €?Ó<É@ØAÀ@Ñ.oAÀAÀ@+µ\AØAÀ@ €?+µ\AØAÀ@Ñ.oAÀAÀ@ÝÁ‡AÜAÀ@ €?‡¦Ao˜BÀ@ð¡AD BÀ@G`ŒABÀ@ €?G`ŒABÀ@ð¡AD BÀ@ ABÀ@ €?ð¡A¼ñBÀ@G`ŒABÀ@ ABÀ@ €?ð¡A¼ñBÀ@+µ\A BÀ@G`ŒABÀ@ €?ð¡A¼ñBÀ@‡¦A‘gBÀ@+µ\A BÀ@ €?+µ\A BÀ@‡¦A‘gBÀ@Þ0­A¼ñBÀ@ €?‡¶Aˆ7BÀ@+µ\A BÀ@Þ0­A¼ñBÀ@ €¿lòØA F|@À@àA F|@0AðçÈA F|@À@ Ù³]¿úÿÿ>àA#¾@0AðçÈA#¾@À@àA F|@0A Ù³]¿úÿÿ>àA F|@0AðçÈA#¾@À@ðçÈA F|@À@ €¿ðçÈA#¾@À@àA#¾@0A¸A#¾@À@ ó5¿ó5?àA#þ@0A¸A#þ@À@àA#¾@0A ó5¿ó5?àA#¾@0A¸A#þ@À@¸A#¾@À@ €¿¸A#þ@À@àA#þ@0AÏ·šA#þ@À@ ¿Ö³]?àAˆA0AÏ·šAˆAÀ@àA#þ@0A ¿Ö³]?àA#þ@0AÏ·šAˆAÀ@Ï·šA#þ@À@ €¿Ï·šAˆAÀ@àAˆA0AšoAˆAÀ@ ¾êFw?àAˆ?A0AšoAˆ?AÀ@àAˆA0A ¾êFw?àAˆA0AšoAˆ?AÀ@šoAˆAÀ@ €?ðAˆ?A0AðAˆ?AÀ@àAˆ?A0A €?àAˆ?A0AðAˆ?AÀ@šoAˆ?AÀ@ €?ðAˆ?A0AàA#þ@0AðAwÖ@0A €?ðAˆ?A0AàAˆA0AàA#þ@0A €?ðAˆ?A0AàAˆ?A0AàAˆA0A €?àA#þ@0AàA#¾@0AðAwÖ@0A €?ðAwÖ@0AàA#¾@0AàA F|@0A €?àAwÖ@0AðAwÖ@0AàA F|@0A €¿ðAwÖ@À@ðAÀ@ðAwÖ@0A €¿ðAwÖ@0AðAÀ@ðA€A €¿ðAˆ?A0AðA€AðA0B€A €¿ðA(BÀ@ðA0B€AðA0B€' €¿ðA(B€'ðA(BÀ@ðA0B€' €¿ðAwÖ@0AðA€AðAˆ?A0A šaØ>¿h?€B¾jxBÄktA†B€BÜFfA€B€BÜFfA ˆx¿öu> ÞAalªA€' ÞAalªAÀ@àA°A€' {&(¿EA¿t`Ú@,}§@€'¤+è@)y›@À@t`Ú@,}§@À@ {&(¿EA¿t`Ú@,}§@€'¤+è@)y›@€'¤+è@)y›@À@ }§4¿9b5¿È·Ç@߸@€'È·Ç@߸@À@tÁº@ ÈÅ@€' }§4¿9b5¿tÁº@ ÈÅ@€'È·Ç@߸@À@tÁº@ ÈÅ@À@ žl?¯R?‘ËAå ¨A€'‘ËAå ¨AÀ@¦¾ÏA¤Ç¤AÀ@ Êh?kaØ>€BÜȈB A†BÜȈB A†ByŠBúªA î³Q?ïÕ?€B”b†BKj;A†B”b†BKj;A†BÜȈB A |­b?Jïí>FYÈAÔ ­A€'FYÈAÔ ­AÀ@‘ËAå ¨AÀ@ €?tBä4…B3~vAtB0ñ‚BòRsAtBÐù…B dA ËZ@¿Óì(¿ú9@½æ@€'˜L©@t^Ø@À@ú9@½æ@À@ -Ù|?}/ ¾ AB€'ð¡A¼ñBÀ@ ABÀ@ îd?»qè¾ð¡A¼ñB€'‡¦A‘gBÀ@ð¡A¼ñBÀ@ ËZ@¿Óì(¿˜L©@t^Ø@€'˜L©@t^Ø@À@ú9@½æ@€' €?tBÇÏŠB§IAtBÉa‰BäÚ[AtBb‚ˆB…ÎOA »2K¿€¶¿·ë@º,A€'Ð @„Óù@À@·ë@º,AÀ@ Ÿ?¿¦Á)¿€ ÞAŸ“µAÀ@ÑÚA7à¹AÀ@ ÞAŸ“µA€' ˆx¿öu¾€ ÞAŸ“µAÀ@ ÞAŸ“µA€'àA°AÀ@ »2K¿€¶¿Ð @„Óù@€'Ð @„Óù@À@·ë@º,A€' à5?5?tBÐù…B dA€BÐù…B dAtBb‚ˆB…ÎOA "U¿éÎ ¿¢ëQ@ü)A€'H1f@ŒAÀ@¢ëQ@ü)AÀ@ žl?¯R¿¦¾ÏA\8»A€'‘ËAõ·AÀ@‘ËAõ·A€' Üö=+"~¿MrÕA˜é»A€'¦¾ÏA\8»AÀ@¦¾ÏA\8»A€' "U¿éÎ ¿H1f@ŒA€'H1f@ŒAÀ@¢ëQ@ü)A€' €?hB–«‚B×—}AhB„B€AhB€B€A €?hBÞx†B Þ|AhBä4…B3~vAhB\{‡BLkA ^¿ùŠþ¾é$@ò(A€'i7@Í!AÀ@é$@ò(AÀ@ ì”y¿¼Ûc>`jÞAÏÙA€'`jÞAÏÙAÀ@àAàA€' ^¿ùŠþ¾i7@Í!A€'i7@Í!AÀ@é$@ò(A€' áÕ?ø³Q?€B€BÜFfA†B€BÜFfA†BImƒBšSA rf¿&Uà¾Ñú?Èo¹¥f¿/ÆA`‚ìA€'pÌAP™ïAÀ@/ÆA`‚ìAÀ@ m¿7 Á¾CpÐ?+HA€'CpÐ?+HAÀ@žÓ´?žŒPA€' €?tBä4…B3~vAtB–«‚B×—}AtB0ñ‚BòRsA (s¿{¡¾Ùu?Ä1eA€'z‰‘?!‚\AÀ@Ùu?Ä1eAÀ@ žl?¯R?‘ËAå ¨A€'¦¾ÏA¤Ç¤AÀ@¦¾ÏA¤Ç¤A€' |­b?Jïí>FYÈAÔ ­A€'‘ËAå ¨AÀ@‘ËAå ¨A€' (s¿{¡¾z‰‘?!‚\A€'z‰‘?!‚\AÀ@Ùu?Ä1eA€' #Öw¿ED€¾˜];?¯kqA€'˜];?¯kqAÀ@o¯?¤GzA€' #Öw¿ED€¾o¯?¤GzA€'˜];?¯kqAÀ@o¯?¤GzAÀ@ ød?’qè>\BÄ›‹BñÆSAhBÞxŠBEžeAhBÄ›‹BñÆSA î³Q?ïÕ?€B”b†BKj;A†BÜȈB A€BÜȈB A ë5?û5?€BImƒBšSA†B”b†BKj;A€B”b†BKj;A 5?ß5?\BÞxŠBEžeAhBɳˆBñÆsAhBÞxŠBEžeA ;{¿¢Ð=¾†mÔ> \ƒA€'†mÔ> \ƒAÀ@1%ž>Û‡A€' ;{¿¢Ð=¾1%ž>Û‡A€'†mÔ> \ƒAÀ@1%ž>Û‡AÀ@ žl?¯R¿¦¾ÏA\8»A€'¦¾ÏA\8»AÀ@‘ËAõ·AÀ@ €?€BxB€A€BÊUpBB}A€B¾jxBÄktA €?€BhB€A€BÊUpBB}A€BxB€A Üö=+"~¿MrÕA˜é»A€'MrÕA˜é»AÀ@¦¾ÏA\8»AÀ@ / >-Ù|?\BÞx†B Þ|AhB„B€AhBÞx†B Þ|A €?hBÇÏŠB§IAhBû²‹B±\5AhBŒB@A C+~¿Óô½âÿó=v²’A€'<ì?>|'ŽAÀ@âÿó=v²’AÀ@ 3?ÃX?hBä4…B3~vAtB\{‡BLkAhB\{‡BLkA Ü©>?¢q?hB–«‚B×—}AtBä4…B3~vAhBä4…B3~vA C+~¿Óô½<ì?>|'ŽA€'<ì?>|'ŽAÀ@âÿó=v²’A€' €?hBÄ›‹BñÆSAhBÉa‰BäÚ[AhBÇÏŠB§IA øÂX?,3?hBÉa‰BäÚ[AtBÇÏŠB§IAhBÇÏŠB§IA S¤¿ä’X½Éߥ<“A€'ÏN=Ö ™AÀ@Éߥ<“AÀ@ 5?ß5?\BɳˆBñÆsAhBɳˆBñÆsA\BÞxŠBEžeA šqè>öd?\BÞx†B Þ|AhBÞx†B Þ|A\BɳˆBñÆsA S¤¿ä’X½ÏN=Ö ™A€'ÏN=Ö ™AÀ@Éߥ<“A€' »qè>îd¿‡¶Aˆ7B€'‡¶Aˆ7BÀ@Þ0­A¼ñB€' ó5?ó5¿Þ0­A¼ñB€'Þ0­A¼ñBÀ@‡¦A‘gB€' -Ù|¿}/ >oÞAD B€'oÞAD BÀ@àAB€' }/ ¾-Ù|?ÀAB€'ÀABÀ@yãÉAxÈB€' }/ >-Ù|?‡¶AxÈB€'‡¶AxÈBÀ@ÀAB€' ,©>^¢q?tB0ñ‚BòRsA€BäBmÊ|A€B0ñ‚BòRsA ™Nå=éc~?tBäBmÊ|A€BxB€A€BäBmÊ|A -Ù|?}/ > AB€' ABÀ@ð¡AD B€' Ç^º%€?àè!B€Br×…Aàè!BŒBr×…A¹ëBŒBr×…A îd?»qè>ð¡AD B€'ð¡AD BÀ@‡¦Ao˜B€' æH½Ï±¿€$¹™A·(3=À@$¹™A·(3=€'fIžAÜ×<À@ æH½Ï±¿€fIžAÜ×<À@$¹™A·(3=€'fIžAÜ×<€' »qè¾îd?"ÏÒADB€'yãÉAxÈBÀ@"ÏÒADBÀ@ ó5¿ó5?yãÙAo˜B€'"ÏÒADBÀ@yãÙAo˜BÀ@ }/ >-Ù|¿‡¶Aˆ7B€'ÀA BÀ@‡¶Aˆ7BÀ@ }/ ¾-Ù|¿ÀA B€'yãÉAˆ7BÀ@ÀA BÀ@ ]Aì½yJ~¿€d]“Aw¾ß=À@oÓŽAæW3>€'d]“Aw¾ß=€' à5?5?tBb‚ˆB…ÎOA€BÐù…B dA€Bb‚ˆB…ÎOA ]Aì½yJ~¿€oÓŽAæW3>À@oÓŽAæW3>€'d]“Aw¾ß=À@ €?€BÐù…B dA€B0ñ‚BòRsA€BImƒBšSA €?€BÐù…B dA€BImƒBšSA€Bb‚ˆB…ÎOA ˆx¿öu> ÞAalªAÀ@àA°AÀ@àA°A€' ¿9¾ÎÀ{¿g„ˆAI–>€'æ„A?WË>À@æ„A?WË>€' ¿9¾ÎÀ{¿g„ˆAI–>€'g„ˆAI–>À@æ„A?WË>À@ ˆx¿öu¾àA°A€'àA°AÀ@ ÞAŸ“µA€' €?tBŒBAtBŒB AtBN™‹B{A W¢q?T©>tB^jŠB‰7A€B^jŠB‰7AtBN™‹B{A ¦ˆ|¾Óx¿€Œ•{A•`?À@˹rAóq5?€'Œ•{A•`?€' }/ ¾-Ù|¿yãÉAˆ7B€'yãÉAˆ7BÀ@ÀA B€' -Ù|¿}/ >àAB€'oÞAD BÀ@àABÀ@ ¦ˆ|¾Óx¿€Ë¹rAóq5?À@˹rAóq5?€'Œ•{A•`?À@ €?€Bb‚ˆB…ÎOA€B”b†BKj;A€B^jŠB‰7A €?€BImƒBšSA€B”b†BKj;A€Bb‚ˆB…ÎOA ¼&Þ>¹¥f¿pÌAP™ïA€'pÌAP™ïAÀ@/ÆA`‚ìA€' â%H?O¿/ÆA`‚ìA€'/ÆA`‚ìAÀ@ •ÁA1ñæA€' Ÿ¾ØSs¿É]Aïæ?€'’yfA›Zn?À@É]Aïæ?À@ Ÿ¾ØSs¿É]Aïæ?€'’yfA›Zn?€'’yfA›Zn?À@ !4¿¾¢zm¿€·QIA%Ì?À@·QIA%Ì?€'âÌQAªÔ°?À@ !4¿¾¢zm¿€âÌQAªÔ°?À@·QIA%Ì?€'âÌQAªÔ°?€' €?€BN™‹B{A€ByŠBúªA€BŒBA ¼&Þ¾¹¥f?ÑùÙA }ÓA€'qÓA°fÐAÀ@ÑùÙA }ÓAÀ@ €?€BŒB€@€BŒBA€B©¢‹BO®Â@ €?€BŒBA€ByŠBúªA€B©¢‹BO®Â@ U{Þ¾U‘f¿€§=AÜcõ?À@òj5Ah– @€'§=AÜcõ?€' U{Þ¾U‘f¿§=AÜcõ?À@òj5Ah– @À@òj5Ah– @€' »qè>îd?‡¶AxÈB€'Þ0­ADBÀ@‡¶AxÈBÀ@ ó5¿ó5¿yãÙA‘gB€'yãÙA‘gBÀ@"ÏÒA¼ñB€' aÀü¾ã¡^¿€A*AÇF"@À@u+"A2U4@€'A*AÇF"@€' €?\BÄ›‹BñÆSA\BŒB€A\BÞxŠBEžeA €?\BÞxŠBEžeA\BŒB€A\BɳˆBñÆsA aÀü¾ã¡^¿€u+"A2U4@À@u+"A2U4@€'A*AÇF"@À@ â%H?O?/ÆA }ÓA€' •ÁAÏÙAÀ@/ÆA }ÓAÀ@ ¼&Þ>¹¥f?pÌA°fÐA€'/ÆA }ÓAÀ@pÌA°fÐAÀ@ Œò ¿y´U¿€A©A6c@À@A©A6c@€'™KAUûN@À@ Œò ¿y´U¿€™KAUûN@À@A©A6c@€'™KAUûN@€' â%H¿O¿`jÞA1ñæAÀ@ÑùÙA`‚ìAÀ@ÑùÙA`‚ìA€' ¼&Þ¾¹¥f¿ÑùÙA`‚ìA€'ÑùÙA`‚ìAÀ@qÓAP™ïA€' 3?ÃX?hBä4…B3~vAtBä4…B3~vAtB\{‡BLkA Lä¿$ÓK¿éòû@š_‹@€'–AAfN€@À@éòû@š_‹@À@ ¼&Þ>¹¥f?/ÆA }ÓA€'/ÆA }ÓAÀ@pÌA°fÐA€' â%H?O? •ÁAÏÙA€' •ÁAÏÙAÀ@/ÆA }ÓA€' Lä¿$ÓK¿–AAfN€@€'–AAfN€@À@éòû@š_‹@€' €?†BFž}B»OA†B€BÜFfA†B.uBüdA +Øq¿oå§>éòû@š_‹@€'éòû@š_‹@À@,AÙ˜@€' +Øq¿oå§>,AÙ˜@€'éòû@š_‹@À@,AÙ˜@À@ ;èv¿ñ>‡>A©A6c@€'A©A6c@À@}nA­ú|@€' ;èv¿ñ>‡>}nA­ú|@€'A©A6c@À@}nA­ú|@À@ ý³k¿ëÌÇ>t`Ú@,}§@€'t`Ú@,}§@À@›ß@„Ó³@€' ý³k¿ëÌÇ>›ß@„Ó³@€'t`Ú@,}§@À@›ß@„Ó³@À@ fM\¿$e?ú9@½æ@€'ú9@½æ@À@³ ¤@Ó¤ñ@€' fM\¿$e?³ ¤@Ó¤ñ@€'ú9@½æ@À@³ ¤@Ó¤ñ@À@ ûl¿q‰=·QIA%Ì?€'·QIA%Ì?À@¦ÄIAwÖ@€' ûl¿q‰=¦ÄIAwÖ@€'·QIA%Ì?À@¦ÄIAwÖ@À@ ÁS¿¾Î?·ë@º,A€'·ë@º,AÀ@0‰@v² A€' ÁS¿¾Î?0‰@v² A€'·ë@º,AÀ@0‰@v² AÀ@ ¡ùH¿`’?¢ëQ@ü)A€'¢ëQ@ü)AÀ@º‚b@¯kA€' ¡ùH¿`’?º‚b@¯kA€'¢ëQ@ü)AÀ@º‚b@¯kAÀ@ €¿ˆa9É]Aïæ?€'É]Aïæ?À@{É]ACÃ?€' €¿ˆa9{É]ACÃ?€'É]Aïæ?À@{É]ACÃ?À@ àn¿Í7ˆ½Ë¹rAóq5?€'˹rAóq5?À@GrAÇF?€' àn¿Í7ˆ½GrAÇF?€'˹rAóq5?À@GrAÇF?À@ &g%¿?dC?žÓ´?žŒPA€'žÓ´?žŒPAÀ@³Ý?ÎßTA€' &g%¿?dC?³Ý?ÎßTA€'žÓ´?žŒPAÀ@³Ý?ÎßTAÀ@ ìþ¿OþM?Ùu?Ä1eA€'Ùu?Ä1eAÀ@¿˜¥?"+iA€' ìþ¿OþM?¿˜¥?"+iA€'Ùu?Ä1eAÀ@¿˜¥?"+iAÀ@ Jé ¿B­W?o¯?¤GzA€'o¯?¤GzAÀ@ªçp?¬â}A€' Jé ¿B­W?ªçp?¬â}A€'o¯?¤GzAÀ@ªçp?¬â}AÀ@ +lö¾/f`?1%ž>Û‡A€'1%ž>Û‡AÀ@´ï,?fw‰A€' +lö¾/f`?´ï,?fw‰A€'1%ž>Û‡AÀ@´ï,?fw‰AÀ@ çïv¿à‡¾$¹™A·(3=€'$¹™A·(3=À@‚Ö˜A{ å>€' çïv¿à‡¾‚Ö˜A{ å>€'$¹™A·(3=À@‚Ö˜A{ å>À@ í×¾ßh?âÿó=v²’A€'âÿó=v²’AÀ@P.ÿ>»”A€' í×¾ßh?P.ÿ>»”A€'âÿó=v²’AÀ@P.ÿ>»”AÀ@ Máq¿Å°§¾žª¤Aͯf;€'žª¤Aͯf;À@‘£AúÕÌ>€' Máq¿Å°§¾‘£AúÕÌ>€'žª¤Aͯf;À@‘£AúÕÌ>À@ Xx¸¾ŒÎn?Éߥ<“A€'Éߥ<“AÀ@Š#Ò>5ÒžA€' Xx¸¾ŒÎn?Š#Ò>5ÒžA€'Éߥ<“AÀ@Š#Ò>5ÒžAÀ@ –±¥¾O9r¿€(¤AÀ@(¤A€'ù Í>|ç¢AÀ@ –±¥¾O9r¿€ù Í>|ç¢AÀ@(¤A€'ù Í>|ç¢A€' €¿ðA(B€'yãÙA‘gB€'"ÏÒA¼ñB€' €¿yãÉAˆ7B€'ðA(B€'"ÏÒA¼ñB€' €¿yãÉAˆ7B€'ÀA B€'ðA(B€' €¿ðA(B€'ÀA B€'‡¶Aˆ7B€' €¿+µ\A B€'‡¶Aˆ7B€'Þ0­A¼ñB€' €¿‡¦A‘gB€'+µ\A B€'Þ0­A¼ñB€' €¿‡¦A‘gB€'ð¡A¼ñB€'+µ\A B€' €¿+µ\A B€'ð¡A¼ñB€' AB€' €¿G`ŒAB€' AB€'ð¡AD B€' €¿‡¦Ao˜B€'G`ŒAB€'ð¡AD B€' €¿‡¦Ao˜B€'Þ0­ADB€'G`ŒAB€' €¿ÝÁ‡AÜA€'+µ\AØA€'G`ŒAB€' €¿ÝÁ‡AÜA€'Ñ.oAÀA€'+µ\AØA€' €€€¿+µ\AØA€'Ñ.oAÀA€'Ó<É@ØA€' €¿µ§è>R-˜A€'Ó<É@ØA€'P.ÿ>»”A€' €¿µ§è>R-˜A€'Š#Ò>5ÒžA€'Ó<É@ØA€' €?hBÄ›‹BñÆSAhBÇÏŠB§IAhBŒB@A €¿ðA(B€'‡¶Aˆ7B€'+µ\A B€' €¿((B€'+µ\A B€'Ó<É@ B€' €¿'L"@B€'((B€'Ó<É@ B€' €¿'L"@B€'(¤A€'((B€' ó5¿ó5?"ÏÒADB€'"ÏÒADBÀ@yãÙAo˜B€' »qè>îd?Þ0­ADB€'Þ0­ADBÀ@‡¶AxÈB€' €¿+µ\A B€' AB€'G`ŒAB€' €¿ÀAàA€'Á¨AÜA€' •ÁA1ñæA€' €¿ÀAàA€' •ÁAÏÙA€'Á¨AÜA€' €¿Á¨AÜA€' •ÁAÏÙA€'0A¸AÀA€' €¿0A¸AÀA€' •ÁAÏÙA€'/ÆA }ÓA€' €¿pÌA°fÐA€'¦¾ÏA\8»A€'‘ËAõ·A€' €¿pÌA°fÐA€'qÓA°fÐA€'¦¾ÏA\8»A€' €¿¦¾ÏA\8»A€'qÓA°fÐA€'MrÕA˜é»A€' €¿MrÕA˜é»A€'qÓA°fÐA€'ÑùÙA }ÓA€' €¿ÑÚA7à¹A€'ÑùÙA }ÓA€'`jÞAÏÙA€' €¿àA°A€' B)–øA€' B£XÂ@€' €¿ÑÚAɦA€'z¶ÛA€A€'=ÛÍA˜A€' €¿MrÕAh¤A€'=ÛÍA˜A€'¦¾ÏA¤Ç¤A€' €¿MrÕAh¤A€'ÑÚAɦA€'=ÛÍA˜A€' €¿ •ÁA1ñæA€'‡¶AxÈB€'/ÆA`‚ìA€' €¿/ÆA`‚ìA€'‡¶AxÈB€'ÀAB€' €¿pÌAP™ïA€'ÀAB€'yãÉAxÈB€' €¿qÓAP™ïA€'yãÉAxÈB€'"ÏÒADB€' €¿ÑùÙA`‚ìA€'"ÏÒADB€'yãÙAo˜B€' €¿àAàA€' B)–øA€'`jÞAÏÙA€' €¿àAàA€'`jÞA1ñæA€' B)–øA€' €¿/ÆA`‚ìA€'ÀAB€'pÌAP™ïA€' €¿pÌAP™ïA€'yãÉAxÈB€'qÓAP™ïA€' €¿qÓAP™ïA€'"ÏÒADB€'ÑùÙA`‚ìA€' €¿ B)–øA€'oÞAD B€' BÛ¼B€' €¿B)–øA€' BÛ¼B€'B)–øA€' €¿B£XÂ@€'B)–øA€'B£XÂ@€' €¿žª¤Aͯf;€'B£XÂ@€'B£XÂ@€' €?†BoŠBz7ž@†B©¢‹BO®Â@†B ƒˆBqqè@ €¿z¶ÛA€A€' B£XÂ@€'=ÛÍAPA€' €¿`jÞA1ñæA€'ÑùÙA`‚ìA€'yãÙAo˜B€' €¿MrÕA˜é»A€'ÑùÙA }ÓA€'ÑÚA7à¹A€' €¿ ÞAŸ“µA€'ÑÚA7à¹A€'`jÞAÏÙA€' €¿‘ËAõ·A€'FYÈA,ß²A€'0A¸AÀA€' €¿Á¨A¤A€'FYÈAÔ ­A€'Ã$²A˜A€' €¿†I¤A€A€'Á¨A¤A€'Ã$²A˜A€' €¿†I¤A€A€'ÝÁ‡A¤A€'Á¨A¤A€' €¿†I¤A€A€'Ÿœµ@¹¥Ý@€'ÝÁ‡A¤A€' €¿†I¤A€A€',AÙ˜@€'Ÿ¬ó@¸X¢@€' €¿†I¤A€A€'Ã$²APA€'P#Aú›N@€' €¿u+"A2U4@€'ó/A.V4@€'A*AÇF"@€' €¿u+"A2U4@€'P#Aú›N@€'ó/A.V4@€' €¿FYÈAÔ ­A€'‘ËAå ¨A€'Ã$²A˜A€' €¿Ã$²A˜A€'‘ËAå ¨A€'=ÛÍA˜A€' €¿=ÛÍA˜A€'‘ËAå ¨A€'¦¾ÏA¤Ç¤A€' €¿ÑÚAɦA€' ÞAalªA€'z¶ÛA€A€' Ç '€? 2BŒBr×…A 2B€Br×…AG=BŒBr×…A -Ù|?}/ ¾ð¡A¼ñB€'ð¡A¼ñBÀ@ AB€' ™Nå=éc~?tBxB€A€BxB€AtBäBmÊ|A €¿ÝÁ‡A¤A€'Ÿœµ@¹¥Ý@€'³ ¤@Ó¤ñ@€' ó5?ó5¿‡¦A‘gB€'Þ0­A¼ñBÀ@‡¦A‘gBÀ@ €¿ðA(B€'+µ\A B€'((B€' €¿ BÛ¼WB€'ðAHB€'ðApB€' €¿ BÛ¼WB€' BÛ¼KB€'ðAHB€' €¿ðAHB€' BÛ¼KB€' BÛ¼IB€' €¿ðA@B€' BÛ¼IB€' BÛ¼=B€' €¿pBÛ¼IB€'pBÛ¼KB€'ŒBŒB€' €¿ŒBàA€'pBÛ¼9B€'pBÛ¼=B€' €¿ŒBàA€'pBÛ¼-B€'pBÛ¼9B€' €¿ŒBàA€'pBÛ¼'B€'pBÛ¼-B€' €¿ŒBàA€'pBÛ¼B€'pBÛ¼'B€' €¿ŒBàA€'pBÛ¼B€'pBÛ¼B€' €¿ŒBàA€'pBÛ¼B€'pBÛ¼B€' €¿ŒBàA€'hBàA€'pBÛ¼B€' €¿pBÛ¼B€'hBàA€'\B)–øA€' €¿PB)–øA€'pBÛ¼B€'\B)–øA€' €¿PB)–øA€'HB)–øA€'pBÛ¼B€' €¿PB)–øA€'HB£XÂ@€'HB)–øA€' €¿PB)–øA€'PB£XÂ@€'HB£XÂ@€' €¿HB£XÂ@€'PB£XÂ@€'hB€' €€€¿?¢q?hB–«‚B×—}AtB–«‚B×—}AtBä4…B3~vA €¿WÄ Aáî‡@€'–AAfN€@€'éòû@š_‹@€' ì”y?¼Ûc>ÀAàA€'ÀAàAÀ@ •ÁAÏÙA€' €¿,AÙ˜@€'WÄ Aáî‡@€'éòû@š_‹@€' Õƒ„>îFw?€BÊUpBB}A†B¾jxBÄktA€B¾jxBÄktA €¿›ß@„Ó³@€'¤+è@)y›@€'t`Ú@,}§@€' €¿›ß@„Ó³@€'Ÿ¬ó@¸X¢@€'¤+è@)y›@€' €?FYÈA,ß²A€'FYÈA,ß²AÀ@FYÈAÔ ­AÀ@ ë5?û5?€BImƒBšSA†BImƒBšSA†B”b†BKj;A €?tBä4…B3~vAtBÐù…B dAtB\{‡BLkA €?tBÇÏŠB§IAtBb‚ˆB…ÎOAtB^jŠB‰7A €¿ƒ¯™@NEþ@€'Ð @„Óù@€'·ë@º,A€' €?\BÞx†B Þ|A\BŒB€A\B„B€A €¿0‰@v² A€'ƒ¯™@NEþ@€'·ë@º,A€' I3?æÂX?tB0ñ‚BòRsA€B0ñ‚BòRsAtBÐù…B dA €¿7ÿ@WA€'H1f@ŒA€'¢ëQ@ü)A€' ³µ¾n]o¿ÑÚA7à¹A€'MrÕA˜é»AÀ@MrÕA˜é»A€' €¿º‚b@¯kA€'7ÿ@WA€'¢ëQ@ü)A€' €?hBä4…B3~vAhB„B€AhB–«‚B×—}A €¿zTQ@+^"A€'i7@Í!A€'é$@ò(A€' ¼&Þ¾¹¥f?qÓA°fÐA€'qÓA°fÐAÀ@ÑùÙA }ÓA€' €¿ÊÝ6@âé-A€'zTQ@+^"A€'é$@ò(A€' šaØ>¿h?€B¾jxBÄktA†B¾jxBÄktA†B€BÜFfA €?hBÄ›‹BñÆSAhBÞxŠBEžeAhBÉa‰BäÚ[A M¢q?Œ©>hBÇÏŠB§IAtBÇÏŠB§IAtBû²‹B±\5A €¿‘í@òŒHA€'CpÐ?+HA€'žÓ´?žŒPA€' €¿pÌAP™ïA€'qÓAP™ïAÀ@pÌAP™ïAÀ@ €¿³Ý?ÎßTA€'‘í@òŒHA€'žÓ´?žŒPA€' €?tBäBmÊ|AtB€B€AtBxB€A €?FYÈA,ß²A€'FYÈAÔ ­AÀ@FYÈAÔ ­A€' €¿˜];?¯kqA€'o¯?¤GzA€'’“?ÇqA€' šqè>öd?\BɳˆBñÆsAhBÞx†B Þ|AhBɳˆBñÆsA áÕ?ø³Q?€B€BÜFfA†BImƒBšSA€BImƒBšSA €¿ªçp?¬â}A€'’“?ÇqA€'o¯?¤GzA€' ³µ¾n]o¿ÑÚA7à¹A€'ÑÚA7à¹AÀ@MrÕA˜é»AÀ@ €¿´ï,?fw‰A€'Ñ.oAÀA€'ÂgT?¦í‚A€' M¢q?Œ©>hBû²‹B±\5AhBÇÏŠB§IAtBû²‹B±\5A / >-Ù|?\B„B€AhB„B€A\BÞx†B Þ|A €¿Š#Ò>5ÒžA€'ù Í>|ç¢A€'Ó<É@ØA€' }/ >-Ù|¿ÀA B€'ÀA BÀ@‡¶Aˆ7B€' €¿pB€'ŒB€'ðApB€' ‰ô£*g·¤€¿ðApB€'ŒB€'†BŒB' €€€¿hBàA€'hBÂA€'\B)–øA€' €¿\B)–øA€'hBÂA€'hB&±A€' €¿hB&±A€'hBÂA€'ŒBÂA€' W¢q?T©>tBN™‹B{A€B^jŠB‰7A€BN™‹B{A }/ ¾-Ù|?yãÉAxÈB€'ÀABÀ@yãÉAxÈBÀ@ €¿‚Ö˜A{ å>€'fIžAÜ×<€'$¹™A·(3=€' €¿‚Ö˜A{ å>€'½{ŸA3ÜÐ>€'fIžAÜ×<€' »qè¾îd¿yãÉAˆ7B€'"ÏÒA¼ñBÀ@yãÉAˆ7BÀ@ €¿ï,Al?€'˹rAóq5?€'GrAÇF?€' €¿ï,Al?€'Œ•{A•`?€'˹rAóq5?€' »qè¾îd¿"ÏÒA¼ñB€'"ÏÒA¼ñBÀ@yãÉAˆ7B€' €¿g„ˆAI–>€'æ„A?WË>€'¾ŠAt{)?€' €?€B0ñ‚BòRsA€B€BÜFfA€BImƒBšSA €¿´“ƒAHP?€'¾ŠAt{)?€'æ„A?WË>€' ðÂX?:3?tBb‚ˆB…ÎOA€Bb‚ˆB…ÎOAtB^jŠB‰7A €¿ËVAÕìÙ?€'Ã$²APA€'{É]ACÃ?€' ì”y¿¼Ûc>àAàA€'`jÞAÏÙAÀ@àAàAÀ@ €¿’yfA›Zn?€'É]Aïæ?€'~ojAþ}¢?€' €¿qÓAP™ïA€'qÓAP™ïAÀ@pÌAP™ïA€' €?€BäBmÊ|A€B€BÜFfA€B0ñ‚BòRsA €¿{É]ACÃ?€'~ojAþ}¢?€'É]Aïæ?€' €¿§=AÜcõ?€'òj5Ah– @€'LBA¦ @€' îd?»qè>‡¦Ao˜B€'ð¡AD BÀ@‡¦Ao˜BÀ@ €?€BN™‹B{A€BÜȈB A€ByŠBúªA €¿ßO6AØ*%@€'LBA¦ @€'òj5Ah– @€' €?\BŒB@A\BŒB€A\BÄ›‹BñÆSA â%H¿O¿€`jÞA1ñæAÀ@ÑùÙA`‚ìA€'`jÞA1ñæA€' €¿PŠAï¬_@€'™KAUûN@€'A©A6c@€' ì”y?¼Ûc> •ÁAÏÙA€'ÀAàAÀ@ •ÁAÏÙAÀ@ €¿}nA­ú|@€'PŠAï¬_@€'A©A6c@€' h?{Ö¾d]“Aw¾ß=À@d]“Aw¾ß=€'ŒÄ”Afû>À@ h?{Ö¾ŒÄ”Afû>À@d]“Aw¾ß=€'ŒÄ”Afû>€' O¨½á"¿‚Ö˜A{ å>€'‚Ö˜A{ å>À@ŒÄ”Afû>€' O¨½á"¿ŒÄ”Afû>€'‚Ö˜A{ å>À@ŒÄ”Afû>À@ ‘M?.Ã[¿¤+è@)y›@À@¤+è@)y›@€'Ÿ¬ó@¸X¢@À@ ‘M?.Ã[¿Ÿ¬ó@¸X¢@À@¤+è@)y›@€'Ÿ¬ó@¸X¢@€' 2š!¿ä‹F¿,AÙ˜@€',AÙ˜@À@Ÿ¬ó@¸X¢@€' 2š!¿ä‹F¿Ÿ¬ó@¸X¢@€',AÙ˜@À@Ÿ¬ó@¸X¢@À@ zD?x˜$¿âÌQAªÔ°?À@âÌQAªÔ°?€'ËVAÕìÙ?À@ zD?x˜$¿ËVAÕìÙ?À@âÌQAªÔ°?€'ËVAÕìÙ?€' 8¯¾ÓŠp¿{É]ACÃ?€'{É]ACÃ?À@ËVAÕìÙ?€' 8¯¾ÓŠp¿ËVAÕìÙ?€'{É]ACÃ?À@ËVAÕìÙ?À@ Y/o?û¶¾fIžAÜ×<À@fIžAÜ×<€'½{ŸA3ÜÐ>À@ Y/o?û¶¾½{ŸA3ÜÐ>À@fIžAÜ×<€'½{ŸA3ÜÐ>€' „C|¼;ø¿‘£AúÕÌ>€'‘£AúÕÌ>À@½{ŸA3ÜÐ>€' „C|¼;ø¿½{ŸA3ÜÐ>€'‘£AúÕÌ>À@½{ŸA3ÜÐ>À@ Wh,?W==¿A*AÇF"@À@A*AÇF"@€'ó/A.V4@À@ Wh,?W==¿ó/A.V4@À@A*AÇF"@€'ó/A.V4@€' š¸í¾Ô»b¿ßO6AØ*%@€'ßO6AØ*%@À@ó/A.V4@€' š¸í¾Ô»b¿ó/A.V4@€'ßO6AØ*%@À@ó/A.V4@À@ Y»i¿³Ûо_A@áAA€'_A@áAAÀ@‘í@òŒHA€' Y»i¿³Ûо‘í@òŒHA€'_A@áAAÀ@‘í@òŒHAÀ@ 'F‰>Ž v¿H1f@ŒAÀ@H1f@ŒA€'7ÿ@WAÀ@ 'F‰>Ž v¿7ÿ@WAÀ@H1f@ŒA€'7ÿ@WA€' ´FP¿6Ú¿0‰@v² A€'0‰@v² AÀ@7ÿ@WA€' ´FP¿6Ú¿7ÿ@WA€'0‰@v² AÀ@7ÿ@WAÀ@ o>X?8 ¿Œ•{A•`?À@Œ•{A•`?€'ï,Al?À@ o>X?8 ¿ï,Al?À@Œ•{A•`?€'ï,Al?€' …5[¾¿z¿´“ƒAHP?€'´“ƒAHP?À@ï,Al?€' …5[¾¿z¿ï,Al?€'´“ƒAHP?À@ï,Al?À@  P>,¨z¿i7@Í!AÀ@i7@Í!A€'zTQ@+^"AÀ@  P>,¨z¿zTQ@+^"AÀ@i7@Í!A€'zTQ@+^"A€' ¥¾Y¿bŸ¿º‚b@¯kA€'º‚b@¯kAÀ@zTQ@+^"A€' ¥¾Y¿bŸ¿zTQ@+^"A€'º‚b@¯kAÀ@zTQ@+^"AÀ@ W½Q€¿€˜];?¯kqAÀ@˜];?¯kqA€'’“?ÇqAÀ@ W½Q€¿€’“?ÇqAÀ@˜];?¯kqA€'’“?ÇqA€' [Žu¿BÀ¾¿˜¥?"+iA€'¿˜¥?"+iAÀ@’“?ÇqA€' [Žu¿BÀ¾’“?ÇqA€'¿˜¥?"+iAÀ@’“?ÇqAÀ@ )ÿ„¾_6w¿€ÏN=Ö ™AÀ@ÏN=Ö ™A€'µ§è>R-˜AÀ@ )ÿ„¾_6w¿€µ§è>R-˜AÀ@ÏN=Ö ™A€'µ§è>R-˜A€' ) ¿é€°½P.ÿ>»”A€'P.ÿ>»”AÀ@µ§è>R-˜A€' ) ¿é€°½µ§è>R-˜A€'P.ÿ>»”AÀ@µ§è>R-˜AÀ@ ó=b¿o–ï¾ÊÝ6@âé-A€'ÊÝ6@âé-AÀ@ ”'@À!5A€' ó=b¿o–ï¾ ”'@À!5A€'ÊÝ6@âé-AÀ@ ”'@À!5AÀ@ À¼É>PJk¿˜L©@t^Ø@À@˜L©@t^Ø@€'Ÿœµ@¹¥Ý@À@ À¼É>PJk¿Ÿœµ@¹¥Ý@À@˜L©@t^Ø@€'Ÿœµ@¹¥Ý@€' ±è>Ìd¿È·Ç@߸@À@È·Ç@߸@€'§Ó@íõ¾@À@ ±è>Ìd¿§Ó@íõ¾@À@È·Ç@߸@€'§Ó@íõ¾@€' v¬?ƒR¿–AAfN€@À@–AAfN€@€'WÄ Aáî‡@À@ v¬?ƒR¿WÄ Aáî‡@À@–AAfN€@€'WÄ Aáî‡@€' %þ¿LãP¿}nA­ú|@€'}nA­ú|@À@WÄ Aáî‡@€' %þ¿LãP¿WÄ Aáî‡@€'}nA­ú|@À@WÄ Aáî‡@À@ ¼žN?$¿’yfA›Zn?À@’yfA›Zn?€'~ojAþ}¢?À@ ¼žN?$¿~ojAþ}¢?À@’yfA›Zn?€'~ojAþ}¢?€' R»Ž¾öÙu¿GrAÇF?€'GrAÇF?À@~ojAþ}¢?€' R»Ž¾öÙu¿~ojAþ}¢?€'GrAÇF?À@~ojAþ}¢?À@ Áò¾¦Ý}¿€†mÔ> \ƒAÀ@†mÔ> \ƒA€'ÂgT?¦í‚AÀ@ Áò¾¦Ý}¿€ÂgT?¦í‚AÀ@†mÔ> \ƒA€'ÂgT?¦í‚A€' žÖy¿8P_¾ªçp?¬â}A€'ªçp?¬â}AÀ@ÂgT?¦í‚A€' žÖy¿8P_¾ÂgT?¦í‚A€'ªçp?¬â}AÀ@ÂgT?¦í‚AÀ@ ò-p¿Ì2±¾³Ý?ÎßTA€'³Ý?ÎßTAÀ@ÆÇ?‹‰\A€' ò-p¿Ì2±¾ÆÇ?‹‰\A€'³Ý?ÎßTAÀ@ÆÇ?‹‰\AÀ@ ¿ã©>q¿Ð @„Óù@À@Ð @„Óù@€'ƒ¯™@NEþ@À@ ¿ã©>q¿ƒ¯™@NEþ@À@Ð @„Óù@€'ƒ¯™@NEþ@€' IáE¿íj"¿³ ¤@Ó¤ñ@€'³ ¤@Ó¤ñ@À@ƒ¯™@NEþ@€' IáE¿íj"¿ƒ¯™@NEþ@€'³ ¤@Ó¤ñ@À@ƒ¯™@NEþ@À@ cø¾D*}¿¢(ŽAr?€'¢(ŽAr?À@¾ŠAt{)?€' cø¾D*}¿¾ŠAt{)?€'¢(ŽAr?À@¾ŠAt{)?À@ †ó¿ïן¼Š#Ò>5ÒžA€'Š#Ò>5ÒžAÀ@ù Í>|ç¢A€' †ó¿ïן¼ù Í>|ç¢A€'Š#Ò>5ÒžAÀ@ù Í>|ç¢AÀ@ je?iRH¿™KAUûN@À@™KAUûN@€'PŠAï¬_@À@ je?iRH¿PŠAï¬_@À@™KAUûN@€'PŠAï¬_@€' ¿¹¿øKZ¿P#Aú›N@€'P#Aú›N@À@PŠAï¬_@€' ¿¹¿øKZ¿PŠAï¬_@€'P#Aú›N@À@PŠAï¬_@À@ €¿(¤A€'(¤AÀ@((B€' €¿((B€'(¤AÀ@((BÀ@ €?tBŒB AtBŒBAhBŒB A €?hBŒB AtBŒBAŸíbBŒBA €?\BŒB{¶AhBŒB AŸíbBŒBA €?ŸíbBŒBAtBŒBA=ÛiBŒB @ €?€BŒB€@ŸíbBŒB@=ÛiBŒB @ €?€BŒB€@†BŒB'ŸíbBŒB@ €?€BŒB€@†BŒB€@†BŒB' €?ŒB€'t*ðAŒB@†BŒB' €?ŒB€'ŒÕÏAŒB@t*ðAŒB@ €?ŒB€'«f‹AŒBÙì@ŒÕÏAŒB@ €?ŒB€'U™„AŒBÙì@«f‹AŒBÙì@ €?ŒB€' AŒBÝ&@U™„AŒBÙì@ €?ŒB€'ôùë@ŒBÝ&@ AŒBÝ&@ €?ŒB€'¤ãÅ@ŒBÿæ@ôùë@ŒBÝ&@ €?ŒB€'‡}¥@ŒB ûJ@¤ãÅ@ŒBÿæ@ €?ŒB€'€ó@ŒB¤ã…@‡}¥@ŒB ûJ@ €?ŒB€'n“@ŒBôù«@€ó@ŒB¤ã…@ €?ŒB€'n“@ŒB Ô@n“@ŒBôù«@ €?ŒB€'ŒB€An“@ŒB Ô@ €?n“@ŒB Ô@ŒB€A€ó@ŒB\ú@ €?€ó@ŒB\ú@ŒB€A‡}¥@ŒB=A A €?‡}¥@ŒB=A AŒB€AAŒBu‚:A €?AŒBu‚:AŒB€AÿJ AŒBíðAA €?ÄΗAŒBwø0AAŒBu‚:AÿJ AŒBíðAA €?U™„AŒBÙì@.AŒBÿæ@³Ò|AŒB߇@ €?U™„AŒBÙì@ AŒBÝ&@.AŒBÿæ@ €?ŒB€ABŒB€AÿJ AŒBíðAA €?ÿJ AŒBíðAABŒB€AàAŒBéT0A €?;ǨAŒBwø0AàAŒBéT0A¢´«AŒBžj'A €?;ǨAŒBwø0AÿJ AŒBíðAAàAŒBéT0A €?«f‹AŒBÙì@§–‘AŒB߇@ŒÕÏAŒB@ €?ŒÕÏAŒB@§–‘AŒB߇@ú –AŒBø§B@ €?Žõ—AŒB]Þv@¿ý–AŒBž]–@«¿AŒB°@ €?,%¬AŒBÞ>AŒÕÏAŒBAIªAŒB¦äA €?,%¬AŒBÞ>A¢´«AŒBžj'AŒÕÏAŒBA €?ŒÕÏAŒBA¢´«AŒBžj'AàAŒBéT0A €?¯HBŒBAaUBŒBAÃ$NBŒB @ €?Ù9BŒB@Ã$NBŒB @aUBŒB@ €?†BŒB'aUBŒB@ŸíbBŒB@ €?†BŒB'Ù9BŒB@aUBŒB@ €?†BŒB''ýBŒB@Ù9BŒB@ €?†BŒB't*ðAŒB@'ýBŒB@ €?'ýBŒB@t*ðAŒB@r*BŒB°@ €?Qú BŒBAr*BŒB°@t*ðAŒBA €?àAŒBéT0AQú BŒBAt*ðAŒBA €?¯HBŒBAÃ$NBŒB @Ù9BŒB@ €?'ýBŒB@r*BŒB°@Qú BŒBA €?hBàA€'hBàA€AhBÂA€' €?hBÂA€'hBàA€AhBÂA€A €?hBÂA€'hBÂA€AŒBÂA€' €?ŒBÂA€'hBÂA€AŒBÂA€A €?hB&±A€'hB&±A€AŒB&±A€' €?ŒB&±A€'hB&±A€AŒB&±A€A €?hBôl—A€'hBôl—A€AŒBôl—A€' €?ŒBôl—A€'hBôl—A€AŒBôl—A€A €¿ŒBàA€'ŒBàA€AhBàA€' €¿hBàA€'ŒBàA€AhBàA€A úÿÿ>Ù³]¿ŒBôl—A€'ŒBôl—A€AhB@A€' úÿÿ>Ù³]¿hB@A€'ŒBôl—A€AhB@A€A €?hB@A€'hB@A€AŒB@A€' €?ŒB@A€'hB@A€AŒB@A€A 탄>êFw¿ŒB&±A€'ŒB&±A€AhBôl—A€' 탄>êFw¿hBôl—A€'ŒB&±A€AhBôl—A€A õÐ1>[|¿ŒBÂA€'ŒBÂA€AhB&±A€' õÐ1>[|¿hB&±A€'ŒBÂA€AhB&±A€A ,ûùÿÿ¿€žª¤Aͯf;À@žª¤Aͯf;€'ðAÀ@ |JŸþÿ¿;,æ¹ðAÀ@žª¤Aͯf;€'hB€' €¿hB€AðAÀ@hB€' €¿hB€AðA€AðAÀ@ €?Ù9B€B@¯HB€BAÙ9BŒB@ Þ³]¿éÿÿ>Ù9BŒB@¯HB€BA¯HBŒBA €?'ýB€B@Ù9B€B@'ýBŒB@ €?'ýBŒB@Ù9B€B@Ù9BŒB@ Þ³]?éÿÿ>Qú B€BA'ýB€B@Qú BŒBA Þ³]?éÿÿ>Qú BŒBA'ýB€B@'ýBŒB@ Þ³]?éÿÿ¾'ýB€BpAQú B€BA'ýBŒBpA Þ³]?éÿÿ¾'ýBŒBpAQú B€BAQú BŒBA €?'ýB€BpAÙ9B€BpAQú B€BA €?Qú B€BAÙ9B€BpA¯HB€BA €?'ýB€B@¯HB€BAÙ9B€B@ €?'ýB€B@Qú B€BA¯HB€BA ó5¿ó5¿t*ðA€BAàA€BéT0At*ðAŒBA ó5¿ó5¿t*ðAŒBAàA€BéT0AàAŒBéT0A â³]?Ûÿÿ¾ŒÕÏA€BA«¿A€B°@ŒÕÏAŒBA â³]?Ûÿÿ¾ŒÕÏAŒBA«¿A€B°@«¿AŒB°@ ó5?ó5¿àA€BéT0AŒÕÏA€BAàAŒBéT0A ó5?ó5¿àAŒBéT0AŒÕÏA€BAŒÕÏAŒBA €?àA€BéT0At*ðA€BAŒÕÏA€BA €?ŒÕÏA€BAt*ðA€BA«¿A€B°@ €?ŒÕÏA€B@r*B€B°@t*ðA€B@ ÷5¿ð5¿ŸíbB€BA\B€B{¶AŸíbBŒBA ÷5¿ð5¿ŸíbBŒBA\B€B{¶A\BŒB{¶A Ù³]¿úÿÿ¾=ÛiB€B @ŸíbB€BA=ÛiBŒB @ Ù³]¿úÿÿ¾=ÛiBŒB @ŸíbB€BAŸíbBŒBA Ù³]¿úÿÿ>ŸíbB€B@=ÛiB€B @ŸíbBŒB@ Ù³]¿úÿÿ>ŸíbBŒB@=ÛiB€B @=ÛiBŒB @ €?aUB€B@ŸíbB€B@aUBŒB@ €?aUBŒB@ŸíbB€B@ŸíbBŒB@ Ù³]?úÿÿ>Ã$NB€B @aUB€B@Ã$NBŒB @ Ù³]?úÿÿ>Ã$NBŒB @aUB€B@aUBŒB@ Ù³]?úÿÿ¾aUB€BAÃ$NB€B @aUBŒBA Ù³]?úÿÿ¾aUBŒBAÃ$NB€B @Ã$NBŒB @ €?\B€B{¶AŸíbB€BAaUB€BA €?aUB€BAŸíbB€BAÃ$NB€B @ €?Ã$NB€B @ŸíbB€BA=ÛiB€B @ €?aUB€B@=ÛiB€B @ŸíbB€B@ €?aUB€B@Ã$NB€B @=ÛiB€B @ ¼O?y¿‡}¥@ŒB=A A‡}¥@pB=A A€ó@ŒB\ú@ ¼O?y¿€ó@ŒB\ú@‡}¥@pB=A A€ó@pB\ú@ qxs?t7ž¾n“@ŒB Ô@€ó@pB\ú@n“@pB Ô@ €?n“@ŒBôù«@n“@pB Ô@n“@pBôù«@ qxs?t7ž>€ó@ŒB¤ã…@n“@pBôù«@€ó@pB¤ã…@ ¼O?y?‡}¥@ŒB ûJ@€ó@pB¤ã…@‡}¥@pB ûJ@ y?¼O?¤ãÅ@ŒBÿæ@‡}¥@pB ûJ@¤ãÅ@pBÿæ@ t7ž>qxs?ôùë@ŒBÝ&@¤ãÅ@pBÿæ@ôùë@pBÝ&@ €? AŒBÝ&@ôùë@pBÝ&@ ApBÝ&@ t7ž¾qxs?.AŒBÿæ@ ApBÝ&@.ApBÿæ@ y¿ÊO?@A-AŒB ûJ@.ApBÿæ@@A-ApB ûJ@ ¶O¿"y?D9AŒB¤ã…@@A-ApB ûJ@D9ApB¤ã…@ xs¿Ë6ž>F6?AŒBôù«@D9ApB¤ã…@F6?ApBôù«@ €¿F6?AŒB Ô@F6?ApBôù«@F6?ApB Ô@ xs¿€Ë6ž¾D9AŒB\ú@F6?ApB Ô@D9ApB\ú@ ¶O¿€"y¿@A-AŒB=A AD9ApB\ú@@A-ApB=A A ¶O¿"y¿@A-AŒB=A AD9AŒB\ú@D9ApB\ú@ qxs?t7ž¾€ó@ŒB\ú@€ó@pB\ú@n“@ŒB Ô@ €?n“@ŒB Ô@n“@pB Ô@n“@ŒBôù«@ qxs?t7ž>n“@ŒBôù«@n“@pBôù«@€ó@ŒB¤ã…@ ¼O?y?€ó@ŒB¤ã…@€ó@pB¤ã…@‡}¥@ŒB ûJ@ y?¼O?‡}¥@ŒB ûJ@‡}¥@pB ûJ@¤ãÅ@ŒBÿæ@ t7ž>qxs?¤ãÅ@ŒBÿæ@¤ãÅ@pBÿæ@ôùë@ŒBÝ&@ €?ôùë@ŒBÝ&@ôùë@pBÝ&@ AŒBÝ&@ t7ž¾qxs? AŒBÝ&@ ApBÝ&@.AŒBÿæ@ y¿ÊO?.AŒBÿæ@.ApBÿæ@@A-AŒB ûJ@ ¶O¿"y?@A-AŒB ûJ@@A-ApB ûJ@D9AŒB¤ã…@ xs¿Ë6ž>D9AŒB¤ã…@D9ApB¤ã…@F6?AŒBôù«@ €¿F6?AŒBôù«@F6?ApBôù«@F6?AŒB Ô@ xs¿€Ë6ž¾F6?AŒB Ô@F6?ApB Ô@D9AŒB\ú@ ë5?ü5¿ApBu‚:A‡}¥@pB=A AAŒBu‚:A ë5?ü5¿AŒBu‚:A‡}¥@pB=A A‡}¥@ŒB=A A å5¿5¿@A-ApB=A AApBu‚:A@A-AŒB=A A å5¿5¿@A-AŒB=A AApBu‚:AAŒBu‚:A ó5?ó5¿ÿJ ApBíðAAÄΗApBwø0AÿJ AŒBíðAA ó5?ó5¿ÿJ AŒBíðAAÄΗApBwø0AÄΗAŒBwø0A ó5¿ó5¿;ǨApBwø0AÿJ ApBíðAA;ǨAŒBwø0A ó5¿ó5¿;ǨAŒBwø0AÿJ ApBíðAAÿJ AŒBíðAA Eƒl?’ïÃ>Îp”ApBÞ>A°•–ApB¦äAÎp”AŒBÞ>A Eƒl?’ïÃ>Îp”AŒBÞ>A°•–ApB¦äA°•–AŒB¦äA Ý o>Cíx?UØšAŒB¨ AUØšApB¨ AÿJ ApBA · o¾6íx?ÿJ AŒBAÿJ ApBA¥½¥ApB¨ A 8B&¿ù©B?¥½¥AŒB¨ A¥½¥ApB¨ AIªApB¦äA Eƒl¿’ïÃ>IªAŒB¦äAIªApB¦äA,%¬ApBÞ>A ö5¿€‘° ½,%¬AŒBÞ>A,%¬ApBÞ>A¢´«ApBžj'A ³FZ¿€Y¿¢´«AŒBžj'A¢´«ApBžj'A;ǨAŒBwø0A ö5¿€‘° ½¢´«AŒBžj'A,%¬AŒBÞ>A¢´«ApBžj'A Ý o>Cíx?UØšAŒB¨ AÿJ ApBAÿJ AŒBA · o¾6íx?ÿJ AŒBA¥½¥ApB¨ A¥½¥AŒB¨ A 8B&¿ù©B?¥½¥AŒB¨ AIªApB¦äAIªAŒB¦äA Eƒl¿’ïÃ>IªAŒB¦äA,%¬ApBÞ>A,%¬AŒBÞ>A ³FZ¿Y¿¢´«ApBžj'A;ǨApBwø0A;ǨAŒBwø0A D\W?¢g ¿e_yApB>A­@rApBž]–@e_yAŒB>A­@ D\W?¢g ¿e_yAŒB>A­@rApBž]–@rAŒBž]–@ ýd}?’¹¾rAŒBž]–@rApBž]–@äpApB]Þv@ w¡u?Y>>äpAŒB]Þv@äpApB]Þv@ êsApBø§B@ ãxA?Û¤'? êsAŒBø§B@ êsApBø§B@³Ò|ApB߇@ ±Ô>±Ýh?³Ò|AŒB߇@³Ò|ApB߇@U™„ApBÙì@ €?U™„AŒBÙì@U™„ApBÙì@«f‹ApBÙì@ ±Ô¾±Ýh?«f‹AŒBÙì@«f‹ApBÙì@§–‘ApB߇@ ãxA¿Û¤'?§–‘AŒB߇@§–‘ApB߇@ú –ApBø§B@ ýd}¿€’¹¾Žõ—AŒB]Þv@Žõ—ApB]Þv@¿ý–ApBž]–@ ýd}¿€’¹¾¿ý–AŒBž]–@Žõ—AŒB]Þv@¿ý–ApBž]–@ ýd}?’¹¾rAŒBž]–@äpApB]Þv@äpAŒB]Þv@ w¡u?Y>>äpAŒB]Þv@ êsApBø§B@ êsAŒBø§B@ ãxA?Û¤'? êsAŒBø§B@³Ò|ApB߇@³Ò|AŒB߇@ ±Ô>±Ýh?³Ò|AŒB߇@U™„ApBÙì@U™„AŒBÙì@ €?U™„AŒBÙì@«f‹ApBÙì@«f‹AŒBÙì@ ±Ô¾±Ýh?«f‹AŒBÙì@§–‘ApB߇@§–‘AŒB߇@ ãxA¿Û¤'?§–‘AŒB߇@ú –ApBø§B@ú –AŒBø§B@ 5?ç5¿ˆApBy‚Ú@e_yApB>A­@ˆAŒBy‚Ú@ 5?ç5¿ˆAŒBy‚Ú@e_yApB>A­@e_yAŒB>A­@ 5¿ç5¿MP“ApB>A­@ˆApBy‚Ú@MP“AŒB>A­@ 5¿ç5¿MP“AŒB>A­@ˆApBy‚Ú@ˆAŒBy‚Ú@ €¿€ó@pB\ú@‡}¥@pB=A ApB€A €¿n“@pB Ô@pB€ApB€' €¿n“@pBôù«@pB€'€ó@pB¤ã…@ €¿n“@pBôù«@n“@pB Ô@pB€' €¿@A-ApB=A AÎp”ApBÞ>AWá”ApBžj'A €¿@A-ApB=A AD9ApB\ú@Îp”ApBÞ>A €¿Îp”ApBÞ>AD9ApB\ú@ˆApBy‚Ú@ €¿°•–ApB¦äAÎp”ApBÞ>AˆApBy‚Ú@ €€¿€ êsApBø§B@@A-ApB ûJ@³Ò|ApB߇@ €¿@A-ApB ûJ@.ApBÿæ@³Ò|ApB߇@ €¿pB€' ApBÝ&@ôùë@pBÝ&@ €¿¤ãÅ@pBÿæ@pB€'ôùë@pBÝ&@ €¿¤ãÅ@pBÿæ@‡}¥@pB ûJ@pB€' €¿pB€'‡}¥@pB ûJ@€ó@pB¤ã…@ €¿U™„ApBÙì@ ApBÝ&@pB€' €¿ðApB€'U™„ApBÙì@pB€' €¿ðApB€'«f‹ApBÙì@U™„ApBÙì@ €¿ðApB€'§–‘ApB߇@«f‹ApBÙì@ €¿ðApB€'ú –ApBø§B@§–‘ApB߇@ €¿ðApB€'Žõ—ApB]Þv@ú –ApBø§B@ €¿ðApB€',%¬ApBÞ>AIªApB¦äA €¿ðApB€'ðApB€A,%¬ApBÞ>A €¿,%¬ApBÞ>AðApB€A¢´«ApBžj'A €¿¢´«ApBžj'AðApB€A;ǨApBwø0A €¿;ǨApBwø0AðApB€AÿJ ApBíðAA €¿ÿJ ApBíðAAðApB€ApB€A €¿ApBu‚:ApB€A‡}¥@pB=A A €¿ApBu‚:AÿJ ApBíðAApB€A €¿ApBu‚:AÄΗApBwø0AÿJ ApBíðAA €¿n“@pB Ô@€ó@pB\ú@pB€A €¿ðA@B€'ðA@B€A(@B€' €¿(@B€'ðA@B€A@B€A €?(8B€'8B€AðA8B€' €?ðA8B€'8B€AðA8B€A €¿ðA8B€'ðA8B€AðA@B€' €¿ðA@B€'ðA8B€AðA@B€A €?ðA(BÀ@ðA(B€'((BÀ@ €?((BÀ@ðA(B€'((B€' €¿€¦8B€A(8B€'0B€A €¿¦0B€A(8B€'(0B€' €¿€¦HB€A(HB€'@B€A €¿¦@B€A(HB€'(@B€' €?BŒB€AðApB€ABpB€A €?BpB€AðApB€A BÛ¼WB€A €?@BpB€A BÛ¼WB€ApBÛ¼WB€A €?hB€B€ApBÛ¼WB€AtBxB€A €?tB€B€AhB€B€AtBxB€A €?HB€AðA@B€AðAHB€A €?HB€A@B€AðA@B€A €?ðA€A B)–øA€AðA0B€A €?ðA€A B£XÂ@€A B)–øA€A €?ðA€AB£XÂ@€A B£XÂ@€A €?ðA€AB£XÂ@€AB£XÂ@€A €?ðA€A&B£XÂ@€AB£XÂ@€A €?ðA€A*B£XÂ@€A&B£XÂ@€A €?ðA€AhB€A*B£XÂ@€A €?*B£XÂ@€AhB€A6B£XÂ@€A €?6B£XÂ@€AhB€A0A¸AÀAÀ@0A¸AÀA€'Á¨A¤AÀ@ â³]¿Ûÿÿ>Á¨A¤AÀ@0A¸AÀA€'Á¨A¤A€' €?=ÛÍAPAÀ@=ÛÍAPA€'Ã$²APAÀ@ €?Ã$²APAÀ@=ÛÍAPA€'Ã$²APA€' Ù³]¿úÿÿ>z¶ÛA€AÀ@z¶ÛA€A€'=ÛÍAPAÀ@ Ù³]¿úÿÿ>=ÛÍAPAÀ@z¶ÛA€A€'=ÛÍAPA€' =íx?H o>ŒBoŠBz7ž@†B%›‹BY0 @†BoŠBz7ž@ ]ƒl?ïÃ>ŒB ƒˆBqqè@†BoŠBz7ž@†B ƒˆBqqè@ ¢FZ?uÂ?ŒBxã…ByA†B ƒˆBqqè@†Bxã…ByA ú©B?7B&?ŒBž ‚Bõ5A†Bxã…ByA†Bž ‚Bõ5A /B&?ªB?ŒBFž}B»OA†Bž ‚Bõ5A†BFž}B»OA kÂ?¨FZ?ŒB.uBüdA†BFž}B»OA†B.uBüdA ïÃ>`ƒl?ŒBïÆkBlxsA†B.uBüdA†BïÆkBlxsA e o>;íx?ŒBbB!Ù|A†BïÆkBlxsA†BbB!Ù|A =íx?H o>ŒB%›‹BY0 @†B%›‹BY0 @ŒBoŠBz7ž@ ]ƒl?ïÃ>ŒBoŠBz7ž@†BoŠBz7ž@ŒB ƒˆBqqè@ ¢FZ?uÂ?ŒB ƒˆBqqè@†B ƒˆBqqè@ŒBxã…ByA ú©B?7B&?ŒBxã…ByA†Bxã…ByAŒBž ‚Bõ5A /B&?ªB?ŒBž ‚Bõ5A†Bž ‚Bõ5AŒBFž}B»OA kÂ?¨FZ?ŒBFž}B»OA†BFž}B»OAŒB.uBüdA ïÃ>`ƒl?ŒB.uBüdA†B.uBüdAŒBïÆkBlxsA e o>;íx?ŒBïÆkBlxsA†BïÆkBlxsAŒBbB!Ù|A €?†BŒB'†BŒB€@†B%›‹BY0 @ €?†B%›‹BY0 @†BŒB€@†BoŠBz7ž@ €?†BoŠBz7ž@†BŒB€@†B©¢‹BO®Â@ €?†B ƒˆBqqè@†B©¢‹BO®Â@†ByŠBúªA €?†B”b†BKj;A†Bxã…ByA†BÜȈB A €?†B”b†BKj;A†Bž ‚Bõ5A†Bxã…ByA €?†B”b†BKj;A†BImƒBšSA†Bž ‚Bõ5A €?†Bž ‚Bõ5A†BImƒBšSA†BFž}B»OA €?†BFž}B»OA†BImƒBšSA†B€BÜFfA €?†B.uBüdA†B€BÜFfA†B¾jxBÄktA €?†BÊUpBB}A†B.uBüdA†B¾jxBÄktA €?†BÊUpBB}A†BïÆkBlxsA†B.uBüdA €?†BÊUpBB}A†BhB€A†BïÆkBlxsA €?†BïÆkBlxsA†BhB€A†BbB!Ù|A €?†BbB!Ù|A†BhB€A†BXB€A îd¿»qè>oÞAD BÀ@oÞAD B€'yãÙAo˜B€' îd¿»qè>oÞAD BÀ@yãÙAo˜B€'yãÙAo˜BÀ@ €?0‰@v² AÀ@ƒ¯™@NEþ@À@šoAˆAÀ@ €?0‰@v² AÀ@šoAˆAÀ@šoAˆ?AÀ@ €?‘í@òŒHAÀ@_A@áAAÀ@ ”'@À!5AÀ@ €?‘í@òŒHAÀ@ ”'@À!5AÀ@šoAˆ?AÀ@ €?ÑÚAɦAÀ@MrÕAh¤AÀ@=ÛÍA˜AÀ@ €?ÑÚAɦAÀ@=ÛÍA˜AÀ@z¶ÛA€AÀ@ €?((BÀ@+µ\A BÀ@‡¶Aˆ7BÀ@ €?((BÀ@‡¶Aˆ7BÀ@ðA(BÀ@ €?ŒB%›‹BY0 @ŒBoŠBz7ž@ŒB ƒˆBqqè@ €?Ùu?Ä1eAÀ@z‰‘?!‚\AÀ@ÆÇ?‹‰\AÀ@ €?Ùu?Ä1eAÀ@ÆÇ?‹‰\AÀ@¿˜¥?"+iAÀ@ €?·ë@º,AÀ@Ð @„Óù@À@ƒ¯™@NEþ@À@ €?·ë@º,AÀ@ƒ¯™@NEþ@À@0‰@v² AÀ@ €?™ËÀ@½Ñ@À@tÁº@ ÈÅ@À@È·Ç@߸@À@ €?™ËÀ@½Ñ@À@È·Ç@߸@À@§Ó@íõ¾@À@ Ÿ?¿¦Á)? ÞAalªA€'ÑÚAɦA€'ÑÚAɦAÀ@ Ÿ?¿¦Á)? ÞAalªA€'ÑÚAɦAÀ@ ÞAalªAÀ@ â%H¿O?`jÞAÏÙAÀ@`jÞAÏÙA€'ÑùÙA }ÓA€' â%H¿O?`jÞAÏÙAÀ@ÑùÙA }ÓA€'ÑùÙA }ÓAÀ@ ì”y¿¼Ûc¾€`jÞA1ñæAÀ@`jÞA1ñæA€'àAàA€' ì”y¿¼Ûc¾`jÞA1ñæAÀ@àAàA€'àAàAÀ@ x²=œ?†BhB€A†BÊUpBB}A€BÊUpBB}A x²=œ?†BhB€A€BÊUpBB}A€BhB€A €?àA°AÀ@ ÞAalªAÀ@z¶ÛA€AÀ@ €?àA°AÀ@z¶ÛA€AÀ@ðAˆ?AÀ@ €?ÑùÙA }ÓAÀ@ÑÚA7à¹AÀ@ ÞAŸ“µAÀ@ €?ÑùÙA }ÓAÀ@ ÞAŸ“µAÀ@`jÞAÏÙAÀ@ €? •ÁA1ñæAÀ@‡¶AxÈBÀ@Þ0­ADBÀ@ €? •ÁA1ñæAÀ@Þ0­ADBÀ@Á¨AÜAÀ@ €?/ÆA`‚ìAÀ@ÀABÀ@‡¶AxÈBÀ@ €?/ÆA`‚ìAÀ@‡¶AxÈBÀ@ •ÁA1ñæAÀ@ €?pÌAP™ïAÀ@yãÉAxÈBÀ@ÀABÀ@ €?pÌAP™ïAÀ@ÀABÀ@/ÆA`‚ìAÀ@ €?àAàAÀ@oÞAD BÀ@yãÙAo˜BÀ@ €?àAàAÀ@yãÙAo˜BÀ@`jÞA1ñæAÀ@ €¿ðAˆ?AÀ@ðAˆ?A0AðA0B€A €¿ðAˆ?AÀ@ðA0B€AðA(BÀ@ ž?¹~²=€B©¢‹BO®Â@†B©¢‹BO®Â@†BŒB€@ ž?¹~²=€B©¢‹BO®Â@†BŒB€@€BŒB€@ €?tBb‚ˆB…ÎOAtBÉa‰BäÚ[AtB\{‡BLkA €?tBb‚ˆB…ÎOAtB\{‡BLkAtBÐù…B dA €?tBû²‹B±\5AtB^jŠB‰7AtBN™‹B{A €?tBû²‹B±\5AtBN™‹B{AtBŒB A ìc~?¥Må=tBN™‹B{A€BN™‹B{A€BŒBA ìc~?¥Må=tBN™‹B{A€BŒBAtBŒBA €?hBÉa‰BäÚ[AhBÞxŠBEžeAhBɳˆBñÆsA €?hBÉa‰BäÚ[AhBɳˆBñÆsAhB\{‡BLkA íc~?nMå=hBû²‹B±\5AtBû²‹B±\5AtBŒB A íc~?nMå=hBû²‹B±\5AtBŒB AhBŒB A €?tBäBmÊ|AtB0ñ‚BòRsAtB–«‚B×—}A €?tBäBmÊ|AtB–«‚B×—}AtB€B€A €?ŒB.uBüdAŒBïÆkBlxsAŒBbB!Ù|A €?ŒB.uBüdAŒBbB!Ù|AŒBXB€A ó5?ó5?Þ0­ADBÀ@Þ0­ADB€'‡¦Ao˜B€' ó5?ó5?Þ0­ADBÀ@‡¦Ao˜B€'‡¦Ao˜BÀ@ ¤Lå=ðc~?tB€B€AtB–«‚B×—}AhB–«‚B×—}A ¤Lå=ðc~?tB€B€AhB–«‚B×—}AhB€B€A €?†B ƒˆBqqè@†ByŠBúªA†BÜȈB A €?†B ƒˆBqqè@†BÜȈB A†Bxã…ByA ‡Þz¿4üK>P#Aú›N@À@P#Aú›N@€'u+"A2U4@€' ‡Þz¿4üK>P#Aú›N@À@u+"A2U4@€'u+"A2U4@À@ ƒd¿Ïæ>™ËÀ@½Ñ@À@™ËÀ@½Ñ@€'tÁº@ ÈÅ@€' ƒd¿Ïæ>™ËÀ@½Ñ@À@tÁº@ ÈÅ@€'tÁº@ ÈÅ@À@ ƒ2¿Më7?_A@áAAÀ@_A@áAA€'Ñú?Èoº}¿p#¾€´“ƒAHP?À@´“ƒAHP?€'æ„A?WË>€' >º}¿p#¾´“ƒAHP?À@æ„A?WË>€'æ„A?WË>À@ €¿Þ0­ADB€'Á¨AÜA€'ÝÁ‡AÜA€' €¿Þ0­ADB€'ÝÁ‡AÜA€'G`ŒAB€' €¿Ó<É@ØA€'»?¨€A€'P.ÿ>»”A€' €¿Š#Ò>5ÒžA€'µ§è>R-˜A€'ÏN=Ö ™A€' €¿Š#Ò>5ÒžA€'ÏN=Ö ™A€'Éߥ<“A€' €¿'L"@B€'Ó<É@ØA€'ù Í>|ç¢A€' €¿'L"@B€'ù Í>|ç¢A€'(¤A€' €¿Þ0­ADB€'‡¶AxÈB€' •ÁA1ñæA€' €¿Þ0­ADB€' •ÁA1ñæA€'Á¨AÜA€' €¿/ÆA }ÓA€'pÌA°fÐA€'‘ËAõ·A€' €¿/ÆA }ÓA€'‘ËAõ·A€'0A¸AÀA€' €¿`jÞAÏÙA€' B)–øA€'àA°A€' €¿`jÞAÏÙA€'àA°A€' ÞAŸ“µA€' €¿z¶ÛA€A€' ÞAalªA€'àA°A€' €¿z¶ÛA€A€'àA°A€' B£XÂ@€' €¿`jÞA1ñæA€'yãÙAo˜B€'oÞAD B€' €¿`jÞA1ñæA€'oÞAD B€' B)–øA€' €¿ BÛ¼B€' BÛ¼B€'oÞAD B€' €¿ BÛ¼B€'oÞAD B€'àAB€' €¿FYÈA,ß²A€'FYÈAÔ ­A€'Á¨A¤A€' €¿FYÈA,ß²A€'Á¨A¤A€'0A¸AÀA€' €¿Ÿœµ@¹¥Ý@€'†I¤A€A€'§Ó@íõ¾@€' €¿Ÿœµ@¹¥Ý@€'§Ó@íõ¾@€'™ËÀ@½Ñ@€' €¿§Ó@íõ¾@€'†I¤A€A€'Ÿ¬ó@¸X¢@€' €¿§Ó@íõ¾@€'Ÿ¬ó@¸X¢@€'›ß@„Ó³@€' €¿}nA­ú|@€'WÄ Aáî‡@€',AÙ˜@€' €¿}nA­ú|@€',AÙ˜@€'†I¤A€A€' €¿P#Aú›N@€'PŠAï¬_@€'}nA­ú|@€' €¿P#Aú›N@€'}nA­ú|@€'†I¤A€A€' €¿ªçp?¬â}A€'ÂgT?¦í‚A€'Ñ.oAÀA€' €¿¿˜¥?"+iA€'’“?ÇqA€'ªçp?¬â}A€' €¿_A@áAA€'‘í@òŒHA€'³Ý?ÎßTA€' €¿_A@áAA€'³Ý?ÎßTA€'ÝÁ‡A¤A€' €¿ÊÝ6@âé-A€' ”'@À!5A€'_A@áAA€' €¿ÊÝ6@âé-A€'_A@áAA€'ÝÁ‡A¤A€' €¿º‚b@¯kA€'zTQ@+^"A€'ÊÝ6@âé-A€' €¿º‚b@¯kA€'ÊÝ6@âé-A€'ÝÁ‡A¤A€' €¿0‰@v² A€'7ÿ@WA€'º‚b@¯kA€' €¿0‰@v² A€'º‚b@¯kA€'ÝÁ‡A¤A€' €¿³ ¤@Ó¤ñ@€'ƒ¯™@NEþ@€'0‰@v² A€' €¿³ ¤@Ó¤ñ@€'0‰@v² A€'ÝÁ‡A¤A€' €¿³ ¤@Ó¤ñ@€'Ÿœµ@¹¥Ý@€'˜L©@t^Ø@€' €¿³ ¤@Ó¤ñ@€'˜L©@t^Ø@€'ú9@½æ@€' Ƚ£3P꤀¿ðApB€'†BŒB'pBÛ¼WB€' €¿ðApB€'pBÛ¼WB€' BÛ¼WB€' €¿ŒBŒB€'ŒBàA€'pBÛ¼=B€' €¿ŒBŒB€'pBÛ¼=B€'pBÛ¼IB€' €¿6B)–øA€'»”A€'»?¨€A€'<ì?>|'ŽA€' €¿P.ÿ>»”A€'<ì?>|'ŽA€'âÿó=v²’A€' %Ù|?I0 >\BÄ›‹BñÆSAhBÄ›‹BñÆSAhBŒB@A %Ù|?I0 >\BÄ›‹BñÆSAhBŒB@A\BŒB@A €¿ðA0B€' BÛ¼-B€' BÛ¼'B€' €¿ðA0B€' BÛ¼'B€'ðA(B€' €¿½{ŸA3ÜÐ>€'=ÛÍAPA€'‘£AúÕÌ>€' €¿¢(ŽAr?€'¾ŠAt{)?€'´“ƒAHP?€' €¿¢(ŽAr?€'´“ƒAHP?€'Ã$²APA€' ³µ¾n]o?ÑÚAɦA€'MrÕAh¤A€'MrÕAh¤AÀ@ ³µ¾n]o?ÑÚAɦA€'MrÕAh¤AÀ@ÑÚAɦAÀ@ €¿GrAÇF?€'~ojAþ}¢?€'{É]ACÃ?€' €¿GrAÇF?€'{É]ACÃ?€'Ã$²APA€' €¿¦ÄIAwÖ@€'LBA¦ @€'ßO6AØ*%@€' ¨‡‘=TZ¿CpÐ?+HAÀ@CpÐ?+HA€'‘í@òŒHA€' ¨‡‘=TZ¿CpÐ?+HAÀ@‘í@òŒHA€'‘í@òŒHAÀ@ t¾ >’}¿² @164AÀ@² @164A€' ”'@À!5A€' t¾ >’}¿² @164AÀ@ ”'@À!5A€' ”'@À!5AÀ@ Q™:¿"C/¿€Ÿœµ@¹¥Ý@À@Ÿœµ@¹¥Ý@€'™ËÀ@½Ñ@€' Q™:¿"C/¿Ÿœµ@¹¥Ý@À@™ËÀ@½Ñ@€'™ËÀ@½Ñ@À@ w¦8?hP1¿§=AÜcõ?À@§=AÜcõ?€'LBA¦ @€' w¦8?hP1¿§=AÜcõ?À@LBA¦ @€'LBA¦ @À@ ElG¾1{¿€<ì?>|'ŽAÀ@<ì?>|'ŽA€'»?¨€A€' ElG¾1{¿<ì?>|'ŽAÀ@»?¨€A€'»?¨€AÀ@ «Å;cÿ¿z‰‘?!‚\AÀ@z‰‘?!‚\A€'ÆÇ?‹‰\A€' «Å;cÿ¿z‰‘?!‚\AÀ@ÆÇ?‹‰\A€'ÆÇ?‹‰\AÀ@ €?@BŒB€A\BŒB€A\BŒB@A €?\BŒB@A\BŒB{¶AaUBŒBA €?\BŒB@AaUBŒBA¯HBŒBA €?hBŒB@AhBŒB A\BŒB{¶A €?hBŒB@A\BŒB{¶A\BŒB@A €?tBŒBA€BŒBA€BŒB€@ €?tBŒBA€BŒB€@=ÛiBŒB @ €?e_yAŒB>A­@F6?AŒB Ô@D9AŒB\ú@ €?e_yAŒB>A­@D9AŒB\ú@ˆAŒBy‚Ú@ €?rAŒBž]–@F6?AŒBôù«@F6?AŒB Ô@ €?rAŒBž]–@F6?AŒB Ô@e_yAŒB>A­@ €?äpAŒB]Þv@D9AŒB¤ã…@F6?AŒBôù«@ €?äpAŒB]Þv@F6?AŒBôù«@rAŒBž]–@ €? êsAŒBø§B@@A-AŒB ûJ@D9AŒB¤ã…@ €? êsAŒBø§B@D9AŒB¤ã…@äpAŒB]Þv@ €?³Ò|AŒB߇@.AŒBÿæ@@A-AŒB ûJ@ €?³Ò|AŒB߇@@A-AŒB ûJ@ êsAŒBø§B@ €?BŒB€A'ýBŒBpAQú BŒBA €?BŒB€AQú BŒBAàAŒBéT0A ó5?ó5¿ŒB@A€'ŒB@A€AhB€A ó5?ó5¿ŒB@A€'hB€AhB€' €?*B£XÂ@€'*B£XÂ@€A6B£XÂ@€A €?*B£XÂ@€'6B£XÂ@€A6B£XÂ@€' €?B£XÂ@€'B£XÂ@€A&B£XÂ@€A €?B£XÂ@€'&B£XÂ@€A&B£XÂ@€' €¿B)–øA€'B)–øA€A B)–øA€A €¿B)–øA€' B)–øA€A B)–øA€' €? BÛ¼=B€' BÛ¼=B€ApBÛ¼=B€A €? BÛ¼=B€'pBÛ¼=B€ApBÛ¼=B€' €¿pBÛ¼9B€'pBÛ¼9B€A BÛ¼9B€A €¿pBÛ¼9B€' BÛ¼9B€A BÛ¼9B€' €? BÛ¼-B€' BÛ¼-B€ApBÛ¼-B€A €? BÛ¼-B€'pBÛ¼-B€ApBÛ¼-B€' €¿pBÛ¼B€'pBÛ¼B€A BÛ¼B€A €¿pBÛ¼B€' BÛ¼B€A BÛ¼B€' €¿pBÛ¼'B€'pBÛ¼'B€A BÛ¼'B€A €¿pBÛ¼'B€' BÛ¼'B€A BÛ¼'B€' г]? ¿Ñ.oAÀAÀ@Ñ.oAÀA€'ÝÁ‡AÜA€' г]? ¿Ñ.oAÀAÀ@ÝÁ‡AÜA€'ÝÁ‡AÜAÀ@ Ù³]?úÿÿ¾†I¤A€AÀ@†I¤A€A€'Ã$²A˜A€' Ù³]?úÿÿ¾†I¤A€AÀ@Ã$²A˜A€'Ã$²A˜AÀ@ â³]¿Ûÿÿ¾r*B€B°@t*ðA€BAt*ðAŒBA â³]¿Ûÿÿ¾r*B€B°@t*ðAŒBAr*BŒB°@ â³]¿Ûÿÿ>t*ðA€B@r*B€B°@r*BŒB°@ â³]¿Ûÿÿ>t*ðA€B@r*BŒB°@t*ðAŒB@ €?ŒÕÏA€B@t*ðA€B@t*ðAŒB@ €?ŒÕÏA€B@t*ðAŒB@ŒÕÏAŒB@ ÷5?ð5¿\B€B{¶AaUB€BAaUBŒBA ÷5?ð5¿\B€B{¶AaUBŒBA\BŒB{¶A HFZ?ÿÄΗAŒBwø0AÄΗApBwø0AWá”ApBžj'A HFZ?ÿÄΗAŒBwø0AWá”ApBžj'AWá”AŒBžj'A D\W¿€¢g ¿¿ý–AŒBž]–@¿ý–ApBž]–@MP“ApB>A­@ D\W¿¢g ¿¿ý–AŒBž]–@MP“ApB>A­@MP“AŒB>A­@ €¿@A-ApB=A AWá”ApBžj'AÄΗApBwø0A €¿@A-ApB=A AÄΗApBwø0AApBu‚:A €¿e_yApB>A­@ˆApBy‚Ú@D9ApB\ú@ €¿e_yApB>A­@D9ApB\ú@F6?ApB Ô@ €¿ êsApBø§B@äpApB]Þv@D9ApB¤ã…@ €¿ êsApBø§B@D9ApB¤ã…@@A-ApB ûJ@ €¿rApBž]–@e_yApB>A­@F6?ApB Ô@ €¿rApBž]–@F6?ApB Ô@F6?ApBôù«@ €¿äpApB]Þv@rApBž]–@F6?ApBôù«@ €¿äpApB]Þv@F6?ApBôù«@D9ApB¤ã…@ €¿ ApBÝ&@U™„ApBÙì@³Ò|ApB߇@ €¿ ApBÝ&@³Ò|ApB߇@.ApBÿæ@ €¿¥½¥ApB¨ A¿ý–ApBž]–@Žõ—ApB]Þv@ €¿ÿJ ApBAMP“ApB>A­@¿ý–ApBž]–@ €¿ÿJ ApBA¿ý–ApBž]–@¥½¥ApB¨ A €¿UØšApB¨ AMP“ApB>A­@ÿJ ApBA €?(HB€'HB€AðAHB€A €?(HB€'ðAHB€AðAHB€' €¿ðAHB€'ðAHB€AðApB€A €¿ðAHB€'ðApB€AðApB€' €¿0B€A(0B€'ðA0B€' €¿0B€AðA0B€'ðA0B€A €¿pB€'pB€AŒB€A €¿pB€'ŒB€AŒB€' €?pB€AðApB€ABŒB€A €?pB€ABŒB€AŒB€A €?ðA8B€A8B€A0B€A €?ðA8B€A0B€AðA0B€A €?pBÛ¼KB€A†BXB€A€BhB€A €?pBÛ¼KB€A€BhB€ApBÛ¼WB€A €? BÛ¼-B€A BÛ¼9B€AðA8B€A г]? ?ÝÁ‡A¤AÀ@ÝÁ‡A¤A€'Ñ.oAÀA€' г]? ?ÝÁ‡A¤AÀ@Ñ.oAÀA€'Ñ.oAÀAÀ@ Ù³]?úÿÿ>Ã$²APAÀ@Ã$²APA€'†I¤A€A€' Ù³]?úÿÿ>Ã$²APAÀ@†I¤A€A€'†I¤A€AÀ@ ù5?.¯ =†B%›‹BY0 @ŒB%›‹BY0 @ŒBŒB€' ŽíK¤ù5?.¯ =†B%›‹BY0 @ŒBŒB€'†BŒB' 篠=ø5?ŒBbB!Ù|A†BbB!Ù|A†BXB€A 篠=ø5?ŒBbB!Ù|A†BXB€AŒBXB€A €?FYÈA,ß²AÀ@0A¸AÀAÀ@Á¨A¤AÀ@ €?Þ0­ADBÀ@‡¦Ao˜BÀ@ÝÁ‡AÜAÀ@ €?Þ0­ADBÀ@ÝÁ‡AÜAÀ@Á¨AÜAÀ@ €?ŒBŒB€'ŒB%›‹BY0 @ŒB ƒˆBqqè@ €?¿ý–AŒBž]–@MP“AŒB>A­@ÿJ AŒBA €?UØšAŒB¨ AÿJ AŒBAMP“AŒB>A­@ €¿°•–ApB¦äAˆApBy‚Ú@MP“ApB>A­@ €¿°•–ApB¦äAMP“ApB>A­@UØšApB¨ A €¿IªApB¦äA¥½¥ApB¨ AŽõ—ApB]Þv@ €¿IªApB¦äAŽõ—ApB]Þv@ðApB€' €? BÛ¼'B€A BÛ¼-B€AðA8B€A €? BÛ¼'B€AðA8B€AðA0B€A €?Ï·šAˆAÀ@¦ÄIAwÖ@À@ËVAÕìÙ?À@ €?¦ÄIAwÖ@À@·QIA%Ì?À@âÌQAªÔ°?À@ €?¦ÄIAwÖ@À@âÌQAªÔ°?À@ËVAÕìÙ?À@ €?{É]ACÃ?À@~ojAþ}¢?À@Ï·šA#þ@À@ €?‡¦Ao˜BÀ@G`ŒABÀ@+µ\AØAÀ@ €?‡¦Ao˜BÀ@+µ\AØAÀ@ÝÁ‡AÜAÀ@ €¿Ñ.oAÀA€'¿˜¥?"+iA€'ªçp?¬â}A€' €¿ÆÇ?‹‰\A€'ÝÁ‡A¤A€'³Ý?ÎßTA€' €¿ BÛ¼=B€' BÛ¼9B€'ðA8B€' €¿ BÛ¼=B€'ðA8B€'ðA@B€' €¿ BÛ¼'B€'yãÙA‘gB€'ðA(B€' €¿ BÛ¼9B€' BÛ¼-B€'ðA0B€' €¿ BÛ¼9B€'ðA0B€'ðA8B€' €¿1%ž>Û‡A€'´ï,?fw‰A€'ÂgT?¦í‚A€' €¿1%ž>Û‡A€'ÂgT?¦í‚A€'†mÔ> \ƒA€' €¿=ÛÍAPA€'½{ŸA3ÜÐ>€'‚Ö˜A{ å>€' €?@BŒB€A\BŒB@A¯HBŒBA €?@BŒB€A¯HBŒBAÙ9BŒBpA €?ˆAŒBy‚Ú@D9AŒB\ú@Îp”AŒBÞ>A €?ˆAŒBy‚Ú@Îp”AŒBÞ>A°•–AŒB¦äA ö5?‘° ½Wá”AŒBžj'AWá”ApBžj'AÎp”ApBÞ>A ö5?‘° ½Wá”AŒBžj'AÎp”ApBÞ>AÎp”AŒBÞ>A 8B&?ù©B?°•–AŒB¦äA°•–ApB¦äAUØšApB¨ A 8B&?ù©B?°•–AŒB¦äAUØšApB¨ AUØšAŒB¨ A €?ó/A.V4@À@ßO6AØ*%@À@Ï·šAˆAÀ@ €?ŒÄ”Afû>À@‚Ö˜A{ å>À@¸A#¾@À@ €¿ŒÄ”Afû>€'=ÛÍAPA€'‚Ö˜A{ å>€' €?ŒB ƒˆBqqè@ŒBxã…ByAŒB.uBüdA €?ŒB ƒˆBqqè@ŒB.uBüdAŒBXB€A €?ŒBFž}B»OAŒB.uBüdAŒBxã…ByA €?ŒBFž}B»OAŒBxã…ByAŒBž ‚Bõ5A €?FYÈA,ß²AÀ@Á¨A¤AÀ@Ã$²A˜AÀ@ €?FYÈA,ß²AÀ@Ã$²A˜AÀ@FYÈAÔ ­AÀ@ €?ŒBŒB€'ŒB ƒˆBqqè@ŒBXB€A €?ŒBŒB€'ŒBXB€AŒBàA€' €?¿ý–AŒBž]–@ÿJ AŒBA¥½¥AŒB¨ A €?¿ý–AŒBž]–@¥½¥AŒB¨ A«¿AŒB°@ €?MP“AŒB>A­@ˆAŒBy‚Ú@°•–AŒB¦äA €?MP“AŒB>A­@°•–AŒB¦äAUØšAŒB¨ A €?P.ÿ>»”AÀ@»?¨€AÀ@Ñ.oAÀAÀ@ €?Ï·šAˆAÀ@ßO6AØ*%@À@LBA¦ @À@ €?Ï·šAˆAÀ@LBA¦ @À@¦ÄIAwÖ@À@ €¿Ñ.oAÀA€'ÝÁ‡A¤A€'ÆÇ?‹‰\A€' €¿Ñ.oAÀA€'ÆÇ?‹‰\A€'¿˜¥?"+iA€' €¿yãÙA‘gB€' BÛ¼'B€' BÛ¼B€' €¿yãÙA‘gB€' BÛ¼B€'oÞA¼ñB€' €?¢(ŽAr?À@ŒÄ”Afû>À@¸A#¾@À@ €?PŠAï¬_@À@Ï·šAˆAÀ@šoAˆAÀ@ €?P#Aú›N@À@ó/A.V4@À@Ï·šAˆAÀ@ €?P#Aú›N@À@Ï·šAˆAÀ@PŠAï¬_@À@ €?ªçp?¬â}AÀ@†I¤A€AÀ@ÝÁ‡A¤AÀ@ €?¿˜¥?"+iAÀ@Ã$²APAÀ@†I¤A€AÀ@ €?†I¤A€AÀ@ªçp?¬â}AÀ@’“?ÇqAÀ@ €?†I¤A€AÀ@’“?ÇqAÀ@¿˜¥?"+iAÀ@ ó5¿ó5¿Ù9B€BpA 2B€Br×…A 2BŒBr×…A ó5¿ó5¿Ù9B€BpA 2BŒBr×…AÙ9BŒBpA ó5?ó5?@BpB€A@BŒB€AG=BpBr×…A €? 2BŒBr×…AG=BŒBr×…AÙ9BŒBpA ó5?ÃÐ%ó5?G=BŒBr×…AG=BpBr×…A@BŒB€A €?@BŒB€AÙ9BŒBpAG=BŒBr×…A Ç^º%€?àè!B€Br×…A¹ëBŒBr×…A¹ëBpBr×…A ³»§&ÍÌÌ%€? 2B€Br×…AG=BpBr×…AG=BŒBr×…A €?lòØAwÖ@À@ðçÈA F|@À@‘£AúÕÌ>À@ €?lòØAwÖ@À@‘£AúÕÌ>À@žª¤Aͯf;À@ €?é$@ò(AÀ@i7@Í!AÀ@zTQ@+^"AÀ@ €?é$@ò(AÀ@zTQ@+^"AÀ@ÊÝ6@âé-AÀ@ €?u+"A2U4@À@A*AÇF"@À@ó/A.V4@À@ €?u+"A2U4@À@ó/A.V4@À@P#Aú›N@À@ €?¾ŠAt{)?À@¢(ŽAr?À@¸A#¾@À@ €?¾ŠAt{)?À@¸A#¾@À@Ï·šA#þ@À@ €?oÓŽAæW3>À@d]“Aw¾ß=À@ŒÄ”Afû>À@ €?oÓŽAæW3>À@ŒÄ”Afû>À@¢(ŽAr?À@ 9Û=¦ðdB&€? 2B€Br×…Aàè!B€Br×…A¹ëBpBr×…A ¦€? 2B€Br×…A¹ëBpBr×…AG=BpBr×…A €?àè!B€Br×…A 2B€Br×…AÙ9B€BpA €?àè!B€Br×…AÙ9B€BpA'ýB€BpA îd¿»qè¾€yãÙA‘gBÀ@yãÙA‘gB€'oÞA¼ñB€' îd¿»qè¾yãÙA‘gBÀ@oÞA¼ñB€'oÞA¼ñBÀ@ ¶}¿¤’>ßO6AØ*%@À@ßO6AØ*%@€'òj5Ah– @€' ¶}¿¤’>ßO6AØ*%@À@òj5Ah– @€'òj5Ah– @À@ =ó=¿ÚŸ+?ÊÝ6@âé-AÀ@ÊÝ6@âé-A€'é$@ò(A€' =ó=¿ÚŸ+?ÊÝ6@âé-AÀ@é$@ò(A€'é$@ò(AÀ@ âãz¿ª’K¾€¢(ŽAr?À@¢(ŽAr?€'oÓŽAæW3>€' âãz¿ª’K¾¢(ŽAr?À@oÓŽAæW3>€'oÓŽAæW3>À@ €¿‘£AúÕÌ>€'=ÛÍAPA€' B£XÂ@€' €¿ BÛ¼KB€'pBÛ¼KB€'pBÛ¼IB€' €¿ BÛ¼KB€'pBÛ¼IB€' BÛ¼IB€' €¿¿˜¥?"+iA€'ÆÇ?‹‰\A€'z‰‘?!‚\A€' €¿¿˜¥?"+iA€'z‰‘?!‚\A€'Ùu?Ä1eA€' €¿´ï,?fw‰A€'»?¨€A€'Ó<É@ØA€' €¿´ï,?fw‰A€'Ó<É@ØA€'Ñ.oAÀA€' }.¿R;¿€§Ó@íõ¾@À@§Ó@íõ¾@€'›ß@„Ó³@€' }.¿R;¿§Ó@íõ¾@À@›ß@„Ó³@€'›ß@„Ó³@À@ è`?›ô¾g„ˆAI–>À@g„ˆAI–>€'¾ŠAt{)?€' è`?›ô¾g„ˆAI–>À@¾ŠAt{)?€'¾ŠAt{)?À@ €?ÄΗAŒBwø0AWá”AŒBžj'A@A-AŒB=A A €?ÄΗAŒBwø0A@A-AŒB=A AAŒBu‚:A €?Wá”AŒBžj'AÎp”AŒBÞ>AD9AŒB\ú@ €?Wá”AŒBžj'AD9AŒB\ú@@A-AŒB=A A €?ú –AŒBø§B@Žõ—AŒB]Þv@«¿AŒB°@ €?ú –AŒBø§B@«¿AŒB°@ŒÕÏAŒB@ €?IªAŒB¦äAŒÕÏAŒBA«¿AŒB°@ €?IªAŒB¦äA«¿AŒB°@¥½¥AŒB¨ A Ô³]¿?G`ŒABÀ@G`ŒAB€'+µ\AØA€' Ô³]¿?G`ŒABÀ@+µ\AØA€'+µ\AØAÀ@ Ô³]¿¿€+µ\A BÀ@+µ\A B€'G`ŒAB€' Ô³]¿¿+µ\A BÀ@G`ŒAB€'G`ŒABÀ@ Þ³]¿éÿÿ¾¯HB€BAÙ9B€BpAÙ9BŒBpA Þ³]¿éÿÿ¾¯HB€BAÙ9BŒBpA¯HBŒBA â³]?Ûÿÿ>«¿A€B°@ŒÕÏA€B@ŒÕÏAŒB@ â³]?Ûÿÿ>«¿A€B°@ŒÕÏAŒB@«¿AŒB°@ €?ŒÕÏA€B@«¿A€B°@t*ðA€BA €?ŒÕÏA€B@t*ðA€BAr*B€B°@ w¡u¿Y>>ú –ApBø§B@Žõ—ApB]Þv@Žõ—AŒB]Þv@ w¡u¿Y>>ú –ApBø§B@Žõ—AŒB]Þv@ú –AŒBø§B@ €?ðA@B€AðA8B€A BÛ¼9B€A €?ðA@B€A BÛ¼9B€A BÛ¼=B€A ׳]??Ó<É@ØAÀ@Ó<É@ØA€''L"@B€' ׳]??Ó<É@ØAÀ@'L"@B€''L"@BÀ@ ׳]?¿'L"@BÀ@'L"@B€'Ó<É@ B€' ׳]?¿'L"@BÀ@Ó<É@ B€'Ó<É@ BÀ@ €?½{ŸA3ÜÐ>À@‘£AúÕÌ>À@ðçÈA F|@À@ €?šoAˆ?AÀ@ ”'@À!5AÀ@ÊÝ6@âé-AÀ@ €?šoAˆ?AÀ@ÊÝ6@âé-AÀ@zTQ@+^"AÀ@ €?šoAˆ?AÀ@ÆÇ?‹‰\AÀ@³Ý?ÎßTAÀ@ €?šoAˆ?AÀ@³Ý?ÎßTAÀ@‘í@òŒHAÀ@ €¿oÞA¼ñB€' BÛ¼B€' BÛ¼B€' €¿oÞA¼ñB€' BÛ¼B€'àAB€' €¿Ã$²APA€'´“ƒAHP?€'ï,Al?€' €¿Ã$²APA€'ï,Al?€'GrAÇF?€' €¿¦ÄIAwÖ@€'ËVAÕìÙ?€'âÌQAªÔ°?€' €¿¦ÄIAwÖ@€'âÌQAªÔ°?€'·QIA%Ì?€' €¿ßO6AØ*%@€'Ã$²APA€'ËVAÕìÙ?€' €¿ßO6AØ*%@€'ËVAÕìÙ?€'¦ÄIAwÖ@€' €¿Ã$²APA€'ßO6AØ*%@€'ó/A.V4@€' €¿Ã$²APA€'ó/A.V4@€'P#Aú›N@€' ÞìξG)j¿LBA¦ @€'¦ÄIAwÖ@€'¦ÄIAwÖ@À@ ÞìξG)j¿LBA¦ @€'¦ÄIAwÖ@À@LBA¦ @À@ À}¿Y!¾»?¨€A€'´ï,?fw‰A€'´ï,?fw‰AÀ@ À}¿Y!¾»?¨€A€'´ï,?fw‰AÀ@»?¨€AÀ@ €¿pBÛ¼-B€ApBÛ¼9B€ApBÛ¼9B€' €¿pBÛ¼-B€ApBÛ¼9B€'pBÛ¼-B€' €?ŒBXB€A†BXB€ApBÛ¼9B€A €?ŒBXB€ApBÛ¼9B€ApBÛ¼-B€A €¿=ÛÍAPA€'ŒÄ”Afû>€'¢(ŽAr?€' €¿=ÛÍAPA€'¢(ŽAr?€'Ã$²APA€' €?Ñ.oAÀAÀ@»?¨€AÀ@´ï,?fw‰AÀ@ €?Ñ.oAÀAÀ@´ï,?fw‰AÀ@ÝÁ‡A¤AÀ@ €?ËVAÕìÙ?À@{É]ACÃ?À@Ï·šA#þ@À@ €?ËVAÕìÙ?À@Ï·šA#þ@À@Ï·šAˆAÀ@ €¿oÓŽAæW3>€'¢(ŽAr?€'ŒÄ”Afû>€' €¿oÓŽAæW3>€'ŒÄ”Afû>€'d]“Aw¾ß=€' €?Ã$²APAÀ@¿˜¥?"+iAÀ@ÆÇ?‹‰\AÀ@ €?Ã$²APAÀ@ÆÇ?‹‰\AÀ@šoAˆ?AÀ@ €?ÝÁ‡A¤AÀ@´ï,?fw‰AÀ@ÂgT?¦í‚AÀ@ €?ÝÁ‡A¤AÀ@ÂgT?¦í‚AÀ@ªçp?¬â}AÀ@ €¿G=BpBr×…A¹ëBpBr×…ABpB€A €¿G=BpBr×…ABpB€A@BpB€A ó5?ó5¿àè!BŒBr×…Aàè!B€Br×…A'ýB€BpA ó5?ó5¿àè!BŒBr×…A'ýB€BpA'ýBŒBpA ó5¿ó5?BpB€A¹ëBpBr×…A¹ëBŒBr×…A ó5¿ó5?BpB€A¹ëBŒBr×…ABŒB€A €?¹ëBŒBr×…Aàè!BŒBr×…A'ýBŒBpA €?¹ëBŒBr×…A'ýBŒBpABŒB€A €?‚Ö˜A{ å>À@½{ŸA3ÜÐ>À@ðçÈA F|@À@ €?‚Ö˜A{ å>À@ðçÈA F|@À@¸A#¾@À@ €?1%ž>Û‡AÀ@†mÔ> \ƒAÀ@ÂgT?¦í‚AÀ@ €?1%ž>Û‡AÀ@ÂgT?¦í‚AÀ@´ï,?fw‰AÀ@ €¿‘£AúÕÌ>€' B£XÂ@€'B£XÂ@€' €¿‘£AúÕÌ>€'B£XÂ@€'žª¤Aͯf;€' -Ù|¿}/ ¾€oÞA¼ñBÀ@oÞA¼ñB€'àAB€' -Ù|¿}/ ¾oÞA¼ñBÀ@àAB€'àABÀ@ €?{É]ACÃ?À@É]Aïæ?À@’yfA›Zn?À@ €?{É]ACÃ?À@’yfA›Zn?À@~ojAþ}¢?À@ €?Ó<É@ØAÀ@µ§è>R-˜AÀ@P.ÿ>»”AÀ@ €?Ó<É@ØAÀ@P.ÿ>»”AÀ@Ñ.oAÀAÀ@ sfact-2011.12.18/calibration/overhang.STL000066400000000000000000000150341167321211700176770ustar00rootroot00000000000000STL File created by netfabb - http://www.netfabb.com UNITS=MM„/½;3€¿€|XA4œ*3€54œ*3€|XA A5/½;3€¿€|XA A5€54œ*3€5 A5±?æd1güH½€|XA4œ*3€|XA A5½AYA A‹ìz?±?¯° 1güH½€|XA4œ*3½AYA A‹ìz?½AYA28³„ìz?¬:}?EZÒ1{@¾½AYA28³„ìz?½AYA A‹ìz?Š[A A6·ù?¬:}?,gð1|@¾½AYA28³„ìz?Š[A A6·ù?Š[A[!·³2·ù?ùSx? G2´Ïx¾Š[A[!·³2·ù?Š[A A6·ù?:`_A A@È9@ùSx? G2³Ïx¾Š[A[!·³2·ù?:`_A A@È9@:`_A>´>È9@ q?ý‰2ß|¬¾:`_A>´>È9@:`_A A@È9@fªdA AÜêt@ q?ý‰2ß|¬¾:`_A>´>È9@fªdA AÜêt@fªdA‹œ3´Úêt@Ûkg?_ ¯2wèÚ¾fªdA‹œ3´Úêt@fªdA AÜêt@akA AÓØ–@Ûkg?_ ¯2wèÚ¾fªdA‹œ3´Úêt@akA AÓØ–@akAµ?]´ÒØ–@”[?—“Ò2>œ¿akAµ?]´ÒØ–@akA AÓØ–@‚ssA AQȱ@”[?—“Ò2>œ¿akAµ?]´ÒØ–@‚ssA AQȱ@‚ssA³`‚´Pȱ@ŸM? ÿó2Ä¿‚ssA³`‚´Pȱ@‚ssA AQȱ@ÿÍ|A A€Ë@ŸM? ÿó2Ä¿‚ssA³`‚´Pȱ@ÿÍ|A A€Ë@ÿÍ|Aà”´Ë@ó®=? ‰ 3Pë+¿ÿÍ|Aà”´Ë@ÿÍ|A A€Ë@µ¬ƒA A1Fâ@ó®=? ‰ 3Pë+¿ÿÍ|Aà”´Ë@µ¬ƒA A1Fâ@µ¬ƒA|ð¥´0Fâ@[ë+?!¿3é®=¿µ¬ƒA|ð¥´0Fâ@µ¬ƒA A1Fâ@à}‰A A]÷@[ë+?!¿3é®=¿µ¬ƒA|ð¥´0Fâ@à}‰A A]÷@à}‰A¾gµ´]÷@Å?2$3ÿžM¿à}‰A¾gµ´]÷@à}‰A A]÷@,ÌA A AÀ?5¤3ŸM¿à}‰A¾gµ´]÷@,ÌA A A,ÌAÄôÿAœ?½©¯3,”[¿,ÌAÄôÿA,ÌA A A ˆ–A A~ A+œ?%”[¿,ÌAÄôÿA ˆ–A A~ A ˆ–A·öδ~ A³èÚ>Íkg¿ ˆ–A·öδ~ A ˆ–A A~ Aå A AÒA˜èÚ>#¹3Òkg¿ ˆ–A·öδ~ Aå A AÒAå AmÏØ´ÒAê|¬>ÔÀ3 q¿å AmÏØ´ÒAå A AÒA8¥A AHAê|¬>ÔÀ3 q¿å AmÏØ´ÒA8¥A AHA8¥Aš‘à´GA©Ïx>•©Æ3ûSx¿8¥Aš‘à´GA8¥A AHAÍ¢¬A AøìA©Ïx>•©Æ3ûSx¿8¥Aš‘à´GAÍ¢¬A AøìAÍ¢¬A*æ´÷ìA»@>T•Ê3©:}¿Í¢¬A*æ´÷ìAÍ¢¬A AøìAÜf´A AÆ:A»@>T•Ê3©:}¿Í¢¬A*æ´÷ìAÜf´A AÆ:AÜf´A2‹é´Å:A^ùH=§Ì3±¿Üf´A2‹é´Å:AÜf´A AÆ:A@>¼A A AaúH=±¿Üf´A2‹é´Å:A@>¼A A A@>¼Az¬ê´ A€? Az¬ê´ A@>¼Az¬ê´ A A A A€€? A A A@>¼Az¬ê´ A@>¼A A A`ÄQ§€¿2½;³,ÌAÄôÿA Az¬ê´ Aà}‰A¾gµ´]÷@ºð'€¿)½;³à}‰A¾gµ´]÷@ Az¬ê´ Aµ¬ƒA|ð¥´0Fâ@Ú‘ú'€¿&½;³,ÌAÄôÿA ˆ–A·öδ~ A Az¬ê´ Aoݧ€¿8½;³ Az¬ê´ A ˆ–A·öδ~ Aå AmÏØ´ÒA¬ü¥'€¿!½;³ Az¬ê´ Aå AmÏØ´ÒA8¥Aš‘à´GA(8f&€¿:½;³8¥Aš‘à´GAÍ¢¬A*æ´÷ìA Az¬ê´ Atõ%€¿B½;³ Az¬ê´ AÍ¢¬A*æ´÷ìAÜf´A2‹é´Å:A€¿a½;³ Az¬ê´ AÜf´A2‹é´Å:A@>¼Az¬ê´ A€¿/½;³€54œ*3€|XA4œ*3Ì[!·³2·ù?ýÈŒ)€¿4½;³IwÜ>>´>È9@{ÂD>[!·³2·ù?_ÞB?‹œ3´Úêt@ÿM祀¿.½;³_ÞB?‹œ3´Úêt@{ÂD>[!·³2·ù?½AYA28³„ìz?Srá&€¿,½;³_ÞB?‹œ3´Úêt@½AYA28³„ìz?$—?µ?]´ÒØ–@ó ?'€¿+½;³$—?µ?]´ÒØ–@½AYA28³„ìz?Š[A[!·³2·ù?`Í&€¿,½;³$—?µ?]´ÒØ–@Š[A[!·³2·ù?¸×?³`‚´Pȱ@fÀ#¦€¿-½;³¸×?³`‚´Pȱ@Š[A[!·³2·ù?:`_A>´>È9@f^ ¦€¿-½;³¸×?³`‚´Pȱ@:`_A>´>È9@ûE@à”´Ë@õ𨀿2½;³ÉA*æ´÷ìAakAµ?]´ÒØ–@8QA2‹é´Å:AÍú©'€¿-½;³8QA2‹é´Å:AakAµ?]´ÒØ–@‚ssA³`‚´Pȱ@^¨€¿2½;³8QA2‹é´Å:A‚ssA³`‚´Pȱ@ Az¬ê´ A¢-”'€¿.½;³ Az¬ê´ A‚ssA³`‚´Pȱ@ÿÍ|Aà”´Ë@œ¢5¨€¿4½;³ Az¬ê´ AÿÍ|Aà”´Ë@µ¬ƒA|ð¥´0Fâ@—¬˜*€¿|½;³£s;@|ð¥´0Fâ@ûE@à”´Ë@ýi@¾gµ´]÷@ 9§€¿/½;³ýi@¾gµ´]÷@ûE@à”´Ë@:`_A>´>È9@¶¥ß§€¿2½;³ýi@¾gµ´]÷@:`_A>´>È9@±7Ž@ÄôÿA<´&€¿-½;³±7Ž@ÄôÿA:`_A>´>È9@fªdA‹œ3´Úêt@̽J(€¿'½;³±7Ž@ÄôÿAfªdA‹œ3´Úêt@/'©@·öδ~ A?!'€¿,½;³/'©@·öδ~ AfªdA‹œ3´Úêt@akAµ?]´ÒØ–@ì*)¨€¿3½;³/'©@·öδ~ AakAµ?]´ÒØ–@“ŠÅ@mÏØ´ÒAúV'€¿,½;³“ŠÅ@mÏØ´ÒAakAµ?]´ÒØ–@ÉA*æ´÷ìAú©€¿Ù¼;³“ŠÅ@mÏØ´ÒAÉA*æ´÷ìAãã@š‘à´GA€? A A A8¥A AHAå A AÒA€?@>¼A A AÜf´A AÆ:A A A A€? A A AÜf´A AÆ:AÍ¢¬A AøìA€? A A AÍ¢¬A AøìA8¥A AHA€?å A AÒA ˆ–A A~ A A A A€? A A A ˆ–A A~ A,ÌA A A€? A A A,ÌA A Aà}‰A A]÷@€?à}‰A A]÷@µ¬ƒA A1Fâ@ A A A€? A A Aµ¬ƒA A1Fâ@ÿÍ|A A€Ë@€? A A AÿÍ|A A€Ë@8QA AÆ:A€?8QA AÆ:AÿÍ|A A€Ë@‚ssA AQȱ@€?8QA AÆ:A‚ssA AQȱ@ÉA AøìA€?ÉA AøìA‚ssA AQȱ@akA AÓØ–@€?ÉA AøìAakA AÓØ–@ãã@ AHA€?ãã@ AHAakA AÓØ–@“ŠÅ@ AÒA€?“ŠÅ@ AÒAakA AÓØ–@/'©@ A~ A€?/'©@ A~ AakA AÓØ–@fªdA AÜêt@€?/'©@ A~ AfªdA AÜêt@±7Ž@ A A€?±7Ž@ A AfªdA AÜêt@ýi@ A]÷@€?ýi@ A]÷@fªdA AÜêt@:`_A A@È9@€?ýi@ A]÷@:`_A A@È9@£s;@ A1Fâ@€?€Š[A A6·ù?¸×? AQȱ@:`_A A@È9@€?:`_A A@È9@¸×? AQȱ@ûE@ A€Ë@€?:`_A A@È9@ûE@ A€Ë@£s;@ A1Fâ@€€?{ÂD> A6·ù?IwÜ> A@È9@½AYA A‹ìz?€?½AYA A‹ìz?IwÜ> A@È9@_ÞB? AÜêt@€?€½AYA A‹ìz?_ÞB? AÜêt@Š[A A6·ù?€?Š[A A6·ù?_ÞB? AÜêt@$—? AÓØ–@€?Š[A A6·ù?$—? AÓØ–@¸×? AQȱ@€?{ÂD> A6·ù?½AYA A‹ìz?Ìœ?¸×?³`‚´Pȱ@¸×? AQȱ@$—? AÓØ–@”[¿—“Ò²>œ?¸×?³`‚´Pȱ@$—? AÓØ–@$—?µ?]´ÒØ–@Ùkg¿c ¯²|èÚ>$—?µ?]´ÒØ–@$—? AÓØ–@_ÞB? AÜêt@Ùkg¿c ¯²|èÚ>$—?µ?]´ÒØ–@_ÞB? AÜêt@_ÞB?‹œ3´Úêt@ q¿wý‰²Õ|¬>_ÞB?‹œ3´Úêt@_ÞB? AÜêt@IwÜ> A@È9@ q¿wý‰²Õ|¬>_ÞB?‹œ3´Úêt@IwÜ> A@È9@IwÜ>>´>È9@ùSx¿£ G²ËÏx>IwÜ>>´>È9@IwÜ> A@È9@{ÂD> A6·ù?ùSx¿£ G²ËÏx>IwÜ>>´>È9@{ÂD> A6·ù?{ÂD>[!·³2·ù?¬:}¿8gð±ƒ@>{ÂD>[!·³2·ù?{ÂD> A6·ù?Ì{ÂD>[!·³2·ù?̈A A B4pA A B”A”AÍLBËc¿V¢é>”A”AÍLB4pA A BŒAŒA€ BËc¿V¢é> B·Q8€? B·Q8€?BvÚAË'ö@€AËc¿V¢é>BvÚAË'ö@€A B·Q8€?¼A„A3³BËc¿V¢é>BvÚAË'ö@€A¼A„A3³B¨A5`AgfâAËc¿V¢é>°A A B¨A˜A33B¬A”AÍLBËc¿V¢é>¨A5`AgfâA¼A„A3³B¬A”AÍLBËc¿V¢é>¬A”AÍLB¼A„A3³BØA A BËc¿V¢é>¬A”AÍLBØA A B°A A BËc¿V¢é>¬A”AÍLB”A”AÍLB¨A5`AgfâAËc¿V¢é>¨A5`AgfâA”A”AÍLBŒAŒA€ BËc¿V¢é>¨A5`AgfâAŒAŒA€ BækAË'ö@€AËc¿V¢é>ækAË'ö@€AŒAŒA€ B·Q8·Q8€?Ëc¿V¢é>ækAË'ö@€A·Q8·Q8€?ià@·Q8€?Ëc?V¢é¾ØAØA B¼A¼A3³B AØA BËc?V¢é¾ AØA B¼A¼A3³B¤A¼A3³BËc?V¢é¾Ë'ö@ækA€A4xA´AÍÌùAækAækA€AËc?V¢é¾ækAækA€A4xA´AÍÌùAŒA´AÍÌùAËc?V¢é¾„A¼A3³B AØA B”A¼A3³BËc?V¢é¾”A¼A3³B AØA B¤A¼A3³BËc?V¢é¾”A¼A3³B¤A¼A3³BŒA´AÍÌùAËc?V¢é¾ŒA´AÍÌùA¤A¼A3³B°A°AòAËc?V¢é¾ŒA´AÍÌùA°A°AòAækAækA€AËc?V¢é> AˆA B¬A”AÍLB AA BËc?V¢é> AA B¬A”AÍLB¨A˜A33BËc?V¢é¾¸A¨AÍÌBÀA¨AÍÌB¨A˜AgfâAËc?V¢é¾¨A˜AgfâAÀA¨AÍÌB ;BæKA€AËc?V¢é¾¨A˜AgfâA ;BæKA€ABvÚAæKA€AËc?V¢é¾ØAØA BØA A B¼A¼A3³BËc?V¢é¾¼A¼A3³BØA A B¼A„A3³BËc?V¢é¾¨A5`AgfâAækAË'ö@€A¨A˜AgfâAËc?V¢é¾¨A˜AgfâAækAË'ö@€AækAækA€AËc?V¢é¾¨A˜AgfâAækAækA€A¸A¨AÍÌBËc?V¢é¾¸A¨AÍÌBækAækA€A°A°AòAËc?V¢é> B B€? B B€? ;BAvêA€AËc?V¢é> ;BAvêA€A B B€?¼A¼A3³BËc?V¢é> ;BAvêA€A¼A¼A3³BÀA¨AÍÌBËc?V¢é>ÀA¨AÍÌB¼A¼A3³B¼A„A3³BËc?V¢é>ÀA¨AÍÌB¼A„A3³B ;BæKA€AËc?V¢é> ;BæKA€A¼A„A3³B B·Q8€?Ëc?V¢é> ;BæKA€A B·Q8€? Bh @€?Ëc?V¢é¾ŒA´A€ B4pAÈA B AÈA BËc¿V¢é¾BvÚAË'ö@€A¨A5`AgfâABvÚAæKA€AËc¿V¢é¾BvÚAæKA€A¨A5`AgfâA¨A˜AgfâAËc¿V¢é¾4pA A B4pAÈA BŒAŒA€ BËc¿V¢é¾ŒAŒA€ B4pAÈA BŒA´A€ B€¿·Q8 B€?·Q8 B·Q8 B€?€¿·Q8 B€?·Q8 B·Q8·Q8€¿·Q8 B€?·Q8·Q8·Q8ià@€?€¿·Q8ià@€?·Q8·Q8·Q8·Q8€?€¿·Q8·Q8€?·Q8·Q8ià@·Q8€?€¿ià@·Q8€?·Q8·Q8 B·Q8€¿ià@·Q8€? B·Q8 B·Q8€?€¿ B·Q8€? B·Q8 B·Q8€?€? B·Q8€? B·Q8 Bh @€?€? Bh @€? B·Q8 B B€? Bh @€? B B B B€?€? B B€? B B B B€?€? B B€? B B B B€?€? B B€? B B·Q8 B€? B B€?·Q8 BÒ@ B€?€?Ò@ B€?·Q8 B·Q8 B€?€¿ B B B·Q8·Q8 B€¿·Q8 B B·Q8·Q8·Q8€?4pAÈA B4pA A BˆA A B€?ˆAˆA B AˆA BˆA A B€?ˆA A B AˆA B AA B€?ˆA A B AA B4pAÈA B€? AA B°AA B4pAÈA B€?4pAÈA B°AA B°A A B€?4pAÈA B°A A B AÈA B€? AÈA B°A A BØA A B€? AÈA BØA A B AØA B€? AØA BØA A BØAØA BËc¿V¢é> AØA B„A¼A3³B AÈA BËc¿V¢é> AÈA B„A¼A3³BŒA´A€ BËc¿V¢é>·Q8ià@€?·Q8·Q8€?Ë'ö@ækA€AËc¿V¢é>Ë'ö@ækA€A·Q8·Q8€?ŒAŒA€ BËc¿V¢é>Ë'ö@ækA€AŒAŒA€ B4xA´AÍÌùAËc¿V¢é>ŒAŒA€ BŒA´A€ B4xA´AÍÌùAËc¿V¢é>4xA´AÍÌùAŒA´A€ B„A¼A3³BËc¿V¢é>4xA´AÍÌùA„A¼A3³BË'ö@AvòA€AËc¿V¢é>Ë'ö@AvòA€A„A¼A3³B·Q8 B€?Ëc¿V¢é>Ë'ö@AvòA€A·Q8 B€?·Q8 B€?Ëc¿V¢é¾AvêAAvêA€A°A°AòAAvêA ;B€AËc¿V¢é¾AvêA ;B€A°A°AòA¤A¼A3³BËc?V¢é>¤A¼A3³B¼A¼A3³BAvêA ;B€AËc?V¢é>AvêA ;B€A¼A¼A3³B B B€?Ëc?V¢é>AvêA ;B€A B B€? B B€?Ëc¿V¢é¾AvêAAvêA€A ;BAvêA€A°A°AòAËc¿V¢é¾°A°AòA ;BAvêA€AÀA¨AÍÌBËc¿V¢é¾°A°AòAÀA¨AÍÌB¸A¨AÍÌBËc¿V¢é¾ˆA A B”A”AÍLBˆAˆA BËc¿V¢é¾¬A”AÍLB AˆA B”A”AÍLBËc¿V¢é¾”A”AÍLB AˆA BˆAˆA BËc¿V¢é¾ AA B¨A˜A33B°AA BËc?V¢é¾¨A˜A33B°A A B°AA BËc¿V¢é¾æAAvòA€AŒA´AÍÌùAË'ö@AvòA€AËc¿V¢é¾Ë'ö@AvòA€AŒA´AÍÌùA4xA´AÍÌùAËc?V¢é¾æA ;B€A”A¼A3³BæAAvòA€AËc?V¢é¾æAAvòA€A”A¼A3³BŒA´AÍÌùAËc?V¢é>Ò@ B€?·Q8 B€?æA ;B€AËc?V¢é>æA ;B€A·Q8 B€?„A¼A3³BËc?V¢é>æA ;B€A„A¼A3³B”A¼A3³B Ë¥€¿ƒÞAË'ö@pABvÚAË'ö@€AbßbAË'ö@pA Ë¥€¿bßbAË'ö@pABvÚAË'ö@€AækAË'ö@€A€?€¢% ;BƒîApA ;BAvêA€A ;BcßBApA€?€¢% ;BcßBApA ;BAvêA€A ;BæKA€A€¿Àó¤Ë'ö@AvòA€AË'ö@„öApAË'ö@ækA€A€¿Àó¤Ë'ö@ækA€AË'ö@„öApAË'ö@bßbApA€¿ ;BcßBApAƒÞAcßBApA ;BƒîApA€¿ ;BƒîApAƒÞAcßBApAƒîAƒîApA€¿Ë'ö@bßbApAË'ö@„öApAbßbAbßbApA€¿bßbAbßbApAË'ö@„öApAbßA„öApA€¿bßA ;BpAƒîA ;BpAbßA„öApA€¿bßA„öApAƒîA ;BpAƒîAƒîApA€¿bßA„öApAƒîAƒîApAbßbAbßbApA€¿bßbAbßbApAƒîAƒîApAƒÞAcßBApA€¿bßbAbßbApAƒÞAcßBApAbßbAË'ö@pA€¿bßbAË'ö@pAƒÞAcßBApAƒÞAË'ö@pA€¢%€?bßA ;BpAæA ;B€AƒîA ;BpA€¢%€?ƒîA ;BpAæA ;B€AAvêA ;B€A€?ækAækA€AækAË'ö@€ABvÚAË'ö@€A€?AvêAAvêA€AAvêA ;B€AæA ;B€A€? ;BæKA€A ;BAvêA€ABvÚAæKA€A€?BvÚAæKA€A ;BAvêA€AAvêAAvêA€A€?BvÚAæKA€AAvêAAvêA€AæAAvòA€A€?æAAvòA€AAvêAAvêA€AæA ;B€A€?Ë'ö@AvòA€AË'ö@ækA€AæAAvòA€A€?æAAvòA€AË'ö@ækA€AækAækA€A€?æAAvòA€AækAækA€ABvÚAæKA€A€?BvÚAæKA€AækAækA€ABvÚAË'ö@€Asfact-2011.12.18/calibration/retraction.STL000066400000000000000000001206501167321211700202410ustar00rootroot00000000000000solid newretracttest :€?âKuA› žAÌÌÌ> ˆ…A› žAÌÌÌ> ˆ…A¸2ªAÌÌÌ>€?âKuAŽI™AÌÌÌ>]OA£Š—AÌÌÌ> ˆ…AŽI™AÌÌÌ>€? ˆ…AŽI™AÌÌÌ>]OA£Š—AÌÌÌ> ˆ…A£Š—AÌÌÌ>€? ˆ…AŽI™AÌÌÌ> ˆ…A£Š—AÌÌÌ>ƒÇ¥AŽI™AÌÌÌ>€?yB/A¸2ªAÌÌÌ>]OA› žAÌÌÌ>]OA¸2ªAÌÌÌ>€?]OA¸2ªAÌÌÌ>]OA› žAÌÌÌ>’ÝdA› žAÌÌÌ>€? ˆ…A¸2ªAÌÌÌ> ˆ…A› žAÌÌÌ>DP±A¸2ªAÌÌÌ>€?DP±A¸2ªAÌÌÌ> ˆ…A› žAÌÌÌ>ƒÇ¥A› žAÌÌÌ>€?DP±A¸2ªAÌÌÌ>ƒÇ¥A› žAÌÌÌ>DP±A£Š—AÌÌÌ>€?Ið @£Š—AÌÌÌ>"²é@£Š—AÌÌÌ>Ið @ŽI™AÌÌÌ>€?Ið @ŽI™AÌÌÌ>"²é@£Š—AÌÌÌ>"²é@ŽI™AÌÌÌ>€?"²é@ŽI™AÌÌÌ>"²é@£Š—AÌÌÌ>>¼ì@ŽI™AÌÌÌ>€?>¼ì@ŽI™AÌÌÌ>"²é@£Š—AÌÌÌ>=Šô@£Š—AÌÌÌ>€?>¼ì@ŽI™AÌÌÌ>=Šô@£Š—AÌÌÌ>>¼ì@› žAÌÌÌ>€?>¼ì@› žAÌÌÌ>=Šô@£Š—AÌÌÌ>=Šô@¸2ªAÌÌÌ>€?>¼ì@› žAÌÌÌ>=Šô@¸2ªAÌÌÌ>"²é@› žAÌÌÌ>€?"²é@› žAÌÌÌ>=Šô@¸2ªAÌÌÌ>"²é@¸2ªAÌÌÌ>€?"²é@› žAÌÌÌ>"²é@¸2ªAÌÌÌ>Ið @¸2ªAÌÌÌ>€?Ið @£Š—AÌÌÌ>Ið @ŽI™AÌÌÌ>£Š—AÌÌÌ>€?£Š—AÌÌÌ>Ið @ŽI™AÌÌÌ>¸É?ŽI™AÌÌÌ>€?£Š—AÌÌÌ>¸É?ŽI™AÌÌÌ>¸2ªAÌÌÌ>€?¸2ªAÌÌÌ>¸É?ŽI™AÌÌÌ>¸É?› žAÌÌÌ>€?¸2ªAÌÌÌ>¸É?› žAÌÌÌ>Ið @¸2ªAÌÌÌ>€?Ið @¸2ªAÌÌÌ>¸É?› žAÌÌÌ>Ið @› žAÌÌÌ>€?Ið @¸2ªAÌÌÌ>Ið @› žAÌÌÌ>"²é@› žAÌÌÌ>€?"²é@æ‚AÌÌÌ>"²é@#û…AÌÌÌ>Ið @#û…AÌÌÌ>€?ƒÇ¥A#û…AÌÌÌ> ˆ…A#û…AÌÌÌ> ˆ…Aæ‚AÌÌÌ>€? ˆ…Aæ‚AÌÌÌ> ˆ…A#û…AÌÌÌ>]OA#û…AÌÌÌ>€? ˆ…Aæ‚AÌÌÌ>]OA#û…AÌÌÌ>]OAæ‚AÌÌÌ>€?]OAæ‚AÌÌÌ>]OA#û…AÌÌÌ>yB/A#û…AÌÌÌ>€?]OAæ‚AÌÌÌ>yB/A#û…AÌÌÌ>yB/Aæ‚AÌÌÌ>€?yB/Aæ‚AÌÌÌ>yB/A#û…AÌÌÌ>=Šô@#û…AÌÌÌ>€?yB/Aæ‚AÌÌÌ>=Šô@#û…AÌÌÌ>=Šô@æ‚AÌÌÌ>€?=Šô@æ‚AÌÌÌ>=Šô@#û…AÌÌÌ>"²é@#û…AÌÌÌ>€?ƒÇ¥A#û…AÌÌÌ>DP±Aæ‚AÌÌÌ>ƒÇ¥A$ŒAÌÌÌ>€?ƒÇ¥A$ŒAÌÌÌ>DP±Aæ‚AÌÌÌ>DP±AŽAÌÌÌ>€?ƒÇ¥A$ŒAÌÌÌ>DP±AŽAÌÌÌ> ˆ…A$ŒAÌÌÌ>€?âKuA‚@`AÌÌÌ>N”aA‚@`AÌÌÌ>]OAß×_AÌÌÌ>€?]OAß×_AÌÌÌ>N”aA‚@`AÌÌÌ>]OAž…qAÌÌÌ>€?âKuA‚@`AÌÌÌ> ˆ…Aß×_AÌÌÌ>âKuAž…qAÌÌÌ>€?âKuAž…qAÌÌÌ> ˆ…Aß×_AÌÌÌ> ˆ…Až…qAÌÌÌ>€?âKuAž…qAÌÌÌ> ˆ…Až…qAÌÌÌ>âKuAHŒtAÌÌÌ>€?âKuAHŒtAÌÌÌ> ˆ…Až…qAÌÌÌ> ˆ…Aæ‚AÌÌÌ>€?âKuAHŒtAÌÌÌ> ˆ…Aæ‚AÌÌÌ>N”aAHŒtAÌÌÌ>€?N”aAHŒtAÌÌÌ> ˆ…Aæ‚AÌÌÌ>]OAæ‚AÌÌÌ>€?N”aAHŒtAÌÌÌ>]OAæ‚AÌÌÌ>N”aAž…qAÌÌÌ>€?ˆá#AtuAÌÌÌ>:ï$Až…qAÌÌÌ>yB/Až…qAÌÌÌ>€?yB/Až…qAÌÌÌ>:ï$Až…qAÌÌÌ>OÆ%AêbnAÌÌÌ>€?yB/Až…qAÌÌÌ>OÆ%AêbnAÌÌÌ>yB/Aß×_AÌÌÌ>€?ç£A‚@`AÌÌÌ>³’AH%bAÌÌÌ>=Šô@ß×_AÌÌÌ>€?=Šô@ß×_AÌÌÌ>³’AH%bAÌÌÌ>Ff AµQgAÌÌÌ>€?=Šô@ß×_AÌÌÌ>Ff AµQgAÌÌÌ>=Šô@ž…qAÌÌÌ>€?OÆ%AêbnAÌÌÌ>ˆá#AµQgAÌÌÌ>yB/Aß×_AÌÌÌ>€?yB/Aß×_AÌÌÌ>ˆá#AµQgAÌÌÌ>µAH%bAÌÌÌ>€?yB/Aß×_AÌÌÌ>µAH%bAÌÌÌ>ç£A‚@`AÌÌÌ>€?Ff AµQgAÌÌÌ> AêbnAÌÌÌ>=Šô@ž…qAÌÌÌ>€?=Šô@ž…qAÌÌÌ> AêbnAÌÌÌ>•X Až…qAÌÌÌ>€?=Šô@ž…qAÌÌÌ>•X Až…qAÌÌÌ>=Šô@æ‚AÌÌÌ>€?•X Až…qAÌÌÌ>Ff AtuAÌÌÌ>=Šô@æ‚AÌÌÌ>€?=Šô@æ‚AÌÌÌ>Ff AtuAÌÌÌ>³’AŒ zAÌÌÌ>€?=Šô@æ‚AÌÌÌ>³’AŒ zAÌÌÌ>yB/Aæ‚AÌÌÌ>€?yB/Aæ‚AÌÌÌ>³’AŒ zAÌÌÌ>ç£AQ…|AÌÌÌ>€?yB/Aæ‚AÌÌÌ>ç£AQ…|AÌÌÌ>µAŒ zAÌÌÌ>€?i$j@øLAÌÌÌ>,]H@{KAÌÌÌ>fÆDAÌÌÌ>€?§úŠ@ß×_AÌÌÌ>§úŠ@HxXAÌÌÌ>Ið @fÆDAÌÌÌ>€?Ið @fÆDAÌÌÌ>§úŠ@HxXAÌÌÌ>›ƒ@ ðPAÌÌÌ>€?Ið @fÆDAÌÌÌ>›ƒ@ ðPAÌÌÌ>i$j@øLAÌÌÌ>€?,]H@{KAÌÌÌ>{Œ(@²NAÌÌÌ>fÆDAÌÌÌ>€?fÆDAÌÌÌ>{Œ(@²NAÌÌÌ>/ü@¸vTAÌÌÌ>€?fÆDAÌÌÌ>/ü@¸vTAÌÌÌ>ß×_AÌÌÌ>€?{Œ(@YkAÌÌÌ>,]H@Ç]nAÌÌÌ>ž…qAÌÌÌ>€?/ü@¸vTAÌÌÌ>× @ ¹\AÌÌÌ>ß×_AÌÌÌ>€?ß×_AÌÌÌ>× @ ¹\AÌÌÌ>ë @ß×_AÌÌÌ>€?ß×_AÌÌÌ>ë @ß×_AÌÌÌ>ž…qAÌÌÌ>€?ž…qAÌÌÌ>ë @ß×_AÌÌÌ>/ü@ŠûdAÌÌÌ>€?ž…qAÌÌÌ>/ü@ŠûdAÌÌÌ>{Œ(@YkAÌÌÌ>€?,]H@Ç]nAÌÌÌ>i$j@IWmAÌÌÌ>Ið @ž…qAÌÌÌ>€?Ið @ž…qAÌÌÌ>i$j@IWmAÌÌÌ>›ƒ@8‚hAÌÌÌ>€?Ið @ž…qAÌÌÌ>›ƒ@8‚hAÌÌÌ>Ið @ß×_AÌÌÌ>€?Ið @ß×_AÌÌÌ>›ƒ@8‚hAÌÌÌ>§úŠ@ùù`AÌÌÌ>€?]OA‚Y(AÌÌÌ>]OAê@ÌÌÌ>ºx]A¹ÈAÌÌÌ>€?ºx]A¹ÈAÌÌÌ>]OAê@ÌÌÌ>ºx]A¬áì@ÌÌÌ>€?ºx]A¹ÈAÌÌÌ>ºx]A¬áì@ÌÌÌ>3ÖA¹ÈAÌÌÌ>€?3ÖA¹ÈAÌÌÌ>ºx]A¬áì@ÌÌÌ>3ÖA¬áì@ÌÌÌ>€?3ÖAÉ)AÌÌÌ>3ÖAÓ+)AÌÌÌ> ˆ…AÓ+)AÌÌÌ>€? ˆ…AÓ+)AÌÌÌ>3ÖAÓ+)AÌÌÌ>3ÖA‚Y(AÌÌÌ>€? ˆ…AÓ+)AÌÌÌ>3ÖA‚Y(AÌÌÌ> ˆ…A‚Y(AÌÌÌ>€?ºx]AÓ+)AÌÌÌ>ºx]AÉ)AÌÌÌ>]OAúI5AÌÌÌ>€?ºx]A¹ÈAÌÌÌ>ºx]A‚Y(AÌÌÌ>]OA‚Y(AÌÌÌ>€?]OA‚Y(AÌÌÌ>ºx]A‚Y(AÌÌÌ>ºx]AÓ+)AÌÌÌ>€?]OA‚Y(AÌÌÌ>ºx]AÓ+)AÌÌÌ>]OAÓ+)AÌÌÌ>€?]OAÓ+)AÌÌÌ>ºx]AÓ+)AÌÌÌ>]OAúI5AÌÌÌ>€? ˆ…Aê@ÌÌÌ>ý“Aê@ÌÌÌ>ý“A¬áì@ÌÌÌ>€? ˆ…A‚Y(AÌÌÌ> ˆ…Aê@ÌÌÌ>ý“A¹ÈAÌÌÌ>€?ý“A¹ÈAÌÌÌ> ˆ…Aê@ÌÌÌ>ý“A¬áì@ÌÌÌ>€?ý“A¹ÈAÌÌÌ>ý“A¬áì@ÌÌÌ>á"¤A¹ÈAÌÌÌ>€?á"¤A¹ÈAÌÌÌ>ý“A¬áì@ÌÌÌ>üéªA¬áì@ÌÌÌ>€?á"¤A¹ÈAÌÌÌ>üéªA¬áì@ÌÌÌ>á"¤A‚Y(AÌÌÌ>€?>¼ì@*§ˆ@ÌÌÌ>"²é@°—@ÌÌÌ>>¼ì@i[@ÌÌÌ>€?>¼ì@i[@ÌÌÌ>"²é@°—@ÌÌÌ>"²é@i[‚?ÌÌÌ>€?>¼ì@i[@ÌÌÌ>"²é@i[‚?ÌÌÌ>=Šô@i[@ÌÌÌ>€?=Šô@i[@ÌÌÌ>"²é@i[‚?ÌÌÌ>=Šô@i[‚?ÌÌÌ>€?=Šô@i[@ÌÌÌ>=Šô@i[‚?ÌÌÌ>æ?'Ai[@ÌÌÌ>€?æ?'Ai[@ÌÌÌ>=Šô@i[‚?ÌÌÌ>yB/Ai[‚?ÌÌÌ>€?æ?'Ai[@ÌÌÌ>yB/Ai[‚?ÌÌÌ>æ?'A*§ˆ@ÌÌÌ>€?æ?'A*§ˆ@ÌÌÌ>yB/Ai[‚?ÌÌÌ>yB/A°—@ÌÌÌ>€?æ?'A*§ˆ@ÌÌÌ>yB/A°—@ÌÌÌ>=Šô@*§ˆ@ÌÌÌ>€?=Šô@*§ˆ@ÌÌÌ>yB/A°—@ÌÌÌ>=Šô@°—@ÌÌÌ>€?3ÖA‚Y(AÌÌÌ>3ÖA¹ÈAÌÌÌ> ˆ…A‚Y(AÌÌÌ>€? ˆ…A‚Y(AÌÌÌ>3ÖA¹ÈAÌÌÌ>3ÖA¬áì@ÌÌÌ>€? ˆ…A‚Y(AÌÌÌ>3ÖA¬áì@ÌÌÌ> ˆ…Aê@ÌÌÌ>€? ˆ…Aê@ÌÌÌ>3ÖA¬áì@ÌÌÌ>3ÖAê@ÌÌÌ>€? ˆ…Aê@ÌÌÌ>3ÖAê@ÌÌÌ> ˆ…A°—@ÌÌÌ>€? ˆ…A°—@ÌÌÌ>3ÖAê@ÌÌÌ>3ÖA6h¥@ÌÌÌ>€? ˆ…A°—@ÌÌÌ>3ÖA6h¥@ÌÌÌ>]OA°—@ÌÌÌ>€?]OA°—@ÌÌÌ>3ÖA6h¥@ÌÌÌ>ºx]A6h¥@ÌÌÌ>€?]OA°—@ÌÌÌ>ºx]A6h¥@ÌÌÌ>]OAê@ÌÌÌ>€?]OAê@ÌÌÌ>ºx]A6h¥@ÌÌÌ>ºx]Aê@ÌÌÌ>€?]OAê@ÌÌÌ>ºx]Aê@ÌÌÌ>ºx]A¬áì@ÌÌÌ>€?n’@¬áì@ÌÌÌ>n’@¹ÈAÌÌÌ>Ï‘$@¬áì@ÌÌÌ>€?Ï‘$@¬áì@ÌÌÌ>n’@¹ÈAÌÌÌ>Ï‘$@¹ÈAÌÌÌ>€?Ï‘$@î$(AÌÌÌ>‚Y(AÌÌÌ>Ï‘$@¹ÈAÌÌÌ>€?Ï‘$@¹ÈAÌÌÌ>‚Y(AÌÌÌ>ê@ÌÌÌ>€?Ï‘$@¹ÈAÌÌÌ>ê@ÌÌÌ>Ï‘$@¬áì@ÌÌÌ>€?n’@î$(AÌÌÌ>n’@¹ÈAÌÌÌ>Ið @‚Y(AÌÌÌ>€?Ið @‚Y(AÌÌÌ>n’@¹ÈAÌÌÌ>n’@¬áì@ÌÌÌ>€?Ið @‚Y(AÌÌÌ>n’@¬áì@ÌÌÌ>Ið @ê@ÌÌÌ>€?Ið @ê@ÌÌÌ>n’@¬áì@ÌÌÌ>n’@ê@ÌÌÌ>€?Ið @ê@ÌÌÌ>n’@ê@ÌÌÌ>Ið @°—@ÌÌÌ>€?Ið @°—@ÌÌÌ>n’@ê@ÌÌÌ>n’@6h¥@ÌÌÌ>€?Ið @°—@ÌÌÌ>n’@6h¥@ÌÌÌ>°—@ÌÌÌ>€?°—@ÌÌÌ>n’@6h¥@ÌÌÌ>Ï‘$@6h¥@ÌÌÌ>€?°—@ÌÌÌ>Ï‘$@6h¥@ÌÌÌ>ê@ÌÌÌ>€?ê@ÌÌÌ>Ï‘$@6h¥@ÌÌÌ>Ï‘$@ê@ÌÌÌ>€?ê@ÌÌÌ>Ï‘$@ê@ÌÌÌ>Ï‘$@¬áì@ÌÌÌ>€?=Šô@Ó+)AÌÌÌ>€?=Šô@Ó+)AÌÌÌ>=Šô@‚Y(AÌÌÌ>€?=Šô@‚Y(AÌÌÌ>€?=Šô@‚Y(AÌÌÌ>=Šô@ê@ÌÌÌ>€?=Šô@ê@ÌÌÌ>æ?'A¹ÈAÌÌÌ>€?æ?'A¹ÈAÌÌÌ>yB/Aê@ÌÌÌ>æ?'A‚Y(AÌÌÌ>€?æ?'A‚Y(AÌÌÌ>yB/Aê@ÌÌÌ>yB/A‚Y(AÌÌÌ>€?æ?'A‚Y(AÌÌÌ>yB/A‚Y(AÌÌÌ>æ?'AŽ(AÌÌÌ>€?æ?'AŽ(AÌÌÌ>yB/A‚Y(AÌÌÌ>yB/AÓ+)AÌÌÌ>€?ý“Aê@ÌÌÌ> ˆ…Aê@ÌÌÌ>ý“A6h¥@ÌÌÌ>€?ý“A6h¥@ÌÌÌ> ˆ…Aê@ÌÌÌ> ˆ…A°—@ÌÌÌ>€?ý“A6h¥@ÌÌÌ> ˆ…A°—@ÌÌÌ>üéªA6h¥@ÌÌÌ>€?üéªA6h¥@ÌÌÌ> ˆ…A°—@ÌÌÌ>DP±A°—@ÌÌÌ>€?üéªA6h¥@ÌÌÌ>DP±A°—@ÌÌÌ>üéªAê@ÌÌÌ>€?üéªAê@ÌÌÌ>DP±A°—@ÌÌÌ>DP±Aê@ÌÌÌ>€?üéªAê@ÌÌÌ>DP±Aê@ÌÌÌ>üéªA¬áì@ÌÌÌ>€?üéªA¬áì@ÌÌÌ>DP±Aê@ÌÌÌ>DP±A‚Y(AÌÌÌ>€?üéªA¬áì@ÌÌÌ>DP±A‚Y(AÌÌÌ>á"¤A‚Y(AÌÌÌ>€?á"¤A‚Y(AÌÌÌ>DP±A‚Y(AÌÌÌ>DP±AÓ+)AÌÌÌ>€?á"¤A‚Y(AÌÌÌ>DP±AÓ+)AÌÌÌ>á"¤AÓ+)AÌÌÌ>€?á"¤AÓ+)AÌÌÌ>DP±AÓ+)AÌÌÌ>á"¤A1n+AÌÌÌ>€?á"¤A1n+AÌÌÌ>DP±AÓ+)AÌÌÌ>DP±AúI5AÌÌÌ>€?á"¤A1n+AÌÌÌ>DP±AúI5AÌÌÌ>ý“A1n+AÌÌÌ>€?ý“A1n+AÌÌÌ>DP±AúI5AÌÌÌ> ˆ…AúI5AÌÌÌ>€?ý“A1n+AÌÌÌ> ˆ…AúI5AÌÌÌ>ý“AÓ+)AÌÌÌ>€?ý“A¹ÈAÌÌÌ>ý“A‚Y(AÌÌÌ> ˆ…A‚Y(AÌÌÌ>€? ˆ…A‚Y(AÌÌÌ>ý“A‚Y(AÌÌÌ>ý“AÓ+)AÌÌÌ>€? ˆ…A‚Y(AÌÌÌ>ý“AÓ+)AÌÌÌ> ˆ…AÓ+)AÌÌÌ>€? ˆ…AÓ+)AÌÌÌ>ý“AÓ+)AÌÌÌ> ˆ…AúI5AÌÌÌ>€? ˆ…AÓ+)AÌÌÌ> ˆ…AúI5AÌÌÌ>3ÖAÉ)AÌÌÌ>€?Ið @fÆDAÌÌÌ>ð?½@â­EAÌÌÌ>U%³@/»JAÌÌÌ>€?U%³@/»JAÌÌÌ>’r¯@Þ¡QAÌÌÌ>Ið @fÆDAÌÌÌ>€?Ið @fÆDAÌÌÌ>’r¯@Þ¡QAÌÌÌ>Ið @ß×_AÌÌÌ>€?Ið @fÆDAÌÌÌ>Ið @ß×_AÌÌÌ>§úŠ@ß×_AÌÌÌ>€?§úŠ@ß×_AÌÌÌ>Ið @ß×_AÌÌÌ>§úŠ@ùù`AÌÌÌ>€?’r¯@Þ¡QAÌÌÌ>U%³@ŒˆXAÌÌÌ>Ið @ß×_AÌÌÌ>€?Ið @ß×_AÌÌÌ>U%³@ŒˆXAÌÌÌ>ð?½@Ù•]AÌÌÌ>€?Ið @ß×_AÌÌÌ>ð?½@Ù•]AÌÌÌ>M Ë@;o_AÌÌÌ>€?Eõâ@/»JAÌÌÌ>"²é@fÆDAÌÌÌ>¨æ@Þ¡QAÌÌÌ>€?¨æ@Þ¡QAÌÌÌ>"²é@fÆDAÌÌÌ>"²é@ß×_AÌÌÌ>€?¨æ@Þ¡QAÌÌÌ>"²é@ß×_AÌÌÌ>Eõâ@ŒˆXAÌÌÌ>€?Eõâ@ŒˆXAÌÌÌ>"²é@ß×_AÌÌÌ>ªÚØ@Ù•]AÌÌÌ>€?Eõâ@/»JAÌÌÌ>ªÚØ@â­EAÌÌÌ>"²é@fÆDAÌÌÌ>€?"²é@fÆDAÌÌÌ>ªÚØ@â­EAÌÌÌ>ÓÒ@fÆDAÌÌÌ>€?"²é@fÆDAÌÌÌ>ÓÒ@fÆDAÌÌÌ>"²é@úI5AÌÌÌ>€?"²é@úI5AÌÌÌ>ÓÒ@fÆDAÌÌÌ>M Ë@ÔCAÌÌÌ>€?"²é@úI5AÌÌÌ>M Ë@ÔCAÌÌÌ>ÇÿÃ@fÆDAÌÌÌ>€?B¡LAK¸EAÌÌÌ>]OAfÆDAÌÌÌ>B¡LAß×_AÌÌÌ>€?B¡LAß×_AÌÌÌ>]OAfÆDAÌÌÌ>]OAß×_AÌÌÌ>€?B¡LAß×_AÌÌÌ>]OAß×_AÌÌÌ>B¡LA‚@`AÌÌÌ>€?B¡LA‚@`AÌÌÌ>]OAß×_AÌÌÌ>]OAž…qAÌÌÌ>€?B¡LA‚@`AÌÌÌ>]OAž…qAÌÌÌ>E7A‚@`AÌÌÌ>€?E7A‚@`AÌÌÌ>]OAž…qAÌÌÌ>yB/Až…qAÌÌÌ>€?E7A‚@`AÌÌÌ>yB/Až…qAÌÌÌ>E7Aß×_AÌÌÌ>€?E7Aß×_AÌÌÌ>yB/Až…qAÌÌÌ>yB/Aß×_AÌÌÌ>€?E7Aß×_AÌÌÌ>yB/Aß×_AÌÌÌ>E7AK¸EAÌÌÌ>€?E7AK¸EAÌÌÌ>yB/Aß×_AÌÌÌ>yB/AfÆDAÌÌÌ>€?E7AK¸EAÌÌÌ>yB/AfÆDAÌÌÌ>B¡LAK¸EAÌÌÌ>€? ;‰AÝoYAÌÌÌ> ˆ…Aß×_AÌÌÌ> ;‰AfÆDAÌÌÌ>€? ;‰AfÆDAÌÌÌ> ˆ…Aß×_AÌÌÌ> ˆ…AfÆDAÌÌÌ>€? ;‰AfÆDAÌÌÌ> ˆ…AfÆDAÌÌÌ> ;‰AÄ%?AÌÌÌ>€? ;‰AÄ%?AÌÌÌ> ˆ…AfÆDAÌÌÌ> ˆ…AúI5AÌÌÌ>€? ;‰AÄ%?AÌÌÌ> ˆ…AúI5AÌÌÌ>ý“AÄ%?AÌÌÌ>€?ý“AÄ%?AÌÌÌ> ˆ…AúI5AÌÌÌ>DP±AúI5AÌÌÌ>€?ý“AÄ%?AÌÌÌ>DP±AúI5AÌÌÌ>ý“AfÆDAÌÌÌ>€?ý“AfÆDAÌÌÌ>DP±AúI5AÌÌÌ>DP±AfÆDAÌÌÌ>€?ý“AfÆDAÌÌÌ>DP±AfÆDAÌÌÌ>ý“AÝoYAÌÌÌ>€?ý“AÝoYAÌÌÌ>DP±AfÆDAÌÌÌ>DP±Aß×_AÌÌÌ>€? ˆ…A·Ë•AÌÌÌ>ƒÇ¥A·Ë•AÌÌÌ>DP±A£Š—AÌÌÌ>€?DP±A£Š—AÌÌÌ>ƒÇ¥A·Ë•AÌÌÌ>DP±AŽAÌÌÌ>€?ƒÇ¥A·Ë•AÌÌÌ>ƒÇ¥A AÌÌÌ>DP±AŽAÌÌÌ>€?DP±AŽAÌÌÌ>ƒÇ¥A AÌÌÌ> ˆ…AŽAÌÌÌ>€?DP±AŽAÌÌÌ> ˆ…AŽAÌÌÌ> ˆ…A$ŒAÌÌÌ>€? ˆ…A$ŒAÌÌÌ> ˆ…AŽAÌÌÌ>]OAŽAÌÌÌ>€? ˆ…A$ŒAÌÌÌ>]OAŽAÌÌÌ>]OA$ŒAÌÌÌ>€?]OA$ŒAÌÌÌ>]OAŽAÌÌÌ>yB/AŽAÌÌÌ>€?]OA$ŒAÌÌÌ>yB/AŽAÌÌÌ>yB/A$ŒAÌÌÌ>€?yB/A$ŒAÌÌÌ>yB/AŽAÌÌÌ>=Šô@ŽAÌÌÌ>€?yB/A$ŒAÌÌÌ>=Šô@ŽAÌÌÌ>=Šô@$ŒAÌÌÌ>€?=Šô@$ŒAÌÌÌ>=Šô@ŽAÌÌÌ>"²é@ŽAÌÌÌ>€?=Šô@$ŒAÌÌÌ>"²é@ŽAÌÌÌ>"²é@$ŒAÌÌÌ>€?"²é@$ŒAÌÌÌ>"²é@ŽAÌÌÌ>Ið @ŽAÌÌÌ>€?"²é@$ŒAÌÌÌ>Ið @ŽAÌÌÌ>Ið @$ŒAÌÌÌ>€?ƒÇ¥A› žAÌÌÌ>ƒÇ¥AŽI™AÌÌÌ>DP±A£Š—AÌÌÌ>€?DP±A£Š—AÌÌÌ>ƒÇ¥AŽI™AÌÌÌ> ˆ…A£Š—AÌÌÌ>€?DP±A£Š—AÌÌÌ> ˆ…A£Š—AÌÌÌ> ˆ…A·Ë•AÌÌÌ>€? ˆ…A·Ë•AÌÌÌ> ˆ…A£Š—AÌÌÌ>]OA£Š—AÌÌÌ>€? ˆ…A·Ë•AÌÌÌ>]OA£Š—AÌÌÌ>]OA·Ë•AÌÌÌ>€?]OA·Ë•AÌÌÌ>yB/A£Š—AÌÌÌ>yB/A·Ë•AÌÌÌ>€?yB/A·Ë•AÌÌÌ>yB/A£Š—AÌÌÌ>=Šô@£Š—AÌÌÌ>€?yB/A·Ë•AÌÌÌ>=Šô@£Š—AÌÌÌ>=Šô@·Ë•AÌÌÌ>€?=Šô@·Ë•AÌÌÌ>=Šô@£Š—AÌÌÌ>"²é@£Š—AÌÌÌ>€?=Šô@·Ë•AÌÌÌ>"²é@£Š—AÌÌÌ>"²é@·Ë•AÌÌÌ>€?"²é@·Ë•AÌÌÌ>"²é@£Š—AÌÌÌ>Ið @£Š—AÌÌÌ>€?"²é@·Ë•AÌÌÌ>Ið @£Š—AÌÌÌ>Ið @·Ë•AÌÌÌ>€?Ið @·Ë•AÌÌÌ>Ið @£Š—AÌÌÌ>¸É?·Ë•AÌÌÌ>€?¸É?·Ë•AÌÌÌ>Ið @£Š—AÌÌÌ>£Š—AÌÌÌ>€?¸É?·Ë•AÌÌÌ>£Š—AÌÌÌ>¸É? AÌÌÌ>€?¸É? AÌÌÌ>£Š—AÌÌÌ>ŽAÌÌÌ>€?¸É? AÌÌÌ>ŽAÌÌÌ>Ið @ AÌÌÌ>€?ƒÇ¥A AÌÌÌ> ˆ…A AÌÌÌ> ˆ…AŽAÌÌÌ>€? ˆ…AŽAÌÌÌ> ˆ…A AÌÌÌ>]OA AÌÌÌ>€? ˆ…AŽAÌÌÌ>]OA AÌÌÌ>]OAŽAÌÌÌ>€?]OAŽAÌÌÌ>]OA AÌÌÌ>yB/A AÌÌÌ>€?]OAŽAÌÌÌ>yB/A AÌÌÌ>yB/AŽAÌÌÌ>€?yB/AŽAÌÌÌ>yB/A AÌÌÌ>=Šô@ AÌÌÌ>€?yB/AŽAÌÌÌ>=Šô@ AÌÌÌ>=Šô@ŽAÌÌÌ>€?=Šô@ŽAÌÌÌ>=Šô@ AÌÌÌ>"²é@ AÌÌÌ>€?=Šô@ŽAÌÌÌ>"²é@ AÌÌÌ>"²é@ŽAÌÌÌ>€?"²é@ŽAÌÌÌ>"²é@ AÌÌÌ>Ið @ AÌÌÌ>€?"²é@ŽAÌÌÌ>Ið @ AÌÌÌ>Ið @ŽAÌÌÌ>€?Ið @ŽAÌÌÌ>Ið @ AÌÌÌ>ŽAÌÌÌ>€? ˆ…A¸2ªAÌÌÌ>]OA¸2ªAÌÌÌ>âKuA› žAÌÌÌ>€?âKuA› žAÌÌÌ>]OA¸2ªAÌÌÌ>’ÝdA› žAÌÌÌ>€?âKuA› žAÌÌÌ>’ÝdA› žAÌÌÌ>âKuAŽI™AÌÌÌ>€?âKuAŽI™AÌÌÌ>’ÝdA› žAÌÌÌ>’ÝdAŽI™AÌÌÌ>€?âKuAŽI™AÌÌÌ>’ÝdAŽI™AÌÌÌ>]OA£Š—AÌÌÌ>€?]OA£Š—AÌÌÌ>’ÝdAŽI™AÌÌÌ>]OAŽI™AÌÌÌ>€?]OA£Š—AÌÌÌ>]OAŽI™AÌÌÌ>yB/AŽI™AÌÌÌ>€?]OA·Ë•AÌÌÌ>]OA£Š—AÌÌÌ>yB/A£Š—AÌÌÌ>€?yB/A£Š—AÌÌÌ>]OA£Š—AÌÌÌ>yB/AŽI™AÌÌÌ>€?yB/A£Š—AÌÌÌ>yB/AŽI™AÌÌÌ>=Šô@£Š—AÌÌÌ>€?=Šô@£Š—AÌÌÌ>yB/AŽI™AÌÌÌ>9 AŽI™AÌÌÌ>€?=Šô@£Š—AÌÌÌ>9 AŽI™AÌÌÌ>=Šô@¸2ªAÌÌÌ>€?=Šô@¸2ªAÌÌÌ>9 AŽI™AÌÌÌ>9 A› žAÌÌÌ>€?=Šô@¸2ªAÌÌÌ>9 A› žAÌÌÌ>yB/A¸2ªAÌÌÌ>€?yB/A¸2ªAÌÌÌ>9 A› žAÌÌÌ>yB/A› žAÌÌÌ>€?yB/A¸2ªAÌÌÌ>yB/A› žAÌÌÌ>]OA› žAÌÌÌ>€?Ið @ÌÌÌ>Ið @i[‚?ÌÌÌ>ÌÌÌ>€?ÌÌÌ>Ið @i[‚?ÌÌÌ>i[‚?ÌÌÌ>€?yB/AÌÌÌ>yB/Ai[‚?ÌÌÌ>=Šô@ÌÌÌ>€?=Šô@ÌÌÌ>yB/Ai[‚?ÌÌÌ>=Šô@i[‚?ÌÌÌ>€?=Šô@ÌÌÌ>=Šô@i[‚?ÌÌÌ>"²é@ÌÌÌ>€?"²é@ÌÌÌ>=Šô@i[‚?ÌÌÌ>"²é@i[‚?ÌÌÌ>€?DP±AÌÌÌ>DP±Ai[‚?ÌÌÌ> ˆ…AÌÌÌ>€? ˆ…AÌÌÌ>DP±Ai[‚?ÌÌÌ> ˆ…Ai[‚?ÌÌÌ>€? ˆ…AÌÌÌ> ˆ…Ai[‚?ÌÌÌ>]OAÌÌÌ>€?]OAÌÌÌ> ˆ…Ai[‚?ÌÌÌ>]OAi[‚?ÌÌÌ>€?¸É?*§ˆ@ÌÌÌ>°—@ÌÌÌ>¸É?i[@ÌÌÌ>€?¸É?i[@ÌÌÌ>°—@ÌÌÌ>i[‚?ÌÌÌ>€?¸É?i[@ÌÌÌ>i[‚?ÌÌÌ>n’@i[@ÌÌÌ>€?n’@i[@ÌÌÌ>i[‚?ÌÌÌ>Ið @i[‚?ÌÌÌ>€?n’@i[@ÌÌÌ>Ið @i[‚?ÌÌÌ>n’@*§ˆ@ÌÌÌ>€?n’@*§ˆ@ÌÌÌ>Ið @i[‚?ÌÌÌ>Ið @°—@ÌÌÌ>€?n’@*§ˆ@ÌÌÌ>Ið @°—@ÌÌÌ>¸É?*§ˆ@ÌÌÌ>€?¸É?*§ˆ@ÌÌÌ>Ið @°—@ÌÌÌ>°—@ÌÌÌ>€?xaRA*§ˆ@ÌÌÌ>]OA°—@ÌÌÌ>xaRAi[@ÌÌÌ>€?xaRAi[@ÌÌÌ>]OA°—@ÌÌÌ>]OAi[‚?ÌÌÌ>€?xaRAi[@ÌÌÌ>]OAi[‚?ÌÌÌ>3ÖAi[@ÌÌÌ>€?3ÖAi[@ÌÌÌ>]OAi[‚?ÌÌÌ> ˆ…Ai[‚?ÌÌÌ>€?3ÖAi[@ÌÌÌ> ˆ…Ai[‚?ÌÌÌ>3ÖA*§ˆ@ÌÌÌ>€?3ÖA*§ˆ@ÌÌÌ> ˆ…Ai[‚?ÌÌÌ> ˆ…A°—@ÌÌÌ>€?3ÖA*§ˆ@ÌÌÌ> ˆ…A°—@ÌÌÌ>xaRA*§ˆ@ÌÌÌ>€?xaRA*§ˆ@ÌÌÌ> ˆ…A°—@ÌÌÌ>]OA°—@ÌÌÌ>€?ý“A*§ˆ@ÌÌÌ> ˆ…A°—@ÌÌÌ>ý“Ai[@ÌÌÌ>€?ý“Ai[@ÌÌÌ> ˆ…A°—@ÌÌÌ> ˆ…Ai[‚?ÌÌÌ>€?ý“Ai[@ÌÌÌ> ˆ…Ai[‚?ÌÌÌ>Æ÷¬Ai[@ÌÌÌ>€?Æ÷¬Ai[@ÌÌÌ> ˆ…Ai[‚?ÌÌÌ>DP±Ai[‚?ÌÌÌ>€?Æ÷¬Ai[@ÌÌÌ>DP±Ai[‚?ÌÌÌ>Æ÷¬A*§ˆ@ÌÌÌ>€?Æ÷¬A*§ˆ@ÌÌÌ>DP±Ai[‚?ÌÌÌ>DP±A°—@ÌÌÌ>€?Æ÷¬A*§ˆ@ÌÌÌ>DP±A°—@ÌÌÌ>ý“A*§ˆ@ÌÌÌ>€?ý“A*§ˆ@ÌÌÌ>DP±A°—@ÌÌÌ> ˆ…A°—@ÌÌÌ>€?æ?'A¹ÈAÌÌÌ>=Šô@ê@ÌÌÌ>yB/Aê@ÌÌÌ>€?yB/Aê@ÌÌÌ>=Šô@ê@ÌÌÌ>æ?'Av!ç@ÌÌÌ>€?yB/Aê@ÌÌÌ>æ?'Av!ç@ÌÌÌ>yB/A°—@ÌÌÌ>€?yB/A°—@ÌÌÌ>æ?'Av!ç@ÌÌÌ>æ?'A6h¥@ÌÌÌ>€?yB/A°—@ÌÌÌ>æ?'A6h¥@ÌÌÌ>=Šô@°—@ÌÌÌ>€?=Šô@°—@ÌÌÌ>æ?'A6h¥@ÌÌÌ>€?=Šô@°—@ÌÌÌ>=Šô@ê@ÌÌÌ>€?=Šô@ê@ÌÌÌ>€?=Šô@ê@ÌÌÌ>æ?'Av!ç@ÌÌÌ>€?ð?½@â­EAÌÌÌ>Ið @fÆDAÌÌÌ>ÇÿÃ@fÆDAÌÌÌ>€?ÇÿÃ@fÆDAÌÌÌ>Ið @fÆDAÌÌÌ>Ið @úI5AÌÌÌ>€?ÇÿÃ@fÆDAÌÌÌ>Ið @úI5AÌÌÌ>"²é@úI5AÌÌÌ>€?"²é@úI5AÌÌÌ>Ið @úI5AÌÌÌ>Ið @Ó+)AÌÌÌ>€?"²é@úI5AÌÌÌ>Ið @Ó+)AÌÌÌ>"²é@Ó+)AÌÌÌ>€?"²é@Ó+)AÌÌÌ>Ið @Ó+)AÌÌÌ>Ið @‚Y(AÌÌÌ>€?"²é@Ó+)AÌÌÌ>Ið @‚Y(AÌÌÌ>"²é@‚Y(AÌÌÌ>€?"²é@‚Y(AÌÌÌ>Ið @‚Y(AÌÌÌ>Ið @ê@ÌÌÌ>€?"²é@‚Y(AÌÌÌ>Ið @ê@ÌÌÌ>"²é@ê@ÌÌÌ>€?"²é@ê@ÌÌÌ>Ið @ê@ÌÌÌ>Ið @°—@ÌÌÌ>€?"²é@ê@ÌÌÌ>Ið @°—@ÌÌÌ>"²é@°—@ÌÌÌ>€?"²é@°—@ÌÌÌ>Ið @°—@ÌÌÌ>Ið @i[‚?ÌÌÌ>€?"²é@°—@ÌÌÌ>Ið @i[‚?ÌÌÌ>"²é@i[‚?ÌÌÌ>€?"²é@i[‚?ÌÌÌ>Ið @i[‚?ÌÌÌ>Ið @ÌÌÌ>€?"²é@i[‚?ÌÌÌ>Ið @ÌÌÌ>"²é@ÌÌÌ>€?i$j@øLAÌÌÌ>fÆDAÌÌÌ>Ið @fÆDAÌÌÌ>€?Ið @fÆDAÌÌÌ>fÆDAÌÌÌ>úI5AÌÌÌ>€?Ið @fÆDAÌÌÌ>úI5AÌÌÌ>Ið @úI5AÌÌÌ>€?Ið @úI5AÌÌÌ>úI5AÌÌÌ>Ó+)AÌÌÌ>€?Ið @úI5AÌÌÌ>Ó+)AÌÌÌ>Ið @Ó+)AÌÌÌ>€?Ið @Ó+)AÌÌÌ>Ó+)AÌÌÌ>‚Y(AÌÌÌ>€?Ið @Ó+)AÌÌÌ>‚Y(AÌÌÌ>Ið @‚Y(AÌÌÌ>€?Ið @‚Y(AÌÌÌ>‚Y(AÌÌÌ>Ï‘$@î$(AÌÌÌ>€?Ið @‚Y(AÌÌÌ>Ï‘$@î$(AÌÌÌ>n’@î$(AÌÌÌ>€?B¡LAK¸EAÌÌÌ>yB/AfÆDAÌÌÌ>]OAfÆDAÌÌÌ>€?]OAfÆDAÌÌÌ>yB/AfÆDAÌÌÌ>yB/AúI5AÌÌÌ>€?]OAfÆDAÌÌÌ>yB/AúI5AÌÌÌ>]OAúI5AÌÌÌ>€?]OAúI5AÌÌÌ>yB/AúI5AÌÌÌ>yB/AÓ+)AÌÌÌ>€?]OAúI5AÌÌÌ>yB/AÓ+)AÌÌÌ>]OAÓ+)AÌÌÌ>€?]OAÓ+)AÌÌÌ>yB/AÓ+)AÌÌÌ>yB/A‚Y(AÌÌÌ>€?]OAÓ+)AÌÌÌ>yB/A‚Y(AÌÌÌ>]OA‚Y(AÌÌÌ>€?]OA‚Y(AÌÌÌ>yB/A‚Y(AÌÌÌ>yB/Aê@ÌÌÌ>€?]OA‚Y(AÌÌÌ>yB/Aê@ÌÌÌ>]OAê@ÌÌÌ>€?]OAê@ÌÌÌ>yB/Aê@ÌÌÌ>yB/A°—@ÌÌÌ>€?]OAê@ÌÌÌ>yB/A°—@ÌÌÌ>]OA°—@ÌÌÌ>€?]OA°—@ÌÌÌ>yB/A°—@ÌÌÌ>yB/Ai[‚?ÌÌÌ>€?]OA°—@ÌÌÌ>yB/Ai[‚?ÌÌÌ>]OAi[‚?ÌÌÌ>€?]OAi[‚?ÌÌÌ>yB/Ai[‚?ÌÌÌ>yB/AÌÌÌ>€?]OAi[‚?ÌÌÌ>yB/AÌÌÌ>]OAÌÌÌ>€?ç£A‚@`AÌÌÌ>=Šô@ß×_AÌÌÌ>yB/Aß×_AÌÌÌ>€?yB/Aß×_AÌÌÌ>=Šô@ß×_AÌÌÌ>=Šô@fÆDAÌÌÌ>€?yB/Aß×_AÌÌÌ>=Šô@fÆDAÌÌÌ>yB/AfÆDAÌÌÌ>€?yB/AfÆDAÌÌÌ>=Šô@fÆDAÌÌÌ>=Šô@úI5AÌÌÌ>€?yB/AfÆDAÌÌÌ>=Šô@úI5AÌÌÌ>yB/AúI5AÌÌÌ>€?yB/AúI5AÌÌÌ>=Šô@úI5AÌÌÌ>=Šô@Ó+)AÌÌÌ>€?yB/AúI5AÌÌÌ>=Šô@Ó+)AÌÌÌ>yB/AÓ+)AÌÌÌ>€?yB/AÓ+)AÌÌÌ>=Šô@Ó+)AÌÌÌ>€?yB/AÓ+)AÌÌÌ>æ?'AŽ(AÌÌÌ>€?âKuA‚@`AÌÌÌ>]OAß×_AÌÌÌ> ˆ…Aß×_AÌÌÌ>€? ˆ…Aß×_AÌÌÌ>]OAß×_AÌÌÌ>]OAfÆDAÌÌÌ>€? ˆ…Aß×_AÌÌÌ>]OAfÆDAÌÌÌ> ˆ…AfÆDAÌÌÌ>€? ˆ…AfÆDAÌÌÌ>]OAfÆDAÌÌÌ>]OAúI5AÌÌÌ>€? ˆ…AfÆDAÌÌÌ>]OAúI5AÌÌÌ> ˆ…AúI5AÌÌÌ>€? ˆ…AúI5AÌÌÌ>]OAúI5AÌÌÌ>ºx]AÉ)AÌÌÌ>€? ˆ…AúI5AÌÌÌ>ºx]AÉ)AÌÌÌ>3ÖAÉ)AÌÌÌ>€?,]H@Ç]nAÌÌÌ>Ið @ž…qAÌÌÌ>ž…qAÌÌÌ>€?ž…qAÌÌÌ>Ið @ž…qAÌÌÌ>Ið @æ‚AÌÌÌ>€?ž…qAÌÌÌ>Ið @æ‚AÌÌÌ>æ‚AÌÌÌ>€?Ið @$ŒAÌÌÌ>Ið @ŽAÌÌÌ>¸É?$ŒAÌÌÌ>€?¸É?$ŒAÌÌÌ>Ið @ŽAÌÌÌ>ŽAÌÌÌ>€?¸É?$ŒAÌÌÌ>ŽAÌÌÌ>¸É?#û…AÌÌÌ>€?¸É?#û…AÌÌÌ>ŽAÌÌÌ>æ‚AÌÌÌ>€?¸É?#û…AÌÌÌ>æ‚AÌÌÌ>Ið @#û…AÌÌÌ>€?Ið @#û…AÌÌÌ>æ‚AÌÌÌ>Ið @æ‚AÌÌÌ>€?Ið @#û…AÌÌÌ>Ið @æ‚AÌÌÌ>"²é@æ‚AÌÌÌ>€?"²é@æ‚AÌÌÌ>Ið @æ‚AÌÌÌ>Ið @ž…qAÌÌÌ>€?"²é@æ‚AÌÌÌ>Ið @ž…qAÌÌÌ>"²é@ž…qAÌÌÌ>€?"²é@ž…qAÌÌÌ>Ið @ž…qAÌÌÌ>Ið @ß×_AÌÌÌ>€?"²é@ž…qAÌÌÌ>Ið @ß×_AÌÌÌ>"²é@ß×_AÌÌÌ>€?"²é@ß×_AÌÌÌ>Ið @ß×_AÌÌÌ>M Ë@;o_AÌÌÌ>€?"²é@ß×_AÌÌÌ>M Ë@;o_AÌÌÌ>ªÚØ@Ù•]AÌÌÌ>€?"²é@#û…AÌÌÌ>"²é@æ‚AÌÌÌ>=Šô@æ‚AÌÌÌ>€?=Šô@æ‚AÌÌÌ>"²é@æ‚AÌÌÌ>"²é@ž…qAÌÌÌ>€?=Šô@æ‚AÌÌÌ>"²é@ž…qAÌÌÌ>=Šô@ž…qAÌÌÌ>€?=Šô@ž…qAÌÌÌ>"²é@ž…qAÌÌÌ>"²é@ß×_AÌÌÌ>€?=Šô@ž…qAÌÌÌ>"²é@ß×_AÌÌÌ>=Šô@ß×_AÌÌÌ>€?=Šô@ß×_AÌÌÌ>"²é@ß×_AÌÌÌ>"²é@fÆDAÌÌÌ>€?=Šô@ß×_AÌÌÌ>"²é@fÆDAÌÌÌ>=Šô@fÆDAÌÌÌ>€?=Šô@fÆDAÌÌÌ>"²é@fÆDAÌÌÌ>"²é@úI5AÌÌÌ>€?=Šô@fÆDAÌÌÌ>"²é@úI5AÌÌÌ>=Šô@úI5AÌÌÌ>€?=Šô@úI5AÌÌÌ>"²é@úI5AÌÌÌ>"²é@Ó+)AÌÌÌ>€?=Šô@úI5AÌÌÌ>"²é@Ó+)AÌÌÌ>=Šô@Ó+)AÌÌÌ>€?=Šô@Ó+)AÌÌÌ>"²é@Ó+)AÌÌÌ>"²é@‚Y(AÌÌÌ>€?=Šô@Ó+)AÌÌÌ>"²é@‚Y(AÌÌÌ>=Šô@‚Y(AÌÌÌ>€?=Šô@‚Y(AÌÌÌ>"²é@‚Y(AÌÌÌ>"²é@ê@ÌÌÌ>€?=Šô@‚Y(AÌÌÌ>"²é@ê@ÌÌÌ>=Šô@ê@ÌÌÌ>€?=Šô@ê@ÌÌÌ>"²é@ê@ÌÌÌ>"²é@°—@ÌÌÌ>€?=Šô@ê@ÌÌÌ>"²é@°—@ÌÌÌ>=Šô@°—@ÌÌÌ>€?=Šô@°—@ÌÌÌ>"²é@°—@ÌÌÌ>>¼ì@*§ˆ@ÌÌÌ>€?=Šô@°—@ÌÌÌ>>¼ì@*§ˆ@ÌÌÌ>=Šô@*§ˆ@ÌÌÌ>€?N”aA‚@`AÌÌÌ>N”aAž…qAÌÌÌ>]OAž…qAÌÌÌ>€?]OAž…qAÌÌÌ>N”aAž…qAÌÌÌ>]OAæ‚AÌÌÌ>€?]OAž…qAÌÌÌ>]OAæ‚AÌÌÌ>yB/Až…qAÌÌÌ>€?yB/Až…qAÌÌÌ>]OAæ‚AÌÌÌ>yB/Aæ‚AÌÌÌ>€?yB/Až…qAÌÌÌ>yB/Aæ‚AÌÌÌ>ˆá#AtuAÌÌÌ>€?ˆá#AtuAÌÌÌ>yB/Aæ‚AÌÌÌ>µAŒ zAÌÌÌ>€?ƒÇ¥A#û…AÌÌÌ> ˆ…Aæ‚AÌÌÌ>DP±Aæ‚AÌÌÌ>€?DP±Aæ‚AÌÌÌ> ˆ…Aæ‚AÌÌÌ> ˆ…Až…qAÌÌÌ>€?DP±Aæ‚AÌÌÌ> ˆ…Až…qAÌÌÌ>DP±Až…qAÌÌÌ>€?DP±Až…qAÌÌÌ> ˆ…Až…qAÌÌÌ> ˆ…Aß×_AÌÌÌ>€?DP±Až…qAÌÌÌ> ˆ…Aß×_AÌÌÌ>DP±Aß×_AÌÌÌ>€?DP±Aß×_AÌÌÌ> ˆ…Aß×_AÌÌÌ> ;‰AÝoYAÌÌÌ>€?DP±Aß×_AÌÌÌ> ;‰AÝoYAÌÌÌ>ý“AÝoYAÌÌÌ>€¿ÌÌÌ>i[‚?ÌÌÌ>€¿i[‚?ÌÌÌ>°—@ÌÌÌ>€¿úI5AÌÌÌ>fÆDAÌÌÌ>¸2ªA€¿°—@ÌÌÌ>ê@ÌÌÌ>€¿ê@ÌÌÌ>‚Y(AÌÌÌ>€¿‚Y(AÌÌÌ>¸2ªA€¿¸2ªA‚Y(AÌÌÌ>Ó+)AÌÌÌ>€¿¸2ªAÓ+)AÌÌÌ>úI5AÌÌÌ>€¿fÆDAÌÌÌ>ß×_AÌÌÌ>¸2ªA€¿¸2ªAß×_AÌÌÌ>ž…qAÌÌÌ>€¿¸2ªAž…qAÌÌÌ>æ‚AÌÌÌ>€¿æ‚AÌÌÌ>ŽAÌÌÌ>¸2ªA€¿¸2ªAŽAÌÌÌ>£Š—AÌÌÌ>€¿¸2ªA£Š—AÌÌÌ>¸2ªAÌÌÌ>€¿DP±AÌÌÌ> ˆ…AÌÌÌ>DP±A€¿DP±A ˆ…AÌÌÌ>]OAÌÌÌ>€¿DP±A]OAÌÌÌ>€¿]OAÌÌÌ>yB/AÌÌÌ>€¿yB/AÌÌÌ>=Šô@ÌÌÌ>€¿=Šô@ÌÌÌ>"²é@ÌÌÌ>€¿"²é@ÌÌÌ>Ið @ÌÌÌ>€¿Ið @ÌÌÌ>ÌÌÌ>€?DP±A¸2ªADP±A¸2ªAÌÌÌ>DP±A£Š—AÌÌÌ>€?DP±A£Š—AÌÌÌ>DP±AŽAÌÌÌ>DP±A¸2ªA€?DP±A¸2ªADP±AŽAÌÌÌ>DP±Aæ‚AÌÌÌ>€?DP±A¸2ªADP±Aæ‚AÌÌÌ>DP±Až…qAÌÌÌ>€?DP±Až…qAÌÌÌ>DP±Aß×_AÌÌÌ>DP±A¸2ªA€?DP±A¸2ªADP±Aß×_AÌÌÌ>DP±AfÆDAÌÌÌ>€?DP±A¸2ªADP±AfÆDAÌÌÌ>DP±A€?DP±ADP±AfÆDAÌÌÌ>DP±AúI5AÌÌÌ>€?DP±AúI5AÌÌÌ>DP±AÓ+)AÌÌÌ>DP±A€?DP±ADP±AÓ+)AÌÌÌ>DP±A‚Y(AÌÌÌ>€?DP±ADP±A‚Y(AÌÌÌ>DP±Aê@ÌÌÌ>€?DP±Aê@ÌÌÌ>DP±A°—@ÌÌÌ>DP±A€?DP±ADP±A°—@ÌÌÌ>DP±Ai[‚?ÌÌÌ>€?DP±ADP±Ai[‚?ÌÌÌ>DP±AÌÌÌ>€?¸2ªAÌÌÌ>Ið @¸2ªAÌÌÌ>¸2ªA€?¸2ªAIð @¸2ªAÌÌÌ>"²é@¸2ªAÌÌÌ>€?¸2ªA"²é@¸2ªAÌÌÌ>DP±A¸2ªA€?DP±A¸2ªA"²é@¸2ªAÌÌÌ>=Šô@¸2ªAÌÌÌ>€?DP±A¸2ªA=Šô@¸2ªAÌÌÌ>yB/A¸2ªAÌÌÌ>€?yB/A¸2ªAÌÌÌ>]OA¸2ªAÌÌÌ>DP±A¸2ªA€?DP±A¸2ªA]OA¸2ªAÌÌÌ> ˆ…A¸2ªAÌÌÌ>€?DP±A¸2ªA ˆ…A¸2ªAÌÌÌ>DP±A¸2ªAÌÌÌ>€¿DP±A¸2ªADP±A¸2ªA€¿¸2ªADP±A€¿¸É?i[@š™Y@¸É?*§ˆ@š™Y@¸É?i[@ÌÌÌ>€¿¸É?i[@ÌÌÌ>¸É?*§ˆ@š™Y@¸É?*§ˆ@ÌÌÌ>€¿n’@i[@š™Y@¸É?i[@š™Y@n’@i[@ÌÌÌ>€¿n’@i[@ÌÌÌ>¸É?i[@š™Y@¸É?i[@ÌÌÌ>€?2Ûß%n’@*§ˆ@š™Y@n’@i[@š™Y@n’@*§ˆ@ÌÌÌ>€?2Ûß%n’@*§ˆ@ÌÌÌ>n’@i[@š™Y@n’@i[@ÌÌÌ>€?¸É?*§ˆ@š™Y@n’@*§ˆ@š™Y@¸É?*§ˆ@ÌÌÌ>€?¸É?*§ˆ@ÌÌÌ>n’@*§ˆ@š™Y@n’@*§ˆ@ÌÌÌ>€?n’@i[@š™Y@n’@*§ˆ@š™Y@¸É?i[@š™Y@€?¸É?i[@š™Y@n’@*§ˆ@š™Y@¸É?*§ˆ@š™Y@€¿>¼ì@i[@š™Y@>¼ì@*§ˆ@š™Y@>¼ì@i[@ÌÌÌ>€¿>¼ì@i[@ÌÌÌ>>¼ì@*§ˆ@š™Y@>¼ì@*§ˆ@ÌÌÌ>€¿æ?'Ai[@ÌÌÌ>æ?'Ai[@š™Y@=Šô@i[@ÌÌÌ>€¿=Šô@i[@ÌÌÌ>æ?'Ai[@š™Y@>¼ì@i[@š™Y@€¿=Šô@i[@ÌÌÌ>>¼ì@i[@š™Y@>¼ì@i[@ÌÌÌ>€?æ?'A*§ˆ@š™Y@æ?'Ai[@š™Y@æ?'A*§ˆ@ÌÌÌ>€?æ?'A*§ˆ@ÌÌÌ>æ?'Ai[@š™Y@æ?'Ai[@ÌÌÌ>€?>¼ì@*§ˆ@ÌÌÌ>>¼ì@*§ˆ@š™Y@=Šô@*§ˆ@ÌÌÌ>€?=Šô@*§ˆ@ÌÌÌ>>¼ì@*§ˆ@š™Y@æ?'A*§ˆ@š™Y@€?=Šô@*§ˆ@ÌÌÌ>æ?'A*§ˆ@š™Y@æ?'A*§ˆ@ÌÌÌ>€?æ?'Ai[@š™Y@æ?'A*§ˆ@š™Y@>¼ì@i[@š™Y@€?>¼ì@i[@š™Y@æ?'A*§ˆ@š™Y@>¼ì@*§ˆ@š™Y@€¿xaRAi[@š™Y@xaRA*§ˆ@š™Y@xaRAi[@ÌÌÌ>€¿xaRAi[@ÌÌÌ>xaRA*§ˆ@š™Y@xaRA*§ˆ@ÌÌÌ>€¿3ÖAi[@š™Y@xaRAi[@š™Y@3ÖAi[@ÌÌÌ>€¿3ÖAi[@ÌÌÌ>xaRAi[@š™Y@xaRAi[@ÌÌÌ>€?3ÖA*§ˆ@š™Y@3ÖAi[@š™Y@3ÖA*§ˆ@ÌÌÌ>€?3ÖA*§ˆ@ÌÌÌ>3ÖAi[@š™Y@3ÖAi[@ÌÌÌ>€?xaRA*§ˆ@š™Y@3ÖA*§ˆ@š™Y@xaRA*§ˆ@ÌÌÌ>€?xaRA*§ˆ@ÌÌÌ>3ÖA*§ˆ@š™Y@3ÖA*§ˆ@ÌÌÌ>€?3ÖAi[@š™Y@3ÖA*§ˆ@š™Y@xaRAi[@š™Y@€?xaRAi[@š™Y@3ÖA*§ˆ@š™Y@xaRA*§ˆ@š™Y@€¿ý“Ai[@š™Y@ý“A*§ˆ@š™Y@ý“Ai[@ÌÌÌ>€¿ý“Ai[@ÌÌÌ>ý“A*§ˆ@š™Y@ý“A*§ˆ@ÌÌÌ>€¿Æ÷¬Ai[@š™Y@ý“Ai[@š™Y@Æ÷¬Ai[@ÌÌÌ>€¿Æ÷¬Ai[@ÌÌÌ>ý“Ai[@š™Y@ý“Ai[@ÌÌÌ>€?Æ÷¬A*§ˆ@š™Y@Æ÷¬Ai[@š™Y@Æ÷¬A*§ˆ@ÌÌÌ>€?Æ÷¬A*§ˆ@ÌÌÌ>Æ÷¬Ai[@š™Y@Æ÷¬Ai[@ÌÌÌ>€?ý“A*§ˆ@š™Y@Æ÷¬A*§ˆ@š™Y@ý“A*§ˆ@ÌÌÌ>€?ý“A*§ˆ@ÌÌÌ>Æ÷¬A*§ˆ@š™Y@Æ÷¬A*§ˆ@ÌÌÌ>€?Æ÷¬Ai[@š™Y@Æ÷¬A*§ˆ@š™Y@ý“Ai[@š™Y@€?ý“Ai[@š™Y@Æ÷¬A*§ˆ@š™Y@ý“A*§ˆ@š™Y@€?üéªA¬áì@ÌÌÌ>üéªA¬áì@š™Y@üéªAê@ÌÌÌ>€?üéªAê@ÌÌÌ>üéªA¬áì@š™Y@üéªA6h¥@š™Y@€?üéªAê@ÌÌÌ>üéªA6h¥@š™Y@üéªA6h¥@ÌÌÌ>€?ý“A¬áì@š™Y@üéªA¬áì@š™Y@ý“A¬áì@ÌÌÌ>€?ý“A¬áì@ÌÌÌ>üéªA¬áì@š™Y@üéªA¬áì@ÌÌÌ>€¿ý“A6h¥@ÌÌÌ>ý“A6h¥@š™Y@ý“Aê@ÌÌÌ>€¿ý“Aê@ÌÌÌ>ý“A6h¥@š™Y@ý“A¬áì@š™Y@€¿ý“Aê@ÌÌÌ>ý“A¬áì@š™Y@ý“A¬áì@ÌÌÌ>€¿üéªA6h¥@š™Y@ý“A6h¥@š™Y@üéªA6h¥@ÌÌÌ>€¿üéªA6h¥@ÌÌÌ>ý“A6h¥@š™Y@ý“A6h¥@ÌÌÌ>€?ý“A¬áì@š™Y@ý“A6h¥@š™Y@üéªA¬áì@š™Y@€?üéªA¬áì@š™Y@ý“A6h¥@š™Y@üéªA6h¥@š™Y@€?3ÖA¬áì@ÌÌÌ>3ÖA¬áì@š™Y@3ÖAê@ÌÌÌ>€?3ÖAê@ÌÌÌ>3ÖA¬áì@š™Y@3ÖA6h¥@š™Y@€?3ÖAê@ÌÌÌ>3ÖA6h¥@š™Y@3ÖA6h¥@ÌÌÌ>€?ºx]A¬áì@š™Y@3ÖA¬áì@š™Y@ºx]A¬áì@ÌÌÌ>€?ºx]A¬áì@ÌÌÌ>3ÖA¬áì@š™Y@3ÖA¬áì@ÌÌÌ>€¿ºx]A6h¥@ÌÌÌ>ºx]A6h¥@š™Y@ºx]Aê@ÌÌÌ>€¿ºx]Aê@ÌÌÌ>ºx]A6h¥@š™Y@ºx]A¬áì@š™Y@€¿ºx]Aê@ÌÌÌ>ºx]A¬áì@š™Y@ºx]A¬áì@ÌÌÌ>€¿3ÖA6h¥@š™Y@ºx]A6h¥@š™Y@3ÖA6h¥@ÌÌÌ>€¿3ÖA6h¥@ÌÌÌ>ºx]A6h¥@š™Y@ºx]A6h¥@ÌÌÌ>€?ºx]A¬áì@š™Y@ºx]A6h¥@š™Y@3ÖA¬áì@š™Y@€?3ÖA¬áì@š™Y@ºx]A6h¥@š™Y@3ÖA6h¥@š™Y@€?æ?'Av!ç@š™Y@æ?'A6h¥@š™Y@æ?'Av!ç@ÌÌÌ>€?æ?'Av!ç@ÌÌÌ>æ?'A6h¥@š™Y@æ?'A6h¥@ÌÌÌ>€?€?æ?'Av!ç@š™Y@æ?'Av!ç@ÌÌÌ>€¿€¿€¿æ?'A6h¥@š™Y@€¿æ?'A6h¥@ÌÌÌ>€?n’@¬áì@š™Y@n’@ê@ÌÌÌ>€?n’@ê@ÌÌÌ>n’@¬áì@š™Y@n’@6h¥@š™Y@€?n’@ê@ÌÌÌ>n’@6h¥@š™Y@n’@6h¥@ÌÌÌ>€?Ï‘$@¬áì@š™Y@n’@¬áì@š™Y@Ï‘$@¬áì@ÌÌÌ>€?Ï‘$@¬áì@ÌÌÌ>n’@¬áì@š™Y@n’@¬áì@ÌÌÌ>€¿Ï‘$@6h¥@ÌÌÌ>Ï‘$@6h¥@š™Y@Ï‘$@ê@ÌÌÌ>€¿Ï‘$@ê@ÌÌÌ>Ï‘$@6h¥@š™Y@Ï‘$@¬áì@š™Y@€¿Ï‘$@ê@ÌÌÌ>Ï‘$@¬áì@š™Y@Ï‘$@¬áì@ÌÌÌ>€¿n’@6h¥@š™Y@Ï‘$@6h¥@š™Y@n’@6h¥@ÌÌÌ>€¿n’@6h¥@ÌÌÌ>Ï‘$@6h¥@š™Y@Ï‘$@6h¥@ÌÌÌ>€?Ï‘$@¬áì@š™Y@Ï‘$@6h¥@š™Y@n’@¬áì@š™Y@€?n’@¬áì@š™Y@Ï‘$@6h¥@š™Y@n’@6h¥@š™Y@€?n’@î$(Aš™Y@n’@¹ÈAš™Y@n’@î$(AÌÌÌ>€?n’@î$(AÌÌÌ>n’@¹ÈAš™Y@n’@¹ÈAÌÌÌ>€?Ï‘$@î$(Aš™Y@n’@î$(Aš™Y@Ï‘$@î$(AÌÌÌ>€?Ï‘$@î$(AÌÌÌ>n’@î$(Aš™Y@n’@î$(AÌÌÌ>€¿Ï‘$@¹ÈAš™Y@Ï‘$@î$(Aš™Y@Ï‘$@¹ÈAÌÌÌ>€¿Ï‘$@¹ÈAÌÌÌ>Ï‘$@î$(Aš™Y@Ï‘$@î$(AÌÌÌ>€¿n’@¹ÈAš™Y@Ï‘$@¹ÈAš™Y@n’@¹ÈAÌÌÌ>€¿n’@¹ÈAÌÌÌ>Ï‘$@¹ÈAš™Y@Ï‘$@¹ÈAÌÌÌ>€?Ï‘$@î$(Aš™Y@Ï‘$@¹ÈAš™Y@n’@î$(Aš™Y@€?n’@î$(Aš™Y@Ï‘$@¹ÈAš™Y@n’@¹ÈAš™Y@€¿€¿€¿æ?'A¹ÈAš™Y@€¿æ?'A¹ÈAÌÌÌ>€?æ?'AŽ(AÌÌÌ>æ?'AŽ(Aš™Y@æ?'A‚Y(AÌÌÌ>€?æ?'A‚Y(AÌÌÌ>æ?'AŽ(Aš™Y@æ?'A¹ÈAš™Y@€?æ?'A‚Y(AÌÌÌ>æ?'A¹ÈAš™Y@æ?'A¹ÈAÌÌÌ>€?€?æ?'AŽ(Aš™Y@æ?'AŽ(AÌÌÌ>€?æ?'A¹ÈAš™Y@æ?'AŽ(Aš™Y@ºx]A¹ÈAš™Y@ºx]A‚Y(AÌÌÌ>€¿ºx]A‚Y(AÌÌÌ>ºx]A¹ÈAš™Y@ºx]AÉ)Aš™Y@€¿ºx]A‚Y(AÌÌÌ>ºx]AÉ)Aš™Y@ºx]AÓ+)AÌÌÌ>€¿ºx]AÓ+)AÌÌÌ>ºx]AÉ)Aš™Y@ºx]AÉ)AÌÌÌ>€¿3ÖA¹ÈAš™Y@ºx]A¹ÈAš™Y@3ÖA¹ÈAÌÌÌ>€¿3ÖA¹ÈAÌÌÌ>ºx]A¹ÈAš™Y@ºx]A¹ÈAÌÌÌ>€?3ÖAÉ)Aš™Y@3ÖA¹ÈAš™Y@3ÖA¹ÈAÌÌÌ>€?3ÖA¹ÈAÌÌÌ>3ÖA‚Y(AÌÌÌ>3ÖAÉ)Aš™Y@€?3ÖAÉ)Aš™Y@3ÖA‚Y(AÌÌÌ>3ÖAÓ+)AÌÌÌ>€?3ÖAÉ)Aš™Y@3ÖAÓ+)AÌÌÌ>3ÖAÉ)AÌÌÌ>€?ºx]AÉ)Aš™Y@3ÖAÉ)Aš™Y@ºx]AÉ)AÌÌÌ>€?ºx]AÉ)AÌÌÌ>3ÖAÉ)Aš™Y@3ÖAÉ)AÌÌÌ>€?3ÖA¹ÈAš™Y@3ÖAÉ)Aš™Y@ºx]A¹ÈAš™Y@€?ºx]A¹ÈAš™Y@3ÖAÉ)Aš™Y@ºx]AÉ)Aš™Y@€¿ý“A¹ÈAÌÌÌ>ý“A¹ÈAš™Y@ý“A‚Y(AÌÌÌ>€¿ý“A‚Y(AÌÌÌ>ý“A¹ÈAš™Y@ý“A1n+Aš™Y@€¿ý“A‚Y(AÌÌÌ>ý“A1n+Aš™Y@ý“AÓ+)AÌÌÌ>€¿ý“AÓ+)AÌÌÌ>ý“A1n+Aš™Y@ý“A1n+AÌÌÌ>€¿á"¤A¹ÈAš™Y@ý“A¹ÈAš™Y@á"¤A¹ÈAÌÌÌ>€¿á"¤A¹ÈAÌÌÌ>ý“A¹ÈAš™Y@ý“A¹ÈAÌÌÌ>€?á"¤A1n+Aš™Y@á"¤A¹ÈAš™Y@á"¤A¹ÈAÌÌÌ>€?á"¤A¹ÈAÌÌÌ>á"¤A‚Y(AÌÌÌ>á"¤A1n+Aš™Y@€?á"¤A1n+Aš™Y@á"¤A‚Y(AÌÌÌ>á"¤AÓ+)AÌÌÌ>€?á"¤A1n+Aš™Y@á"¤AÓ+)AÌÌÌ>á"¤A1n+AÌÌÌ>€?ý“A1n+Aš™Y@á"¤A1n+Aš™Y@ý“A1n+AÌÌÌ>€?ý“A1n+AÌÌÌ>á"¤A1n+Aš™Y@á"¤A1n+AÌÌÌ>€?á"¤A¹ÈAš™Y@á"¤A1n+Aš™Y@ý“A¹ÈAš™Y@€?ý“A¹ÈAš™Y@á"¤A1n+Aš™Y@ý“A1n+Aš™Y@¹µr¿Ó¢¾× @ ¹\Aš™Y@/ü@¸vTAÌÌÌ>/ü@¸vTAš™Y@1àL¿»¿/ü@¸vTAš™Y@/ü@¸vTAÌÌÌ>{Œ(@²NAÌÌÌ>'1¿6á8¿/ü@¸vTAš™Y@{Œ(@²NAÌÌÌ>{Œ(@²NAš™Y@Þ%ܾˆ g¿{Œ(@²NAš™Y@{Œ(@²NAÌÌÌ>,]H@{KAÌÌÌ>„¿¾_þu¿{Œ(@²NAš™Y@,]H@{KAÌÌÌ>,]H@{KAš™Y@ƒ=‰Î¿,]H@{KAš™Y@,]H@{KAÌÌÌ>i$j@øLAÌÌÌ>™@N>ÜÀz¿,]H@{KAš™Y@i$j@øLAÌÌÌ>i$j@øLAš™Y@”^ÿ>]â]¿i$j@øLAš™Y@i$j@øLAÌÌÌ>›ƒ@ ðPAÌÌÌ>0"?ŠF¿i$j@øLAš™Y@›ƒ@ ðPAÌÌÌ>›ƒ@ ðPAš™Y@ˆ,X?t! ¿›ƒ@ ðPAš™Y@›ƒ@ ðPAÌÌÌ>§úŠ@HxXAÌÌÌ>:¨k?bȾ›ƒ@ ðPAš™Y@§úŠ@HxXAÌÌÌ>§úŠ@HxXAš™Y@|­|?(p$¾§úŠ@HxXAš™Y@§úŠ@HxXAÌÌÌ>Œ@ ¹\Aš™Y@Üñ?•(ª¼Œ@ ¹\Aš™Y@§úŠ@HxXAÌÌÌ>§úŠ@ß×_AÌÌÌ>P|}?À*>Œ@ ¹\Aš™Y@§úŠ@ß×_AÌÌÌ>§úŠ@ùù`Aš™Y@áÉy?Æ3`>§úŠ@ß×_AÌÌÌ>§úŠ@ùù`AÌÌÌ>§úŠ@ùù`Aš™Y@:¨k?bÈ>§úŠ@ùù`Aš™Y@§úŠ@ùù`AÌÌÌ>›ƒ@8‚hAÌÌÌ>ˆ,X?t! ?§úŠ@ùù`Aš™Y@›ƒ@8‚hAÌÌÌ>›ƒ@8‚hAš™Y@0"?ŠF?›ƒ@8‚hAš™Y@›ƒ@8‚hAÌÌÌ>i$j@IWmAÌÌÌ>”^ÿ>]â]?›ƒ@8‚hAš™Y@i$j@IWmAÌÌÌ>i$j@IWmAš™Y@™@N>ÜÀz?i$j@IWmAš™Y@i$j@IWmAÌÌÌ>,]H@Ç]nAÌÌÌ>ƒ=‰Î?i$j@IWmAš™Y@,]H@Ç]nAÌÌÌ>,]H@Ç]nAš™Y@„¿¾_þu?,]H@Ç]nAš™Y@,]H@Ç]nAÌÌÌ>{Œ(@YkAÌÌÌ>Þ%ܾˆ g?,]H@Ç]nAš™Y@{Œ(@YkAÌÌÌ>{Œ(@YkAš™Y@'1¿6á8?{Œ(@YkAš™Y@{Œ(@YkAÌÌÌ>/ü@ŠûdAÌÌÌ>1àL¿»?{Œ(@YkAš™Y@/ü@ŠûdAÌÌÌ>/ü@ŠûdAš™Y@“rm¿%\¿>/ü@ŠûdAš™Y@/ü@ŠûdAÌÌÌ>ë @ß×_AÌÌÌ>!Ãy¿í«`>/ü@ŠûdAš™Y@ë @ß×_AÌÌÌ>× @ ¹\Aš™Y@lˆ¿,Rw=× @ ¹\Aš™Y@ë @ß×_AÌÌÌ>× @ ¹\AÌÌÌ>5¾|¿ÿÒ"¾× @ ¹\Aš™Y@× @ ¹\AÌÌÌ>/ü@¸vTAÌÌÌ>€?{Œ(@YkAš™Y@/ü@ŠûdAš™Y@× @ ¹\Aš™Y@€?,]H@{KAš™Y@i$j@øLAš™Y@{Œ(@²NAš™Y@€?{Œ(@²NAš™Y@i$j@øLAš™Y@›ƒ@ ðPAš™Y@€?{Œ(@²NAš™Y@›ƒ@ ðPAš™Y@/ü@¸vTAš™Y@€?/ü@¸vTAš™Y@›ƒ@ ðPAš™Y@§úŠ@HxXAš™Y@€?/ü@¸vTAš™Y@§úŠ@HxXAš™Y@× @ ¹\Aš™Y@€?× @ ¹\Aš™Y@§úŠ@HxXAš™Y@Œ@ ¹\Aš™Y@€?× @ ¹\Aš™Y@Œ@ ¹\Aš™Y@§úŠ@ùù`Aš™Y@€?,]H@Ç]nAš™Y@{Œ(@YkAš™Y@i$j@IWmAš™Y@€?i$j@IWmAš™Y@{Œ(@YkAš™Y@× @ ¹\Aš™Y@€?i$j@IWmAš™Y@× @ ¹\Aš™Y@›ƒ@8‚hAš™Y@€?›ƒ@8‚hAš™Y@× @ ¹\Aš™Y@§úŠ@ùù`Aš™Y@?‚…>µ$w¿ÓÒ@fÆDAÌÌÌ>ªÚØ@â­EAš™Y@M Ë@ÔCAš™Y@CcÙ>€Çg¿ÓÒ@fÆDAÌÌÌ>ªÚØ@â­EAÌÌÌ>ªÚØ@â­EAš™Y@œ2$?ÎgD¿ªÚØ@â­EAš™Y@ªÚØ@â­EAÌÌÌ>Eõâ@/»JAÌÌÌ>ÎgD?œ2$¿ªÚØ@â­EAš™Y@Eõâ@/»JAÌÌÌ>Eõâ@/»JAš™Y@ñfp?ü¯¾Eõâ@/»JAš™Y@Eõâ@/»JAÌÌÌ>¨æ@Þ¡QAÌÌÌ>ä0|?ü/¾Eõâ@/»JAš™Y@¨æ@Þ¡QAÌÌÌ>¨æ@Þ¡QAš™Y@ä0|?ü/>¨æ@Þ¡QAš™Y@¨æ@Þ¡QAÌÌÌ>Eõâ@ŒˆXAÌÌÌ>ñfp?ü¯>¨æ@Þ¡QAš™Y@Eõâ@ŒˆXAÌÌÌ>Eõâ@ŒˆXAš™Y@ÎgD?œ2$?Eõâ@ŒˆXAš™Y@Eõâ@ŒˆXAÌÌÌ>ªÚØ@Ù•]AÌÌÌ>œ2$?ÎgD?Eõâ@ŒˆXAš™Y@ªÚØ@Ù•]AÌÌÌ>ªÚØ@Ù•]Aš™Y@ü¯>ñfp?ªÚØ@Ù•]Aš™Y@ªÚØ@Ù•]AÌÌÌ>M Ë@;o_AÌÌÌ>ü/>ä0|?ªÚØ@Ù•]Aš™Y@M Ë@;o_AÌÌÌ>M Ë@;o_Aš™Y@ü/¾ä0|?M Ë@;o_Aš™Y@M Ë@;o_AÌÌÌ>ð?½@Ù•]AÌÌÌ>ü¯¾ñfp?M Ë@;o_Aš™Y@ð?½@Ù•]AÌÌÌ>ð?½@Ù•]Aš™Y@œ2$¿ÎgD?ð?½@Ù•]Aš™Y@ð?½@Ù•]AÌÌÌ>U%³@ŒˆXAÌÌÌ>ÎgD¿œ2$?ð?½@Ù•]Aš™Y@U%³@ŒˆXAÌÌÌ>U%³@ŒˆXAš™Y@ñfp¿ü¯>U%³@ŒˆXAš™Y@U%³@ŒˆXAÌÌÌ>’r¯@Þ¡QAÌÌÌ>ä0|¿ü/>U%³@ŒˆXAš™Y@’r¯@Þ¡QAÌÌÌ>’r¯@Þ¡QAš™Y@ä0|¿ü/¾’r¯@Þ¡QAš™Y@’r¯@Þ¡QAÌÌÌ>U%³@/»JAÌÌÌ>ñfp¿ü¯¾’r¯@Þ¡QAš™Y@U%³@/»JAÌÌÌ>U%³@/»JAš™Y@ÎgD¿œ2$¿U%³@/»JAš™Y@U%³@/»JAÌÌÌ>ð?½@â­EAÌÌÌ>œ2$¿ÎgD¿U%³@/»JAš™Y@ð?½@â­EAÌÌÌ>ð?½@â­EAš™Y@CcÙ¾€Çg¿ð?½@â­EAš™Y@ð?½@â­EAÌÌÌ>ÇÿÃ@fÆDAÌÌÌ>?‚…¾µ$w¿ð?½@â­EAš™Y@ÇÿÃ@fÆDAÌÌÌ>M Ë@ÔCAš™Y@˶½©ü~¿M Ë@ÔCAš™Y@ÇÿÃ@fÆDAÌÌÌ>M Ë@ÔCAÌÌÌ>˶=©ü~¿M Ë@ÔCAš™Y@M Ë@ÔCAÌÌÌ>ÓÒ@fÆDAÌÌÌ>€?ð?½@Ù•]Aš™Y@M Ë@ÔCAš™Y@M Ë@;o_Aš™Y@€?M Ë@;o_Aš™Y@M Ë@ÔCAš™Y@ªÚØ@â­EAš™Y@€?ð?½@â­EAš™Y@M Ë@ÔCAš™Y@U%³@/»JAš™Y@€?U%³@/»JAš™Y@M Ë@ÔCAš™Y@ð?½@Ù•]Aš™Y@€?U%³@/»JAš™Y@ð?½@Ù•]Aš™Y@’r¯@Þ¡QAš™Y@€?’r¯@Þ¡QAš™Y@ð?½@Ù•]Aš™Y@U%³@ŒˆXAš™Y@€?Eõâ@ŒˆXAš™Y@ªÚØ@Ù•]Aš™Y@¨æ@Þ¡QAš™Y@€?¨æ@Þ¡QAš™Y@ªÚØ@Ù•]Aš™Y@M Ë@;o_Aš™Y@€?¨æ@Þ¡QAš™Y@M Ë@;o_Aš™Y@Eõâ@/»JAš™Y@€?Eõâ@/»JAš™Y@M Ë@;o_Aš™Y@ªÚØ@â­EAš™Y@ñfp¿ü¯¾ AêbnAš™Y@Ff AµQgAÌÌÌ>Ff AµQgAš™Y@ÎgD¿œ2$¿Ff AµQgAš™Y@Ff AµQgAÌÌÌ>³’AH%bAÌÌÌ>œ2$¿ÎgD¿Ff AµQgAš™Y@³’AH%bAÌÌÌ>³’AH%bAš™Y@ü¯¾ñfp¿³’AH%bAš™Y@³’AH%bAÌÌÌ>ç£A‚@`AÌÌÌ>ü/¾ä0|¿³’AH%bAš™Y@ç£A‚@`AÌÌÌ>ç£A‚@`Aš™Y@ü/>ä0|¿ç£A‚@`Aš™Y@ç£A‚@`AÌÌÌ>µAH%bAÌÌÌ>ü¯>ñfp¿ç£A‚@`Aš™Y@µAH%bAÌÌÌ>µAH%bAš™Y@œ2$?ÎgD¿µAH%bAš™Y@µAH%bAÌÌÌ>ˆá#AµQgAÌÌÌ>ÎgD?œ2$¿µAH%bAš™Y@ˆá#AµQgAÌÌÌ>ˆá#AµQgAš™Y@ñfp?ü¯¾ˆá#AµQgAš™Y@ˆá#AµQgAÌÌÌ>OÆ%AêbnAÌÌÌ>ä0|?ü/¾ˆá#AµQgAš™Y@OÆ%AêbnAÌÌÌ>OÆ%AêbnAš™Y@‹=?ª¦=OÆ%AêbnAš™Y@OÆ%AêbnAÌÌÌ>:ï$Až…qAÌÌÌ> òw?`Ö~>OÆ%AêbnAš™Y@:ï$Až…qAÌÌÌ>ˆá#AtuAš™Y@÷i?ÂØÓ>:ï$Až…qAÌÌÌ>ˆá#AtuAÌÌÌ>ˆá#AtuAš™Y@ÎgD?œ2$?ˆá#AtuAš™Y@ˆá#AtuAÌÌÌ>µAŒ zAÌÌÌ>œ2$?ÎgD?ˆá#AtuAš™Y@µAŒ zAÌÌÌ>µAŒ zAš™Y@ü¯>ñfp?µAŒ zAš™Y@µAŒ zAÌÌÌ>ç£AQ…|AÌÌÌ>ü/>ä0|?µAŒ zAš™Y@ç£AQ…|AÌÌÌ>ç£AQ…|Aš™Y@ü/¾ä0|?ç£AQ…|Aš™Y@ç£AQ…|AÌÌÌ>³’AŒ zAÌÌÌ>ü¯¾ñfp?ç£AQ…|Aš™Y@³’AŒ zAÌÌÌ>³’AŒ zAš™Y@œ2$¿ÎgD?³’AŒ zAš™Y@³’AŒ zAÌÌÌ>Ff AtuAÌÌÌ>ÎgD¿œ2$?³’AŒ zAš™Y@Ff AtuAÌÌÌ>Ff AtuAš™Y@÷i¿ÂØÓ>Ff AtuAš™Y@Ff AtuAÌÌÌ>•X Až…qAÌÌÌ> òw¿`Ö~>Ff AtuAš™Y@•X Až…qAÌÌÌ> AêbnAš™Y@‹=¿ª¦= AêbnAš™Y@•X Až…qAÌÌÌ> AêbnAÌÌÌ>ä0|¿ü/¾ AêbnAš™Y@ AêbnAÌÌÌ>Ff AµQgAÌÌÌ>€?ˆá#AtuAš™Y@µAŒ zAš™Y@ç£AQ…|Aš™Y@€?OÆ%AêbnAš™Y@ˆá#AtuAš™Y@ˆá#AµQgAš™Y@€?ˆá#AµQgAš™Y@ˆá#AtuAš™Y@ç£AQ…|Aš™Y@€?ˆá#AµQgAš™Y@ç£AQ…|Aš™Y@µAH%bAš™Y@€?µAH%bAš™Y@ç£AQ…|Aš™Y@ç£A‚@`Aš™Y@€?ç£AQ…|Aš™Y@³’AŒ zAš™Y@ç£A‚@`Aš™Y@€?ç£A‚@`Aš™Y@³’AŒ zAš™Y@Ff AtuAš™Y@€?ç£A‚@`Aš™Y@Ff AtuAš™Y@³’AH%bAš™Y@€?³’AH%bAš™Y@Ff AtuAš™Y@ AêbnAš™Y@€?³’AH%bAš™Y@ AêbnAš™Y@Ff AµQgAš™Y@€¿E7AK¸EAÌÌÌ>E7AK¸EAš™Y@E7Aß×_AÌÌÌ>€¿E7Aß×_AÌÌÌ>E7AK¸EAš™Y@E7A‚@`Aš™Y@€¿E7Aß×_AÌÌÌ>E7A‚@`Aš™Y@E7A‚@`AÌÌÌ>€¿B¡LAK¸EAš™Y@E7AK¸EAš™Y@B¡LAK¸EAÌÌÌ>€¿B¡LAK¸EAÌÌÌ>E7AK¸EAš™Y@E7AK¸EAÌÌÌ>€?B¡LA‚@`AÌÌÌ>B¡LA‚@`Aš™Y@B¡LAß×_AÌÌÌ>€?B¡LAß×_AÌÌÌ>B¡LA‚@`Aš™Y@B¡LAK¸EAš™Y@€?B¡LAß×_AÌÌÌ>B¡LAK¸EAš™Y@B¡LAK¸EAÌÌÌ>€?E7A‚@`Aš™Y@B¡LA‚@`Aš™Y@E7A‚@`AÌÌÌ>€?E7A‚@`AÌÌÌ>B¡LA‚@`Aš™Y@B¡LA‚@`AÌÌÌ>€?B¡LAK¸EAš™Y@B¡LA‚@`Aš™Y@E7AK¸EAš™Y@€?E7AK¸EAš™Y@B¡LA‚@`Aš™Y@E7A‚@`Aš™Y@€¿N”aA‚@`AÌÌÌ>N”aA‚@`Aš™Y@N”aAž…qAÌÌÌ>€¿N”aAž…qAÌÌÌ>N”aA‚@`Aš™Y@N”aAHŒtAš™Y@€¿N”aAž…qAÌÌÌ>N”aAHŒtAš™Y@N”aAHŒtAÌÌÌ>€¿âKuA‚@`Aš™Y@N”aA‚@`Aš™Y@âKuA‚@`AÌÌÌ>€¿âKuA‚@`AÌÌÌ>N”aA‚@`Aš™Y@N”aA‚@`AÌÌÌ>€?âKuAHŒtAÌÌÌ>âKuAHŒtAš™Y@âKuAž…qAÌÌÌ>€?âKuAž…qAÌÌÌ>âKuAHŒtAš™Y@âKuA‚@`Aš™Y@€?âKuAž…qAÌÌÌ>âKuA‚@`Aš™Y@âKuA‚@`AÌÌÌ>€?N”aAHŒtAš™Y@âKuAHŒtAš™Y@N”aAHŒtAÌÌÌ>€?N”aAHŒtAÌÌÌ>âKuAHŒtAš™Y@âKuAHŒtAÌÌÌ>€?âKuA‚@`Aš™Y@âKuAHŒtAš™Y@N”aA‚@`Aš™Y@€?N”aA‚@`Aš™Y@âKuAHŒtAš™Y@N”aAHŒtAš™Y@€¿ ;‰AÄ%?AÌÌÌ> ;‰AÄ%?Aš™Y@ ;‰AfÆDAÌÌÌ>€¿ ;‰AfÆDAÌÌÌ> ;‰AÄ%?Aš™Y@ ;‰AÝoYAš™Y@€¿ ;‰AfÆDAÌÌÌ> ;‰AÝoYAš™Y@ ;‰AÝoYAÌÌÌ>€¿ý“AÄ%?Aš™Y@ ;‰AÄ%?Aš™Y@ý“AÄ%?AÌÌÌ>€¿ý“AÄ%?AÌÌÌ> ;‰AÄ%?Aš™Y@ ;‰AÄ%?AÌÌÌ>€?ý“AÝoYAÌÌÌ>ý“AÝoYAš™Y@ý“AfÆDAÌÌÌ>€?ý“AfÆDAÌÌÌ>ý“AÝoYAš™Y@ý“AÄ%?Aš™Y@€?ý“AfÆDAÌÌÌ>ý“AÄ%?Aš™Y@ý“AÄ%?AÌÌÌ>€? ;‰AÝoYAš™Y@ý“AÝoYAš™Y@ ;‰AÝoYAÌÌÌ>€? ;‰AÝoYAÌÌÌ>ý“AÝoYAš™Y@ý“AÝoYAÌÌÌ>€?ý“AÄ%?Aš™Y@ý“AÝoYAš™Y@ ;‰AÄ%?Aš™Y@€? ;‰AÄ%?Aš™Y@ý“AÝoYAš™Y@ ;‰AÝoYAš™Y@€¿¸É?#û…Aš™Y@¸É?$ŒAš™Y@¸É?#û…AÌÌÌ>€¿¸É?#û…AÌÌÌ>¸É?$ŒAš™Y@¸É?$ŒAÌÌÌ>€¿ ˆ…A#û…AÌÌÌ>ƒÇ¥A#û…AÌÌÌ>ƒÇ¥A#û…Aš™Y@€¿¸É?#û…AÌÌÌ>Ið @#û…AÌÌÌ>¸É?#û…Aš™Y@€¿¸É?#û…Aš™Y@Ið @#û…AÌÌÌ>"²é@#û…AÌÌÌ>€¿"²é@#û…AÌÌÌ>=Šô@#û…AÌÌÌ>¸É?#û…Aš™Y@€¿¸É?#û…Aš™Y@=Šô@#û…AÌÌÌ>yB/A#û…AÌÌÌ>€¿¸É?#û…Aš™Y@yB/A#û…AÌÌÌ>ƒÇ¥A#û…Aš™Y@€¿ƒÇ¥A#û…Aš™Y@yB/A#û…AÌÌÌ>]OA#û…AÌÌÌ>€¿ƒÇ¥A#û…Aš™Y@]OA#û…AÌÌÌ> ˆ…A#û…AÌÌÌ>€?ƒÇ¥A$ŒAš™Y@ƒÇ¥A#û…Aš™Y@ƒÇ¥A$ŒAÌÌÌ>€?ƒÇ¥A$ŒAÌÌÌ>ƒÇ¥A#û…Aš™Y@ƒÇ¥A#û…AÌÌÌ>€?ƒÇ¥A$ŒAÌÌÌ> ˆ…A$ŒAÌÌÌ>ƒÇ¥A$ŒAš™Y@€?ƒÇ¥A$ŒAš™Y@ ˆ…A$ŒAÌÌÌ>]OA$ŒAÌÌÌ>€?ƒÇ¥A$ŒAš™Y@]OA$ŒAÌÌÌ>¸É?$ŒAš™Y@€?¸É?$ŒAš™Y@]OA$ŒAÌÌÌ>yB/A$ŒAÌÌÌ>€?¸É?$ŒAš™Y@yB/A$ŒAÌÌÌ>=Šô@$ŒAÌÌÌ>€?=Šô@$ŒAÌÌÌ>"²é@$ŒAÌÌÌ>¸É?$ŒAš™Y@€?¸É?$ŒAš™Y@"²é@$ŒAÌÌÌ>Ið @$ŒAÌÌÌ>€?¸É?$ŒAš™Y@Ið @$ŒAÌÌÌ>¸É?$ŒAÌÌÌ>€?ƒÇ¥A#û…Aš™Y@ƒÇ¥A$ŒAš™Y@¸É?#û…Aš™Y@€?¸É?#û…Aš™Y@ƒÇ¥A$ŒAš™Y@¸É?$ŒAš™Y@€?ƒÇ¥A·Ë•Aš™Y@ƒÇ¥A Aš™Y@ƒÇ¥A·Ë•AÌÌÌ>€?ƒÇ¥A·Ë•AÌÌÌ>ƒÇ¥A Aš™Y@ƒÇ¥A AÌÌÌ>€?ƒÇ¥A·Ë•AÌÌÌ> ˆ…A·Ë•AÌÌÌ>ƒÇ¥A·Ë•Aš™Y@€?ƒÇ¥A·Ë•Aš™Y@ ˆ…A·Ë•AÌÌÌ>]OA·Ë•AÌÌÌ>€?ƒÇ¥A·Ë•Aš™Y@]OA·Ë•AÌÌÌ>¸É?·Ë•Aš™Y@€?¸É?·Ë•Aš™Y@]OA·Ë•AÌÌÌ>yB/A·Ë•AÌÌÌ>€?¸É?·Ë•Aš™Y@yB/A·Ë•AÌÌÌ>=Šô@·Ë•AÌÌÌ>€?=Šô@·Ë•AÌÌÌ>"²é@·Ë•AÌÌÌ>¸É?·Ë•Aš™Y@€?¸É?·Ë•Aš™Y@"²é@·Ë•AÌÌÌ>Ið @·Ë•AÌÌÌ>€?¸É?·Ë•Aš™Y@Ið @·Ë•AÌÌÌ>¸É?·Ë•AÌÌÌ>€¿¸É? Aš™Y@¸É?·Ë•Aš™Y@¸É? AÌÌÌ>€¿¸É? AÌÌÌ>¸É?·Ë•Aš™Y@¸É?·Ë•AÌÌÌ>€¿ ˆ…A AÌÌÌ>ƒÇ¥A AÌÌÌ>ƒÇ¥A Aš™Y@€¿¸É? AÌÌÌ>Ið @ AÌÌÌ>¸É? Aš™Y@€¿¸É? Aš™Y@Ið @ AÌÌÌ>"²é@ AÌÌÌ>€¿"²é@ AÌÌÌ>=Šô@ AÌÌÌ>¸É? Aš™Y@€¿¸É? Aš™Y@=Šô@ AÌÌÌ>yB/A AÌÌÌ>€¿¸É? Aš™Y@yB/A AÌÌÌ>ƒÇ¥A Aš™Y@€¿ƒÇ¥A Aš™Y@yB/A AÌÌÌ>]OA AÌÌÌ>€¿ƒÇ¥A Aš™Y@]OA AÌÌÌ> ˆ…A AÌÌÌ>€?¸É?·Ë•Aš™Y@¸É? Aš™Y@ƒÇ¥A·Ë•Aš™Y@€?ƒÇ¥A·Ë•Aš™Y@¸É? Aš™Y@ƒÇ¥A Aš™Y@€¿¸É?ŽI™Aš™Y@¸É?› žAš™Y@¸É?ŽI™AÌÌÌ>€¿¸É?ŽI™AÌÌÌ>¸É?› žAš™Y@¸É?› žAÌÌÌ>€¿>¼ì@ŽI™Aš™Y@¸É?ŽI™Aš™Y@¸É?ŽI™AÌÌÌ>€¿¸É?ŽI™AÌÌÌ>Ið @ŽI™AÌÌÌ>>¼ì@ŽI™Aš™Y@€¿>¼ì@ŽI™Aš™Y@Ið @ŽI™AÌÌÌ>"²é@ŽI™AÌÌÌ>€¿>¼ì@ŽI™Aš™Y@"²é@ŽI™AÌÌÌ>>¼ì@ŽI™AÌÌÌ>€?>¼ì@› žAš™Y@>¼ì@ŽI™Aš™Y@>¼ì@› žAÌÌÌ>€?>¼ì@› žAÌÌÌ>>¼ì@ŽI™Aš™Y@>¼ì@ŽI™AÌÌÌ>€?¸É?› žAÌÌÌ>¸É?› žAš™Y@Ið @› žAÌÌÌ>€?Ið @› žAÌÌÌ>¸É?› žAš™Y@>¼ì@› žAš™Y@€?Ið @› žAÌÌÌ>>¼ì@› žAš™Y@"²é@› žAÌÌÌ>€?"²é@› žAÌÌÌ>>¼ì@› žAš™Y@>¼ì@› žAÌÌÌ>€?>¼ì@ŽI™Aš™Y@>¼ì@› žAš™Y@¸É?ŽI™Aš™Y@€?¸É?ŽI™Aš™Y@>¼ì@› žAš™Y@¸É?› žAš™Y@€¿9 AŽI™Aš™Y@9 A› žAš™Y@9 AŽI™AÌÌÌ>€¿9 AŽI™AÌÌÌ>9 A› žAš™Y@9 A› žAÌÌÌ>€¿’ÝdAŽI™AÌÌÌ>’ÝdAŽI™Aš™Y@]OAŽI™AÌÌÌ>€¿]OAŽI™AÌÌÌ>’ÝdAŽI™Aš™Y@9 AŽI™Aš™Y@€¿]OAŽI™AÌÌÌ>9 AŽI™Aš™Y@yB/AŽI™AÌÌÌ>€¿yB/AŽI™AÌÌÌ>9 AŽI™Aš™Y@9 AŽI™AÌÌÌ>€?’ÝdA› žAš™Y@’ÝdAŽI™Aš™Y@’ÝdA› žAÌÌÌ>€?’ÝdA› žAÌÌÌ>’ÝdAŽI™Aš™Y@’ÝdAŽI™AÌÌÌ>€?9 A› žAÌÌÌ>9 A› žAš™Y@yB/A› žAÌÌÌ>€?yB/A› žAÌÌÌ>9 A› žAš™Y@’ÝdA› žAš™Y@€?yB/A› žAÌÌÌ>’ÝdA› žAš™Y@]OA› žAÌÌÌ>€?]OA› žAÌÌÌ>’ÝdA› žAš™Y@’ÝdA› žAÌÌÌ>€?’ÝdAŽI™Aš™Y@’ÝdA› žAš™Y@9 AŽI™Aš™Y@€?9 AŽI™Aš™Y@’ÝdA› žAš™Y@9 A› žAš™Y@€¿âKuAŽI™Aš™Y@âKuA› žAš™Y@âKuAŽI™AÌÌÌ>€¿âKuAŽI™AÌÌÌ>âKuA› žAš™Y@âKuA› žAÌÌÌ>€¿ƒÇ¥AŽI™AÌÌÌ>ƒÇ¥AŽI™Aš™Y@ ˆ…AŽI™AÌÌÌ>€¿ ˆ…AŽI™AÌÌÌ>ƒÇ¥AŽI™Aš™Y@âKuAŽI™Aš™Y@€¿ ˆ…AŽI™AÌÌÌ>âKuAŽI™Aš™Y@âKuAŽI™AÌÌÌ>€?ƒÇ¥A› žAš™Y@ƒÇ¥AŽI™Aš™Y@ƒÇ¥A› žAÌÌÌ>€?ƒÇ¥A› žAÌÌÌ>ƒÇ¥AŽI™Aš™Y@ƒÇ¥AŽI™AÌÌÌ>€?âKuA› žAÌÌÌ>âKuA› žAš™Y@ ˆ…A› žAÌÌÌ>€? ˆ…A› žAÌÌÌ>âKuA› žAš™Y@ƒÇ¥A› žAš™Y@€? ˆ…A› žAÌÌÌ>ƒÇ¥A› žAš™Y@ƒÇ¥A› žAÌÌÌ>€?ƒÇ¥AŽI™Aš™Y@ƒÇ¥A› žAš™Y@âKuAŽI™Aš™Y@€?âKuAŽI™Aš™Y@ƒÇ¥A› žAš™Y@âKuA› žAš™Y@sfact-2011.12.18/calibration/short_full.STL000066400000000000000000027224111167321211700202550ustar00rootroot00000000000000solid ultimate facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.183016e+000 1.599934e+001 2.000025e+000 vertex 2.261967e+000 1.629399e+001 2.000025e+000 vertex 0.000000e+000 2.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.000025e+000 vertex 2.261967e+000 1.629399e+001 2.000025e+000 vertex 2.390885e+000 1.657046e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.550891e+000 1.629399e+001 2.000025e+000 vertex 5.629843e+000 1.599934e+001 2.000025e+000 vertex 7.978277e+000 1.800000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.156430e+000 1.003403e+001 2.000025e+000 vertex 6.122247e+000 9.643323e+000 2.000025e+000 vertex 6.037245e+000 5.516113e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.037245e+000 5.516113e+000 2.000025e+000 vertex 6.122247e+000 9.643323e+000 2.000025e+000 vertex 6.020738e+000 9.264486e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.978277e+000 1.800000e+001 2.000025e+000 vertex 5.629843e+000 1.599934e+001 2.000025e+000 vertex 7.978277e+000 1.500000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.020738e+000 9.264486e+000 2.000025e+000 vertex 5.854987e+000 8.909031e+000 2.000025e+000 vertex 6.037245e+000 5.516113e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.037245e+000 5.516113e+000 2.000025e+000 vertex 5.854987e+000 8.909031e+000 2.000025e+000 vertex 5.630029e+000 8.587759e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.037245e+000 5.516113e+000 2.000025e+000 vertex 5.630029e+000 8.587759e+000 2.000025e+000 vertex 6.082822e+000 4.995169e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.730047e+000 5.449674e-001 2.000025e+000 vertex 3.454915e+000 2.447174e-001 2.000025e+000 vertex 4.217828e+000 6.155830e-002 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.390885e+000 1.657046e+001 2.000025e+000 vertex 2.565852e+000 1.682034e+001 2.000025e+000 vertex 0.000000e+000 2.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.000025e+000 vertex 2.565852e+000 1.682034e+001 2.000025e+000 vertex 2.781551e+000 1.703604e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.000025e+000 vertex 2.781551e+000 1.703604e+001 2.000025e+000 vertex 3.031429e+000 1.721100e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.003935e+001 1.095492e+001 2.000025e+000 vertex 9.442743e+000 1.146447e+001 2.000025e+000 vertex 5.247007e+000 1.457058e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.247007e+000 1.457058e+001 2.000025e+000 vertex 9.442743e+000 1.146447e+001 2.000025e+000 vertex 8.933192e+000 1.206107e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.247007e+000 1.457058e+001 2.000025e+000 vertex 8.933192e+000 1.206107e+001 2.000025e+000 vertex 5.421974e+000 1.482046e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 2.781551e+000 1.435488e+001 2.000025e+000 vertex 2.565852e+000 1.457058e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 2.183016e+000 1.539157e+001 2.000025e+000 vertex 0.000000e+000 2.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.000025e+000 vertex 2.183016e+000 1.539157e+001 2.000025e+000 vertex 2.156430e+000 1.569546e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.000025e+000 vertex 2.156430e+000 1.569546e+001 2.000025e+000 vertex 2.183016e+000 1.599934e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.263852e+000 1.953209e+001 2.000025e+000 vertex 6.978277e+000 1.973205e+001 2.000025e+000 vertex 5.031308e+000 1.703604e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.031308e+000 1.703604e+001 2.000025e+000 vertex 6.978277e+000 1.973205e+001 2.000025e+000 vertex 6.662317e+000 1.987938e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.031308e+000 1.703604e+001 2.000025e+000 vertex 6.662317e+000 1.987938e+001 2.000025e+000 vertex 4.781430e+000 1.721100e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.781430e+000 1.721100e+001 2.000025e+000 vertex 6.662317e+000 1.987938e+001 2.000025e+000 vertex 6.325573e+000 1.996962e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.781430e+000 1.721100e+001 2.000025e+000 vertex 6.325573e+000 1.996962e+001 2.000025e+000 vertex 4.504965e+000 1.733992e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.504965e+000 1.733992e+001 2.000025e+000 vertex 6.325573e+000 1.996962e+001 2.000025e+000 vertex 5.978277e+000 2.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.504965e+000 1.733992e+001 2.000025e+000 vertex 5.978277e+000 2.000000e+001 2.000025e+000 vertex 4.210314e+000 1.741887e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.629843e+000 1.599934e+001 2.000025e+000 vertex 5.656430e+000 1.569546e+001 2.000025e+000 vertex 7.978277e+000 1.500000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.978277e+000 1.500000e+001 2.000025e+000 vertex 5.656430e+000 1.569546e+001 2.000025e+000 vertex 5.629843e+000 1.539157e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.978277e+000 1.500000e+001 2.000025e+000 vertex 5.629843e+000 1.539157e+001 2.000025e+000 vertex 8.039835e+000 1.421783e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.039835e+000 1.421783e+001 2.000025e+000 vertex 5.629843e+000 1.539157e+001 2.000025e+000 vertex 5.550891e+000 1.509692e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.039835e+000 1.421783e+001 2.000025e+000 vertex 5.550891e+000 1.509692e+001 2.000025e+000 vertex 8.222995e+000 1.345492e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.222995e+000 1.345492e+001 2.000025e+000 vertex 5.550891e+000 1.509692e+001 2.000025e+000 vertex 5.421974e+000 1.482046e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.222995e+000 1.345492e+001 2.000025e+000 vertex 5.421974e+000 1.482046e+001 2.000025e+000 vertex 8.523245e+000 1.273005e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.523245e+000 1.273005e+001 2.000025e+000 vertex 5.421974e+000 1.482046e+001 2.000025e+000 vertex 8.933192e+000 1.206107e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.537245e+000 2.918037e+000 2.000025e+000 vertex 7.108882e+000 3.217980e+000 2.000025e+000 vertex 4.800000e+000 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.800000e+000 4.001601e-003 2.000025e+000 vertex 7.108882e+000 3.217980e+000 2.000025e+000 vertex 6.739111e+000 3.587750e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.800000e+000 4.001601e-003 2.000025e+000 vertex 6.739111e+000 3.587750e+000 2.000025e+000 vertex 6.439169e+000 4.016113e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.630029e+000 8.587759e+000 2.000025e+000 vertex 5.352702e+000 8.310431e+000 2.000025e+000 vertex 6.082822e+000 4.995169e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.082822e+000 4.995169e+000 2.000025e+000 vertex 5.352702e+000 8.310431e+000 2.000025e+000 vertex 5.031430e+000 8.085474e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.082822e+000 4.995169e+000 2.000025e+000 vertex 5.031430e+000 8.085474e+000 2.000025e+000 vertex 6.218167e+000 4.490052e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.218167e+000 4.490052e+000 2.000025e+000 vertex 5.031430e+000 8.085474e+000 2.000025e+000 vertex 4.675974e+000 7.919722e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.218167e+000 4.490052e+000 2.000025e+000 vertex 4.675974e+000 7.919722e+000 2.000025e+000 vertex 4.297138e+000 7.818213e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.906429e+000 7.784031e+000 2.000025e+000 vertex 3.515721e+000 7.818213e+000 2.000025e+000 vertex 2.061074e+000 9.549150e-001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.061074e+000 9.549150e-001 2.000025e+000 vertex 3.515721e+000 7.818213e+000 2.000025e+000 vertex 1.464466e+000 1.464466e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 2.000025e+000 vertex 3.515721e+000 7.818213e+000 2.000025e+000 vertex 3.136884e+000 7.919722e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 2.000025e+000 vertex 3.136884e+000 7.919722e+000 2.000025e+000 vertex 9.549150e-001 2.061074e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.297138e+000 1.224985e+001 2.000025e+000 vertex 4.504965e+000 1.405100e+001 2.000025e+000 vertex 4.210314e+000 1.397204e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.565852e+000 1.457058e+001 2.000025e+000 vertex 2.390885e+000 1.482046e+001 2.000025e+000 vertex 0.000000e+000 5.000000e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 2.390885e+000 1.482046e+001 2.000025e+000 vertex 2.261967e+000 1.509692e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 2.261967e+000 1.509692e+001 2.000025e+000 vertex 2.183016e+000 1.539157e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.031429e+000 1.721100e+001 2.000025e+000 vertex 3.307894e+000 1.733992e+001 2.000025e+000 vertex 0.000000e+000 2.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.000025e+000 vertex 3.307894e+000 1.733992e+001 2.000025e+000 vertex 3.602545e+000 1.741887e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.000025e+000 vertex 3.602545e+000 1.741887e+001 2.000025e+000 vertex 5.978277e+000 2.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.978277e+000 2.000000e+001 2.000025e+000 vertex 3.602545e+000 1.741887e+001 2.000025e+000 vertex 3.906429e+000 1.744546e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.978277e+000 2.000000e+001 2.000025e+000 vertex 3.906429e+000 1.744546e+001 2.000025e+000 vertex 4.210314e+000 1.741887e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.947892e+000 1.834730e+001 2.000025e+000 vertex 5.247007e+000 1.682034e+001 2.000025e+000 vertex 7.978277e+000 1.800000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.978277e+000 1.800000e+001 2.000025e+000 vertex 5.247007e+000 1.682034e+001 2.000025e+000 vertex 5.421974e+000 1.657046e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.978277e+000 1.800000e+001 2.000025e+000 vertex 5.421974e+000 1.657046e+001 2.000025e+000 vertex 5.550891e+000 1.629399e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.263852e+000 1.953209e+001 2.000025e+000 vertex 5.031308e+000 1.703604e+001 2.000025e+000 vertex 7.510366e+000 1.928557e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.510366e+000 1.928557e+001 2.000025e+000 vertex 5.031308e+000 1.703604e+001 2.000025e+000 vertex 5.247007e+000 1.682034e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.510366e+000 1.928557e+001 2.000025e+000 vertex 5.247007e+000 1.682034e+001 2.000025e+000 vertex 7.710328e+000 1.900000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.710328e+000 1.900000e+001 2.000025e+000 vertex 5.247007e+000 1.682034e+001 2.000025e+000 vertex 7.947892e+000 1.834730e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.710328e+000 1.900000e+001 2.000025e+000 vertex 7.947892e+000 1.834730e+001 2.000025e+000 vertex 7.857662e+000 1.868404e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.549150e-001 2.061074e+000 2.000025e+000 vertex 3.136884e+000 7.919722e+000 2.000025e+000 vertex 5.449674e-001 2.730047e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.449674e-001 2.730047e+000 2.000025e+000 vertex 3.136884e+000 7.919722e+000 2.000025e+000 vertex 2.781430e+000 8.085474e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.449674e-001 2.730047e+000 2.000025e+000 vertex 2.781430e+000 8.085474e+000 2.000025e+000 vertex 2.447174e-001 3.454915e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.447174e-001 3.454915e+000 2.000025e+000 vertex 2.781430e+000 8.085474e+000 2.000025e+000 vertex 6.155830e-002 4.217828e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.155830e-002 4.217828e+000 2.000025e+000 vertex 2.781430e+000 8.085474e+000 2.000025e+000 vertex 2.460157e+000 8.310431e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.155830e-002 4.217828e+000 2.000025e+000 vertex 2.460157e+000 8.310431e+000 2.000025e+000 vertex 0.000000e+000 5.000000e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 2.460157e+000 8.310431e+000 2.000025e+000 vertex 2.182829e+000 8.587759e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 2.182829e+000 8.587759e+000 2.000025e+000 vertex 1.957872e+000 8.909031e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.957872e+000 8.909031e+000 2.000025e+000 vertex 1.792121e+000 9.264486e+000 2.000025e+000 vertex 0.000000e+000 5.000000e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 1.792121e+000 9.264486e+000 2.000025e+000 vertex 1.690612e+000 9.643323e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 1.690612e+000 9.643323e+000 2.000025e+000 vertex 1.656430e+000 1.003403e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.656430e+000 1.003403e+001 2.000025e+000 vertex 1.690612e+000 1.042474e+001 2.000025e+000 vertex 0.000000e+000 5.000000e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 1.690612e+000 1.042474e+001 2.000025e+000 vertex 1.792121e+000 1.080358e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 1.792121e+000 1.080358e+001 2.000025e+000 vertex 2.781551e+000 1.435488e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.781551e+000 1.435488e+001 2.000025e+000 vertex 1.792121e+000 1.080358e+001 2.000025e+000 vertex 1.957872e+000 1.115903e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.781551e+000 1.435488e+001 2.000025e+000 vertex 1.957872e+000 1.115903e+001 2.000025e+000 vertex 2.182829e+000 1.148030e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.439169e+000 4.016113e+000 2.000025e+000 vertex 6.218167e+000 4.490052e+000 2.000025e+000 vertex 4.800000e+000 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.800000e+000 4.001601e-003 2.000025e+000 vertex 6.218167e+000 4.490052e+000 2.000025e+000 vertex 4.297138e+000 7.818213e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.800000e+000 4.001601e-003 2.000025e+000 vertex 4.297138e+000 7.818213e+000 2.000025e+000 vertex 4.217828e+000 6.155830e-002 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.217828e+000 6.155830e-002 2.000025e+000 vertex 4.297138e+000 7.818213e+000 2.000025e+000 vertex 3.906429e+000 7.784031e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.217828e+000 6.155830e-002 2.000025e+000 vertex 3.906429e+000 7.784031e+000 2.000025e+000 vertex 2.730047e+000 5.449674e-001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.730047e+000 5.449674e-001 2.000025e+000 vertex 3.906429e+000 7.784031e+000 2.000025e+000 vertex 2.061074e+000 9.549150e-001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.182829e+000 1.148030e+001 2.000025e+000 vertex 2.460157e+000 1.175763e+001 2.000025e+000 vertex 2.781551e+000 1.435488e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.781551e+000 1.435488e+001 2.000025e+000 vertex 2.460157e+000 1.175763e+001 2.000025e+000 vertex 2.781430e+000 1.198259e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.781551e+000 1.435488e+001 2.000025e+000 vertex 2.781430e+000 1.198259e+001 2.000025e+000 vertex 3.136884e+000 1.214834e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.185632e+001 4.490052e+000 2.000025e+000 vertex 1.163532e+001 4.016113e+000 2.000025e+000 vertex 1.500000e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 4.001601e-003 2.000025e+000 vertex 1.163532e+001 4.016113e+000 2.000025e+000 vertex 1.133538e+001 3.587750e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.037245e+000 2.516113e+000 2.000025e+000 vertex 4.800000e+000 4.001601e-003 2.000025e+000 vertex 9.558189e+000 2.561690e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.558189e+000 2.561690e+000 2.000025e+000 vertex 4.800000e+000 4.001601e-003 2.000025e+000 vertex 1.500000e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.558189e+000 2.561690e+000 2.000025e+000 vertex 1.500000e+001 4.001601e-003 2.000025e+000 vertex 1.006331e+001 2.697035e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 9.037245e+000 2.516113e+000 2.000025e+000 vertex 8.516300e+000 2.561690e+000 2.000025e+000 vertex 4.800000e+000 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.800000e+000 4.001601e-003 2.000025e+000 vertex 8.516300e+000 2.561690e+000 2.000025e+000 vertex 8.011185e+000 2.697035e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.800000e+000 4.001601e-003 2.000025e+000 vertex 8.011185e+000 2.697035e+000 2.000025e+000 vertex 7.537245e+000 2.918037e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.297138e+000 1.224985e+001 2.000025e+000 vertex 4.210314e+000 1.397204e+001 2.000025e+000 vertex 3.906429e+000 1.228403e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.906429e+000 1.228403e+001 2.000025e+000 vertex 4.210314e+000 1.397204e+001 2.000025e+000 vertex 3.906429e+000 1.394546e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.906429e+000 1.228403e+001 2.000025e+000 vertex 3.906429e+000 1.394546e+001 2.000025e+000 vertex 3.515721e+000 1.224985e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.185632e+001 6.542173e+000 2.000025e+000 vertex 1.199167e+001 6.037057e+000 2.000025e+000 vertex 1.500000e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 2.000025e+000 vertex 1.199167e+001 6.037057e+000 2.000025e+000 vertex 1.203724e+001 5.516113e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 2.000025e+000 vertex 1.203724e+001 5.516113e+000 2.000025e+000 vertex 1.500000e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 4.001601e-003 2.000025e+000 vertex 1.203724e+001 5.516113e+000 2.000025e+000 vertex 1.199167e+001 4.995169e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 4.001601e-003 2.000025e+000 vertex 1.199167e+001 4.995169e+000 2.000025e+000 vertex 1.185632e+001 4.490052e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.133538e+001 3.587750e+000 2.000025e+000 vertex 1.096561e+001 3.217980e+000 2.000025e+000 vertex 1.500000e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 4.001601e-003 2.000025e+000 vertex 1.096561e+001 3.217980e+000 2.000025e+000 vertex 1.053725e+001 2.918037e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 4.001601e-003 2.000025e+000 vertex 1.053725e+001 2.918037e+000 2.000025e+000 vertex 1.006331e+001 2.697035e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.906429e+000 1.394546e+001 2.000025e+000 vertex 3.602545e+000 1.397204e+001 2.000025e+000 vertex 3.515721e+000 1.224985e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.515721e+000 1.224985e+001 2.000025e+000 vertex 3.602545e+000 1.397204e+001 2.000025e+000 vertex 3.307894e+000 1.405100e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.515721e+000 1.224985e+001 2.000025e+000 vertex 3.307894e+000 1.405100e+001 2.000025e+000 vertex 3.136884e+000 1.214834e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.136884e+000 1.214834e+001 2.000025e+000 vertex 3.307894e+000 1.405100e+001 2.000025e+000 vertex 3.031429e+000 1.417991e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.136884e+000 1.214834e+001 2.000025e+000 vertex 3.031429e+000 1.417991e+001 2.000025e+000 vertex 2.781551e+000 1.435488e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.031308e+000 1.435488e+001 2.000025e+000 vertex 4.781430e+000 1.417991e+001 2.000025e+000 vertex 5.031430e+000 1.198259e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.504965e+000 1.405100e+001 2.000025e+000 vertex 4.297138e+000 1.224985e+001 2.000025e+000 vertex 4.781430e+000 1.417991e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.781430e+000 1.417991e+001 2.000025e+000 vertex 4.297138e+000 1.224985e+001 2.000025e+000 vertex 4.675974e+000 1.214834e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.781430e+000 1.417991e+001 2.000025e+000 vertex 4.675974e+000 1.214834e+001 2.000025e+000 vertex 5.031430e+000 1.198259e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.031308e+000 1.435488e+001 2.000025e+000 vertex 5.031430e+000 1.198259e+001 2.000025e+000 vertex 5.247007e+000 1.457058e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.247007e+000 1.457058e+001 2.000025e+000 vertex 5.031430e+000 1.198259e+001 2.000025e+000 vertex 5.352702e+000 1.175763e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.247007e+000 1.457058e+001 2.000025e+000 vertex 5.352702e+000 1.175763e+001 2.000025e+000 vertex 1.003935e+001 1.095492e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.003935e+001 1.095492e+001 2.000025e+000 vertex 5.352702e+000 1.175763e+001 2.000025e+000 vertex 5.630029e+000 1.148030e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.003935e+001 1.095492e+001 2.000025e+000 vertex 5.630029e+000 1.148030e+001 2.000025e+000 vertex 5.854987e+000 1.115903e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.011185e+000 8.335191e+000 2.000025e+000 vertex 8.516300e+000 8.470536e+000 2.000025e+000 vertex 6.122247e+000 1.042474e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.122247e+000 1.042474e+001 2.000025e+000 vertex 8.516300e+000 8.470536e+000 2.000025e+000 vertex 1.003935e+001 1.095492e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.122247e+000 1.042474e+001 2.000025e+000 vertex 1.003935e+001 1.095492e+001 2.000025e+000 vertex 6.020738e+000 1.080358e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.020738e+000 1.080358e+001 2.000025e+000 vertex 1.003935e+001 1.095492e+001 2.000025e+000 vertex 5.854987e+000 1.115903e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.096561e+001 7.814246e+000 2.000025e+000 vertex 1.133538e+001 7.444476e+000 2.000025e+000 vertex 1.500000e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 2.000025e+000 vertex 1.133538e+001 7.444476e+000 2.000025e+000 vertex 1.163532e+001 7.016113e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 2.000025e+000 vertex 1.163532e+001 7.016113e+000 2.000025e+000 vertex 1.185632e+001 6.542173e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.037245e+000 5.516113e+000 2.000025e+000 vertex 6.082822e+000 6.037057e+000 2.000025e+000 vertex 6.156430e+000 1.003403e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.156430e+000 1.003403e+001 2.000025e+000 vertex 6.082822e+000 6.037057e+000 2.000025e+000 vertex 6.218167e+000 6.542173e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.156430e+000 1.003403e+001 2.000025e+000 vertex 6.218167e+000 6.542173e+000 2.000025e+000 vertex 6.439169e+000 7.016113e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.439169e+000 7.016113e+000 2.000025e+000 vertex 6.739111e+000 7.444476e+000 2.000025e+000 vertex 6.156430e+000 1.003403e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.156430e+000 1.003403e+001 2.000025e+000 vertex 6.739111e+000 7.444476e+000 2.000025e+000 vertex 7.108882e+000 7.814246e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.156430e+000 1.003403e+001 2.000025e+000 vertex 7.108882e+000 7.814246e+000 2.000025e+000 vertex 6.122247e+000 1.042474e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.122247e+000 1.042474e+001 2.000025e+000 vertex 7.108882e+000 7.814246e+000 2.000025e+000 vertex 7.537245e+000 8.114189e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.122247e+000 1.042474e+001 2.000025e+000 vertex 7.537245e+000 8.114189e+000 2.000025e+000 vertex 8.011185e+000 8.335191e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.516300e+000 8.470536e+000 2.000025e+000 vertex 9.037245e+000 8.516113e+000 2.000025e+000 vertex 1.003935e+001 1.095492e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.003935e+001 1.095492e+001 2.000025e+000 vertex 9.037245e+000 8.516113e+000 2.000025e+000 vertex 9.558189e+000 8.470536e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.003935e+001 1.095492e+001 2.000025e+000 vertex 9.558189e+000 8.470536e+000 2.000025e+000 vertex 1.070832e+001 1.054497e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.070832e+001 1.054497e+001 2.000025e+000 vertex 9.558189e+000 8.470536e+000 2.000025e+000 vertex 1.006331e+001 8.335191e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.070832e+001 1.054497e+001 2.000025e+000 vertex 1.006331e+001 8.335191e+000 2.000025e+000 vertex 1.143319e+001 1.024472e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.143319e+001 1.024472e+001 2.000025e+000 vertex 1.006331e+001 8.335191e+000 2.000025e+000 vertex 1.053725e+001 8.114189e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.143319e+001 1.024472e+001 2.000025e+000 vertex 1.053725e+001 8.114189e+000 2.000025e+000 vertex 1.219611e+001 1.006156e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.219611e+001 1.006156e+001 2.000025e+000 vertex 1.053725e+001 8.114189e+000 2.000025e+000 vertex 1.096561e+001 7.814246e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.219611e+001 1.006156e+001 2.000025e+000 vertex 1.096561e+001 7.814246e+000 2.000025e+000 vertex 1.297828e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.297828e+001 1.000000e+001 2.000025e+000 vertex 1.096561e+001 7.814246e+000 2.000025e+000 vertex 1.500000e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.500000e+001 8.673617e-016 1.800025e+000 vertex 3.500000e+001 8.673617e-016 2.500000e-005 vertex 5.405000e+001 0.000000e+000 1.800025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 5.405000e+001 0.000000e+000 1.800025e+000 vertex 3.500000e+001 8.673617e-016 2.500000e-005 vertex 5.405000e+001 0.000000e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.769029e+001 1.940100e+001 2.000025e+000 vertex 4.770000e+001 1.940100e+001 2.000025e+000 vertex 4.770000e+001 1.905000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.756567e+001 1.270000e+001 2.000025e+000 vertex 3.756567e+001 1.000000e+001 2.000025e+000 vertex 4.135000e+001 1.270000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.135000e+001 1.270000e+001 2.000025e+000 vertex 3.756567e+001 1.000000e+001 2.000025e+000 vertex 4.256568e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.135000e+001 1.270000e+001 2.000025e+000 vertex 4.256568e+001 1.000000e+001 2.000025e+000 vertex 4.245252e+001 1.279644e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.245252e+001 1.279644e+001 2.000025e+000 vertex 4.256568e+001 1.000000e+001 2.000025e+000 vertex 4.256568e+001 1.281745e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.000000e+001 4.001601e-003 2.000025e+000 vertex 2.000000e+001 1.000000e+001 2.000025e+000 vertex 3.499908e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.499908e+001 4.001601e-003 2.000025e+000 vertex 2.000000e+001 1.000000e+001 2.000025e+000 vertex 3.270000e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 8.673617e-016 2.500000e-005 vertex 2.000000e+001 1.000000e+001 2.500000e-005 vertex 2.000000e+001 8.673617e-016 1.800025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 8.673617e-016 1.800025e+000 vertex 2.000000e+001 1.000000e+001 2.500000e-005 vertex 2.000000e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 8.673617e-016 1.800025e+000 vertex 2.000000e+001 1.000000e+001 2.000025e+000 vertex 2.000000e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 1.000000e+001 3.200025e+000 vertex 4.256568e+001 1.000000e+001 2.000025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 4.256568e+001 1.000000e+001 2.000025e+000 vertex 3.756567e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 1.297828e+001 1.000000e+001 2.500000e-005 vertex 1.297828e+001 1.000000e+001 2.000025e+000 vertex 2.000000e+001 1.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 1.000000e+001 2.500000e-005 vertex 1.297828e+001 1.000000e+001 2.000025e+000 vertex 1.500000e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 1.000000e+001 2.500000e-005 vertex 1.500000e+001 1.000000e+001 2.000025e+000 vertex 2.000000e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 1.000000e+001 2.000025e+000 vertex 1.500000e+001 1.000000e+001 2.000025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 1.000000e+001 2.000025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 3.270000e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.270000e+001 1.000000e+001 2.000025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 3.756567e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.270000e+001 1.000000e+001 2.000025e+000 vertex 3.756567e+001 1.000000e+001 2.000025e+000 vertex 3.270000e+001 1.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.270000e+001 1.000000e+001 2.500000e-005 vertex 3.756567e+001 1.000000e+001 2.000025e+000 vertex 3.756567e+001 1.000000e+001 2.500000e-005 endloop endfacet facet normal 5.228807e-002 9.986320e-001 0.000000e+000 outer loop vertex 1.297828e+001 1.000000e+001 2.000025e+000 vertex 1.297828e+001 1.000000e+001 2.500000e-005 vertex 1.219611e+001 1.006156e+001 2.500000e-005 endloop endfacet facet normal 1.045761e-001 9.945168e-001 0.000000e+000 outer loop vertex 1.297828e+001 1.000000e+001 2.000025e+000 vertex 1.219611e+001 1.006156e+001 2.500000e-005 vertex 1.219611e+001 1.006156e+001 2.000025e+000 endloop endfacet facet normal 2.078648e-001 9.781576e-001 0.000000e+000 outer loop vertex 1.219611e+001 1.006156e+001 2.000025e+000 vertex 1.219611e+001 1.006156e+001 2.500000e-005 vertex 1.143319e+001 1.024472e+001 2.500000e-005 endloop endfacet facet normal 2.588654e-001 9.659134e-001 0.000000e+000 outer loop vertex 1.219611e+001 1.006156e+001 2.000025e+000 vertex 1.143319e+001 1.024472e+001 2.500000e-005 vertex 1.143319e+001 1.024472e+001 2.000025e+000 endloop endfacet facet normal 3.583232e-001 9.335976e-001 0.000000e+000 outer loop vertex 1.143319e+001 1.024472e+001 2.000025e+000 vertex 1.143319e+001 1.024472e+001 2.500000e-005 vertex 1.070832e+001 1.054497e+001 2.500000e-005 endloop endfacet facet normal 4.067805e-001 9.135259e-001 0.000000e+000 outer loop vertex 1.143319e+001 1.024472e+001 2.000025e+000 vertex 1.070832e+001 1.054497e+001 2.500000e-005 vertex 1.070832e+001 1.054497e+001 2.000025e+000 endloop endfacet facet normal 4.999585e-001 8.660493e-001 0.000000e+000 outer loop vertex 1.070832e+001 1.054497e+001 2.000025e+000 vertex 1.070832e+001 1.054497e+001 2.500000e-005 vertex 1.003935e+001 1.095492e+001 2.500000e-005 endloop endfacet facet normal 5.446792e-001 8.386444e-001 0.000000e+000 outer loop vertex 1.070832e+001 1.054497e+001 2.000025e+000 vertex 1.003935e+001 1.095492e+001 2.500000e-005 vertex 1.003935e+001 1.095492e+001 2.000025e+000 endloop endfacet facet normal 6.292831e-001 7.771761e-001 0.000000e+000 outer loop vertex 1.003935e+001 1.095492e+001 2.000025e+000 vertex 1.003935e+001 1.095492e+001 2.500000e-005 vertex 9.442743e+000 1.146447e+001 2.500000e-005 endloop endfacet facet normal 6.691663e-001 7.431127e-001 0.000000e+000 outer loop vertex 1.003935e+001 1.095492e+001 2.000025e+000 vertex 9.442743e+000 1.146447e+001 2.500000e-005 vertex 9.442743e+000 1.146447e+001 2.000025e+000 endloop endfacet facet normal 7.431127e-001 6.691663e-001 0.000000e+000 outer loop vertex 9.442743e+000 1.146447e+001 2.000025e+000 vertex 9.442743e+000 1.146447e+001 2.500000e-005 vertex 8.933192e+000 1.206107e+001 2.500000e-005 endloop endfacet facet normal 7.771761e-001 6.292831e-001 0.000000e+000 outer loop vertex 9.442743e+000 1.146447e+001 2.000025e+000 vertex 8.933192e+000 1.206107e+001 2.500000e-005 vertex 8.933192e+000 1.206107e+001 2.000025e+000 endloop endfacet facet normal 8.386444e-001 5.446792e-001 0.000000e+000 outer loop vertex 8.933192e+000 1.206107e+001 2.000025e+000 vertex 8.933192e+000 1.206107e+001 2.500000e-005 vertex 8.523245e+000 1.273005e+001 2.500000e-005 endloop endfacet facet normal 8.660493e-001 4.999585e-001 0.000000e+000 outer loop vertex 8.933192e+000 1.206107e+001 2.000025e+000 vertex 8.523245e+000 1.273005e+001 2.500000e-005 vertex 8.523245e+000 1.273005e+001 2.000025e+000 endloop endfacet facet normal 9.135259e-001 4.067805e-001 0.000000e+000 outer loop vertex 8.523245e+000 1.273005e+001 2.000025e+000 vertex 8.523245e+000 1.273005e+001 2.500000e-005 vertex 8.222995e+000 1.345492e+001 2.500000e-005 endloop endfacet facet normal 9.335976e-001 3.583232e-001 0.000000e+000 outer loop vertex 8.523245e+000 1.273005e+001 2.000025e+000 vertex 8.222995e+000 1.345492e+001 2.500000e-005 vertex 8.222995e+000 1.345492e+001 2.000025e+000 endloop endfacet facet normal 9.659134e-001 2.588654e-001 0.000000e+000 outer loop vertex 8.222995e+000 1.345492e+001 2.000025e+000 vertex 8.222995e+000 1.345492e+001 2.500000e-005 vertex 8.039835e+000 1.421783e+001 2.500000e-005 endloop endfacet facet normal 9.781576e-001 2.078648e-001 0.000000e+000 outer loop vertex 8.222995e+000 1.345492e+001 2.000025e+000 vertex 8.039835e+000 1.421783e+001 2.500000e-005 vertex 8.039835e+000 1.421783e+001 2.000025e+000 endloop endfacet facet normal 9.945168e-001 1.045761e-001 0.000000e+000 outer loop vertex 8.039835e+000 1.421783e+001 2.000025e+000 vertex 8.039835e+000 1.421783e+001 2.500000e-005 vertex 7.978277e+000 1.500000e+001 2.500000e-005 endloop endfacet facet normal 9.986320e-001 5.228807e-002 0.000000e+000 outer loop vertex 8.039835e+000 1.421783e+001 2.000025e+000 vertex 7.978277e+000 1.500000e+001 2.500000e-005 vertex 7.978277e+000 1.500000e+001 2.000025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 7.978277e+000 1.800000e+001 2.000025e+000 vertex 7.978277e+000 1.500000e+001 2.000025e+000 vertex 7.978277e+000 1.800000e+001 2.500000e-005 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 7.978277e+000 1.800000e+001 2.500000e-005 vertex 7.978277e+000 1.500000e+001 2.000025e+000 vertex 7.978277e+000 1.500000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.978277e+000 2.000000e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 5.978277e+000 2.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.978277e+000 2.000000e+001 2.000025e+000 vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.000025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 0.000000e+000 2.000000e+001 2.000025e+000 vertex 0.000000e+000 5.000000e+000 2.500000e-005 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.000025e+000 vertex 0.000000e+000 2.000000e+001 2.500000e-005 endloop endfacet facet normal -5.228807e-002 -9.986320e-001 0.000000e+000 outer loop vertex 4.217828e+000 6.155830e-002 2.500000e-005 vertex 5.000000e+000 8.673617e-016 2.500000e-005 vertex 5.000000e+000 8.673617e-016 1.800025e+000 endloop endfacet facet normal -9.986320e-001 -5.228807e-002 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 0.000000e+000 5.000000e+000 2.500000e-005 vertex 6.155830e-002 4.217828e+000 2.500000e-005 endloop endfacet facet normal -9.945168e-001 -1.045761e-001 0.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.000025e+000 vertex 6.155830e-002 4.217828e+000 2.500000e-005 vertex 6.155830e-002 4.217828e+000 2.000025e+000 endloop endfacet facet normal -9.781576e-001 -2.078648e-001 0.000000e+000 outer loop vertex 6.155830e-002 4.217828e+000 2.000025e+000 vertex 6.155830e-002 4.217828e+000 2.500000e-005 vertex 2.447174e-001 3.454915e+000 2.500000e-005 endloop endfacet facet normal -9.659134e-001 -2.588654e-001 0.000000e+000 outer loop vertex 6.155830e-002 4.217828e+000 2.000025e+000 vertex 2.447174e-001 3.454915e+000 2.500000e-005 vertex 2.447174e-001 3.454915e+000 2.000025e+000 endloop endfacet facet normal -9.335976e-001 -3.583232e-001 0.000000e+000 outer loop vertex 2.447174e-001 3.454915e+000 2.000025e+000 vertex 2.447174e-001 3.454915e+000 2.500000e-005 vertex 5.449674e-001 2.730047e+000 2.500000e-005 endloop endfacet facet normal -9.135259e-001 -4.067805e-001 0.000000e+000 outer loop vertex 2.447174e-001 3.454915e+000 2.000025e+000 vertex 5.449674e-001 2.730047e+000 2.500000e-005 vertex 5.449674e-001 2.730047e+000 2.000025e+000 endloop endfacet facet normal -8.660493e-001 -4.999585e-001 0.000000e+000 outer loop vertex 5.449674e-001 2.730047e+000 2.000025e+000 vertex 5.449674e-001 2.730047e+000 2.500000e-005 vertex 9.549150e-001 2.061074e+000 2.500000e-005 endloop endfacet facet normal -8.386444e-001 -5.446792e-001 0.000000e+000 outer loop vertex 5.449674e-001 2.730047e+000 2.000025e+000 vertex 9.549150e-001 2.061074e+000 2.500000e-005 vertex 9.549150e-001 2.061074e+000 2.000025e+000 endloop endfacet facet normal -7.771761e-001 -6.292831e-001 0.000000e+000 outer loop vertex 9.549150e-001 2.061074e+000 2.000025e+000 vertex 9.549150e-001 2.061074e+000 2.500000e-005 vertex 1.464466e+000 1.464466e+000 2.500000e-005 endloop endfacet facet normal -7.431127e-001 -6.691663e-001 0.000000e+000 outer loop vertex 9.549150e-001 2.061074e+000 2.000025e+000 vertex 1.464466e+000 1.464466e+000 2.500000e-005 vertex 1.464466e+000 1.464466e+000 2.000025e+000 endloop endfacet facet normal -6.691663e-001 -7.431127e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 2.000025e+000 vertex 1.464466e+000 1.464466e+000 2.500000e-005 vertex 2.061074e+000 9.549150e-001 2.500000e-005 endloop endfacet facet normal -6.292831e-001 -7.771761e-001 0.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 2.000025e+000 vertex 2.061074e+000 9.549150e-001 2.500000e-005 vertex 2.061074e+000 9.549150e-001 2.000025e+000 endloop endfacet facet normal -5.446792e-001 -8.386444e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549150e-001 2.000025e+000 vertex 2.061074e+000 9.549150e-001 2.500000e-005 vertex 2.730047e+000 5.449674e-001 2.500000e-005 endloop endfacet facet normal -4.999585e-001 -8.660493e-001 0.000000e+000 outer loop vertex 2.061074e+000 9.549150e-001 2.000025e+000 vertex 2.730047e+000 5.449674e-001 2.500000e-005 vertex 2.730047e+000 5.449674e-001 2.000025e+000 endloop endfacet facet normal -4.067805e-001 -9.135259e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449674e-001 2.000025e+000 vertex 2.730047e+000 5.449674e-001 2.500000e-005 vertex 3.454915e+000 2.447174e-001 2.500000e-005 endloop endfacet facet normal -3.583232e-001 -9.335976e-001 0.000000e+000 outer loop vertex 2.730047e+000 5.449674e-001 2.000025e+000 vertex 3.454915e+000 2.447174e-001 2.500000e-005 vertex 3.454915e+000 2.447174e-001 2.000025e+000 endloop endfacet facet normal -2.588654e-001 -9.659134e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447174e-001 2.000025e+000 vertex 3.454915e+000 2.447174e-001 2.500000e-005 vertex 4.217828e+000 6.155830e-002 2.500000e-005 endloop endfacet facet normal -2.078648e-001 -9.781576e-001 0.000000e+000 outer loop vertex 3.454915e+000 2.447174e-001 2.000025e+000 vertex 4.217828e+000 6.155830e-002 2.500000e-005 vertex 4.217828e+000 6.155830e-002 2.000025e+000 endloop endfacet facet normal -1.045761e-001 -9.945168e-001 0.000000e+000 outer loop vertex 4.217828e+000 6.155830e-002 2.000025e+000 vertex 4.217828e+000 6.155830e-002 2.500000e-005 vertex 5.000000e+000 8.673617e-016 1.800025e+000 endloop endfacet facet normal -6.562383e-002 -9.978445e-001 0.000000e+000 outer loop vertex 4.217828e+000 6.155830e-002 2.000025e+000 vertex 5.000000e+000 8.673617e-016 1.800025e+000 vertex 4.800000e+000 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 5.000000e+000 8.673617e-016 1.800025e+000 vertex 5.000000e+000 8.673617e-016 2.500000e-005 vertex 2.000000e+001 8.673617e-016 1.800025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.000000e+001 8.673617e-016 1.800025e+000 vertex 5.000000e+000 8.673617e-016 2.500000e-005 vertex 2.000000e+001 8.673617e-016 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.210314e+000 1.741887e+001 2.500000e-005 vertex 3.906429e+000 1.744546e+001 2.500000e-005 vertex 5.978277e+000 2.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.352702e+000 1.175763e+001 2.500000e-005 vertex 5.031430e+000 1.198259e+001 2.500000e-005 vertex 2.781551e+000 1.435488e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.781551e+000 1.435488e+001 2.500000e-005 vertex 5.031430e+000 1.198259e+001 2.500000e-005 vertex 4.675974e+000 1.214834e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.781551e+000 1.435488e+001 2.500000e-005 vertex 4.675974e+000 1.214834e+001 2.500000e-005 vertex 2.565852e+000 1.457058e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.957872e+000 1.115903e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 2.182829e+000 1.148030e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.182829e+000 1.148030e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 2.460157e+000 1.175763e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.656430e+000 1.003403e+001 2.500000e-005 vertex 0.000000e+000 5.000000e+000 2.500000e-005 vertex 1.690612e+000 1.042474e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.690612e+000 1.042474e+001 2.500000e-005 vertex 0.000000e+000 5.000000e+000 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.690612e+000 1.042474e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 1.792121e+000 1.080358e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.792121e+000 1.080358e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 1.957872e+000 1.115903e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.565852e+000 1.682034e+001 2.500000e-005 vertex 2.390885e+000 1.657046e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 2.390885e+000 1.657046e+001 2.500000e-005 vertex 2.261967e+000 1.629399e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 2.261967e+000 1.629399e+001 2.500000e-005 vertex 2.183016e+000 1.599934e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.656430e+000 1.003403e+001 2.500000e-005 vertex 1.690612e+000 9.643323e+000 2.500000e-005 vertex 0.000000e+000 5.000000e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.500000e-005 vertex 1.690612e+000 9.643323e+000 2.500000e-005 vertex 1.792121e+000 9.264486e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.500000e-005 vertex 1.792121e+000 9.264486e+000 2.500000e-005 vertex 1.957872e+000 8.909031e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.297138e+000 7.818213e+000 2.500000e-005 vertex 5.000000e+000 8.673617e-016 2.500000e-005 vertex 3.906429e+000 7.784031e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.906429e+000 7.784031e+000 2.500000e-005 vertex 5.000000e+000 8.673617e-016 2.500000e-005 vertex 4.217828e+000 6.155830e-002 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.136884e+000 7.919722e+000 2.500000e-005 vertex 3.515721e+000 7.818213e+000 2.500000e-005 vertex 1.464466e+000 1.464466e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.217828e+000 6.155830e-002 2.500000e-005 vertex 3.454915e+000 2.447174e-001 2.500000e-005 vertex 3.906429e+000 7.784031e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.906429e+000 7.784031e+000 2.500000e-005 vertex 3.454915e+000 2.447174e-001 2.500000e-005 vertex 2.730047e+000 5.449674e-001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.906429e+000 7.784031e+000 2.500000e-005 vertex 2.730047e+000 5.449674e-001 2.500000e-005 vertex 3.515721e+000 7.818213e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.515721e+000 7.818213e+000 2.500000e-005 vertex 2.730047e+000 5.449674e-001 2.500000e-005 vertex 2.061074e+000 9.549150e-001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.515721e+000 7.818213e+000 2.500000e-005 vertex 2.061074e+000 9.549150e-001 2.500000e-005 vertex 1.464466e+000 1.464466e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.297138e+000 7.818213e+000 2.500000e-005 vertex 4.675974e+000 7.919722e+000 2.500000e-005 vertex 5.000000e+000 8.673617e-016 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 8.673617e-016 2.500000e-005 vertex 4.675974e+000 7.919722e+000 2.500000e-005 vertex 5.031430e+000 8.085474e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.000000e+000 8.673617e-016 2.500000e-005 vertex 5.031430e+000 8.085474e+000 2.500000e-005 vertex 2.000000e+001 8.673617e-016 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.000000e+001 8.673617e-016 2.500000e-005 vertex 5.031430e+000 8.085474e+000 2.500000e-005 vertex 5.352702e+000 8.310431e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.000000e+001 8.673617e-016 2.500000e-005 vertex 5.352702e+000 8.310431e+000 2.500000e-005 vertex 5.630029e+000 8.587759e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.781551e+000 1.435488e+001 2.500000e-005 vertex 3.031429e+000 1.417991e+001 2.500000e-005 vertex 5.352702e+000 1.175763e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.352702e+000 1.175763e+001 2.500000e-005 vertex 3.031429e+000 1.417991e+001 2.500000e-005 vertex 3.307894e+000 1.405100e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.352702e+000 1.175763e+001 2.500000e-005 vertex 3.307894e+000 1.405100e+001 2.500000e-005 vertex 5.630029e+000 1.148030e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.421974e+000 1.482046e+001 2.500000e-005 vertex 8.523245e+000 1.273005e+001 2.500000e-005 vertex 5.247007e+000 1.457058e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.247007e+000 1.457058e+001 2.500000e-005 vertex 8.523245e+000 1.273005e+001 2.500000e-005 vertex 8.933192e+000 1.206107e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.978277e+000 1.500000e+001 2.500000e-005 vertex 8.039835e+000 1.421783e+001 2.500000e-005 vertex 5.550891e+000 1.509692e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.307894e+000 1.733992e+001 2.500000e-005 vertex 3.031429e+000 1.721100e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 3.031429e+000 1.721100e+001 2.500000e-005 vertex 2.781551e+000 1.703604e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 2.781551e+000 1.703604e+001 2.500000e-005 vertex 2.565852e+000 1.682034e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.183016e+000 1.599934e+001 2.500000e-005 vertex 2.156430e+000 1.569546e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 2.156430e+000 1.569546e+001 2.500000e-005 vertex 2.183016e+000 1.539157e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 2.183016e+000 1.539157e+001 2.500000e-005 vertex 2.261967e+000 1.509692e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.957872e+000 8.909031e+000 2.500000e-005 vertex 2.182829e+000 8.587759e+000 2.500000e-005 vertex 0.000000e+000 5.000000e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.500000e-005 vertex 2.182829e+000 8.587759e+000 2.500000e-005 vertex 2.460157e+000 8.310431e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 5.000000e+000 2.500000e-005 vertex 2.460157e+000 8.310431e+000 2.500000e-005 vertex 6.155830e-002 4.217828e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.155830e-002 4.217828e+000 2.500000e-005 vertex 2.460157e+000 8.310431e+000 2.500000e-005 vertex 2.781430e+000 8.085474e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.464466e+000 1.464466e+000 2.500000e-005 vertex 9.549150e-001 2.061074e+000 2.500000e-005 vertex 3.136884e+000 7.919722e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.136884e+000 7.919722e+000 2.500000e-005 vertex 9.549150e-001 2.061074e+000 2.500000e-005 vertex 5.449674e-001 2.730047e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.136884e+000 7.919722e+000 2.500000e-005 vertex 5.449674e-001 2.730047e+000 2.500000e-005 vertex 2.781430e+000 8.085474e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.781430e+000 8.085474e+000 2.500000e-005 vertex 5.449674e-001 2.730047e+000 2.500000e-005 vertex 2.447174e-001 3.454915e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.781430e+000 8.085474e+000 2.500000e-005 vertex 2.447174e-001 3.454915e+000 2.500000e-005 vertex 6.155830e-002 4.217828e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.210314e+000 1.397204e+001 2.500000e-005 vertex 5.854987e+000 1.115903e+001 2.500000e-005 vertex 3.906429e+000 1.394546e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.906429e+000 1.394546e+001 2.500000e-005 vertex 5.854987e+000 1.115903e+001 2.500000e-005 vertex 5.630029e+000 1.148030e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.906429e+000 1.394546e+001 2.500000e-005 vertex 5.630029e+000 1.148030e+001 2.500000e-005 vertex 3.602545e+000 1.397204e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.602545e+000 1.397204e+001 2.500000e-005 vertex 5.630029e+000 1.148030e+001 2.500000e-005 vertex 3.307894e+000 1.405100e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.550891e+000 1.509692e+001 2.500000e-005 vertex 8.039835e+000 1.421783e+001 2.500000e-005 vertex 5.421974e+000 1.482046e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.421974e+000 1.482046e+001 2.500000e-005 vertex 8.039835e+000 1.421783e+001 2.500000e-005 vertex 8.222995e+000 1.345492e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.421974e+000 1.482046e+001 2.500000e-005 vertex 8.222995e+000 1.345492e+001 2.500000e-005 vertex 8.523245e+000 1.273005e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.629843e+000 1.599934e+001 2.500000e-005 vertex 7.978277e+000 1.800000e+001 2.500000e-005 vertex 5.656430e+000 1.569546e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.656430e+000 1.569546e+001 2.500000e-005 vertex 7.978277e+000 1.800000e+001 2.500000e-005 vertex 7.978277e+000 1.500000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.656430e+000 1.569546e+001 2.500000e-005 vertex 7.978277e+000 1.500000e+001 2.500000e-005 vertex 5.629843e+000 1.539157e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.629843e+000 1.539157e+001 2.500000e-005 vertex 7.978277e+000 1.500000e+001 2.500000e-005 vertex 5.550891e+000 1.509692e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.978277e+000 2.000000e+001 2.500000e-005 vertex 3.906429e+000 1.744546e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 3.906429e+000 1.744546e+001 2.500000e-005 vertex 3.602545e+000 1.741887e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 3.602545e+000 1.741887e+001 2.500000e-005 vertex 3.307894e+000 1.733992e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.675974e+000 1.214834e+001 2.500000e-005 vertex 4.297138e+000 1.224985e+001 2.500000e-005 vertex 2.565852e+000 1.457058e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.565852e+000 1.457058e+001 2.500000e-005 vertex 4.297138e+000 1.224985e+001 2.500000e-005 vertex 3.906429e+000 1.228403e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.565852e+000 1.457058e+001 2.500000e-005 vertex 3.906429e+000 1.228403e+001 2.500000e-005 vertex 2.390885e+000 1.482046e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.390885e+000 1.482046e+001 2.500000e-005 vertex 3.906429e+000 1.228403e+001 2.500000e-005 vertex 3.515721e+000 1.224985e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.390885e+000 1.482046e+001 2.500000e-005 vertex 3.515721e+000 1.224985e+001 2.500000e-005 vertex 2.261967e+000 1.509692e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.261967e+000 1.509692e+001 2.500000e-005 vertex 3.515721e+000 1.224985e+001 2.500000e-005 vertex 3.136884e+000 1.214834e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.261967e+000 1.509692e+001 2.500000e-005 vertex 3.136884e+000 1.214834e+001 2.500000e-005 vertex 0.000000e+000 2.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 3.136884e+000 1.214834e+001 2.500000e-005 vertex 2.781430e+000 1.198259e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 0.000000e+000 2.000000e+001 2.500000e-005 vertex 2.781430e+000 1.198259e+001 2.500000e-005 vertex 2.460157e+000 1.175763e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.143319e+001 1.024472e+001 2.500000e-005 vertex 1.219611e+001 1.006156e+001 2.500000e-005 vertex 6.122247e+000 9.643323e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.630029e+000 8.587759e+000 2.500000e-005 vertex 5.854987e+000 8.909031e+000 2.500000e-005 vertex 2.000000e+001 8.673617e-016 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.000000e+001 8.673617e-016 2.500000e-005 vertex 5.854987e+000 8.909031e+000 2.500000e-005 vertex 6.020738e+000 9.264486e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.000000e+001 8.673617e-016 2.500000e-005 vertex 6.020738e+000 9.264486e+000 2.500000e-005 vertex 2.000000e+001 1.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.000000e+001 1.000000e+001 2.500000e-005 vertex 6.020738e+000 9.264486e+000 2.500000e-005 vertex 6.122247e+000 9.643323e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 2.000000e+001 1.000000e+001 2.500000e-005 vertex 6.122247e+000 9.643323e+000 2.500000e-005 vertex 1.297828e+001 1.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.297828e+001 1.000000e+001 2.500000e-005 vertex 6.122247e+000 9.643323e+000 2.500000e-005 vertex 1.219611e+001 1.006156e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.156430e+000 1.003403e+001 2.500000e-005 vertex 6.122247e+000 1.042474e+001 2.500000e-005 vertex 1.003935e+001 1.095492e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 1.003935e+001 1.095492e+001 2.500000e-005 vertex 6.122247e+000 1.042474e+001 2.500000e-005 vertex 6.020738e+000 1.080358e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.156430e+000 1.003403e+001 2.500000e-005 vertex 1.003935e+001 1.095492e+001 2.500000e-005 vertex 6.122247e+000 9.643323e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.122247e+000 9.643323e+000 2.500000e-005 vertex 1.003935e+001 1.095492e+001 2.500000e-005 vertex 1.070832e+001 1.054497e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.122247e+000 9.643323e+000 2.500000e-005 vertex 1.070832e+001 1.054497e+001 2.500000e-005 vertex 1.143319e+001 1.024472e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 8.933192e+000 1.206107e+001 2.500000e-005 vertex 9.442743e+000 1.146447e+001 2.500000e-005 vertex 5.247007e+000 1.457058e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.247007e+000 1.457058e+001 2.500000e-005 vertex 9.442743e+000 1.146447e+001 2.500000e-005 vertex 1.003935e+001 1.095492e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.247007e+000 1.457058e+001 2.500000e-005 vertex 1.003935e+001 1.095492e+001 2.500000e-005 vertex 5.031308e+000 1.435488e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.031308e+000 1.435488e+001 2.500000e-005 vertex 1.003935e+001 1.095492e+001 2.500000e-005 vertex 6.020738e+000 1.080358e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.031308e+000 1.435488e+001 2.500000e-005 vertex 6.020738e+000 1.080358e+001 2.500000e-005 vertex 4.781430e+000 1.417991e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.781430e+000 1.417991e+001 2.500000e-005 vertex 6.020738e+000 1.080358e+001 2.500000e-005 vertex 5.854987e+000 1.115903e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.781430e+000 1.417991e+001 2.500000e-005 vertex 5.854987e+000 1.115903e+001 2.500000e-005 vertex 4.504965e+000 1.405100e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.504965e+000 1.405100e+001 2.500000e-005 vertex 5.854987e+000 1.115903e+001 2.500000e-005 vertex 4.210314e+000 1.397204e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.629843e+000 1.599934e+001 2.500000e-005 vertex 5.550891e+000 1.629399e+001 2.500000e-005 vertex 7.978277e+000 1.800000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.978277e+000 1.800000e+001 2.500000e-005 vertex 5.550891e+000 1.629399e+001 2.500000e-005 vertex 5.421974e+000 1.657046e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.978277e+000 1.800000e+001 2.500000e-005 vertex 5.421974e+000 1.657046e+001 2.500000e-005 vertex 7.947892e+000 1.834730e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.947892e+000 1.834730e+001 2.500000e-005 vertex 5.421974e+000 1.657046e+001 2.500000e-005 vertex 5.247007e+000 1.682034e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.947892e+000 1.834730e+001 2.500000e-005 vertex 5.247007e+000 1.682034e+001 2.500000e-005 vertex 7.857662e+000 1.868404e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.857662e+000 1.868404e+001 2.500000e-005 vertex 5.247007e+000 1.682034e+001 2.500000e-005 vertex 7.710328e+000 1.900000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.710328e+000 1.900000e+001 2.500000e-005 vertex 5.247007e+000 1.682034e+001 2.500000e-005 vertex 7.510366e+000 1.928557e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.510366e+000 1.928557e+001 2.500000e-005 vertex 5.247007e+000 1.682034e+001 2.500000e-005 vertex 5.031308e+000 1.703604e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 7.510366e+000 1.928557e+001 2.500000e-005 vertex 5.031308e+000 1.703604e+001 2.500000e-005 vertex 7.263852e+000 1.953209e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.978277e+000 1.973205e+001 2.500000e-005 vertex 7.263852e+000 1.953209e+001 2.500000e-005 vertex 6.662317e+000 1.987938e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.662317e+000 1.987938e+001 2.500000e-005 vertex 7.263852e+000 1.953209e+001 2.500000e-005 vertex 5.031308e+000 1.703604e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.662317e+000 1.987938e+001 2.500000e-005 vertex 5.031308e+000 1.703604e+001 2.500000e-005 vertex 6.325573e+000 1.996962e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.325573e+000 1.996962e+001 2.500000e-005 vertex 5.031308e+000 1.703604e+001 2.500000e-005 vertex 4.781430e+000 1.721100e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.325573e+000 1.996962e+001 2.500000e-005 vertex 4.781430e+000 1.721100e+001 2.500000e-005 vertex 5.978277e+000 2.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.978277e+000 2.000000e+001 2.500000e-005 vertex 4.781430e+000 1.721100e+001 2.500000e-005 vertex 4.504965e+000 1.733992e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.978277e+000 2.000000e+001 2.500000e-005 vertex 4.504965e+000 1.733992e+001 2.500000e-005 vertex 4.210314e+000 1.741887e+001 2.500000e-005 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.500000e+001 6.155830e-002 2.582197e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.500000e+001 6.155830e-002 2.582197e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.500000e+001 1.000000e+001 2.000025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 1.500000e+001 6.155830e-002 2.582197e+000 vertex 1.500000e+001 1.000000e+001 2.000025e+000 vertex 1.500000e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.861306e+001 4.069511e+000 3.200025e+000 vertex 1.832537e+001 4.043572e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 1.832537e+001 4.043572e+000 3.200025e+000 vertex 1.815991e+001 3.997679e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.146947e+001 6.555998e+000 3.200025e+000 vertex 4.108012e+001 5.853295e+000 3.200025e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.006042e+001 3.641685e+000 3.200025e+000 vertex 2.006407e+001 3.724917e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.905618e+001 3.170650e+000 3.200025e+000 vertex 3.895345e+001 3.008364e+000 3.200025e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 3.895345e+001 3.008364e+000 3.200025e+000 vertex 3.884526e+001 2.880932e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 3.884526e+001 2.880932e+000 3.200025e+000 vertex 3.870705e+001 2.764786e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.346356e+001 4.501944e+000 3.200025e+000 vertex 2.628028e+001 4.501944e+000 3.200025e+000 vertex 2.997032e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.108012e+001 5.853295e+000 3.200025e+000 vertex 4.001002e+001 5.853295e+000 3.200025e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 4.001002e+001 5.853295e+000 3.200025e+000 vertex 3.914515e+001 3.367653e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 3.914515e+001 3.367653e+000 3.200025e+000 vertex 3.905618e+001 3.170650e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.870705e+001 2.764786e+000 3.200025e+000 vertex 3.866585e+001 2.737305e+000 3.200025e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 3.866585e+001 2.737305e+000 3.200025e+000 vertex 3.850486e+001 2.653722e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 3.850486e+001 2.653722e+000 3.200025e+000 vertex 3.833492e+001 2.598041e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.109454e+001 6.065140e+000 3.200025e+000 vertex 2.101403e+001 6.051478e+000 3.200025e+000 vertex 2.095458e+001 6.032044e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.631576e+001 4.322890e+000 3.200025e+000 vertex 2.702711e+001 4.460593e+000 3.200025e+000 vertex 2.624228e+001 4.384831e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.624228e+001 4.384831e+000 3.200025e+000 vertex 2.702711e+001 4.460593e+000 3.200025e+000 vertex 2.628028e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.628028e+001 4.501944e+000 3.200025e+000 vertex 2.702711e+001 4.460593e+000 3.200025e+000 vertex 2.997032e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.997032e+001 6.555998e+000 3.200025e+000 vertex 2.702711e+001 4.460593e+000 3.200025e+000 vertex 2.775072e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.997032e+001 6.555998e+000 3.200025e+000 vertex 2.775072e+001 4.501944e+000 3.200025e+000 vertex 2.829887e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.631576e+001 4.322890e+000 3.200025e+000 vertex 2.624228e+001 4.384831e+000 3.200025e+000 vertex 2.624589e+001 4.302198e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.624589e+001 4.302198e+000 3.200025e+000 vertex 2.624228e+001 4.384831e+000 3.200025e+000 vertex 2.620843e+001 4.323749e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.624589e+001 4.302198e+000 3.200025e+000 vertex 2.620843e+001 4.323749e+000 3.200025e+000 vertex 2.617619e+001 4.280954e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 2.006407e+001 3.724917e+000 3.200025e+000 vertex 1.926255e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.067640e+001 4.501944e+000 3.200025e+000 vertex 3.173466e+001 4.501944e+000 3.200025e+000 vertex 3.182188e+001 4.771779e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.815991e+001 3.997679e+000 3.200025e+000 vertex 1.805140e+001 3.952957e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 1.805140e+001 3.952957e+000 3.200025e+000 vertex 1.796161e+001 3.901403e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 1.796161e+001 3.901403e+000 3.200025e+000 vertex 1.789301e+001 3.848914e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.197369e+001 3.240942e+000 3.200025e+000 vertex 3.185274e+001 3.414602e+000 3.200025e+000 vertex 3.001002e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.067640e+001 4.501944e+000 3.200025e+000 vertex 3.182188e+001 4.771779e+000 3.200025e+000 vertex 3.138670e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.182188e+001 4.771779e+000 3.200025e+000 vertex 3.198890e+001 5.105829e+000 3.200025e+000 vertex 3.138670e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 3.200025e+000 vertex 3.198890e+001 5.105829e+000 3.200025e+000 vertex 3.226681e+001 5.490809e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 3.200025e+000 vertex 3.226681e+001 5.490809e+000 3.200025e+000 vertex 3.257662e+001 5.796973e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.774192e+001 3.544773e+000 3.200025e+000 vertex 1.773974e+001 3.501944e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 1.773974e+001 3.501944e+000 3.200025e+000 vertex 1.774729e+001 3.415194e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 1.774729e+001 3.415194e+000 3.200025e+000 vertex 1.776498e+001 3.347373e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.817218e+001 2.972383e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 vertex 1.810614e+001 3.003853e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.810614e+001 3.003853e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.810614e+001 3.003853e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 1.799337e+001 3.069825e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.799337e+001 3.069825e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 1.776498e+001 3.347373e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.799337e+001 3.069825e+000 3.200025e+000 vertex 1.776498e+001 3.347373e+000 3.200025e+000 vertex 1.789379e+001 3.151021e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.789379e+001 3.151021e+000 3.200025e+000 vertex 1.776498e+001 3.347373e+000 3.200025e+000 vertex 1.779280e+001 3.283037e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.789379e+001 3.151021e+000 3.200025e+000 vertex 1.779280e+001 3.283037e+000 3.200025e+000 vertex 1.783493e+001 3.216788e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.888586e+001 2.826268e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 vertex 1.874229e+001 2.832124e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.874229e+001 2.832124e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 vertex 1.817218e+001 2.972383e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.874229e+001 2.832124e+000 3.200025e+000 vertex 1.817218e+001 2.972383e+000 3.200025e+000 vertex 1.846527e+001 2.873987e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.197369e+001 3.240942e+000 3.200025e+000 vertex 3.001002e+001 2.555998e+000 3.200025e+000 vertex 3.211307e+001 3.097985e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.582179e+001 2.898758e+000 3.200025e+000 vertex 3.579260e+001 2.833500e+000 3.200025e+000 vertex 3.605597e+001 2.775135e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.006407e+001 3.724917e+000 3.200025e+000 vertex 2.003253e+001 4.000062e+000 3.200025e+000 vertex 1.986816e+001 4.556346e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.775203e+001 3.615100e+000 3.200025e+000 vertex 1.774192e+001 3.544773e+000 3.200025e+000 vertex 1.777220e+001 3.679322e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.777220e+001 3.679322e+000 3.200025e+000 vertex 1.774192e+001 3.544773e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.777220e+001 3.679322e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 1.780268e+001 3.741352e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.780268e+001 3.741352e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 1.789301e+001 3.848914e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.780268e+001 3.741352e+000 3.200025e+000 vertex 1.789301e+001 3.848914e+000 3.200025e+000 vertex 1.784237e+001 3.797465e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.919246e+001 2.850029e+000 3.200025e+000 vertex 1.941135e+001 2.902604e+000 3.200025e+000 vertex 1.888586e+001 2.826268e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.888586e+001 2.826268e+000 3.200025e+000 vertex 1.941135e+001 2.902604e+000 3.200025e+000 vertex 1.959893e+001 2.981532e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.888586e+001 2.826268e+000 3.200025e+000 vertex 1.959893e+001 2.981532e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.000307e+001 3.395886e+000 3.200025e+000 vertex 2.004197e+001 3.519632e+000 3.200025e+000 vertex 1.995123e+001 3.294544e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.995123e+001 3.294544e+000 3.200025e+000 vertex 2.004197e+001 3.519632e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.771231e+001 4.090940e+000 3.200025e+000 vertex 3.757827e+001 4.031086e+000 3.200025e+000 vertex 3.584785e+001 2.988430e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.757827e+001 4.031086e+000 3.200025e+000 vertex 3.739110e+001 3.983120e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.685820e+001 3.981283e+000 3.200025e+000 vertex 3.663758e+001 4.035502e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.605597e+001 2.775135e+000 3.200025e+000 vertex 3.579260e+001 2.833500e+000 3.200025e+000 vertex 3.595596e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.257662e+001 5.796973e+000 3.200025e+000 vertex 3.295127e+001 6.067502e+000 3.200025e+000 vertex 3.138670e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 3.200025e+000 vertex 3.295127e+001 6.067502e+000 3.200025e+000 vertex 3.314093e+001 6.175086e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 3.200025e+000 vertex 3.314093e+001 6.175086e+000 3.200025e+000 vertex 3.365337e+001 6.393368e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.988647e+001 3.204496e+000 3.200025e+000 vertex 1.995123e+001 3.294544e+000 3.200025e+000 vertex 1.980193e+001 3.118547e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.980193e+001 3.118547e+000 3.200025e+000 vertex 1.995123e+001 3.294544e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.980193e+001 3.118547e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 vertex 1.968991e+001 3.034883e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.968991e+001 3.034883e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 vertex 1.959893e+001 2.981532e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.572285e+001 5.392146e+000 3.200025e+000 vertex 3.561232e+001 5.313697e+000 3.200025e+000 vertex 3.586516e+001 5.303418e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.778228e+001 5.183082e+000 3.200025e+000 vertex 3.787234e+001 5.106674e+000 3.200025e+000 vertex 3.898637e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 3.200025e+000 vertex 3.787234e+001 5.106674e+000 3.200025e+000 vertex 3.794726e+001 5.017816e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.267049e+001 6.277335e+000 3.200025e+000 vertex 2.273219e+001 6.193780e+000 3.200025e+000 vertex 2.309110e+001 6.015457e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.309110e+001 6.015457e+000 3.200025e+000 vertex 2.273219e+001 6.193780e+000 3.200025e+000 vertex 2.277458e+001 6.110955e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.137114e+001 5.608021e+000 3.200025e+000 vertex 2.133514e+001 5.697336e+000 3.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.739110e+001 3.983120e+000 3.200025e+000 vertex 3.715083e+001 3.961946e+000 3.200025e+000 vertex 3.584785e+001 2.988430e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.715083e+001 3.961946e+000 3.200025e+000 vertex 3.711981e+001 3.961403e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.711981e+001 3.961403e+000 3.200025e+000 vertex 3.685820e+001 3.981283e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.520174e+001 5.204647e+000 3.200025e+000 vertex 3.505911e+001 5.216029e+000 3.200025e+000 vertex 3.357499e+001 3.114775e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.305370e+001 3.508620e+000 3.200025e+000 vertex 3.315278e+001 3.384182e+000 3.200025e+000 vertex 3.467555e+001 5.397214e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.467555e+001 5.397214e+000 3.200025e+000 vertex 3.315278e+001 3.384182e+000 3.200025e+000 vertex 3.471583e+001 5.365334e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.334701e+001 5.425931e+000 3.200025e+000 vertex 3.448911e+001 5.652171e+000 3.200025e+000 vertex 3.445865e+001 5.748045e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.185274e+001 3.414602e+000 3.200025e+000 vertex 3.177435e+001 3.582894e+000 3.200025e+000 vertex 3.001002e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.001002e+001 2.555998e+000 3.200025e+000 vertex 3.177435e+001 3.582894e+000 3.200025e+000 vertex 3.171952e+001 3.769147e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.001002e+001 2.555998e+000 3.200025e+000 vertex 3.171952e+001 3.769147e+000 3.200025e+000 vertex 3.052775e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.052775e+001 4.069511e+000 3.200025e+000 vertex 3.171952e+001 3.769147e+000 3.200025e+000 vertex 3.169009e+001 3.974148e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.052775e+001 4.069511e+000 3.200025e+000 vertex 3.169009e+001 3.974148e+000 3.200025e+000 vertex 3.168638e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.579260e+001 2.833500e+000 3.200025e+000 vertex 3.575074e+001 2.770387e+000 3.200025e+000 vertex 3.595596e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.595596e+001 2.555998e+000 3.200025e+000 vertex 3.575074e+001 2.770387e+000 3.200025e+000 vertex 3.570092e+001 2.717005e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.595596e+001 2.555998e+000 3.200025e+000 vertex 3.570092e+001 2.717005e+000 3.200025e+000 vertex 3.564011e+001 2.669571e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 3.200025e+000 vertex 3.800050e+001 4.373044e+000 3.200025e+000 vertex 3.795374e+001 4.298023e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.277458e+001 6.110955e+000 3.200025e+000 vertex 2.280476e+001 6.019302e+000 3.200025e+000 vertex 2.309110e+001 6.015457e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.309110e+001 6.015457e+000 3.200025e+000 vertex 2.280476e+001 6.019302e+000 3.200025e+000 vertex 2.281837e+001 5.934666e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.309110e+001 6.015457e+000 3.200025e+000 vertex 2.281837e+001 5.934666e+000 3.200025e+000 vertex 2.282083e+001 5.876099e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.274731e+001 5.583439e+000 3.200025e+000 vertex 2.255224e+001 4.501944e+000 3.200025e+000 vertex 2.278642e+001 5.670285e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.278642e+001 5.670285e+000 3.200025e+000 vertex 2.255224e+001 4.501944e+000 3.200025e+000 vertex 2.309110e+001 6.015457e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.278642e+001 5.670285e+000 3.200025e+000 vertex 2.309110e+001 6.015457e+000 3.200025e+000 vertex 2.281060e+001 5.758884e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.281060e+001 5.758884e+000 3.200025e+000 vertex 2.309110e+001 6.015457e+000 3.200025e+000 vertex 2.282083e+001 5.876099e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.274731e+001 5.583439e+000 3.200025e+000 vertex 2.269183e+001 5.500207e+000 3.200025e+000 vertex 2.255224e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.255224e+001 4.501944e+000 3.200025e+000 vertex 2.269183e+001 5.500207e+000 3.200025e+000 vertex 2.260748e+001 5.410102e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.255224e+001 4.501944e+000 3.200025e+000 vertex 2.260748e+001 5.410102e+000 3.200025e+000 vertex 2.250027e+001 5.327528e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.602639e+001 4.474357e+000 3.200025e+000 vertex 3.594708e+001 4.611193e+000 3.200025e+000 vertex 3.357499e+001 3.114775e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.357499e+001 3.114775e+000 3.200025e+000 vertex 3.594708e+001 4.611193e+000 3.200025e+000 vertex 3.589002e+001 4.763933e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.595596e+001 5.882011e+000 3.200025e+000 vertex 3.594813e+001 5.776505e+000 3.200025e+000 vertex 3.599011e+001 5.675723e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.599011e+001 5.675723e+000 3.200025e+000 vertex 3.594813e+001 5.776505e+000 3.200025e+000 vertex 3.592517e+001 5.683188e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.599011e+001 5.675723e+000 3.200025e+000 vertex 3.592517e+001 5.683188e+000 3.200025e+000 vertex 3.590902e+001 5.486102e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.505911e+001 5.216029e+000 3.200025e+000 vertex 3.494287e+001 5.244747e+000 3.200025e+000 vertex 3.357499e+001 3.114775e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.357499e+001 3.114775e+000 3.200025e+000 vertex 3.494287e+001 5.244747e+000 3.200025e+000 vertex 3.482317e+001 5.295907e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.357499e+001 3.114775e+000 3.200025e+000 vertex 3.482317e+001 5.295907e+000 3.200025e+000 vertex 3.341020e+001 3.189356e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.341020e+001 3.189356e+000 3.200025e+000 vertex 3.482317e+001 5.295907e+000 3.200025e+000 vertex 3.471583e+001 5.365334e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.341020e+001 3.189356e+000 3.200025e+000 vertex 3.471583e+001 5.365334e+000 3.200025e+000 vertex 3.326696e+001 3.281403e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.326696e+001 3.281403e+000 3.200025e+000 vertex 3.471583e+001 5.365334e+000 3.200025e+000 vertex 3.315278e+001 3.384182e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.298082e+001 3.639853e+000 3.200025e+000 vertex 3.305370e+001 3.508620e+000 3.200025e+000 vertex 3.292393e+001 3.795351e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.292393e+001 3.795351e+000 3.200025e+000 vertex 3.305370e+001 3.508620e+000 3.200025e+000 vertex 3.467555e+001 5.397214e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.292393e+001 3.795351e+000 3.200025e+000 vertex 3.467555e+001 5.397214e+000 3.200025e+000 vertex 3.288729e+001 3.976790e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.288729e+001 3.976790e+000 3.200025e+000 vertex 3.467555e+001 5.397214e+000 3.200025e+000 vertex 3.459350e+001 5.479983e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.288729e+001 3.976790e+000 3.200025e+000 vertex 3.459350e+001 5.479983e+000 3.200025e+000 vertex 3.287488e+001 4.185221e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.287488e+001 4.185221e+000 3.200025e+000 vertex 3.459350e+001 5.479983e+000 3.200025e+000 vertex 3.453214e+001 5.566125e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.334701e+001 5.425931e+000 3.200025e+000 vertex 3.312604e+001 5.097305e+000 3.200025e+000 vertex 3.448911e+001 5.652171e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.448911e+001 5.652171e+000 3.200025e+000 vertex 3.312604e+001 5.097305e+000 3.200025e+000 vertex 3.299145e+001 4.809980e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.448911e+001 5.652171e+000 3.200025e+000 vertex 3.299145e+001 4.809980e+000 3.200025e+000 vertex 3.453214e+001 5.566125e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.453214e+001 5.566125e+000 3.200025e+000 vertex 3.299145e+001 4.809980e+000 3.200025e+000 vertex 3.290936e+001 4.526751e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.453214e+001 5.566125e+000 3.200025e+000 vertex 3.290936e+001 4.526751e+000 3.200025e+000 vertex 3.287488e+001 4.185221e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.001002e+001 2.555998e+000 3.200025e+000 vertex 3.329603e+001 2.613956e+000 3.200025e+000 vertex 3.280565e+001 2.728420e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.794726e+001 5.017816e+000 3.200025e+000 vertex 3.799866e+001 4.932467e+000 3.200025e+000 vertex 3.898637e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 3.200025e+000 vertex 3.799866e+001 4.932467e+000 3.200025e+000 vertex 3.803732e+001 4.835501e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 3.200025e+000 vertex 3.803732e+001 4.835501e+000 3.200025e+000 vertex 3.805677e+001 4.747995e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.582179e+001 2.898758e+000 3.200025e+000 vertex 3.605597e+001 2.775135e+000 3.200025e+000 vertex 3.584785e+001 2.988430e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.605597e+001 2.775135e+000 3.200025e+000 vertex 3.617809e+001 2.982518e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.617809e+001 2.982518e+000 3.200025e+000 vertex 3.624706e+001 3.062424e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.077898e+001 5.820881e+000 3.200025e+000 vertex 2.076910e+001 5.749654e+000 3.200025e+000 vertex 2.079353e+001 5.868840e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.079353e+001 5.868840e+000 3.200025e+000 vertex 2.076910e+001 5.749654e+000 3.200025e+000 vertex 2.200241e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.079353e+001 5.868840e+000 3.200025e+000 vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.081412e+001 5.911561e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.081412e+001 5.911561e+000 3.200025e+000 vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.081412e+001 5.911561e+000 3.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 vertex 2.083975e+001 5.948543e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.083975e+001 5.948543e+000 3.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 vertex 2.087238e+001 5.982143e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.133012e+001 6.057687e+000 3.200025e+000 vertex 2.125293e+001 6.064973e+000 3.200025e+000 vertex 2.131461e+001 5.972906e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 3.200025e+000 vertex 2.125293e+001 6.064973e+000 3.200025e+000 vertex 2.117556e+001 6.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.589002e+001 4.763933e+000 3.200025e+000 vertex 3.585817e+001 4.922856e+000 3.200025e+000 vertex 3.561232e+001 5.313697e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.561232e+001 5.313697e+000 3.200025e+000 vertex 3.585817e+001 4.922856e+000 3.200025e+000 vertex 3.584785e+001 5.087248e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.561232e+001 5.313697e+000 3.200025e+000 vertex 3.584785e+001 5.087248e+000 3.200025e+000 vertex 3.586516e+001 5.303418e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.446525e+001 6.069511e+000 3.200025e+000 vertex 3.425444e+001 6.048870e+000 3.200025e+000 vertex 3.444749e+001 5.985519e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.444749e+001 5.985519e+000 3.200025e+000 vertex 3.425444e+001 6.048870e+000 3.200025e+000 vertex 3.407401e+001 5.998157e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.444749e+001 5.985519e+000 3.200025e+000 vertex 3.407401e+001 5.998157e+000 3.200025e+000 vertex 3.444245e+001 5.899748e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.444245e+001 5.899748e+000 3.200025e+000 vertex 3.407401e+001 5.998157e+000 3.200025e+000 vertex 3.389362e+001 5.914418e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.444245e+001 5.899748e+000 3.200025e+000 vertex 3.389362e+001 5.914418e+000 3.200025e+000 vertex 3.444469e+001 5.840539e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.444469e+001 5.840539e+000 3.200025e+000 vertex 3.389362e+001 5.914418e+000 3.200025e+000 vertex 3.368468e+001 5.773034e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.444469e+001 5.840539e+000 3.200025e+000 vertex 3.368468e+001 5.773034e+000 3.200025e+000 vertex 3.445865e+001 5.748045e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.445865e+001 5.748045e+000 3.200025e+000 vertex 3.368468e+001 5.773034e+000 3.200025e+000 vertex 3.346085e+001 5.560289e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.445865e+001 5.748045e+000 3.200025e+000 vertex 3.346085e+001 5.560289e+000 3.200025e+000 vertex 3.334701e+001 5.425931e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.280565e+001 2.728420e+000 3.200025e+000 vertex 3.251593e+001 2.840626e+000 3.200025e+000 vertex 3.001002e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.001002e+001 2.555998e+000 3.200025e+000 vertex 3.251593e+001 2.840626e+000 3.200025e+000 vertex 3.229612e+001 2.960717e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.001002e+001 2.555998e+000 3.200025e+000 vertex 3.229612e+001 2.960717e+000 3.200025e+000 vertex 3.211307e+001 3.097985e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.564011e+001 2.669571e+000 3.200025e+000 vertex 3.556581e+001 2.628944e+000 3.200025e+000 vertex 3.595596e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.595596e+001 2.555998e+000 3.200025e+000 vertex 3.556581e+001 2.628944e+000 3.200025e+000 vertex 3.545889e+001 2.591131e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.595596e+001 2.555998e+000 3.200025e+000 vertex 3.545889e+001 2.591131e+000 3.200025e+000 vertex 3.530741e+001 2.563509e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.805677e+001 4.747995e+000 3.200025e+000 vertex 3.806407e+001 4.646369e+000 3.200025e+000 vertex 3.898637e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 3.200025e+000 vertex 3.806407e+001 4.646369e+000 3.200025e+000 vertex 3.805639e+001 4.545071e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 3.200025e+000 vertex 3.805639e+001 4.545071e+000 3.200025e+000 vertex 3.798890e+001 2.987586e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 3.200025e+000 vertex 3.805639e+001 4.545071e+000 3.200025e+000 vertex 3.803274e+001 4.450180e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 3.200025e+000 vertex 3.803274e+001 4.450180e+000 3.200025e+000 vertex 3.800050e+001 4.373044e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.624706e+001 3.062424e+000 3.200025e+000 vertex 3.631043e+001 3.116841e+000 3.200025e+000 vertex 3.584785e+001 2.988430e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.631043e+001 3.116841e+000 3.200025e+000 vertex 3.637543e+001 3.157461e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.637543e+001 3.157461e+000 3.200025e+000 vertex 3.771231e+001 4.090940e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.771231e+001 4.090940e+000 3.200025e+000 vertex 3.637543e+001 3.157461e+000 3.200025e+000 vertex 3.643799e+001 3.184169e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.771231e+001 4.090940e+000 3.200025e+000 vertex 3.643799e+001 3.184169e+000 3.200025e+000 vertex 3.783687e+001 4.175931e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.206238e+001 5.204647e+000 3.200025e+000 vertex 2.192347e+001 5.215448e+000 3.200025e+000 vertex 2.200241e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.192347e+001 5.215448e+000 3.200025e+000 vertex 2.180478e+001 5.243255e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.180478e+001 5.243255e+000 3.200025e+000 vertex 2.169907e+001 5.286629e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.169907e+001 5.286629e+000 3.200025e+000 vertex 2.159562e+001 5.349894e+000 3.200025e+000 vertex 2.200241e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.159562e+001 5.349894e+000 3.200025e+000 vertex 2.150039e+001 5.431047e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.150039e+001 5.431047e+000 3.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.091064e+001 6.009905e+000 3.200025e+000 vertex 2.150039e+001 5.431047e+000 3.200025e+000 vertex 2.141991e+001 5.525266e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.091064e+001 6.009905e+000 3.200025e+000 vertex 2.141991e+001 5.525266e+000 3.200025e+000 vertex 2.137114e+001 5.608021e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.663758e+001 4.035502e+000 3.200025e+000 vertex 3.645763e+001 4.109829e+000 3.200025e+000 vertex 3.584785e+001 2.988430e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.645763e+001 4.109829e+000 3.200025e+000 vertex 3.625664e+001 4.236741e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.625664e+001 4.236741e+000 3.200025e+000 vertex 3.441289e+001 2.988430e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.441289e+001 2.988430e+000 3.200025e+000 vertex 3.625664e+001 4.236741e+000 3.200025e+000 vertex 3.612392e+001 4.354509e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.441289e+001 2.988430e+000 3.200025e+000 vertex 3.612392e+001 4.354509e+000 3.200025e+000 vertex 3.424180e+001 2.992802e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.424180e+001 2.992802e+000 3.200025e+000 vertex 3.612392e+001 4.354509e+000 3.200025e+000 vertex 3.602639e+001 4.474357e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.424180e+001 2.992802e+000 3.200025e+000 vertex 3.602639e+001 4.474357e+000 3.200025e+000 vertex 3.384801e+001 3.038748e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.384801e+001 3.038748e+000 3.200025e+000 vertex 3.602639e+001 4.474357e+000 3.200025e+000 vertex 3.357499e+001 3.114775e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.592517e+001 5.683188e+000 3.200025e+000 vertex 3.588581e+001 5.590718e+000 3.200025e+000 vertex 3.590902e+001 5.486102e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.590902e+001 5.486102e+000 3.200025e+000 vertex 3.588581e+001 5.590718e+000 3.200025e+000 vertex 3.583331e+001 5.508509e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.590902e+001 5.486102e+000 3.200025e+000 vertex 3.583331e+001 5.508509e+000 3.200025e+000 vertex 3.586516e+001 5.303418e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.586516e+001 5.303418e+000 3.200025e+000 vertex 3.583331e+001 5.508509e+000 3.200025e+000 vertex 3.576385e+001 5.429909e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.586516e+001 5.303418e+000 3.200025e+000 vertex 3.576385e+001 5.429909e+000 3.200025e+000 vertex 3.572285e+001 5.392146e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.640246e+001 4.879472e+000 3.200025e+000 vertex 3.641783e+001 4.832980e+000 3.200025e+000 vertex 3.660741e+001 4.868336e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.660741e+001 4.868336e+000 3.200025e+000 vertex 3.641783e+001 4.832980e+000 3.200025e+000 vertex 3.643568e+001 4.798648e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.655056e+001 4.718160e+000 3.200025e+000 vertex 3.660741e+001 4.868336e+000 3.200025e+000 vertex 3.651631e+001 4.729245e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.651631e+001 4.729245e+000 3.200025e+000 vertex 3.660741e+001 4.868336e+000 3.200025e+000 vertex 3.643568e+001 4.798648e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.651631e+001 4.729245e+000 3.200025e+000 vertex 3.643568e+001 4.798648e+000 3.200025e+000 vertex 3.649402e+001 4.740480e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.649402e+001 4.740480e+000 3.200025e+000 vertex 3.643568e+001 4.798648e+000 3.200025e+000 vertex 3.645226e+001 4.775826e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.649402e+001 4.740480e+000 3.200025e+000 vertex 3.645226e+001 4.775826e+000 3.200025e+000 vertex 3.647124e+001 4.756949e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.666818e+001 4.973625e+000 3.200025e+000 vertex 3.638839e+001 5.012079e+000 3.200025e+000 vertex 3.660741e+001 4.868336e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.660741e+001 4.868336e+000 3.200025e+000 vertex 3.638839e+001 5.012079e+000 3.200025e+000 vertex 3.639240e+001 4.936398e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.660741e+001 4.868336e+000 3.200025e+000 vertex 3.639240e+001 4.936398e+000 3.200025e+000 vertex 3.640246e+001 4.879472e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.673830e+001 5.061723e+000 3.200025e+000 vertex 3.642010e+001 5.234116e+000 3.200025e+000 vertex 3.666818e+001 4.973625e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.666818e+001 4.973625e+000 3.200025e+000 vertex 3.642010e+001 5.234116e+000 3.200025e+000 vertex 3.639725e+001 5.133657e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.666818e+001 4.973625e+000 3.200025e+000 vertex 3.639725e+001 5.133657e+000 3.200025e+000 vertex 3.638839e+001 5.012079e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.556422e+001 6.477963e+000 3.200025e+000 vertex 3.567940e+001 6.403383e+000 3.200025e+000 vertex 3.656573e+001 6.266929e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.117556e+001 6.069511e+000 3.200025e+000 vertex 2.109454e+001 6.065140e+000 3.200025e+000 vertex 2.131461e+001 5.972906e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 3.200025e+000 vertex 2.109454e+001 6.065140e+000 3.200025e+000 vertex 2.095458e+001 6.032044e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 3.200025e+000 vertex 2.095458e+001 6.032044e+000 3.200025e+000 vertex 2.130731e+001 5.887079e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.130731e+001 5.887079e+000 3.200025e+000 vertex 2.095458e+001 6.032044e+000 3.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.130731e+001 5.887079e+000 3.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 vertex 2.131480e+001 5.783948e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.131480e+001 5.783948e+000 3.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 vertex 2.133514e+001 5.697336e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.699149e+001 5.242303e+000 3.200025e+000 vertex 3.670427e+001 5.628633e+000 3.200025e+000 vertex 3.686221e+001 5.169174e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.686221e+001 5.169174e+000 3.200025e+000 vertex 3.670427e+001 5.628633e+000 3.200025e+000 vertex 3.659898e+001 5.534632e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.686221e+001 5.169174e+000 3.200025e+000 vertex 3.659898e+001 5.534632e+000 3.200025e+000 vertex 3.682832e+001 5.142647e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.682832e+001 5.142647e+000 3.200025e+000 vertex 3.659898e+001 5.534632e+000 3.200025e+000 vertex 3.652083e+001 5.440029e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.682832e+001 5.142647e+000 3.200025e+000 vertex 3.652083e+001 5.440029e+000 3.200025e+000 vertex 3.673830e+001 5.061723e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.673830e+001 5.061723e+000 3.200025e+000 vertex 3.652083e+001 5.440029e+000 3.200025e+000 vertex 3.646354e+001 5.343081e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.673830e+001 5.061723e+000 3.200025e+000 vertex 3.646354e+001 5.343081e+000 3.200025e+000 vertex 3.642010e+001 5.234116e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.643799e+001 3.184169e+000 3.200025e+000 vertex 3.649423e+001 3.198350e+000 3.200025e+000 vertex 3.783687e+001 4.175931e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.783687e+001 4.175931e+000 3.200025e+000 vertex 3.649423e+001 3.198350e+000 3.200025e+000 vertex 3.656998e+001 3.204647e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.783687e+001 4.175931e+000 3.200025e+000 vertex 3.656998e+001 3.204647e+000 3.200025e+000 vertex 3.660639e+001 3.202881e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.483340e+001 3.134158e+000 3.200025e+000 vertex 2.486559e+001 3.258564e+000 3.200025e+000 vertex 2.373908e+001 3.985847e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.561232e+001 5.313697e+000 3.200025e+000 vertex 3.549575e+001 5.257381e+000 3.200025e+000 vertex 3.589002e+001 4.763933e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.589002e+001 4.763933e+000 3.200025e+000 vertex 3.549575e+001 5.257381e+000 3.200025e+000 vertex 3.538346e+001 5.223536e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.589002e+001 4.763933e+000 3.200025e+000 vertex 3.538346e+001 5.223536e+000 3.200025e+000 vertex 3.357499e+001 3.114775e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.357499e+001 3.114775e+000 3.200025e+000 vertex 3.538346e+001 5.223536e+000 3.200025e+000 vertex 3.526373e+001 5.206391e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.357499e+001 3.114775e+000 3.200025e+000 vertex 3.526373e+001 5.206391e+000 3.200025e+000 vertex 3.520174e+001 5.204647e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.515697e+001 2.555998e+000 3.200025e+000 vertex 3.410799e+001 2.555998e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.530741e+001 2.563509e+000 3.200025e+000 vertex 3.515697e+001 2.555998e+000 3.200025e+000 vertex 3.595596e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.595596e+001 2.555998e+000 3.200025e+000 vertex 3.515697e+001 2.555998e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.595596e+001 2.555998e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 3.796694e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.796694e+001 2.555998e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.796694e+001 2.555998e+000 3.200025e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 3.810260e+001 2.561219e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.810260e+001 2.561219e+000 3.200025e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 3.833492e+001 2.598041e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.733265e+001 5.312755e+000 3.200025e+000 vertex 3.747779e+001 5.302271e+000 3.200025e+000 vertex 3.735376e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.735376e+001 5.853295e+000 3.200025e+000 vertex 3.747779e+001 5.302271e+000 3.200025e+000 vertex 3.759322e+001 5.275767e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.735376e+001 5.853295e+000 3.200025e+000 vertex 3.759322e+001 5.275767e+000 3.200025e+000 vertex 3.898637e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 3.200025e+000 vertex 3.759322e+001 5.275767e+000 3.200025e+000 vertex 3.769533e+001 5.234879e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 3.200025e+000 vertex 3.769533e+001 5.234879e+000 3.200025e+000 vertex 3.778228e+001 5.183082e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.795374e+001 4.298023e+000 3.200025e+000 vertex 3.789184e+001 4.225810e+000 3.200025e+000 vertex 3.798890e+001 2.987586e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 3.200025e+000 vertex 3.789184e+001 4.225810e+000 3.200025e+000 vertex 3.783687e+001 4.175931e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 3.200025e+000 vertex 3.783687e+001 4.175931e+000 3.200025e+000 vertex 3.664262e+001 3.198734e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.664262e+001 3.198734e+000 3.200025e+000 vertex 3.783687e+001 4.175931e+000 3.200025e+000 vertex 3.660639e+001 3.202881e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.631914e+001 6.085559e+000 3.200025e+000 vertex 3.656573e+001 6.266929e+000 3.200025e+000 vertex 3.593454e+001 6.042812e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.593454e+001 6.042812e+000 3.200025e+000 vertex 3.656573e+001 6.266929e+000 3.200025e+000 vertex 3.589819e+001 6.139915e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.250027e+001 5.327528e+000 3.200025e+000 vertex 2.238523e+001 5.266520e+000 3.200025e+000 vertex 2.255224e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.255224e+001 4.501944e+000 3.200025e+000 vertex 2.238523e+001 5.266520e+000 3.200025e+000 vertex 2.227851e+001 5.231004e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.255224e+001 4.501944e+000 3.200025e+000 vertex 2.227851e+001 5.231004e+000 3.200025e+000 vertex 2.200241e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.227851e+001 5.231004e+000 3.200025e+000 vertex 2.213434e+001 5.207653e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.213434e+001 5.207653e+000 3.200025e+000 vertex 2.206238e+001 5.204647e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.491925e+001 2.650554e+000 3.200025e+000 vertex 2.487749e+001 2.724321e+000 3.200025e+000 vertex 2.373908e+001 3.985847e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.373908e+001 3.985847e+000 3.200025e+000 vertex 2.487749e+001 2.724321e+000 3.200025e+000 vertex 2.484638e+001 2.806348e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.373908e+001 3.985847e+000 3.200025e+000 vertex 2.486559e+001 3.258564e+000 3.200025e+000 vertex 2.366542e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.366542e+001 4.069511e+000 3.200025e+000 vertex 2.486559e+001 3.258564e+000 3.200025e+000 vertex 2.492107e+001 3.383970e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.366542e+001 4.069511e+000 3.200025e+000 vertex 2.492107e+001 3.383970e+000 3.200025e+000 vertex 2.502317e+001 3.545587e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.567940e+001 6.403383e+000 3.200025e+000 vertex 3.577528e+001 6.314840e+000 3.200025e+000 vertex 3.656573e+001 6.266929e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.656573e+001 6.266929e+000 3.200025e+000 vertex 3.577528e+001 6.314840e+000 3.200025e+000 vertex 3.585004e+001 6.222932e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.656573e+001 6.266929e+000 3.200025e+000 vertex 3.585004e+001 6.222932e+000 3.200025e+000 vertex 3.589819e+001 6.139915e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.491925e+001 2.650554e+000 3.200025e+000 vertex 2.373908e+001 3.985847e+000 3.200025e+000 vertex 2.498601e+001 2.568571e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.498601e+001 2.568571e+000 3.200025e+000 vertex 2.373908e+001 3.985847e+000 3.200025e+000 vertex 2.379199e+001 3.897038e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.498601e+001 2.568571e+000 3.200025e+000 vertex 2.379199e+001 3.897038e+000 3.200025e+000 vertex 2.384816e+001 3.755558e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.113661e+001 3.336027e+000 3.200025e+000 vertex 2.104632e+001 3.187544e+000 3.200025e+000 vertex 2.159785e+001 1.821201e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.159785e+001 1.821201e+000 3.200025e+000 vertex 2.104632e+001 3.187544e+000 3.200025e+000 vertex 2.092884e+001 3.046693e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.159785e+001 1.821201e+000 3.200025e+000 vertex 2.092884e+001 3.046693e+000 3.200025e+000 vertex 2.158293e+001 1.772760e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 3.200025e+000 vertex 2.561042e+001 4.071100e+000 3.200025e+000 vertex 2.558199e+001 4.025043e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.558199e+001 4.025043e+000 3.200025e+000 vertex 2.561042e+001 4.071100e+000 3.200025e+000 vertex 2.554971e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.558199e+001 4.025043e+000 3.200025e+000 vertex 2.554971e+001 4.069511e+000 3.200025e+000 vertex 2.530402e+001 3.833575e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.530402e+001 3.833575e+000 3.200025e+000 vertex 2.554971e+001 4.069511e+000 3.200025e+000 vertex 2.366542e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.530402e+001 3.833575e+000 3.200025e+000 vertex 2.366542e+001 4.069511e+000 3.200025e+000 vertex 2.507505e+001 3.610052e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.507505e+001 3.610052e+000 3.200025e+000 vertex 2.366542e+001 4.069511e+000 3.200025e+000 vertex 2.502317e+001 3.545587e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.006407e+001 3.724917e+000 3.200025e+000 vertex 1.986816e+001 4.556346e+000 3.200025e+000 vertex 1.926255e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.926255e+001 4.501944e+000 3.200025e+000 vertex 1.986816e+001 4.556346e+000 3.200025e+000 vertex 1.966306e+001 5.228972e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.926255e+001 4.501944e+000 3.200025e+000 vertex 1.966306e+001 5.228972e+000 3.200025e+000 vertex 1.818062e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.818062e+001 4.501944e+000 3.200025e+000 vertex 1.966306e+001 5.228972e+000 3.200025e+000 vertex 1.963164e+001 5.511234e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.818062e+001 4.501944e+000 3.200025e+000 vertex 1.963164e+001 5.511234e+000 3.200025e+000 vertex 1.764915e+001 4.469552e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.076910e+001 5.749654e+000 3.200025e+000 vertex 2.076677e+001 5.706336e+000 3.200025e+000 vertex 2.200241e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.076677e+001 5.706336e+000 3.200025e+000 vertex 2.079131e+001 5.542764e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.079131e+001 5.542764e+000 3.200025e+000 vertex 2.196850e+001 4.401275e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.196850e+001 4.401275e+000 3.200025e+000 vertex 2.079131e+001 5.542764e+000 3.200025e+000 vertex 2.098772e+001 4.933215e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.196850e+001 4.401275e+000 3.200025e+000 vertex 2.098772e+001 4.933215e+000 3.200025e+000 vertex 2.195596e+001 4.295863e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.195596e+001 4.295863e+000 3.200025e+000 vertex 2.098772e+001 4.933215e+000 3.200025e+000 vertex 2.119498e+001 4.285280e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.195596e+001 4.295863e+000 3.200025e+000 vertex 2.119498e+001 4.285280e+000 3.200025e+000 vertex 2.196043e+001 4.238191e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.196043e+001 4.238191e+000 3.200025e+000 vertex 2.119498e+001 4.285280e+000 3.200025e+000 vertex 2.120317e+001 4.250323e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.196043e+001 4.238191e+000 3.200025e+000 vertex 2.120317e+001 4.250323e+000 3.200025e+000 vertex 2.197223e+001 4.181031e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.197223e+001 4.181031e+000 3.200025e+000 vertex 2.120317e+001 4.250323e+000 3.200025e+000 vertex 2.125000e+001 3.953780e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.197223e+001 4.181031e+000 3.200025e+000 vertex 2.125000e+001 3.953780e+000 3.200025e+000 vertex 2.199379e+001 4.123733e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.199379e+001 4.123733e+000 3.200025e+000 vertex 2.125000e+001 3.953780e+000 3.200025e+000 vertex 2.125326e+001 3.859207e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.199379e+001 4.123733e+000 3.200025e+000 vertex 2.125326e+001 3.859207e+000 3.200025e+000 vertex 2.202447e+001 4.068987e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.733265e+001 5.312755e+000 3.200025e+000 vertex 3.735376e+001 5.853295e+000 3.200025e+000 vertex 3.721776e+001 5.305002e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.721776e+001 5.305002e+000 3.200025e+000 vertex 3.735376e+001 5.853295e+000 3.200025e+000 vertex 3.717976e+001 5.839212e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.721776e+001 5.305002e+000 3.200025e+000 vertex 3.717976e+001 5.839212e+000 3.200025e+000 vertex 3.710032e+001 5.282188e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.710032e+001 5.282188e+000 3.200025e+000 vertex 3.717976e+001 5.839212e+000 3.200025e+000 vertex 3.702763e+001 5.803219e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.710032e+001 5.282188e+000 3.200025e+000 vertex 3.702763e+001 5.803219e+000 3.200025e+000 vertex 3.699149e+001 5.242303e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.699149e+001 5.242303e+000 3.200025e+000 vertex 3.702763e+001 5.803219e+000 3.200025e+000 vertex 3.687299e+001 5.737394e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.699149e+001 5.242303e+000 3.200025e+000 vertex 3.687299e+001 5.737394e+000 3.200025e+000 vertex 3.670427e+001 5.628633e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.484638e+001 2.806348e+000 3.200025e+000 vertex 2.482629e+001 2.903027e+000 3.200025e+000 vertex 2.373908e+001 3.985847e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.373908e+001 3.985847e+000 3.200025e+000 vertex 2.482629e+001 2.903027e+000 3.200025e+000 vertex 2.482083e+001 2.996032e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.373908e+001 3.985847e+000 3.200025e+000 vertex 2.482083e+001 2.996032e+000 3.200025e+000 vertex 2.483340e+001 3.134158e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.750514e+001 2.949922e+000 3.200025e+000 vertex 2.702461e+001 2.626600e+000 3.200025e+000 vertex 2.899397e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.157758e+001 1.722383e+000 3.200025e+000 vertex 1.985567e+001 2.503588e+000 3.200025e+000 vertex 1.929369e+001 2.411791e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.232674e+001 3.853295e+000 3.200025e+000 vertex 2.223761e+001 3.885249e+000 3.200025e+000 vertex 2.159785e+001 1.821201e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.159785e+001 1.821201e+000 3.200025e+000 vertex 2.223761e+001 3.885249e+000 3.200025e+000 vertex 2.217411e+001 3.920629e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.159785e+001 1.821201e+000 3.200025e+000 vertex 2.217411e+001 3.920629e+000 3.200025e+000 vertex 2.113661e+001 3.336027e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.595596e+001 5.882011e+000 3.200025e+000 vertex 3.599011e+001 5.675723e+000 3.200025e+000 vertex 3.595133e+001 5.958773e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.595133e+001 5.958773e+000 3.200025e+000 vertex 3.599011e+001 5.675723e+000 3.200025e+000 vertex 3.609706e+001 5.845630e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.595133e+001 5.958773e+000 3.200025e+000 vertex 3.609706e+001 5.845630e+000 3.200025e+000 vertex 3.593454e+001 6.042812e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.593454e+001 6.042812e+000 3.200025e+000 vertex 3.609706e+001 5.845630e+000 3.200025e+000 vertex 3.623904e+001 6.009370e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.593454e+001 6.042812e+000 3.200025e+000 vertex 3.623904e+001 6.009370e+000 3.200025e+000 vertex 3.631914e+001 6.085559e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.181840e+001 1.427426e+000 3.200025e+000 vertex 2.177628e+001 1.439914e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 2.177628e+001 1.439914e+000 3.200025e+000 vertex 2.173006e+001 1.462375e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 2.173006e+001 1.462375e+000 3.200025e+000 vertex 2.168871e+001 1.492140e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.967211e+001 5.804854e+000 3.200025e+000 vertex 1.972443e+001 5.937308e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.092884e+001 3.046693e+000 3.200025e+000 vertex 2.074987e+001 2.891915e+000 3.200025e+000 vertex 2.158293e+001 1.772760e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.158293e+001 1.772760e+000 3.200025e+000 vertex 2.074987e+001 2.891915e+000 3.200025e+000 vertex 2.049224e+001 2.734193e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.158293e+001 1.772760e+000 3.200025e+000 vertex 2.049224e+001 2.734193e+000 3.200025e+000 vertex 2.157758e+001 1.722383e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.157758e+001 1.722383e+000 3.200025e+000 vertex 2.049224e+001 2.734193e+000 3.200025e+000 vertex 2.038586e+001 2.682687e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.157758e+001 1.722383e+000 3.200025e+000 vertex 2.038586e+001 2.682687e+000 3.200025e+000 vertex 1.985567e+001 2.503588e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.125326e+001 3.859207e+000 3.200025e+000 vertex 2.123813e+001 3.658577e+000 3.200025e+000 vertex 2.202447e+001 4.068987e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.202447e+001 4.068987e+000 3.200025e+000 vertex 2.123813e+001 3.658577e+000 3.200025e+000 vertex 2.119694e+001 3.484721e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.202447e+001 4.068987e+000 3.200025e+000 vertex 2.119694e+001 3.484721e+000 3.200025e+000 vertex 2.207336e+001 4.007856e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.207336e+001 4.007856e+000 3.200025e+000 vertex 2.119694e+001 3.484721e+000 3.200025e+000 vertex 2.113661e+001 3.336027e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.207336e+001 4.007856e+000 3.200025e+000 vertex 2.113661e+001 3.336027e+000 3.200025e+000 vertex 2.211550e+001 3.966825e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.211550e+001 3.966825e+000 3.200025e+000 vertex 2.113661e+001 3.336027e+000 3.200025e+000 vertex 2.217411e+001 3.920629e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.384816e+001 3.755558e+000 3.200025e+000 vertex 2.388682e+001 3.571214e+000 3.200025e+000 vertex 2.498601e+001 2.568571e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.498601e+001 2.568571e+000 3.200025e+000 vertex 2.388682e+001 3.571214e+000 3.200025e+000 vertex 2.390364e+001 3.294121e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.498601e+001 2.568571e+000 3.200025e+000 vertex 2.390364e+001 3.294121e+000 3.200025e+000 vertex 2.506216e+001 2.501009e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.506216e+001 2.501009e+000 3.200025e+000 vertex 2.390364e+001 3.294121e+000 3.200025e+000 vertex 2.390191e+001 3.211403e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.506216e+001 2.501009e+000 3.200025e+000 vertex 2.390191e+001 3.211403e+000 3.200025e+000 vertex 2.516204e+001 2.436065e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.516204e+001 2.436065e+000 3.200025e+000 vertex 2.390191e+001 3.211403e+000 3.200025e+000 vertex 2.386987e+001 2.957672e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.516204e+001 2.436065e+000 3.200025e+000 vertex 2.386987e+001 2.957672e+000 3.200025e+000 vertex 2.532370e+001 2.363159e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.532370e+001 2.363159e+000 3.200025e+000 vertex 2.386987e+001 2.957672e+000 3.200025e+000 vertex 2.380128e+001 2.735877e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.532370e+001 2.363159e+000 3.200025e+000 vertex 2.380128e+001 2.735877e+000 3.200025e+000 vertex 2.553387e+001 2.309567e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.553387e+001 2.309567e+000 3.200025e+000 vertex 2.380128e+001 2.735877e+000 3.200025e+000 vertex 2.369053e+001 2.513875e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.553387e+001 2.309567e+000 3.200025e+000 vertex 2.369053e+001 2.513875e+000 3.200025e+000 vertex 2.351545e+001 2.271196e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.168871e+001 1.492140e+000 3.200025e+000 vertex 2.164507e+001 1.535839e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 2.164507e+001 1.535839e+000 3.200025e+000 vertex 2.161900e+001 1.571960e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 2.161900e+001 1.571960e+000 3.200025e+000 vertex 2.159803e+001 1.614061e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.997032e+001 6.555998e+000 3.200025e+000 vertex 2.242289e+001 6.473251e+000 3.200025e+000 vertex 2.252559e+001 6.410197e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.949903e+001 4.069511e+000 3.200025e+000 vertex 2.860208e+001 4.069511e+000 3.200025e+000 vertex 2.899397e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.899397e+001 2.555998e+000 3.200025e+000 vertex 2.860208e+001 4.069511e+000 3.200025e+000 vertex 2.791843e+001 3.310633e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.899397e+001 2.555998e+000 3.200025e+000 vertex 2.791843e+001 3.310633e+000 3.200025e+000 vertex 2.750514e+001 2.949922e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.606751e+001 2.299473e+000 3.200025e+000 vertex 2.582674e+001 2.285728e+000 3.200025e+000 vertex 2.222927e+001 1.455257e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.222927e+001 1.455257e+000 3.200025e+000 vertex 2.582674e+001 2.285728e+000 3.200025e+000 vertex 2.553387e+001 2.309567e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.222927e+001 1.455257e+000 3.200025e+000 vertex 2.553387e+001 2.309567e+000 3.200025e+000 vertex 2.248483e+001 1.533015e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.248483e+001 1.533015e+000 3.200025e+000 vertex 2.553387e+001 2.309567e+000 3.200025e+000 vertex 2.276652e+001 1.666767e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 3.714959e+001 6.493544e+000 3.200025e+000 vertex 3.758270e+001 6.550544e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.346356e+001 4.501944e+000 3.200025e+000 vertex 2.997032e+001 6.555998e+000 3.200025e+000 vertex 2.411812e+001 6.015457e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.411812e+001 6.015457e+000 3.200025e+000 vertex 2.997032e+001 6.555998e+000 3.200025e+000 vertex 2.252559e+001 6.410197e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.411812e+001 6.015457e+000 3.200025e+000 vertex 2.252559e+001 6.410197e+000 3.200025e+000 vertex 2.309110e+001 6.015457e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.309110e+001 6.015457e+000 3.200025e+000 vertex 2.252559e+001 6.410197e+000 3.200025e+000 vertex 2.258687e+001 6.361741e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.309110e+001 6.015457e+000 3.200025e+000 vertex 2.258687e+001 6.361741e+000 3.200025e+000 vertex 2.267049e+001 6.277335e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 4.256568e+001 1.000000e+001 3.200025e+000 vertex 4.146947e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.146947e+001 6.555998e+000 3.200025e+000 vertex 4.256568e+001 1.000000e+001 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.146947e+001 6.555998e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 3.776762e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.776762e+001 6.555998e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 3.758270e+001 6.550544e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.746610e+001 2.614275e+000 3.200025e+000 vertex 1.721914e+001 2.718450e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 1.721914e+001 2.718450e+000 3.200025e+000 vertex 1.703224e+001 2.826606e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 1.703224e+001 2.826606e+000 3.200025e+000 vertex 1.687265e+001 2.954101e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.687265e+001 2.954101e+000 3.200025e+000 vertex 1.677189e+001 3.065296e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 1.677189e+001 3.065296e+000 3.200025e+000 vertex 1.670302e+001 3.170838e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 1.670302e+001 3.170838e+000 3.200025e+000 vertex 1.665080e+001 3.287392e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.222927e+001 1.455257e+000 3.200025e+000 vertex 2.200705e+001 1.423892e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 2.200705e+001 1.423892e+000 3.200025e+000 vertex 2.187403e+001 1.420863e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 2.187403e+001 1.420863e+000 3.200025e+000 vertex 2.181840e+001 1.427426e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.351545e+001 2.271196e+000 3.200025e+000 vertex 2.325911e+001 2.015348e+000 3.200025e+000 vertex 2.553387e+001 2.309567e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.553387e+001 2.309567e+000 3.200025e+000 vertex 2.325911e+001 2.015348e+000 3.200025e+000 vertex 2.314008e+001 1.917484e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.553387e+001 2.309567e+000 3.200025e+000 vertex 2.314008e+001 1.917484e+000 3.200025e+000 vertex 2.276652e+001 1.666767e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.665080e+001 3.287392e+000 3.200025e+000 vertex 1.661873e+001 3.408270e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 1.661873e+001 3.408270e+000 3.200025e+000 vertex 1.660461e+001 3.566978e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 1.660461e+001 3.566978e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.660461e+001 3.566978e+000 3.200025e+000 vertex 1.661395e+001 3.707921e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.661395e+001 3.707921e+000 3.200025e+000 vertex 1.664092e+001 3.828664e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.664092e+001 3.828664e+000 3.200025e+000 vertex 1.668431e+001 3.939104e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.668431e+001 3.939104e+000 3.200025e+000 vertex 1.674828e+001 4.046607e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.693494e+001 4.227113e+000 3.200025e+000 vertex 1.709907e+001 4.321096e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.972443e+001 5.937308e+000 3.200025e+000 vertex 1.978541e+001 6.039046e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.978541e+001 6.039046e+000 3.200025e+000 vertex 1.982245e+001 6.087405e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.982245e+001 6.087405e+000 3.200025e+000 vertex 1.992107e+001 6.188916e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.702461e+001 2.626600e+000 3.200025e+000 vertex 2.661934e+001 2.435870e+000 3.200025e+000 vertex 2.899397e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.899397e+001 2.555998e+000 3.200025e+000 vertex 2.661934e+001 2.435870e+000 3.200025e+000 vertex 2.638799e+001 2.361197e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.899397e+001 2.555998e+000 3.200025e+000 vertex 2.638799e+001 2.361197e+000 3.200025e+000 vertex 2.606751e+001 2.299473e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.674828e+001 4.046607e+000 3.200025e+000 vertex 1.676508e+001 4.068985e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.676508e+001 4.068985e+000 3.200025e+000 vertex 1.684071e+001 4.151348e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.684071e+001 4.151348e+000 3.200025e+000 vertex 1.693494e+001 4.227113e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.967211e+001 5.804854e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.964198e+001 5.668105e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.964198e+001 5.668105e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 1.709907e+001 4.321096e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.964198e+001 5.668105e+000 3.200025e+000 vertex 1.709907e+001 4.321096e+000 3.200025e+000 vertex 1.963164e+001 5.511234e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.963164e+001 5.511234e+000 3.200025e+000 vertex 1.709907e+001 4.321096e+000 3.200025e+000 vertex 1.731359e+001 4.400511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.963164e+001 5.511234e+000 3.200025e+000 vertex 1.731359e+001 4.400511e+000 3.200025e+000 vertex 1.764915e+001 4.469552e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.714959e+001 6.493544e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 3.684798e+001 6.403257e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.684798e+001 6.403257e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 3.537339e+001 6.544735e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.684798e+001 6.403257e+000 3.200025e+000 vertex 3.537339e+001 6.544735e+000 3.200025e+000 vertex 3.656573e+001 6.266929e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.656573e+001 6.266929e+000 3.200025e+000 vertex 3.537339e+001 6.544735e+000 3.200025e+000 vertex 3.547242e+001 6.518541e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.656573e+001 6.266929e+000 3.200025e+000 vertex 3.547242e+001 6.518541e+000 3.200025e+000 vertex 3.556422e+001 6.477963e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.606751e+001 2.299473e+000 3.200025e+000 vertex 2.222927e+001 1.455257e+000 3.200025e+000 vertex 2.899397e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.899397e+001 2.555998e+000 3.200025e+000 vertex 2.222927e+001 1.455257e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.899397e+001 2.555998e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 3.001002e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.001002e+001 2.555998e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 3.410799e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.001002e+001 2.555998e+000 3.200025e+000 vertex 3.410799e+001 2.555998e+000 3.200025e+000 vertex 3.329603e+001 2.613956e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.159803e+001 1.614061e+000 3.200025e+000 vertex 2.158555e+001 1.653413e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 2.158555e+001 1.653413e+000 3.200025e+000 vertex 2.157923e+001 1.697007e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 2.157923e+001 1.697007e+000 3.200025e+000 vertex 2.157758e+001 1.722383e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.992107e+001 6.188916e+000 3.200025e+000 vertex 2.003585e+001 6.274529e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 2.003585e+001 6.274529e+000 3.200025e+000 vertex 2.022012e+001 6.371653e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 2.022012e+001 6.371653e+000 3.200025e+000 vertex 2.034992e+001 6.421170e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.929369e+001 2.411791e+000 3.200025e+000 vertex 1.887150e+001 2.393836e+000 3.200025e+000 vertex 2.157758e+001 1.722383e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.157758e+001 1.722383e+000 3.200025e+000 vertex 1.887150e+001 2.393836e+000 3.200025e+000 vertex 1.815905e+001 2.443472e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.157758e+001 1.722383e+000 3.200025e+000 vertex 1.815905e+001 2.443472e+000 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 1.815905e+001 2.443472e+000 3.200025e+000 vertex 1.756545e+001 2.580856e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 1.756545e+001 2.580856e+000 3.200025e+000 vertex 1.746610e+001 2.614275e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.034992e+001 6.421170e+000 3.200025e+000 vertex 2.070188e+001 6.506922e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 2.070188e+001 6.506922e+000 3.200025e+000 vertex 2.128266e+001 6.554683e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 2.128266e+001 6.554683e+000 3.200025e+000 vertex 2.137995e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.137995e+001 6.555998e+000 3.200025e+000 vertex 2.207505e+001 6.555998e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 2.207505e+001 6.555998e+000 3.200025e+000 vertex 2.220584e+001 6.545606e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 2.220584e+001 6.545606e+000 3.200025e+000 vertex 2.231094e+001 6.520463e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 2.997032e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.997032e+001 6.555998e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 2.231094e+001 6.520463e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.997032e+001 6.555998e+000 3.200025e+000 vertex 2.231094e+001 6.520463e+000 3.200025e+000 vertex 2.242289e+001 6.473251e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.365337e+001 6.393368e+000 3.200025e+000 vertex 3.413707e+001 6.512548e+000 3.200025e+000 vertex 3.138670e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 3.200025e+000 vertex 3.413707e+001 6.512548e+000 3.200025e+000 vertex 3.467893e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 3.200025e+000 vertex 3.467893e+001 6.555998e+000 3.200025e+000 vertex 1.500000e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 3.467893e+001 6.555998e+000 3.200025e+000 vertex 3.524650e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.500000e+001 1.000000e+001 3.200025e+000 vertex 3.524650e+001 6.555998e+000 3.200025e+000 vertex 3.537339e+001 6.544735e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.970789e+001 3.467160e+000 2.000025e+000 vertex 6.008921e+001 4.387742e+000 2.000025e+000 vertex 6.032182e+001 5.356641e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.806172e+001 2.540000e+001 2.000025e+000 vertex 5.322232e+001 1.076001e+001 2.000025e+000 vertex 6.040000e+001 2.540000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.040000e+001 2.540000e+001 2.000025e+000 vertex 5.322232e+001 1.076001e+001 2.000025e+000 vertex 5.647232e+001 8.883622e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.040000e+001 2.540000e+001 2.000025e+000 vertex 5.647232e+001 8.883622e+000 2.000025e+000 vertex 6.040000e+001 6.350000e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.040000e+001 6.350000e+000 2.000025e+000 vertex 5.647232e+001 8.883622e+000 2.000025e+000 vertex 5.647232e+001 5.130845e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.040000e+001 6.350000e+000 2.000025e+000 vertex 5.647232e+001 5.130845e+000 2.000025e+000 vertex 6.032182e+001 5.356641e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.427540e+001 4.001601e-003 2.000025e+000 vertex 5.322232e+001 3.254457e+000 2.000025e+000 vertex 4.806172e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.806172e+001 4.001601e-003 2.000025e+000 vertex 5.322232e+001 3.254457e+000 2.000025e+000 vertex 4.997232e+001 5.130845e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.806172e+001 4.001601e-003 2.000025e+000 vertex 4.997232e+001 5.130845e+000 2.000025e+000 vertex 4.806172e+001 2.540000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.806172e+001 2.540000e+001 2.000025e+000 vertex 4.997232e+001 5.130845e+000 2.000025e+000 vertex 4.997232e+001 8.883622e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.806172e+001 2.540000e+001 2.000025e+000 vertex 4.997232e+001 8.883622e+000 2.000025e+000 vertex 5.322232e+001 1.076001e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.032182e+001 5.356641e+000 2.000025e+000 vertex 5.647232e+001 5.130845e+000 2.000025e+000 vertex 5.970789e+001 3.467160e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.970789e+001 3.467160e+000 2.000025e+000 vertex 5.647232e+001 5.130845e+000 2.000025e+000 vertex 5.854013e+001 1.859872e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.970789e+001 3.467160e+000 2.000025e+000 vertex 5.854013e+001 1.859872e+000 2.000025e+000 vertex 5.918726e+001 2.617563e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.778244e+001 1.212742e+000 2.000025e+000 vertex 5.854013e+001 1.859872e+000 2.000025e+000 vertex 5.693284e+001 6.921086e-001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.693284e+001 6.921086e-001 2.000025e+000 vertex 5.854013e+001 1.859872e+000 2.000025e+000 vertex 5.647232e+001 5.130845e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.693284e+001 6.921086e-001 2.000025e+000 vertex 5.647232e+001 5.130845e+000 2.000025e+000 vertex 5.601226e+001 3.107911e-001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.601226e+001 3.107911e-001 2.000025e+000 vertex 5.647232e+001 5.130845e+000 2.000025e+000 vertex 5.322232e+001 3.254457e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.601226e+001 3.107911e-001 2.000025e+000 vertex 5.322232e+001 3.254457e+000 2.000025e+000 vertex 5.504336e+001 7.817904e-002 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.504336e+001 7.817904e-002 2.000025e+000 vertex 5.322232e+001 3.254457e+000 2.000025e+000 vertex 5.427540e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal -9.745552e-001 -2.241477e-001 0.000000e+000 outer loop vertex 3.499908e+001 4.001601e-003 2.000025e+000 vertex 3.270000e+001 1.000000e+001 2.000025e+000 vertex 3.500000e+001 8.673617e-016 1.800025e+000 endloop endfacet facet normal -9.745552e-001 -2.241477e-001 0.000000e+000 outer loop vertex 3.500000e+001 8.673617e-016 1.800025e+000 vertex 3.270000e+001 1.000000e+001 2.000025e+000 vertex 3.270000e+001 1.000000e+001 2.500000e-005 endloop endfacet facet normal -9.745552e-001 -2.241477e-001 0.000000e+000 outer loop vertex 3.500000e+001 8.673617e-016 1.800025e+000 vertex 3.270000e+001 1.000000e+001 2.500000e-005 vertex 3.500000e+001 8.673617e-016 2.500000e-005 endloop endfacet facet normal 6.257646e-004 -9.999998e-001 0.000000e+000 outer loop vertex 5.405000e+001 0.000000e+000 1.800025e+000 vertex 5.405000e+001 0.000000e+000 2.500000e-005 vertex 5.406192e+001 1.118944e-005 1.810603e+000 endloop endfacet facet normal 5.291384e-002 -9.985991e-001 0.000000e+000 outer loop vertex 5.406192e+001 1.118944e-005 1.810603e+000 vertex 5.405000e+001 0.000000e+000 2.500000e-005 vertex 5.504336e+001 7.817904e-002 2.500000e-005 endloop endfacet facet normal 6.474631e-002 -9.979017e-001 0.000000e+000 outer loop vertex 5.406192e+001 1.118944e-005 1.810603e+000 vertex 5.504336e+001 7.817904e-002 2.500000e-005 vertex 5.427540e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 1.163125e-001 -9.932127e-001 0.000000e+000 outer loop vertex 5.427540e+001 4.001601e-003 2.000025e+000 vertex 5.504336e+001 7.817904e-002 2.500000e-005 vertex 5.504336e+001 7.817904e-002 2.000025e+000 endloop endfacet facet normal 2.078648e-001 -9.781576e-001 0.000000e+000 outer loop vertex 5.504336e+001 7.817904e-002 2.000025e+000 vertex 5.504336e+001 7.817904e-002 2.500000e-005 vertex 5.601226e+001 3.107911e-001 2.500000e-005 endloop endfacet facet normal 2.588654e-001 -9.659134e-001 0.000000e+000 outer loop vertex 5.504336e+001 7.817904e-002 2.000025e+000 vertex 5.601226e+001 3.107911e-001 2.500000e-005 vertex 5.601226e+001 3.107911e-001 2.000025e+000 endloop endfacet facet normal 3.583232e-001 -9.335976e-001 0.000000e+000 outer loop vertex 5.601226e+001 3.107911e-001 2.000025e+000 vertex 5.601226e+001 3.107911e-001 2.500000e-005 vertex 5.693284e+001 6.921086e-001 2.500000e-005 endloop endfacet facet normal 4.067805e-001 -9.135259e-001 0.000000e+000 outer loop vertex 5.601226e+001 3.107911e-001 2.000025e+000 vertex 5.693284e+001 6.921086e-001 2.500000e-005 vertex 5.693284e+001 6.921086e-001 2.000025e+000 endloop endfacet facet normal 4.999585e-001 -8.660493e-001 0.000000e+000 outer loop vertex 5.693284e+001 6.921086e-001 2.000025e+000 vertex 5.693284e+001 6.921086e-001 2.500000e-005 vertex 5.778244e+001 1.212742e+000 2.500000e-005 endloop endfacet facet normal 5.446792e-001 -8.386444e-001 0.000000e+000 outer loop vertex 5.693284e+001 6.921086e-001 2.000025e+000 vertex 5.778244e+001 1.212742e+000 2.500000e-005 vertex 5.778244e+001 1.212742e+000 2.000025e+000 endloop endfacet facet normal 6.292831e-001 -7.771761e-001 0.000000e+000 outer loop vertex 5.778244e+001 1.212742e+000 2.000025e+000 vertex 5.778244e+001 1.212742e+000 2.500000e-005 vertex 5.854013e+001 1.859872e+000 2.500000e-005 endloop endfacet facet normal 6.691663e-001 -7.431127e-001 0.000000e+000 outer loop vertex 5.778244e+001 1.212742e+000 2.000025e+000 vertex 5.854013e+001 1.859872e+000 2.500000e-005 vertex 5.854013e+001 1.859872e+000 2.000025e+000 endloop endfacet facet normal 7.431127e-001 -6.691663e-001 0.000000e+000 outer loop vertex 5.854013e+001 1.859872e+000 2.000025e+000 vertex 5.854013e+001 1.859872e+000 2.500000e-005 vertex 5.918726e+001 2.617563e+000 2.500000e-005 endloop endfacet facet normal 7.771761e-001 -6.292831e-001 0.000000e+000 outer loop vertex 5.854013e+001 1.859872e+000 2.000025e+000 vertex 5.918726e+001 2.617563e+000 2.500000e-005 vertex 5.918726e+001 2.617563e+000 2.000025e+000 endloop endfacet facet normal 8.386444e-001 -5.446792e-001 0.000000e+000 outer loop vertex 5.918726e+001 2.617563e+000 2.000025e+000 vertex 5.918726e+001 2.617563e+000 2.500000e-005 vertex 5.970789e+001 3.467160e+000 2.500000e-005 endloop endfacet facet normal 8.660493e-001 -4.999585e-001 0.000000e+000 outer loop vertex 5.918726e+001 2.617563e+000 2.000025e+000 vertex 5.970789e+001 3.467160e+000 2.500000e-005 vertex 5.970789e+001 3.467160e+000 2.000025e+000 endloop endfacet facet normal 9.135259e-001 -4.067805e-001 0.000000e+000 outer loop vertex 5.970789e+001 3.467160e+000 2.000025e+000 vertex 5.970789e+001 3.467160e+000 2.500000e-005 vertex 6.008921e+001 4.387742e+000 2.500000e-005 endloop endfacet facet normal 9.335976e-001 -3.583232e-001 0.000000e+000 outer loop vertex 5.970789e+001 3.467160e+000 2.000025e+000 vertex 6.008921e+001 4.387742e+000 2.500000e-005 vertex 6.008921e+001 4.387742e+000 2.000025e+000 endloop endfacet facet normal 9.659134e-001 -2.588654e-001 0.000000e+000 outer loop vertex 6.008921e+001 4.387742e+000 2.000025e+000 vertex 6.008921e+001 4.387742e+000 2.500000e-005 vertex 6.032182e+001 5.356641e+000 2.500000e-005 endloop endfacet facet normal 9.781576e-001 -2.078648e-001 0.000000e+000 outer loop vertex 6.008921e+001 4.387742e+000 2.000025e+000 vertex 6.032182e+001 5.356641e+000 2.500000e-005 vertex 6.032182e+001 5.356641e+000 2.000025e+000 endloop endfacet facet normal 9.945168e-001 -1.045761e-001 0.000000e+000 outer loop vertex 6.032182e+001 5.356641e+000 2.000025e+000 vertex 6.032182e+001 5.356641e+000 2.500000e-005 vertex 6.040000e+001 6.350000e+000 2.500000e-005 endloop endfacet facet normal 9.986320e-001 -5.228807e-002 0.000000e+000 outer loop vertex 6.032182e+001 5.356641e+000 2.000025e+000 vertex 6.040000e+001 6.350000e+000 2.500000e-005 vertex 6.040000e+001 6.350000e+000 2.000025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 6.040000e+001 2.540000e+001 2.000025e+000 vertex 6.040000e+001 6.350000e+000 2.000025e+000 vertex 6.040000e+001 2.540000e+001 2.500000e-005 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 6.040000e+001 2.540000e+001 2.500000e-005 vertex 6.040000e+001 6.350000e+000 2.000025e+000 vertex 6.040000e+001 6.350000e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 6.040000e+001 2.540000e+001 2.000025e+000 vertex 6.040000e+001 2.540000e+001 2.500000e-005 vertex 4.806172e+001 2.540000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.806172e+001 2.540000e+001 2.000025e+000 vertex 6.040000e+001 2.540000e+001 2.500000e-005 vertex 4.770000e+001 2.540000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.806172e+001 2.540000e+001 2.000025e+000 vertex 4.770000e+001 2.540000e+001 2.500000e-005 vertex 4.770000e+001 2.540000e+001 2.000025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.770000e+001 2.540000e+001 2.000025e+000 vertex 4.770000e+001 2.540000e+001 2.500000e-005 vertex 4.770000e+001 1.940100e+001 2.000025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.770000e+001 1.940100e+001 2.000025e+000 vertex 4.770000e+001 2.540000e+001 2.500000e-005 vertex 4.770000e+001 1.905000e+001 2.500000e-005 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.770000e+001 1.940100e+001 2.000025e+000 vertex 4.770000e+001 1.905000e+001 2.500000e-005 vertex 4.770000e+001 1.905000e+001 2.000025e+000 endloop endfacet facet normal -1.000000e+000 7.190510e-005 0.000000e+000 outer loop vertex 4.770000e+001 1.905000e+001 2.000025e+000 vertex 4.770000e+001 1.905000e+001 2.500000e-005 vertex 4.770000e+001 1.904863e+001 2.500000e-005 endloop endfacet facet normal -2.364065e-001 9.716542e-001 0.000000e+000 outer loop vertex 4.245252e+001 1.279644e+001 2.000025e+000 vertex 4.256568e+001 1.281745e+001 2.000025e+000 vertex 4.352154e+001 1.308285e+001 2.500000e-005 endloop endfacet facet normal -2.305208e-001 9.730674e-001 0.000000e+000 outer loop vertex 4.352154e+001 1.308285e+001 2.500000e-005 vertex 4.245252e+001 1.279644e+001 2.500000e-005 vertex 4.245252e+001 1.279644e+001 2.000025e+000 endloop endfacet facet normal -1.161424e-001 9.932325e-001 0.000000e+000 outer loop vertex 4.245252e+001 1.279644e+001 2.000025e+000 vertex 4.245252e+001 1.279644e+001 2.500000e-005 vertex 4.135000e+001 1.270000e+001 2.500000e-005 endloop endfacet facet normal -5.807119e-002 9.983124e-001 0.000000e+000 outer loop vertex 4.245252e+001 1.279644e+001 2.000025e+000 vertex 4.135000e+001 1.270000e+001 2.500000e-005 vertex 4.135000e+001 1.270000e+001 2.000025e+000 endloop endfacet facet normal -9.993203e-001 -3.686292e-002 0.000000e+000 outer loop vertex 4.769029e+001 1.940100e+001 2.000025e+000 vertex 4.770000e+001 1.905000e+001 2.000025e+000 vertex 4.769029e+001 1.940100e+001 2.009101e+000 endloop endfacet facet normal -9.998314e-001 -1.835955e-002 0.000000e+000 outer loop vertex 4.769029e+001 1.940100e+001 2.009101e+000 vertex 4.770000e+001 1.905000e+001 2.000025e+000 vertex 4.770000e+001 1.904863e+001 6.800025e+000 endloop endfacet facet normal -9.982615e-001 -5.893992e-002 0.000000e+000 outer loop vertex 4.769029e+001 1.940100e+001 2.009101e+000 vertex 4.770000e+001 1.904863e+001 6.800025e+000 vertex 4.765293e+001 1.982178e+001 2.044035e+000 endloop endfacet facet normal -9.951362e-001 -9.850848e-002 0.000000e+000 outer loop vertex 4.765293e+001 1.982178e+001 2.044035e+000 vertex 4.770000e+001 1.904863e+001 6.800025e+000 vertex 4.760379e+001 2.015117e+001 6.800025e+000 endloop endfacet facet normal -9.666964e-001 -2.559261e-001 0.000000e+000 outer loop vertex 4.731762e+001 2.122025e+001 6.800025e+000 vertex 4.749731e+001 2.064157e+001 2.189517e+000 vertex 4.760379e+001 2.015117e+001 6.800025e+000 endloop endfacet facet normal -9.799417e-001 -1.992844e-001 0.000000e+000 outer loop vertex 4.760379e+001 2.015117e+001 6.800025e+000 vertex 4.749731e+001 2.064157e+001 2.189517e+000 vertex 4.759086e+001 2.014871e+001 2.102054e+000 endloop endfacet facet normal -9.877318e-001 -1.561601e-001 0.000000e+000 outer loop vertex 4.760379e+001 2.015117e+001 6.800025e+000 vertex 4.759086e+001 2.014871e+001 2.102054e+000 vertex 4.765293e+001 1.982178e+001 2.044035e+000 endloop endfacet facet normal -9.125251e-001 -4.090207e-001 0.000000e+000 outer loop vertex 4.685017e+001 2.222342e+001 6.800025e+000 vertex 4.721800e+001 2.147674e+001 2.450639e+000 vertex 4.731762e+001 2.122025e+001 6.800025e+000 endloop endfacet facet normal -9.347422e-001 -3.553268e-001 0.000000e+000 outer loop vertex 4.731762e+001 2.122025e+001 6.800025e+000 vertex 4.721800e+001 2.147674e+001 2.450639e+000 vertex 4.730518e+001 2.121608e+001 2.369142e+000 endloop endfacet facet normal -9.501716e-001 -3.117274e-001 0.000000e+000 outer loop vertex 4.731762e+001 2.122025e+001 6.800025e+000 vertex 4.730518e+001 2.121608e+001 2.369142e+000 vertex 4.749731e+001 2.064157e+001 2.189517e+000 endloop endfacet facet normal -8.321943e-001 -5.544841e-001 0.000000e+000 outer loop vertex 4.621565e+001 2.313019e+001 6.800025e+000 vertex 4.678906e+001 2.232706e+001 2.851649e+000 vertex 4.685017e+001 2.222342e+001 6.800025e+000 endloop endfacet facet normal -8.629844e-001 -5.052307e-001 0.000000e+000 outer loop vertex 4.685017e+001 2.222342e+001 6.800025e+000 vertex 4.678906e+001 2.232706e+001 2.851649e+000 vertex 4.684314e+001 2.221985e+001 2.801087e+000 endloop endfacet facet normal -8.871627e-001 -4.614567e-001 0.000000e+000 outer loop vertex 4.685017e+001 2.222342e+001 6.800025e+000 vertex 4.684314e+001 2.221985e+001 2.801087e+000 vertex 4.721800e+001 2.147674e+001 2.450639e+000 endloop endfacet facet normal -6.422518e-001 -7.664938e-001 0.000000e+000 outer loop vertex 4.541831e+001 2.392559e+001 4.133146e+000 vertex 4.543221e+001 2.391186e+001 4.120145e+000 vertex 4.543333e+001 2.391301e+001 6.800025e+000 endloop endfacet facet normal -6.840044e-001 -7.294778e-001 0.000000e+000 outer loop vertex 4.543333e+001 2.391301e+001 6.800025e+000 vertex 4.543221e+001 2.391186e+001 4.120145e+000 vertex 4.617456e+001 2.317870e+001 3.426139e+000 endloop endfacet facet normal -7.253404e-001 -6.883904e-001 0.000000e+000 outer loop vertex 4.543333e+001 2.391301e+001 6.800025e+000 vertex 4.617456e+001 2.317870e+001 3.426139e+000 vertex 4.621565e+001 2.313019e+001 6.800025e+000 endloop endfacet facet normal -7.640846e-001 -6.451161e-001 0.000000e+000 outer loop vertex 4.621565e+001 2.313019e+001 6.800025e+000 vertex 4.617456e+001 2.317870e+001 3.426139e+000 vertex 4.621166e+001 2.312727e+001 3.391448e+000 endloop endfacet facet normal -7.984797e-001 -6.020216e-001 0.000000e+000 outer loop vertex 4.621565e+001 2.313019e+001 6.800025e+000 vertex 4.621166e+001 2.312727e+001 3.391448e+000 vertex 4.678906e+001 2.232706e+001 2.851649e+000 endloop endfacet facet normal -2.928851e-001 -9.561477e-001 0.000000e+000 outer loop vertex 4.256568e+001 2.528255e+001 6.800025e+000 vertex 4.352260e+001 2.501108e+001 5.905413e+000 vertex 4.352412e+001 2.501621e+001 6.800025e+000 endloop endfacet facet normal -3.457668e-001 -9.383205e-001 0.000000e+000 outer loop vertex 4.352412e+001 2.501621e+001 6.800025e+000 vertex 4.352260e+001 2.501108e+001 5.905413e+000 vertex 4.358823e+001 2.499246e+001 5.844057e+000 endloop endfacet facet normal -3.996626e-001 -9.166623e-001 0.000000e+000 outer loop vertex 4.352412e+001 2.501621e+001 6.800025e+000 vertex 4.358823e+001 2.499246e+001 5.844057e+000 vertex 4.452697e+001 2.454812e+001 6.800025e+000 endloop endfacet facet normal -4.523862e-001 -8.918222e-001 0.000000e+000 outer loop vertex 4.452697e+001 2.454812e+001 6.800025e+000 vertex 4.358823e+001 2.499246e+001 5.844057e+000 vertex 4.452610e+001 2.454633e+001 4.967255e+000 endloop endfacet facet normal -5.497537e-001 -8.353268e-001 0.000000e+000 outer loop vertex 4.452697e+001 2.454812e+001 6.800025e+000 vertex 4.452610e+001 2.454633e+001 4.967255e+000 vertex 4.543333e+001 2.391301e+001 6.800025e+000 endloop endfacet facet normal -5.508245e-001 -8.346211e-001 0.000000e+000 outer loop vertex 4.543333e+001 2.391301e+001 6.800025e+000 vertex 4.452610e+001 2.454633e+001 4.967255e+000 vertex 4.454807e+001 2.453588e+001 4.946717e+000 endloop endfacet facet normal -5.976837e-001 -8.017321e-001 0.000000e+000 outer loop vertex 4.543333e+001 2.391301e+001 6.800025e+000 vertex 4.454807e+001 2.453588e+001 4.946717e+000 vertex 4.541831e+001 2.392559e+001 4.133146e+000 endloop endfacet facet normal -1.000000e+000 1.438102e-004 0.000000e+000 outer loop vertex 4.770000e+001 1.905000e+001 2.000025e+000 vertex 4.770000e+001 1.904863e+001 2.500000e-005 vertex 4.770000e+001 1.904863e+001 6.800025e+000 endloop endfacet facet normal -9.982999e-001 5.828654e-002 0.000000e+000 outer loop vertex 4.770000e+001 1.904863e+001 6.800025e+000 vertex 4.770000e+001 1.904863e+001 2.500000e-005 vertex 4.760332e+001 1.794613e+001 2.500000e-005 endloop endfacet facet normal -9.932075e-001 1.163566e-001 0.000000e+000 outer loop vertex 4.770000e+001 1.904863e+001 6.800025e+000 vertex 4.760332e+001 1.794613e+001 2.500000e-005 vertex 4.760332e+001 1.794613e+001 6.800025e+000 endloop endfacet facet normal -9.730177e-001 2.307307e-001 0.000000e+000 outer loop vertex 4.760332e+001 1.794613e+001 6.800025e+000 vertex 4.760332e+001 1.794613e+001 2.500000e-005 vertex 4.731668e+001 1.687717e+001 2.500000e-005 endloop endfacet facet normal -9.579202e-001 2.870346e-001 0.000000e+000 outer loop vertex 4.760332e+001 1.794613e+001 6.800025e+000 vertex 4.731668e+001 1.687717e+001 2.500000e-005 vertex 4.731668e+001 1.687717e+001 6.800025e+000 endloop endfacet facet normal -9.181789e-001 3.961661e-001 0.000000e+000 outer loop vertex 4.731668e+001 1.687717e+001 6.800025e+000 vertex 4.731668e+001 1.687717e+001 2.500000e-005 vertex 4.684880e+001 1.587421e+001 2.500000e-005 endloop endfacet facet normal -8.935350e-001 4.489936e-001 0.000000e+000 outer loop vertex 4.731668e+001 1.687717e+001 6.800025e+000 vertex 4.684880e+001 1.587421e+001 2.500000e-005 vertex 4.684880e+001 1.587421e+001 6.800025e+000 endloop endfacet facet normal -8.354493e-001 5.495675e-001 0.000000e+000 outer loop vertex 4.684880e+001 1.587421e+001 6.800025e+000 vertex 4.684880e+001 1.587421e+001 2.500000e-005 vertex 4.621389e+001 1.496772e+001 2.500000e-005 endloop endfacet facet normal -8.020076e-001 5.973139e-001 0.000000e+000 outer loop vertex 4.684880e+001 1.587421e+001 6.800025e+000 vertex 4.621389e+001 1.496772e+001 2.500000e-005 vertex 4.621389e+001 1.496772e+001 6.800025e+000 endloop endfacet facet normal -7.273421e-001 6.862751e-001 0.000000e+000 outer loop vertex 4.621389e+001 1.496772e+001 6.800025e+000 vertex 4.621389e+001 1.496772e+001 2.500000e-005 vertex 4.543123e+001 1.418523e+001 2.500000e-005 endloop endfacet facet normal -6.861182e-001 7.274901e-001 0.000000e+000 outer loop vertex 4.621389e+001 1.496772e+001 6.800025e+000 vertex 4.543123e+001 1.418523e+001 2.500000e-005 vertex 4.543123e+001 1.418523e+001 6.800025e+000 endloop endfacet facet normal -5.971408e-001 8.021364e-001 0.000000e+000 outer loop vertex 4.543123e+001 1.418523e+001 6.800025e+000 vertex 4.543123e+001 1.418523e+001 2.500000e-005 vertex 4.452460e+001 1.355051e+001 2.500000e-005 endloop endfacet facet normal -5.493873e-001 8.355678e-001 0.000000e+000 outer loop vertex 4.543123e+001 1.418523e+001 6.800025e+000 vertex 4.452460e+001 1.355051e+001 2.500000e-005 vertex 4.452460e+001 1.355051e+001 6.800025e+000 endloop endfacet facet normal -4.488008e-001 8.936318e-001 0.000000e+000 outer loop vertex 4.452460e+001 1.355051e+001 6.800025e+000 vertex 4.452460e+001 1.355051e+001 2.500000e-005 vertex 4.352154e+001 1.308285e+001 2.500000e-005 endloop endfacet facet normal -3.959680e-001 9.182643e-001 0.000000e+000 outer loop vertex 4.452460e+001 1.355051e+001 6.800025e+000 vertex 4.352154e+001 1.308285e+001 2.500000e-005 vertex 4.352154e+001 1.308285e+001 6.800025e+000 endloop endfacet facet normal -2.925929e-001 9.562371e-001 0.000000e+000 outer loop vertex 4.352154e+001 1.308285e+001 6.800025e+000 vertex 4.352154e+001 1.308285e+001 2.500000e-005 vertex 4.256568e+001 1.281745e+001 2.000025e+000 endloop endfacet facet normal -2.422796e-001 9.702065e-001 0.000000e+000 outer loop vertex 4.352154e+001 1.308285e+001 6.800025e+000 vertex 4.256568e+001 1.281745e+001 2.000025e+000 vertex 4.256568e+001 1.281745e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.756567e+001 1.270000e+001 2.000025e+000 vertex 4.135000e+001 1.270000e+001 2.000025e+000 vertex 3.756567e+001 1.270000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.756567e+001 1.270000e+001 2.500000e-005 vertex 4.135000e+001 1.270000e+001 2.000025e+000 vertex 4.135000e+001 1.270000e+001 2.500000e-005 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.756567e+001 1.000000e+001 2.000025e+000 vertex 3.756567e+001 1.270000e+001 2.000025e+000 vertex 3.756567e+001 1.000000e+001 2.500000e-005 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 3.756567e+001 1.000000e+001 2.500000e-005 vertex 3.756567e+001 1.270000e+001 2.000025e+000 vertex 3.756567e+001 1.270000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.500000e+001 8.673617e-016 2.500000e-005 vertex 3.270000e+001 1.000000e+001 2.500000e-005 vertex 5.405000e+001 0.000000e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.405000e+001 0.000000e+000 2.500000e-005 vertex 3.270000e+001 1.000000e+001 2.500000e-005 vertex 3.756567e+001 1.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.647232e+001 5.130845e+000 2.500000e-005 vertex 5.970789e+001 3.467160e+000 2.500000e-005 vertex 5.918726e+001 2.617563e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 3.756567e+001 1.270000e+001 2.500000e-005 vertex 4.135000e+001 1.270000e+001 2.500000e-005 vertex 4.997232e+001 5.130845e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.918726e+001 2.617563e+000 2.500000e-005 vertex 5.854013e+001 1.859872e+000 2.500000e-005 vertex 5.647232e+001 5.130845e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.647232e+001 5.130845e+000 2.500000e-005 vertex 5.854013e+001 1.859872e+000 2.500000e-005 vertex 5.778244e+001 1.212742e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.647232e+001 5.130845e+000 2.500000e-005 vertex 5.778244e+001 1.212742e+000 2.500000e-005 vertex 5.693284e+001 6.921086e-001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.997232e+001 5.130845e+000 2.500000e-005 vertex 4.135000e+001 1.270000e+001 2.500000e-005 vertex 4.997232e+001 8.883622e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.997232e+001 8.883622e+000 2.500000e-005 vertex 4.135000e+001 1.270000e+001 2.500000e-005 vertex 4.245252e+001 1.279644e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.997232e+001 8.883622e+000 2.500000e-005 vertex 4.245252e+001 1.279644e+001 2.500000e-005 vertex 4.352154e+001 1.308285e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.684880e+001 1.587421e+001 2.500000e-005 vertex 4.731668e+001 1.687717e+001 2.500000e-005 vertex 5.322232e+001 1.076001e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.322232e+001 1.076001e+001 2.500000e-005 vertex 4.731668e+001 1.687717e+001 2.500000e-005 vertex 4.760332e+001 1.794613e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.322232e+001 1.076001e+001 2.500000e-005 vertex 4.760332e+001 1.794613e+001 2.500000e-005 vertex 4.770000e+001 1.904863e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.770000e+001 1.904863e+001 2.500000e-005 vertex 4.770000e+001 1.905000e+001 2.500000e-005 vertex 5.322232e+001 1.076001e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.322232e+001 1.076001e+001 2.500000e-005 vertex 4.770000e+001 1.905000e+001 2.500000e-005 vertex 4.770000e+001 2.540000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.322232e+001 1.076001e+001 2.500000e-005 vertex 4.770000e+001 2.540000e+001 2.500000e-005 vertex 5.647232e+001 8.883622e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.647232e+001 8.883622e+000 2.500000e-005 vertex 4.770000e+001 2.540000e+001 2.500000e-005 vertex 6.040000e+001 2.540000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.647232e+001 8.883622e+000 2.500000e-005 vertex 6.040000e+001 2.540000e+001 2.500000e-005 vertex 5.647232e+001 5.130845e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.693284e+001 6.921086e-001 2.500000e-005 vertex 5.601226e+001 3.107911e-001 2.500000e-005 vertex 5.647232e+001 5.130845e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.647232e+001 5.130845e+000 2.500000e-005 vertex 5.601226e+001 3.107911e-001 2.500000e-005 vertex 5.504336e+001 7.817904e-002 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.647232e+001 5.130845e+000 2.500000e-005 vertex 5.504336e+001 7.817904e-002 2.500000e-005 vertex 5.322232e+001 3.254457e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.322232e+001 3.254457e+000 2.500000e-005 vertex 5.504336e+001 7.817904e-002 2.500000e-005 vertex 5.405000e+001 0.000000e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.322232e+001 3.254457e+000 2.500000e-005 vertex 5.405000e+001 0.000000e+000 2.500000e-005 vertex 4.997232e+001 5.130845e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.997232e+001 5.130845e+000 2.500000e-005 vertex 5.405000e+001 0.000000e+000 2.500000e-005 vertex 3.756567e+001 1.000000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.997232e+001 5.130845e+000 2.500000e-005 vertex 3.756567e+001 1.000000e+001 2.500000e-005 vertex 3.756567e+001 1.270000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.008921e+001 4.387742e+000 2.500000e-005 vertex 5.970789e+001 3.467160e+000 2.500000e-005 vertex 6.032182e+001 5.356641e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.032182e+001 5.356641e+000 2.500000e-005 vertex 5.970789e+001 3.467160e+000 2.500000e-005 vertex 5.647232e+001 5.130845e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.032182e+001 5.356641e+000 2.500000e-005 vertex 5.647232e+001 5.130845e+000 2.500000e-005 vertex 6.040000e+001 6.350000e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 6.040000e+001 6.350000e+000 2.500000e-005 vertex 5.647232e+001 5.130845e+000 2.500000e-005 vertex 6.040000e+001 2.540000e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.352154e+001 1.308285e+001 2.500000e-005 vertex 4.452460e+001 1.355051e+001 2.500000e-005 vertex 4.997232e+001 8.883622e+000 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.997232e+001 8.883622e+000 2.500000e-005 vertex 4.452460e+001 1.355051e+001 2.500000e-005 vertex 4.543123e+001 1.418523e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.997232e+001 8.883622e+000 2.500000e-005 vertex 4.543123e+001 1.418523e+001 2.500000e-005 vertex 5.322232e+001 1.076001e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.322232e+001 1.076001e+001 2.500000e-005 vertex 4.543123e+001 1.418523e+001 2.500000e-005 vertex 4.621389e+001 1.496772e+001 2.500000e-005 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 5.322232e+001 1.076001e+001 2.500000e-005 vertex 4.621389e+001 1.496772e+001 2.500000e-005 vertex 4.684880e+001 1.587421e+001 2.500000e-005 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 1.281745e+001 2.000025e+000 vertex 4.256568e+001 1.000000e+001 2.000025e+000 vertex 4.256568e+001 1.281745e+001 6.800025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 1.281745e+001 6.800025e+000 vertex 4.256568e+001 1.000000e+001 2.000025e+000 vertex 4.256568e+001 1.000000e+001 3.200025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 1.281745e+001 6.800025e+000 vertex 4.256568e+001 1.000000e+001 3.200025e+000 vertex 4.256568e+001 5.000000e+000 6.800025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 5.000000e+000 6.800025e+000 vertex 4.256568e+001 1.000000e+001 3.200025e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 5.000000e+000 6.800025e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 4.256568e+001 4.217828e+000 6.738467e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 4.217828e+000 6.738467e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 4.256568e+001 2.447174e-001 3.345110e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 4.217828e+000 6.738467e+000 vertex 4.256568e+001 2.447174e-001 3.345110e+000 vertex 4.256568e+001 3.454915e+000 6.555308e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 3.454915e+000 6.555308e+000 vertex 4.256568e+001 2.447174e-001 3.345110e+000 vertex 4.256568e+001 5.449674e-001 4.069977e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 3.454915e+000 6.555308e+000 vertex 4.256568e+001 5.449674e-001 4.069977e+000 vertex 4.256568e+001 2.730047e+000 6.255058e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 2.730047e+000 6.255058e+000 vertex 4.256568e+001 5.449674e-001 4.069977e+000 vertex 4.256568e+001 9.549150e-001 4.738952e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 2.730047e+000 6.255058e+000 vertex 4.256568e+001 9.549150e-001 4.738952e+000 vertex 4.256568e+001 2.061074e+000 5.845110e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 2.061074e+000 5.845110e+000 vertex 4.256568e+001 9.549150e-001 4.738952e+000 vertex 4.256568e+001 1.464466e+000 5.335559e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.806172e+001 2.540100e+001 2.000025e+000 vertex 4.806172e+001 2.540000e+001 2.000025e+000 vertex 4.770000e+001 2.540100e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 -1.000000e+000 outer loop vertex 4.770000e+001 2.540100e+001 2.000025e+000 vertex 4.806172e+001 2.540000e+001 2.000025e+000 vertex 4.770000e+001 2.540000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.452697e+001 2.454812e+001 6.800025e+000 vertex 4.543333e+001 2.391301e+001 6.800025e+000 vertex 5.256567e+001 2.540100e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.543333e+001 2.391301e+001 6.800025e+000 vertex 4.621565e+001 2.313019e+001 6.800025e+000 vertex 5.256567e+001 2.540100e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.256567e+001 2.540100e+001 6.800025e+000 vertex 4.621565e+001 2.313019e+001 6.800025e+000 vertex 4.685017e+001 2.222342e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.256567e+001 2.540100e+001 6.800025e+000 vertex 4.685017e+001 2.222342e+001 6.800025e+000 vertex 4.731762e+001 2.122025e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.760332e+001 1.794613e+001 6.800025e+000 vertex 5.256567e+001 5.000000e+000 6.800025e+000 vertex 4.770000e+001 1.904863e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.770000e+001 1.904863e+001 6.800025e+000 vertex 5.256567e+001 5.000000e+000 6.800025e+000 vertex 5.256567e+001 2.540100e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.770000e+001 1.904863e+001 6.800025e+000 vertex 5.256567e+001 2.540100e+001 6.800025e+000 vertex 4.760379e+001 2.015117e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.760379e+001 2.015117e+001 6.800025e+000 vertex 5.256567e+001 2.540100e+001 6.800025e+000 vertex 4.731762e+001 2.122025e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.760332e+001 1.794613e+001 6.800025e+000 vertex 4.731668e+001 1.687717e+001 6.800025e+000 vertex 5.256567e+001 5.000000e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.256567e+001 5.000000e+000 6.800025e+000 vertex 4.731668e+001 1.687717e+001 6.800025e+000 vertex 4.684880e+001 1.587421e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.256567e+001 5.000000e+000 6.800025e+000 vertex 4.684880e+001 1.587421e+001 6.800025e+000 vertex 4.621389e+001 1.496772e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.621389e+001 1.496772e+001 6.800025e+000 vertex 4.543123e+001 1.418523e+001 6.800025e+000 vertex 5.256567e+001 5.000000e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.256567e+001 5.000000e+000 6.800025e+000 vertex 4.543123e+001 1.418523e+001 6.800025e+000 vertex 4.452460e+001 1.355051e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.256567e+001 5.000000e+000 6.800025e+000 vertex 4.452460e+001 1.355051e+001 6.800025e+000 vertex 4.256568e+001 5.000000e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.256568e+001 5.000000e+000 6.800025e+000 vertex 4.452460e+001 1.355051e+001 6.800025e+000 vertex 4.352154e+001 1.308285e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.256568e+001 5.000000e+000 6.800025e+000 vertex 4.352154e+001 1.308285e+001 6.800025e+000 vertex 4.256568e+001 1.281745e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 4.256568e+001 2.540100e+001 6.800025e+000 vertex 4.256568e+001 2.528255e+001 6.800025e+000 vertex 5.256567e+001 2.540100e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.256567e+001 2.540100e+001 6.800025e+000 vertex 4.256568e+001 2.528255e+001 6.800025e+000 vertex 4.352412e+001 2.501621e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 5.256567e+001 2.540100e+001 6.800025e+000 vertex 4.352412e+001 2.501621e+001 6.800025e+000 vertex 4.452697e+001 2.454812e+001 6.800025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 5.256567e+001 4.217828e+000 6.738467e+000 vertex 5.256567e+001 3.454915e+000 6.555308e+000 vertex 5.256567e+001 5.000000e+000 6.800025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 5.256567e+001 5.000000e+000 6.800025e+000 vertex 5.256567e+001 3.454915e+000 6.555308e+000 vertex 5.256567e+001 3.040408e+000 6.400025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 5.256567e+001 5.000000e+000 6.800025e+000 vertex 5.256567e+001 3.040408e+000 6.400025e+000 vertex 5.256567e+001 2.540100e+001 6.800025e+000 endloop endfacet facet normal 1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 5.256567e+001 2.540100e+001 6.800025e+000 vertex 5.256567e+001 3.040408e+000 6.400025e+000 vertex 5.256567e+001 2.540100e+001 6.400025e+000 endloop endfacet facet normal 9.967573e-001 3.144029e-020 -8.046643e-002 outer loop vertex 4.806172e+001 2.540000e+001 2.000025e+000 vertex 4.806172e+001 2.540100e+001 2.000025e+000 vertex 4.814610e+001 2.540100e+001 2.769081e+000 endloop endfacet facet normal 9.986914e-001 1.027683e-015 -5.114166e-002 outer loop vertex 4.808622e+001 3.326160e-002 2.375794e+000 vertex 4.806172e+001 4.001601e-003 2.000025e+000 vertex 4.806172e+001 2.540000e+001 2.000025e+000 endloop endfacet facet normal 9.744641e-001 1.027804e-015 -2.245433e-001 outer loop vertex 4.824518e+001 1.918319e-001 3.171710e+000 vertex 4.814753e+001 9.623373e-002 2.776281e+000 vertex 4.814610e+001 2.540100e+001 2.769081e+000 endloop endfacet facet normal 9.808936e-001 1.026854e-015 -1.945450e-001 outer loop vertex 4.814610e+001 2.540100e+001 2.769081e+000 vertex 4.814753e+001 9.623373e-002 2.776281e+000 vertex 4.814642e+001 9.509387e-002 2.769032e+000 endloop endfacet facet normal 9.904935e-001 5.151491e-016 -1.375593e-001 outer loop vertex 4.814610e+001 2.540100e+001 2.769081e+000 vertex 4.814642e+001 9.509387e-002 2.769032e+000 vertex 4.806172e+001 2.540000e+001 2.000025e+000 endloop endfacet facet normal 9.923303e-001 1.030161e-015 -1.236147e-001 outer loop vertex 4.806172e+001 2.540000e+001 2.000025e+000 vertex 4.814642e+001 9.509387e-002 2.769032e+000 vertex 4.811772e+001 6.561589e-002 2.581559e+000 endloop endfacet facet normal 9.955420e-001 1.028889e-015 -9.431868e-002 outer loop vertex 4.806172e+001 2.540000e+001 2.000025e+000 vertex 4.811772e+001 6.561589e-002 2.581559e+000 vertex 4.808622e+001 3.326160e-002 2.375794e+000 endloop endfacet facet normal 9.024241e-001 1.028528e-015 -4.308488e-001 outer loop vertex 4.836082e+001 2.540100e+001 3.512359e+000 vertex 4.861576e+001 5.407910e-001 4.061762e+000 vertex 4.854350e+001 4.737741e-001 3.924473e+000 endloop endfacet facet normal 9.194987e-001 1.027892e-015 -3.930930e-001 outer loop vertex 4.854350e+001 4.737741e-001 3.924473e+000 vertex 4.837771e+001 3.183412e-001 3.555608e+000 vertex 4.836082e+001 2.540100e+001 3.512359e+000 endloop endfacet facet normal 9.320961e-001 1.026866e-015 -3.622111e-001 outer loop vertex 4.836082e+001 2.540100e+001 3.512359e+000 vertex 4.837771e+001 3.183412e-001 3.555608e+000 vertex 4.836257e+001 3.038892e-001 3.511753e+000 endloop endfacet facet normal 9.523488e-001 5.151177e-016 -3.050110e-001 outer loop vertex 4.836082e+001 2.540100e+001 3.512359e+000 vertex 4.836257e+001 3.038892e-001 3.511753e+000 vertex 4.814610e+001 2.540100e+001 2.769081e+000 endloop endfacet facet normal 9.562841e-001 1.030155e-015 -2.924393e-001 outer loop vertex 4.814610e+001 2.540100e+001 2.769081e+000 vertex 4.836257e+001 3.038892e-001 3.511753e+000 vertex 4.830460e+001 2.485572e-001 3.343845e+000 endloop endfacet facet normal 9.637383e-001 1.028951e-015 -2.668490e-001 outer loop vertex 4.814610e+001 2.540100e+001 2.769081e+000 vertex 4.830460e+001 2.485572e-001 3.343845e+000 vertex 4.824518e+001 1.918319e-001 3.171710e+000 endloop endfacet facet normal 8.035970e-001 1.029491e-015 -5.951738e-001 outer loop vertex 4.907279e+001 9.558219e-001 4.738336e+000 vertex 4.869954e+001 2.540100e+001 4.207938e+000 vertex 4.909079e+001 9.720252e-001 4.762359e+000 endloop endfacet facet normal 7.980335e-001 5.149346e-016 -6.026132e-001 outer loop vertex 4.909079e+001 9.720252e-001 4.762359e+000 vertex 4.869954e+001 2.540100e+001 4.207938e+000 vertex 4.915229e+001 2.540100e+001 4.835300e+000 endloop endfacet facet normal 8.218086e-001 1.028807e-015 -5.697637e-001 outer loop vertex 4.907279e+001 9.558219e-001 4.738336e+000 vertex 4.883790e+001 7.443990e-001 4.424880e+000 vertex 4.869954e+001 2.540100e+001 4.207938e+000 endloop endfacet facet normal 8.482184e-001 1.027226e-015 -5.296466e-001 outer loop vertex 4.869954e+001 2.540100e+001 4.207938e+000 vertex 4.883790e+001 7.443990e-001 4.424880e+000 vertex 4.870365e+001 6.213484e-001 4.205430e+000 endloop endfacet facet normal 8.861199e-001 5.151175e-016 -4.634561e-001 outer loop vertex 4.869954e+001 2.540100e+001 4.207938e+000 vertex 4.870365e+001 6.213484e-001 4.205430e+000 vertex 4.836082e+001 2.540100e+001 3.512359e+000 endloop endfacet facet normal 8.915241e-001 1.029732e-015 -4.529732e-001 outer loop vertex 4.836082e+001 2.540100e+001 3.512359e+000 vertex 4.870365e+001 6.213484e-001 4.205430e+000 vertex 4.862068e+001 5.452952e-001 4.069795e+000 endloop endfacet facet normal 8.971047e-001 1.029004e-015 -4.418181e-001 outer loop vertex 4.836082e+001 2.540100e+001 3.512359e+000 vertex 4.862068e+001 5.452952e-001 4.069795e+000 vertex 4.861576e+001 5.407910e-001 4.061762e+000 endloop endfacet facet normal 6.842405e-001 1.029800e-015 -7.292565e-001 outer loop vertex 4.965766e+001 1.464715e+000 5.335324e+000 vertex 4.915229e+001 2.540100e+001 4.835300e+000 vertex 4.966528e+001 1.471254e+000 5.342334e+000 endloop endfacet facet normal 6.808332e-001 5.150104e-016 -7.324385e-001 outer loop vertex 4.966528e+001 1.471254e+000 5.342334e+000 vertex 4.915229e+001 2.540100e+001 4.835300e+000 vertex 4.970571e+001 2.540100e+001 5.375945e+000 endloop endfacet facet normal 7.053419e-001 1.029048e-015 -7.088673e-001 outer loop vertex 4.965766e+001 1.464715e+000 5.335324e+000 vertex 4.937396e+001 1.221427e+000 5.074531e+000 vertex 4.915229e+001 2.540100e+001 4.835300e+000 endloop endfacet facet normal 7.416804e-001 1.027452e-015 -6.707534e-001 outer loop vertex 4.915229e+001 2.540100e+001 4.835300e+000 vertex 4.937396e+001 1.221427e+000 5.074531e+000 vertex 4.915486e+001 1.028451e+000 4.832986e+000 endloop endfacet facet normal 7.622383e-001 1.026905e-015 -6.472964e-001 outer loop vertex 4.915229e+001 2.540100e+001 4.835300e+000 vertex 4.915486e+001 1.028451e+000 4.832986e+000 vertex 4.909079e+001 9.720252e-001 4.762359e+000 endloop endfacet facet normal 5.650501e-001 5.146950e-016 -8.250566e-001 outer loop vertex 5.034347e+001 2.540100e+001 5.813924e+000 vertex 5.002942e+001 1.771990e+000 5.618395e+000 vertex 4.970571e+001 2.540100e+001 5.375945e+000 endloop endfacet facet normal 6.114001e-001 1.027774e-015 -7.913217e-001 outer loop vertex 4.970571e+001 2.540100e+001 5.375945e+000 vertex 5.002942e+001 1.771990e+000 5.618395e+000 vertex 4.970715e+001 1.505826e+000 5.374070e+000 endloop endfacet facet normal 6.378053e-001 1.026869e-015 -7.701977e-001 outer loop vertex 4.970571e+001 2.540100e+001 5.375945e+000 vertex 4.970715e+001 1.505826e+000 5.374070e+000 vertex 4.966528e+001 1.471254e+000 5.342334e+000 endloop endfacet facet normal 4.831766e-001 1.027032e-015 -8.755230e-001 outer loop vertex 5.042283e+001 2.078715e+000 5.857869e+000 vertex 5.040083e+001 2.061562e+000 5.844477e+000 vertex 5.034347e+001 2.540100e+001 5.813924e+000 endloop endfacet facet normal 4.890355e-001 1.027019e-015 -8.722639e-001 outer loop vertex 5.034347e+001 2.540100e+001 5.813924e+000 vertex 5.040083e+001 2.061562e+000 5.844477e+000 vertex 5.034540e+001 2.018347e+000 5.810737e+000 endloop endfacet facet normal 5.168490e-001 1.027624e-015 -8.560766e-001 outer loop vertex 5.034347e+001 2.540100e+001 5.813924e+000 vertex 5.034540e+001 2.018347e+000 5.810737e+000 vertex 5.002942e+001 1.771990e+000 5.618395e+000 endloop endfacet facet normal 3.069100e-001 1.027834e-015 -9.517385e-001 outer loop vertex 5.143454e+001 2.730199e+000 6.254772e+000 vertex 5.107096e+001 2.525730e+000 6.144906e+000 vertex 5.104677e+001 2.540100e+001 6.136322e+000 endloop endfacet facet normal 3.353249e-001 1.026857e-015 -9.421026e-001 outer loop vertex 5.104677e+001 2.540100e+001 6.136322e+000 vertex 5.107096e+001 2.525730e+000 6.144906e+000 vertex 5.104699e+001 2.510269e+000 6.135757e+000 endloop endfacet facet normal 3.904339e-001 5.151176e-016 -9.206310e-001 outer loop vertex 5.104677e+001 2.540100e+001 6.136322e+000 vertex 5.104699e+001 2.510269e+000 6.135757e+000 vertex 5.034347e+001 2.540100e+001 5.813924e+000 endloop endfacet facet normal 4.048620e-001 1.029562e-015 -9.143778e-001 outer loop vertex 5.034347e+001 2.540100e+001 5.813924e+000 vertex 5.104699e+001 2.510269e+000 6.135757e+000 vertex 5.084885e+001 2.382492e+000 6.060148e+000 endloop endfacet facet normal 4.506399e-001 1.028394e-015 -8.927059e-001 outer loop vertex 5.034347e+001 2.540100e+001 5.813924e+000 vertex 5.084885e+001 2.382492e+000 6.060148e+000 vertex 5.042283e+001 2.078715e+000 5.857869e+000 endloop endfacet facet normal 5.717352e-002 5.151176e-016 -9.983643e-001 outer loop vertex 5.256567e+001 2.540100e+001 6.400025e+000 vertex 5.256567e+001 3.040408e+000 6.400025e+000 vertex 5.179486e+001 2.540100e+001 6.333629e+000 endloop endfacet facet normal 7.985974e-002 1.029425e-015 -9.968061e-001 outer loop vertex 5.179486e+001 2.540100e+001 6.333629e+000 vertex 5.256567e+001 3.040408e+000 6.400025e+000 vertex 5.225923e+001 3.016127e+000 6.389606e+000 endloop endfacet facet normal 1.253284e-001 1.027811e-015 -9.921153e-001 outer loop vertex 5.179486e+001 2.540100e+001 6.333629e+000 vertex 5.225923e+001 3.016127e+000 6.389606e+000 vertex 5.195005e+001 2.944095e+000 6.357794e+000 endloop endfacet facet normal 1.571225e-001 1.026969e-015 -9.875792e-001 outer loop vertex 5.195005e+001 2.944095e+000 6.357794e+000 vertex 5.182820e+001 2.903553e+000 6.339288e+000 vertex 5.179486e+001 2.540100e+001 6.333629e+000 endloop endfacet facet normal 1.685861e-001 1.026860e-015 -9.856869e-001 outer loop vertex 5.179486e+001 2.540100e+001 6.333629e+000 vertex 5.182820e+001 2.903553e+000 6.339288e+000 vertex 5.179512e+001 2.889224e+000 6.332356e+000 endloop endfacet facet normal 2.271508e-001 5.151177e-016 -9.738595e-001 outer loop vertex 5.179486e+001 2.540100e+001 6.333629e+000 vertex 5.179512e+001 2.889224e+000 6.332356e+000 vertex 5.104677e+001 2.540100e+001 6.136322e+000 endloop endfacet facet normal 2.520747e-001 1.029398e-015 -9.677078e-001 outer loop vertex 5.104677e+001 2.540100e+001 6.136322e+000 vertex 5.179512e+001 2.889224e+000 6.332356e+000 vertex 5.145636e+001 2.742468e+000 6.261364e+000 endloop endfacet facet normal 2.783988e-001 1.027944e-015 -9.604656e-001 outer loop vertex 5.104677e+001 2.540100e+001 6.136322e+000 vertex 5.145636e+001 2.742468e+000 6.261364e+000 vertex 5.143454e+001 2.730199e+000 6.254772e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.256567e+001 2.540100e+001 6.800025e+000 vertex 5.256567e+001 2.540100e+001 6.400025e+000 vertex 5.179486e+001 2.540100e+001 6.333629e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.034347e+001 2.540100e+001 5.813924e+000 vertex 4.970571e+001 2.540100e+001 5.375945e+000 vertex 4.256568e+001 2.540100e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 2.540100e+001 6.800025e+000 vertex 4.970571e+001 2.540100e+001 5.375945e+000 vertex 4.915229e+001 2.540100e+001 4.835300e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 2.540100e+001 6.800025e+000 vertex 4.915229e+001 2.540100e+001 4.835300e+000 vertex 4.869954e+001 2.540100e+001 4.207938e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.806172e+001 2.540100e+001 2.000025e+000 vertex 4.770000e+001 2.540100e+001 2.000025e+000 vertex 4.814610e+001 2.540100e+001 2.769081e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.814610e+001 2.540100e+001 2.769081e+000 vertex 4.770000e+001 2.540100e+001 2.000025e+000 vertex 4.256568e+001 2.540100e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.814610e+001 2.540100e+001 2.769081e+000 vertex 4.256568e+001 2.540100e+001 6.800025e+000 vertex 4.836082e+001 2.540100e+001 3.512359e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.836082e+001 2.540100e+001 3.512359e+000 vertex 4.256568e+001 2.540100e+001 6.800025e+000 vertex 4.869954e+001 2.540100e+001 4.207938e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 5.256567e+001 2.540100e+001 6.800025e+000 vertex 5.179486e+001 2.540100e+001 6.333629e+000 vertex 4.256568e+001 2.540100e+001 6.800025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 2.540100e+001 6.800025e+000 vertex 5.179486e+001 2.540100e+001 6.333629e+000 vertex 5.104677e+001 2.540100e+001 6.136322e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.256568e+001 2.540100e+001 6.800025e+000 vertex 5.104677e+001 2.540100e+001 6.136322e+000 vertex 5.034347e+001 2.540100e+001 5.813924e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 4.769029e+001 1.940100e+001 2.009101e+000 vertex 4.770000e+001 1.940100e+001 2.000025e+000 vertex 4.769029e+001 1.940100e+001 2.000025e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.770000e+001 2.540000e+001 2.000025e+000 vertex 4.770000e+001 1.940100e+001 2.000025e+000 vertex 4.769029e+001 1.940100e+001 2.009101e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.769029e+001 1.940100e+001 2.009101e+000 vertex 4.765293e+001 1.982178e+001 2.044035e+000 vertex 4.770000e+001 2.540000e+001 2.000025e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.770000e+001 2.540000e+001 2.000025e+000 vertex 4.765293e+001 1.982178e+001 2.044035e+000 vertex 4.759086e+001 2.014871e+001 2.102054e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.770000e+001 2.540000e+001 2.000025e+000 vertex 4.759086e+001 2.014871e+001 2.102054e+000 vertex 4.749731e+001 2.064157e+001 2.189517e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.749731e+001 2.064157e+001 2.189517e+000 vertex 4.730518e+001 2.121608e+001 2.369142e+000 vertex 4.770000e+001 2.540000e+001 2.000025e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.770000e+001 2.540000e+001 2.000025e+000 vertex 4.730518e+001 2.121608e+001 2.369142e+000 vertex 4.721800e+001 2.147674e+001 2.450639e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.770000e+001 2.540000e+001 2.000025e+000 vertex 4.721800e+001 2.147674e+001 2.450639e+000 vertex 4.684314e+001 2.221985e+001 2.801087e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.617456e+001 2.317870e+001 3.426139e+000 vertex 4.770000e+001 2.540100e+001 2.000025e+000 vertex 4.621166e+001 2.312727e+001 3.391448e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.621166e+001 2.312727e+001 3.391448e+000 vertex 4.770000e+001 2.540100e+001 2.000025e+000 vertex 4.770000e+001 2.540000e+001 2.000025e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.621166e+001 2.312727e+001 3.391448e+000 vertex 4.770000e+001 2.540000e+001 2.000025e+000 vertex 4.678906e+001 2.232706e+001 2.851649e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.678906e+001 2.232706e+001 2.851649e+000 vertex 4.770000e+001 2.540000e+001 2.000025e+000 vertex 4.684314e+001 2.221985e+001 2.801087e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.617456e+001 2.317870e+001 3.426139e+000 vertex 4.543221e+001 2.391186e+001 4.120145e+000 vertex 4.770000e+001 2.540100e+001 2.000025e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.770000e+001 2.540100e+001 2.000025e+000 vertex 4.543221e+001 2.391186e+001 4.120145e+000 vertex 4.541831e+001 2.392559e+001 4.133146e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.770000e+001 2.540100e+001 2.000025e+000 vertex 4.541831e+001 2.392559e+001 4.133146e+000 vertex 4.454807e+001 2.453588e+001 4.946717e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.454807e+001 2.453588e+001 4.946717e+000 vertex 4.452610e+001 2.454633e+001 4.967255e+000 vertex 4.770000e+001 2.540100e+001 2.000025e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.770000e+001 2.540100e+001 2.000025e+000 vertex 4.452610e+001 2.454633e+001 4.967255e+000 vertex 4.358823e+001 2.499246e+001 5.844057e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.770000e+001 2.540100e+001 2.000025e+000 vertex 4.358823e+001 2.499246e+001 5.844057e+000 vertex 4.256568e+001 2.540100e+001 6.800025e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.256568e+001 2.540100e+001 6.800025e+000 vertex 4.358823e+001 2.499246e+001 5.844057e+000 vertex 4.352260e+001 2.501108e+001 5.905413e+000 endloop endfacet facet normal -6.829236e-001 0.000000e+000 -7.304899e-001 outer loop vertex 4.256568e+001 2.540100e+001 6.800025e+000 vertex 4.352260e+001 2.501108e+001 5.905413e+000 vertex 4.256568e+001 2.528255e+001 6.800025e+000 endloop endfacet facet normal 9.983119e-001 5.807913e-002 0.000000e+000 outer loop vertex 7.978277e+000 1.800000e+001 2.000025e+000 vertex 7.978277e+000 1.800000e+001 2.500000e-005 vertex 7.947892e+000 1.834730e+001 2.500000e-005 endloop endfacet facet normal 9.932307e-001 1.161583e-001 0.000000e+000 outer loop vertex 7.978277e+000 1.800000e+001 2.000025e+000 vertex 7.947892e+000 1.834730e+001 2.500000e-005 vertex 7.947892e+000 1.834730e+001 2.000025e+000 endloop endfacet facet normal 9.730601e-001 2.305518e-001 0.000000e+000 outer loop vertex 7.947892e+000 1.834730e+001 2.000025e+000 vertex 7.947892e+000 1.834730e+001 2.500000e-005 vertex 7.857662e+000 1.868404e+001 2.500000e-005 endloop endfacet facet normal 9.579706e-001 2.868663e-001 0.000000e+000 outer loop vertex 7.947892e+000 1.834730e+001 2.000025e+000 vertex 7.857662e+000 1.868404e+001 2.500000e-005 vertex 7.857662e+000 1.868404e+001 2.000025e+000 endloop endfacet facet normal 9.182422e-001 3.960194e-001 0.000000e+000 outer loop vertex 7.857662e+000 1.868404e+001 2.000025e+000 vertex 7.857662e+000 1.868404e+001 2.500000e-005 vertex 7.710328e+000 1.900000e+001 2.500000e-005 endloop endfacet facet normal 8.936031e-001 4.488580e-001 0.000000e+000 outer loop vertex 7.857662e+000 1.868404e+001 2.000025e+000 vertex 7.710328e+000 1.900000e+001 2.500000e-005 vertex 7.710328e+000 1.900000e+001 2.000025e+000 endloop endfacet facet normal 8.355240e-001 5.494540e-001 0.000000e+000 outer loop vertex 7.710328e+000 1.900000e+001 2.000025e+000 vertex 7.710328e+000 1.900000e+001 2.500000e-005 vertex 7.510366e+000 1.928557e+001 2.500000e-005 endloop endfacet facet normal 8.020838e-001 5.972114e-001 0.000000e+000 outer loop vertex 7.710328e+000 1.900000e+001 2.000025e+000 vertex 7.510366e+000 1.928557e+001 2.500000e-005 vertex 7.510366e+000 1.928557e+001 2.000025e+000 endloop endfacet facet normal 7.274188e-001 6.861938e-001 0.000000e+000 outer loop vertex 7.510366e+000 1.928557e+001 2.000025e+000 vertex 7.510366e+000 1.928557e+001 2.500000e-005 vertex 7.263852e+000 1.953209e+001 2.500000e-005 endloop endfacet facet normal 6.861938e-001 7.274188e-001 0.000000e+000 outer loop vertex 7.510366e+000 1.928557e+001 2.000025e+000 vertex 7.263852e+000 1.953209e+001 2.500000e-005 vertex 7.263852e+000 1.953209e+001 2.000025e+000 endloop endfacet facet normal 5.972114e-001 8.020838e-001 0.000000e+000 outer loop vertex 7.263852e+000 1.953209e+001 2.000025e+000 vertex 7.263852e+000 1.953209e+001 2.500000e-005 vertex 6.978277e+000 1.973205e+001 2.500000e-005 endloop endfacet facet normal 5.494540e-001 8.355240e-001 0.000000e+000 outer loop vertex 7.263852e+000 1.953209e+001 2.000025e+000 vertex 6.978277e+000 1.973205e+001 2.500000e-005 vertex 6.978277e+000 1.973205e+001 2.000025e+000 endloop endfacet facet normal 4.488580e-001 8.936031e-001 0.000000e+000 outer loop vertex 6.978277e+000 1.973205e+001 2.000025e+000 vertex 6.978277e+000 1.973205e+001 2.500000e-005 vertex 6.662317e+000 1.987938e+001 2.500000e-005 endloop endfacet facet normal 3.960194e-001 9.182422e-001 0.000000e+000 outer loop vertex 6.978277e+000 1.973205e+001 2.000025e+000 vertex 6.662317e+000 1.987938e+001 2.500000e-005 vertex 6.662317e+000 1.987938e+001 2.000025e+000 endloop endfacet facet normal 2.868663e-001 9.579706e-001 0.000000e+000 outer loop vertex 6.662317e+000 1.987938e+001 2.000025e+000 vertex 6.662317e+000 1.987938e+001 2.500000e-005 vertex 6.325573e+000 1.996962e+001 2.500000e-005 endloop endfacet facet normal 2.305518e-001 9.730601e-001 0.000000e+000 outer loop vertex 6.662317e+000 1.987938e+001 2.000025e+000 vertex 6.325573e+000 1.996962e+001 2.500000e-005 vertex 6.325573e+000 1.996962e+001 2.000025e+000 endloop endfacet facet normal 1.161583e-001 9.932307e-001 0.000000e+000 outer loop vertex 6.325573e+000 1.996962e+001 2.000025e+000 vertex 6.325573e+000 1.996962e+001 2.500000e-005 vertex 5.978277e+000 2.000000e+001 2.500000e-005 endloop endfacet facet normal 5.807913e-002 9.983119e-001 0.000000e+000 outer loop vertex 6.325573e+000 1.996962e+001 2.000025e+000 vertex 5.978277e+000 2.000000e+001 2.500000e-005 vertex 5.978277e+000 2.000000e+001 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -9.709609e-001 2.392381e-001 outer loop vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 1.500000e+001 2.000000e-001 3.200025e+000 vertex 1.500000e+001 6.155830e-002 2.582197e+000 endloop endfacet facet normal 0.000000e+000 -4.067801e-001 9.135261e-001 outer loop vertex 4.256568e+001 3.454915e+000 6.555308e+000 vertex 4.256568e+001 2.730047e+000 6.255058e+000 vertex 5.143454e+001 2.730199e+000 6.254772e+000 endloop endfacet facet normal 0.000000e+000 -3.803812e-001 9.248298e-001 outer loop vertex 5.182820e+001 2.903553e+000 6.339288e+000 vertex 5.195005e+001 2.944095e+000 6.357794e+000 vertex 5.256567e+001 3.454915e+000 6.555308e+000 endloop endfacet facet normal 0.000000e+000 -3.727603e-001 9.279276e-001 outer loop vertex 5.256567e+001 3.454915e+000 6.555308e+000 vertex 5.195005e+001 2.944095e+000 6.357794e+000 vertex 5.225923e+001 3.016127e+000 6.389606e+000 endloop endfacet facet normal 0.000000e+000 -3.662426e-001 9.305194e-001 outer loop vertex 5.256567e+001 3.454915e+000 6.555308e+000 vertex 5.225923e+001 3.016127e+000 6.389606e+000 vertex 5.256567e+001 3.040408e+000 6.400025e+000 endloop endfacet facet normal 0.000000e+000 -4.059304e-001 9.139040e-001 outer loop vertex 5.143454e+001 2.730199e+000 6.254772e+000 vertex 5.145636e+001 2.742468e+000 6.261364e+000 vertex 4.256568e+001 3.454915e+000 6.555308e+000 endloop endfacet facet normal 0.000000e+000 -3.951040e-001 9.186364e-001 outer loop vertex 4.256568e+001 3.454915e+000 6.555308e+000 vertex 5.145636e+001 2.742468e+000 6.261364e+000 vertex 5.179512e+001 2.889224e+000 6.332356e+000 endloop endfacet facet normal 0.000000e+000 -3.841102e-001 9.232873e-001 outer loop vertex 4.256568e+001 3.454915e+000 6.555308e+000 vertex 5.179512e+001 2.889224e+000 6.332356e+000 vertex 5.182820e+001 2.903553e+000 6.339288e+000 endloop endfacet facet normal 0.000000e+000 -4.920879e-001 8.705455e-001 outer loop vertex 5.084885e+001 2.382492e+000 6.060148e+000 vertex 5.104699e+001 2.510269e+000 6.135757e+000 vertex 4.256568e+001 2.730047e+000 6.255058e+000 endloop endfacet facet normal 0.000000e+000 -4.823976e-001 8.759524e-001 outer loop vertex 4.256568e+001 2.730047e+000 6.255058e+000 vertex 5.104699e+001 2.510269e+000 6.135757e+000 vertex 5.107096e+001 2.525730e+000 6.144906e+000 endloop endfacet facet normal 0.000000e+000 -4.677234e-001 8.838749e-001 outer loop vertex 4.256568e+001 2.730047e+000 6.255058e+000 vertex 5.107096e+001 2.525730e+000 6.144906e+000 vertex 5.143454e+001 2.730199e+000 6.254772e+000 endloop endfacet facet normal 0.000000e+000 -6.452954e-001 7.639332e-001 outer loop vertex 4.970715e+001 1.505826e+000 5.374070e+000 vertex 5.002942e+001 1.771990e+000 5.618395e+000 vertex 4.256568e+001 2.061074e+000 5.845110e+000 endloop endfacet facet normal 0.000000e+000 -6.103210e-001 7.921543e-001 outer loop vertex 5.002942e+001 1.771990e+000 5.618395e+000 vertex 5.034540e+001 2.018347e+000 5.810737e+000 vertex 4.256568e+001 2.061074e+000 5.845110e+000 endloop endfacet facet normal 0.000000e+000 -5.907356e-001 8.068653e-001 outer loop vertex 4.256568e+001 2.061074e+000 5.845110e+000 vertex 5.034540e+001 2.018347e+000 5.810737e+000 vertex 5.040083e+001 2.061562e+000 5.844477e+000 endloop endfacet facet normal 0.000000e+000 -5.446779e-001 8.386453e-001 outer loop vertex 4.256568e+001 2.061074e+000 5.845110e+000 vertex 5.040083e+001 2.061562e+000 5.844477e+000 vertex 4.256568e+001 2.730047e+000 6.255058e+000 endloop endfacet facet normal 0.000000e+000 -5.434585e-001 8.394361e-001 outer loop vertex 4.256568e+001 2.730047e+000 6.255058e+000 vertex 5.040083e+001 2.061562e+000 5.844477e+000 vertex 5.042283e+001 2.078715e+000 5.857869e+000 endloop endfacet facet normal 0.000000e+000 -5.215971e-001 8.531920e-001 outer loop vertex 4.256568e+001 2.730047e+000 6.255058e+000 vertex 5.042283e+001 2.078715e+000 5.857869e+000 vertex 5.084885e+001 2.382492e+000 6.060148e+000 endloop endfacet facet normal 0.000000e+000 -7.771747e-001 6.292849e-001 outer loop vertex 4.256568e+001 9.549150e-001 4.738952e+000 vertex 4.907279e+001 9.558219e-001 4.738336e+000 vertex 4.256568e+001 1.464466e+000 5.335559e+000 endloop endfacet facet normal 0.000000e+000 -7.759551e-001 6.307881e-001 outer loop vertex 4.256568e+001 1.464466e+000 5.335559e+000 vertex 4.907279e+001 9.558219e-001 4.738336e+000 vertex 4.909079e+001 9.720252e-001 4.762359e+000 endloop endfacet facet normal 0.000000e+000 -7.709051e-001 6.369501e-001 outer loop vertex 4.256568e+001 1.464466e+000 5.335559e+000 vertex 4.909079e+001 9.720252e-001 4.762359e+000 vertex 4.915486e+001 1.028451e+000 4.832986e+000 endloop endfacet facet normal 0.000000e+000 -7.536410e-001 6.572862e-001 outer loop vertex 4.915486e+001 1.028451e+000 4.832986e+000 vertex 4.937396e+001 1.221427e+000 5.074531e+000 vertex 4.256568e+001 1.464466e+000 5.335559e+000 endloop endfacet facet normal 0.000000e+000 -7.237182e-001 6.900957e-001 outer loop vertex 4.256568e+001 1.464466e+000 5.335559e+000 vertex 4.937396e+001 1.221427e+000 5.074531e+000 vertex 4.965766e+001 1.464715e+000 5.335324e+000 endloop endfacet facet normal 0.000000e+000 -6.691657e-001 7.431132e-001 outer loop vertex 4.256568e+001 1.464466e+000 5.335559e+000 vertex 4.965766e+001 1.464715e+000 5.335324e+000 vertex 4.256568e+001 2.061074e+000 5.845110e+000 endloop endfacet facet normal 0.000000e+000 -6.686898e-001 7.435414e-001 outer loop vertex 4.256568e+001 2.061074e+000 5.845110e+000 vertex 4.965766e+001 1.464715e+000 5.335324e+000 vertex 4.966528e+001 1.471254e+000 5.342334e+000 endloop endfacet facet normal 0.000000e+000 -6.658812e-001 7.460578e-001 outer loop vertex 4.256568e+001 2.061074e+000 5.845110e+000 vertex 4.966528e+001 1.471254e+000 5.342334e+000 vertex 4.970715e+001 1.505826e+000 5.374070e+000 endloop endfacet facet normal 0.000000e+000 -8.608109e-001 5.089250e-001 outer loop vertex 4.256568e+001 5.449674e-001 4.069977e+000 vertex 4.870365e+001 6.213484e-001 4.205430e+000 vertex 4.256568e+001 9.549150e-001 4.738952e+000 endloop endfacet facet normal 0.000000e+000 -8.466658e-001 5.321251e-001 outer loop vertex 4.256568e+001 9.549150e-001 4.738952e+000 vertex 4.870365e+001 6.213484e-001 4.205430e+000 vertex 4.883790e+001 7.443990e-001 4.424880e+000 endloop endfacet facet normal 0.000000e+000 -8.235735e-001 5.672095e-001 outer loop vertex 4.256568e+001 9.549150e-001 4.738952e+000 vertex 4.883790e+001 7.443990e-001 4.424880e+000 vertex 4.907279e+001 9.558219e-001 4.738336e+000 endloop endfacet facet normal 0.000000e+000 -8.961301e-001 4.437915e-001 outer loop vertex 4.854350e+001 4.737741e-001 3.924473e+000 vertex 4.861576e+001 5.407910e-001 4.061762e+000 vertex 4.256568e+001 5.449674e-001 4.069977e+000 endloop endfacet facet normal 0.000000e+000 -8.912857e-001 4.534422e-001 outer loop vertex 4.256568e+001 5.449674e-001 4.069977e+000 vertex 4.861576e+001 5.407910e-001 4.061762e+000 vertex 4.862068e+001 5.452952e-001 4.069795e+000 endloop endfacet facet normal 0.000000e+000 -8.862524e-001 4.632027e-001 outer loop vertex 4.256568e+001 5.449674e-001 4.069977e+000 vertex 4.862068e+001 5.452952e-001 4.069795e+000 vertex 4.870365e+001 6.213484e-001 4.205430e+000 endloop endfacet facet normal 0.000000e+000 -9.547220e-001 2.974994e-001 outer loop vertex 4.824518e+001 1.918319e-001 3.171710e+000 vertex 4.830460e+001 2.485572e-001 3.343845e+000 vertex 4.256568e+001 2.447174e-001 3.345110e+000 endloop endfacet facet normal 0.000000e+000 -9.473473e-001 3.202077e-001 outer loop vertex 4.256568e+001 2.447174e-001 3.345110e+000 vertex 4.830460e+001 2.485572e-001 3.343845e+000 vertex 4.836257e+001 3.038892e-001 3.511753e+000 endloop endfacet facet normal 0.000000e+000 -9.293006e-001 3.693241e-001 outer loop vertex 4.256568e+001 2.447174e-001 3.345110e+000 vertex 4.836257e+001 3.038892e-001 3.511753e+000 vertex 4.256568e+001 5.449674e-001 4.069977e+000 endloop endfacet facet normal 0.000000e+000 -9.237036e-001 3.831080e-001 outer loop vertex 4.256568e+001 5.449674e-001 4.069977e+000 vertex 4.836257e+001 3.038892e-001 3.511753e+000 vertex 4.837771e+001 3.183412e-001 3.555608e+000 endloop endfacet facet normal 0.000000e+000 -9.118798e-001 4.104574e-001 outer loop vertex 4.256568e+001 5.449674e-001 4.069977e+000 vertex 4.837771e+001 3.183412e-001 3.555608e+000 vertex 4.854350e+001 4.737741e-001 3.924473e+000 endloop endfacet facet normal 0.000000e+000 -9.802068e-001 1.979763e-001 outer loop vertex 1.500000e+001 6.155830e-002 2.582197e+000 vertex 4.811772e+001 6.561589e-002 2.581559e+000 vertex 4.256568e+001 2.000000e-001 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -9.776199e-001 2.103792e-001 outer loop vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 4.811772e+001 6.561589e-002 2.581559e+000 vertex 4.814642e+001 9.509387e-002 2.769032e+000 endloop endfacet facet normal 0.000000e+000 -9.652639e-001 2.612768e-001 outer loop vertex 4.256568e+001 2.000000e-001 3.200025e+000 vertex 4.814642e+001 9.509387e-002 2.769032e+000 vertex 4.256568e+001 2.447174e-001 3.345110e+000 endloop endfacet facet normal 0.000000e+000 -9.724632e-001 2.330564e-001 outer loop vertex 4.256568e+001 2.447174e-001 3.345110e+000 vertex 4.814642e+001 9.509387e-002 2.769032e+000 vertex 4.814753e+001 9.623373e-002 2.776281e+000 endloop endfacet facet normal 0.000000e+000 -9.656492e-001 2.598494e-001 outer loop vertex 4.256568e+001 2.447174e-001 3.345110e+000 vertex 4.814753e+001 9.623373e-002 2.776281e+000 vertex 4.824518e+001 1.918319e-001 3.171710e+000 endloop endfacet facet normal 0.000000e+000 -9.996252e-001 2.737623e-002 outer loop vertex 5.406192e+001 1.118944e-005 1.810603e+000 vertex 5.427540e+001 4.001601e-003 2.000025e+000 vertex 4.806172e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -9.999998e-001 7.052009e-004 outer loop vertex 5.405000e+001 0.000000e+000 1.800025e+000 vertex 5.406192e+001 1.118944e-005 1.810603e+000 vertex 3.500000e+001 8.673617e-016 1.800025e+000 endloop endfacet facet normal 0.000000e+000 -9.999014e-001 1.404091e-002 outer loop vertex 3.500000e+001 8.673617e-016 1.800025e+000 vertex 5.406192e+001 1.118944e-005 1.810603e+000 vertex 4.806172e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -9.996443e-001 2.667141e-002 outer loop vertex 3.500000e+001 8.673617e-016 1.800025e+000 vertex 4.806172e+001 4.001601e-003 2.000025e+000 vertex 3.499908e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -9.996443e-001 2.667141e-002 outer loop vertex 4.800000e+000 4.001601e-003 2.000025e+000 vertex 5.000000e+000 8.673617e-016 1.800025e+000 vertex 1.500000e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -9.999111e-001 1.333570e-002 outer loop vertex 1.500000e+001 4.001601e-003 2.000025e+000 vertex 5.000000e+000 8.673617e-016 1.800025e+000 vertex 2.000000e+001 8.673617e-016 1.800025e+000 endloop endfacet facet normal 0.000000e+000 -9.978445e-001 6.562383e-002 outer loop vertex 1.500000e+001 4.001601e-003 2.000025e+000 vertex 2.000000e+001 8.673617e-016 1.800025e+000 vertex 1.500000e+001 6.155830e-002 2.582197e+000 endloop endfacet facet normal 0.000000e+000 -9.978445e-001 6.562383e-002 outer loop vertex 1.500000e+001 6.155830e-002 2.582197e+000 vertex 2.000000e+001 8.673617e-016 1.800025e+000 vertex 2.000000e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -9.930370e-001 1.178026e-001 outer loop vertex 1.500000e+001 6.155830e-002 2.582197e+000 vertex 2.000000e+001 4.001601e-003 2.000025e+000 vertex 4.811772e+001 6.561589e-002 2.581559e+000 endloop endfacet facet normal 0.000000e+000 -9.968800e-001 7.893194e-002 outer loop vertex 4.811772e+001 6.561589e-002 2.581559e+000 vertex 2.000000e+001 4.001601e-003 2.000025e+000 vertex 3.499908e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -9.945788e-001 1.039850e-001 outer loop vertex 4.811772e+001 6.561589e-002 2.581559e+000 vertex 3.499908e+001 4.001601e-003 2.000025e+000 vertex 4.808622e+001 3.326160e-002 2.375794e+000 endloop endfacet facet normal 0.000000e+000 -9.978793e-001 6.509236e-002 outer loop vertex 4.808622e+001 3.326160e-002 2.375794e+000 vertex 3.499908e+001 4.001601e-003 2.000025e+000 vertex 4.806172e+001 4.001601e-003 2.000025e+000 endloop endfacet facet normal 0.000000e+000 -3.463146e-001 9.381185e-001 outer loop vertex 5.182820e+001 2.903553e+000 6.339288e+000 vertex 5.256567e+001 3.454915e+000 6.555308e+000 vertex 4.256568e+001 3.454915e+000 6.555308e+000 endloop endfacet facet normal 0.000000e+000 -2.588654e-001 9.659134e-001 outer loop vertex 4.256568e+001 3.454915e+000 6.555308e+000 vertex 5.256567e+001 3.454915e+000 6.555308e+000 vertex 5.256567e+001 4.217828e+000 6.738467e+000 endloop endfacet facet normal 0.000000e+000 -2.078648e-001 9.781576e-001 outer loop vertex 4.256568e+001 3.454915e+000 6.555308e+000 vertex 5.256567e+001 4.217828e+000 6.738467e+000 vertex 4.256568e+001 4.217828e+000 6.738467e+000 endloop endfacet facet normal 0.000000e+000 -1.045761e-001 9.945168e-001 outer loop vertex 4.256568e+001 4.217828e+000 6.738467e+000 vertex 5.256567e+001 4.217828e+000 6.738467e+000 vertex 5.256567e+001 5.000000e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 -5.228807e-002 9.986320e-001 outer loop vertex 4.256568e+001 4.217828e+000 6.738467e+000 vertex 5.256567e+001 5.000000e+000 6.800025e+000 vertex 4.256568e+001 5.000000e+000 6.800025e+000 endloop endfacet facet normal -9.983119e-001 5.807913e-002 0.000000e+000 outer loop vertex 5.629843e+000 1.539157e+001 2.500000e-005 vertex 5.656430e+000 1.569546e+001 2.000025e+000 vertex 5.656430e+000 1.569546e+001 2.500000e-005 endloop endfacet facet normal -9.983119e-001 -5.807913e-002 0.000000e+000 outer loop vertex 5.656430e+000 1.569546e+001 2.500000e-005 vertex 5.656430e+000 1.569546e+001 2.000025e+000 vertex 5.629843e+000 1.599934e+001 2.000025e+000 endloop endfacet facet normal -9.932307e-001 -1.161583e-001 0.000000e+000 outer loop vertex 5.656430e+000 1.569546e+001 2.500000e-005 vertex 5.629843e+000 1.599934e+001 2.000025e+000 vertex 5.629843e+000 1.599934e+001 2.500000e-005 endloop endfacet facet normal -9.730601e-001 -2.305518e-001 0.000000e+000 outer loop vertex 5.629843e+000 1.599934e+001 2.500000e-005 vertex 5.629843e+000 1.599934e+001 2.000025e+000 vertex 5.550891e+000 1.629399e+001 2.000025e+000 endloop endfacet facet normal -9.579706e-001 -2.868663e-001 0.000000e+000 outer loop vertex 5.629843e+000 1.599934e+001 2.500000e-005 vertex 5.550891e+000 1.629399e+001 2.000025e+000 vertex 5.550891e+000 1.629399e+001 2.500000e-005 endloop endfacet facet normal -9.182422e-001 -3.960194e-001 0.000000e+000 outer loop vertex 5.550891e+000 1.629399e+001 2.500000e-005 vertex 5.550891e+000 1.629399e+001 2.000025e+000 vertex 5.421974e+000 1.657046e+001 2.000025e+000 endloop endfacet facet normal -8.936031e-001 -4.488580e-001 0.000000e+000 outer loop vertex 5.550891e+000 1.629399e+001 2.500000e-005 vertex 5.421974e+000 1.657046e+001 2.000025e+000 vertex 5.421974e+000 1.657046e+001 2.500000e-005 endloop endfacet facet normal -8.355240e-001 -5.494540e-001 0.000000e+000 outer loop vertex 5.421974e+000 1.657046e+001 2.500000e-005 vertex 5.421974e+000 1.657046e+001 2.000025e+000 vertex 5.247007e+000 1.682034e+001 2.000025e+000 endloop endfacet facet normal -8.020838e-001 -5.972114e-001 0.000000e+000 outer loop vertex 5.421974e+000 1.657046e+001 2.500000e-005 vertex 5.247007e+000 1.682034e+001 2.000025e+000 vertex 5.247007e+000 1.682034e+001 2.500000e-005 endloop endfacet facet normal -7.274188e-001 -6.861938e-001 0.000000e+000 outer loop vertex 5.247007e+000 1.682034e+001 2.500000e-005 vertex 5.247007e+000 1.682034e+001 2.000025e+000 vertex 5.031308e+000 1.703604e+001 2.000025e+000 endloop endfacet facet normal -6.861938e-001 -7.274188e-001 0.000000e+000 outer loop vertex 5.247007e+000 1.682034e+001 2.500000e-005 vertex 5.031308e+000 1.703604e+001 2.000025e+000 vertex 5.031308e+000 1.703604e+001 2.500000e-005 endloop endfacet facet normal -5.972114e-001 -8.020838e-001 0.000000e+000 outer loop vertex 5.031308e+000 1.703604e+001 2.500000e-005 vertex 5.031308e+000 1.703604e+001 2.000025e+000 vertex 4.781430e+000 1.721100e+001 2.000025e+000 endloop endfacet facet normal -5.494540e-001 -8.355240e-001 0.000000e+000 outer loop vertex 5.031308e+000 1.703604e+001 2.500000e-005 vertex 4.781430e+000 1.721100e+001 2.000025e+000 vertex 4.781430e+000 1.721100e+001 2.500000e-005 endloop endfacet facet normal -4.488580e-001 -8.936031e-001 0.000000e+000 outer loop vertex 4.781430e+000 1.721100e+001 2.500000e-005 vertex 4.781430e+000 1.721100e+001 2.000025e+000 vertex 4.504965e+000 1.733992e+001 2.000025e+000 endloop endfacet facet normal -3.960194e-001 -9.182422e-001 0.000000e+000 outer loop vertex 4.781430e+000 1.721100e+001 2.500000e-005 vertex 4.504965e+000 1.733992e+001 2.000025e+000 vertex 4.504965e+000 1.733992e+001 2.500000e-005 endloop endfacet facet normal -2.868663e-001 -9.579706e-001 0.000000e+000 outer loop vertex 4.504965e+000 1.733992e+001 2.500000e-005 vertex 4.504965e+000 1.733992e+001 2.000025e+000 vertex 4.210314e+000 1.741887e+001 2.000025e+000 endloop endfacet facet normal -2.305518e-001 -9.730601e-001 0.000000e+000 outer loop vertex 4.504965e+000 1.733992e+001 2.500000e-005 vertex 4.210314e+000 1.741887e+001 2.000025e+000 vertex 4.210314e+000 1.741887e+001 2.500000e-005 endloop endfacet facet normal -1.161583e-001 -9.932307e-001 0.000000e+000 outer loop vertex 4.210314e+000 1.741887e+001 2.500000e-005 vertex 4.210314e+000 1.741887e+001 2.000025e+000 vertex 3.906429e+000 1.744546e+001 2.000025e+000 endloop endfacet facet normal -5.807913e-002 -9.983119e-001 0.000000e+000 outer loop vertex 4.210314e+000 1.741887e+001 2.500000e-005 vertex 3.906429e+000 1.744546e+001 2.000025e+000 vertex 3.906429e+000 1.744546e+001 2.500000e-005 endloop endfacet facet normal 5.807913e-002 -9.983119e-001 0.000000e+000 outer loop vertex 3.906429e+000 1.744546e+001 2.500000e-005 vertex 3.906429e+000 1.744546e+001 2.000025e+000 vertex 3.602545e+000 1.741887e+001 2.000025e+000 endloop endfacet facet normal 1.161583e-001 -9.932307e-001 0.000000e+000 outer loop vertex 3.906429e+000 1.744546e+001 2.500000e-005 vertex 3.602545e+000 1.741887e+001 2.000025e+000 vertex 3.602545e+000 1.741887e+001 2.500000e-005 endloop endfacet facet normal 2.305518e-001 -9.730601e-001 0.000000e+000 outer loop vertex 3.602545e+000 1.741887e+001 2.500000e-005 vertex 3.602545e+000 1.741887e+001 2.000025e+000 vertex 3.307894e+000 1.733992e+001 2.000025e+000 endloop endfacet facet normal 2.868663e-001 -9.579706e-001 0.000000e+000 outer loop vertex 3.602545e+000 1.741887e+001 2.500000e-005 vertex 3.307894e+000 1.733992e+001 2.000025e+000 vertex 3.307894e+000 1.733992e+001 2.500000e-005 endloop endfacet facet normal 3.960194e-001 -9.182422e-001 0.000000e+000 outer loop vertex 3.307894e+000 1.733992e+001 2.500000e-005 vertex 3.307894e+000 1.733992e+001 2.000025e+000 vertex 3.031429e+000 1.721100e+001 2.000025e+000 endloop endfacet facet normal 4.488580e-001 -8.936031e-001 0.000000e+000 outer loop vertex 3.307894e+000 1.733992e+001 2.500000e-005 vertex 3.031429e+000 1.721100e+001 2.000025e+000 vertex 3.031429e+000 1.721100e+001 2.500000e-005 endloop endfacet facet normal 5.494540e-001 -8.355240e-001 0.000000e+000 outer loop vertex 3.031429e+000 1.721100e+001 2.500000e-005 vertex 3.031429e+000 1.721100e+001 2.000025e+000 vertex 2.781551e+000 1.703604e+001 2.000025e+000 endloop endfacet facet normal 5.972114e-001 -8.020838e-001 0.000000e+000 outer loop vertex 3.031429e+000 1.721100e+001 2.500000e-005 vertex 2.781551e+000 1.703604e+001 2.000025e+000 vertex 2.781551e+000 1.703604e+001 2.500000e-005 endloop endfacet facet normal 6.861938e-001 -7.274188e-001 0.000000e+000 outer loop vertex 2.781551e+000 1.703604e+001 2.500000e-005 vertex 2.781551e+000 1.703604e+001 2.000025e+000 vertex 2.565852e+000 1.682034e+001 2.000025e+000 endloop endfacet facet normal 7.274188e-001 -6.861938e-001 0.000000e+000 outer loop vertex 2.781551e+000 1.703604e+001 2.500000e-005 vertex 2.565852e+000 1.682034e+001 2.000025e+000 vertex 2.565852e+000 1.682034e+001 2.500000e-005 endloop endfacet facet normal 8.020838e-001 -5.972114e-001 0.000000e+000 outer loop vertex 2.565852e+000 1.682034e+001 2.500000e-005 vertex 2.565852e+000 1.682034e+001 2.000025e+000 vertex 2.390885e+000 1.657046e+001 2.000025e+000 endloop endfacet facet normal 8.355240e-001 -5.494540e-001 0.000000e+000 outer loop vertex 2.565852e+000 1.682034e+001 2.500000e-005 vertex 2.390885e+000 1.657046e+001 2.000025e+000 vertex 2.390885e+000 1.657046e+001 2.500000e-005 endloop endfacet facet normal 8.936031e-001 -4.488580e-001 0.000000e+000 outer loop vertex 2.390885e+000 1.657046e+001 2.500000e-005 vertex 2.390885e+000 1.657046e+001 2.000025e+000 vertex 2.261967e+000 1.629399e+001 2.000025e+000 endloop endfacet facet normal 9.182422e-001 -3.960194e-001 0.000000e+000 outer loop vertex 2.390885e+000 1.657046e+001 2.500000e-005 vertex 2.261967e+000 1.629399e+001 2.000025e+000 vertex 2.261967e+000 1.629399e+001 2.500000e-005 endloop endfacet facet normal 9.579706e-001 -2.868663e-001 0.000000e+000 outer loop vertex 2.261967e+000 1.629399e+001 2.500000e-005 vertex 2.261967e+000 1.629399e+001 2.000025e+000 vertex 2.183016e+000 1.599934e+001 2.000025e+000 endloop endfacet facet normal 9.730601e-001 -2.305518e-001 0.000000e+000 outer loop vertex 2.261967e+000 1.629399e+001 2.500000e-005 vertex 2.183016e+000 1.599934e+001 2.000025e+000 vertex 2.183016e+000 1.599934e+001 2.500000e-005 endloop endfacet facet normal 9.932307e-001 -1.161583e-001 0.000000e+000 outer loop vertex 2.183016e+000 1.599934e+001 2.500000e-005 vertex 2.183016e+000 1.599934e+001 2.000025e+000 vertex 2.156430e+000 1.569546e+001 2.000025e+000 endloop endfacet facet normal 9.983119e-001 -5.807913e-002 0.000000e+000 outer loop vertex 2.183016e+000 1.599934e+001 2.500000e-005 vertex 2.156430e+000 1.569546e+001 2.000025e+000 vertex 2.156430e+000 1.569546e+001 2.500000e-005 endloop endfacet facet normal 9.983119e-001 5.807913e-002 0.000000e+000 outer loop vertex 2.156430e+000 1.569546e+001 2.500000e-005 vertex 2.156430e+000 1.569546e+001 2.000025e+000 vertex 2.183016e+000 1.539157e+001 2.000025e+000 endloop endfacet facet normal 9.932307e-001 1.161583e-001 0.000000e+000 outer loop vertex 2.156430e+000 1.569546e+001 2.500000e-005 vertex 2.183016e+000 1.539157e+001 2.000025e+000 vertex 2.183016e+000 1.539157e+001 2.500000e-005 endloop endfacet facet normal 9.730601e-001 2.305518e-001 0.000000e+000 outer loop vertex 2.183016e+000 1.539157e+001 2.500000e-005 vertex 2.183016e+000 1.539157e+001 2.000025e+000 vertex 2.261967e+000 1.509692e+001 2.000025e+000 endloop endfacet facet normal 9.579706e-001 2.868663e-001 0.000000e+000 outer loop vertex 2.183016e+000 1.539157e+001 2.500000e-005 vertex 2.261967e+000 1.509692e+001 2.000025e+000 vertex 2.261967e+000 1.509692e+001 2.500000e-005 endloop endfacet facet normal 9.182422e-001 3.960194e-001 0.000000e+000 outer loop vertex 2.261967e+000 1.509692e+001 2.500000e-005 vertex 2.261967e+000 1.509692e+001 2.000025e+000 vertex 2.390885e+000 1.482046e+001 2.000025e+000 endloop endfacet facet normal 8.936031e-001 4.488580e-001 0.000000e+000 outer loop vertex 2.261967e+000 1.509692e+001 2.500000e-005 vertex 2.390885e+000 1.482046e+001 2.000025e+000 vertex 2.390885e+000 1.482046e+001 2.500000e-005 endloop endfacet facet normal 8.355240e-001 5.494540e-001 0.000000e+000 outer loop vertex 2.390885e+000 1.482046e+001 2.500000e-005 vertex 2.390885e+000 1.482046e+001 2.000025e+000 vertex 2.565852e+000 1.457058e+001 2.000025e+000 endloop endfacet facet normal 8.020838e-001 5.972114e-001 0.000000e+000 outer loop vertex 2.390885e+000 1.482046e+001 2.500000e-005 vertex 2.565852e+000 1.457058e+001 2.000025e+000 vertex 2.565852e+000 1.457058e+001 2.500000e-005 endloop endfacet facet normal 7.274188e-001 6.861938e-001 0.000000e+000 outer loop vertex 2.565852e+000 1.457058e+001 2.500000e-005 vertex 2.565852e+000 1.457058e+001 2.000025e+000 vertex 2.781551e+000 1.435488e+001 2.000025e+000 endloop endfacet facet normal 6.861938e-001 7.274188e-001 0.000000e+000 outer loop vertex 2.565852e+000 1.457058e+001 2.500000e-005 vertex 2.781551e+000 1.435488e+001 2.000025e+000 vertex 2.781551e+000 1.435488e+001 2.500000e-005 endloop endfacet facet normal 5.972114e-001 8.020838e-001 0.000000e+000 outer loop vertex 2.781551e+000 1.435488e+001 2.500000e-005 vertex 2.781551e+000 1.435488e+001 2.000025e+000 vertex 3.031429e+000 1.417991e+001 2.000025e+000 endloop endfacet facet normal 5.494540e-001 8.355240e-001 0.000000e+000 outer loop vertex 2.781551e+000 1.435488e+001 2.500000e-005 vertex 3.031429e+000 1.417991e+001 2.000025e+000 vertex 3.031429e+000 1.417991e+001 2.500000e-005 endloop endfacet facet normal 4.488580e-001 8.936031e-001 0.000000e+000 outer loop vertex 3.031429e+000 1.417991e+001 2.500000e-005 vertex 3.031429e+000 1.417991e+001 2.000025e+000 vertex 3.307894e+000 1.405100e+001 2.000025e+000 endloop endfacet facet normal 3.960194e-001 9.182422e-001 0.000000e+000 outer loop vertex 3.031429e+000 1.417991e+001 2.500000e-005 vertex 3.307894e+000 1.405100e+001 2.000025e+000 vertex 3.307894e+000 1.405100e+001 2.500000e-005 endloop endfacet facet normal 2.868663e-001 9.579706e-001 0.000000e+000 outer loop vertex 3.307894e+000 1.405100e+001 2.500000e-005 vertex 3.307894e+000 1.405100e+001 2.000025e+000 vertex 3.602545e+000 1.397204e+001 2.000025e+000 endloop endfacet facet normal 2.305518e-001 9.730601e-001 0.000000e+000 outer loop vertex 3.307894e+000 1.405100e+001 2.500000e-005 vertex 3.602545e+000 1.397204e+001 2.000025e+000 vertex 3.602545e+000 1.397204e+001 2.500000e-005 endloop endfacet facet normal 1.161583e-001 9.932307e-001 0.000000e+000 outer loop vertex 3.602545e+000 1.397204e+001 2.500000e-005 vertex 3.602545e+000 1.397204e+001 2.000025e+000 vertex 3.906429e+000 1.394546e+001 2.000025e+000 endloop endfacet facet normal 5.807913e-002 9.983119e-001 0.000000e+000 outer loop vertex 3.602545e+000 1.397204e+001 2.500000e-005 vertex 3.906429e+000 1.394546e+001 2.000025e+000 vertex 3.906429e+000 1.394546e+001 2.500000e-005 endloop endfacet facet normal -5.807913e-002 9.983119e-001 0.000000e+000 outer loop vertex 3.906429e+000 1.394546e+001 2.500000e-005 vertex 3.906429e+000 1.394546e+001 2.000025e+000 vertex 4.210314e+000 1.397204e+001 2.000025e+000 endloop endfacet facet normal -1.161583e-001 9.932307e-001 0.000000e+000 outer loop vertex 3.906429e+000 1.394546e+001 2.500000e-005 vertex 4.210314e+000 1.397204e+001 2.000025e+000 vertex 4.210314e+000 1.397204e+001 2.500000e-005 endloop endfacet facet normal -2.305518e-001 9.730601e-001 0.000000e+000 outer loop vertex 4.210314e+000 1.397204e+001 2.500000e-005 vertex 4.210314e+000 1.397204e+001 2.000025e+000 vertex 4.504965e+000 1.405100e+001 2.000025e+000 endloop endfacet facet normal -2.868663e-001 9.579706e-001 0.000000e+000 outer loop vertex 4.210314e+000 1.397204e+001 2.500000e-005 vertex 4.504965e+000 1.405100e+001 2.000025e+000 vertex 4.504965e+000 1.405100e+001 2.500000e-005 endloop endfacet facet normal -3.960194e-001 9.182422e-001 0.000000e+000 outer loop vertex 4.504965e+000 1.405100e+001 2.500000e-005 vertex 4.504965e+000 1.405100e+001 2.000025e+000 vertex 4.781430e+000 1.417991e+001 2.000025e+000 endloop endfacet facet normal -4.488580e-001 8.936031e-001 0.000000e+000 outer loop vertex 4.504965e+000 1.405100e+001 2.500000e-005 vertex 4.781430e+000 1.417991e+001 2.000025e+000 vertex 4.781430e+000 1.417991e+001 2.500000e-005 endloop endfacet facet normal -5.494540e-001 8.355240e-001 0.000000e+000 outer loop vertex 4.781430e+000 1.417991e+001 2.500000e-005 vertex 4.781430e+000 1.417991e+001 2.000025e+000 vertex 5.031308e+000 1.435488e+001 2.000025e+000 endloop endfacet facet normal -5.972114e-001 8.020838e-001 0.000000e+000 outer loop vertex 4.781430e+000 1.417991e+001 2.500000e-005 vertex 5.031308e+000 1.435488e+001 2.000025e+000 vertex 5.031308e+000 1.435488e+001 2.500000e-005 endloop endfacet facet normal -6.861938e-001 7.274188e-001 0.000000e+000 outer loop vertex 5.031308e+000 1.435488e+001 2.500000e-005 vertex 5.031308e+000 1.435488e+001 2.000025e+000 vertex 5.247007e+000 1.457058e+001 2.000025e+000 endloop endfacet facet normal -7.274188e-001 6.861938e-001 0.000000e+000 outer loop vertex 5.031308e+000 1.435488e+001 2.500000e-005 vertex 5.247007e+000 1.457058e+001 2.000025e+000 vertex 5.247007e+000 1.457058e+001 2.500000e-005 endloop endfacet facet normal -8.020838e-001 5.972114e-001 0.000000e+000 outer loop vertex 5.247007e+000 1.457058e+001 2.500000e-005 vertex 5.247007e+000 1.457058e+001 2.000025e+000 vertex 5.421974e+000 1.482046e+001 2.000025e+000 endloop endfacet facet normal -8.355240e-001 5.494540e-001 0.000000e+000 outer loop vertex 5.247007e+000 1.457058e+001 2.500000e-005 vertex 5.421974e+000 1.482046e+001 2.000025e+000 vertex 5.421974e+000 1.482046e+001 2.500000e-005 endloop endfacet facet normal -8.936031e-001 4.488580e-001 0.000000e+000 outer loop vertex 5.421974e+000 1.482046e+001 2.500000e-005 vertex 5.421974e+000 1.482046e+001 2.000025e+000 vertex 5.550891e+000 1.509692e+001 2.000025e+000 endloop endfacet facet normal -9.182422e-001 3.960194e-001 0.000000e+000 outer loop vertex 5.421974e+000 1.482046e+001 2.500000e-005 vertex 5.550891e+000 1.509692e+001 2.000025e+000 vertex 5.550891e+000 1.509692e+001 2.500000e-005 endloop endfacet facet normal -9.579706e-001 2.868663e-001 0.000000e+000 outer loop vertex 5.550891e+000 1.509692e+001 2.500000e-005 vertex 5.550891e+000 1.509692e+001 2.000025e+000 vertex 5.629843e+000 1.539157e+001 2.000025e+000 endloop endfacet facet normal -9.730601e-001 2.305518e-001 0.000000e+000 outer loop vertex 5.550891e+000 1.509692e+001 2.500000e-005 vertex 5.629843e+000 1.539157e+001 2.000025e+000 vertex 5.629843e+000 1.539157e+001 2.500000e-005 endloop endfacet facet normal -9.932307e-001 1.161583e-001 0.000000e+000 outer loop vertex 5.629843e+000 1.539157e+001 2.500000e-005 vertex 5.629843e+000 1.539157e+001 2.000025e+000 vertex 5.656430e+000 1.569546e+001 2.000025e+000 endloop endfacet facet normal -9.983119e-001 5.807913e-002 0.000000e+000 outer loop vertex 6.122247e+000 9.643323e+000 2.500000e-005 vertex 6.156430e+000 1.003403e+001 2.000025e+000 vertex 6.156430e+000 1.003403e+001 2.500000e-005 endloop endfacet facet normal -9.983119e-001 -5.807913e-002 0.000000e+000 outer loop vertex 6.156430e+000 1.003403e+001 2.500000e-005 vertex 6.156430e+000 1.003403e+001 2.000025e+000 vertex 6.122247e+000 1.042474e+001 2.000025e+000 endloop endfacet facet normal -9.932307e-001 -1.161583e-001 0.000000e+000 outer loop vertex 6.156430e+000 1.003403e+001 2.500000e-005 vertex 6.122247e+000 1.042474e+001 2.000025e+000 vertex 6.122247e+000 1.042474e+001 2.500000e-005 endloop endfacet facet normal -9.730601e-001 -2.305518e-001 0.000000e+000 outer loop vertex 6.122247e+000 1.042474e+001 2.500000e-005 vertex 6.122247e+000 1.042474e+001 2.000025e+000 vertex 6.020738e+000 1.080358e+001 2.000025e+000 endloop endfacet facet normal -9.579706e-001 -2.868663e-001 0.000000e+000 outer loop vertex 6.122247e+000 1.042474e+001 2.500000e-005 vertex 6.020738e+000 1.080358e+001 2.000025e+000 vertex 6.020738e+000 1.080358e+001 2.500000e-005 endloop endfacet facet normal -9.182422e-001 -3.960194e-001 0.000000e+000 outer loop vertex 6.020738e+000 1.080358e+001 2.500000e-005 vertex 6.020738e+000 1.080358e+001 2.000025e+000 vertex 5.854987e+000 1.115903e+001 2.000025e+000 endloop endfacet facet normal -8.936031e-001 -4.488580e-001 0.000000e+000 outer loop vertex 6.020738e+000 1.080358e+001 2.500000e-005 vertex 5.854987e+000 1.115903e+001 2.000025e+000 vertex 5.854987e+000 1.115903e+001 2.500000e-005 endloop endfacet facet normal -8.355240e-001 -5.494540e-001 0.000000e+000 outer loop vertex 5.854987e+000 1.115903e+001 2.500000e-005 vertex 5.854987e+000 1.115903e+001 2.000025e+000 vertex 5.630029e+000 1.148030e+001 2.000025e+000 endloop endfacet facet normal -8.020838e-001 -5.972114e-001 0.000000e+000 outer loop vertex 5.854987e+000 1.115903e+001 2.500000e-005 vertex 5.630029e+000 1.148030e+001 2.000025e+000 vertex 5.630029e+000 1.148030e+001 2.500000e-005 endloop endfacet facet normal -7.274188e-001 -6.861938e-001 0.000000e+000 outer loop vertex 5.630029e+000 1.148030e+001 2.500000e-005 vertex 5.630029e+000 1.148030e+001 2.000025e+000 vertex 5.352702e+000 1.175763e+001 2.000025e+000 endloop endfacet facet normal -6.861938e-001 -7.274188e-001 0.000000e+000 outer loop vertex 5.630029e+000 1.148030e+001 2.500000e-005 vertex 5.352702e+000 1.175763e+001 2.000025e+000 vertex 5.352702e+000 1.175763e+001 2.500000e-005 endloop endfacet facet normal -5.972114e-001 -8.020838e-001 0.000000e+000 outer loop vertex 5.352702e+000 1.175763e+001 2.500000e-005 vertex 5.352702e+000 1.175763e+001 2.000025e+000 vertex 5.031430e+000 1.198259e+001 2.000025e+000 endloop endfacet facet normal -5.494540e-001 -8.355240e-001 0.000000e+000 outer loop vertex 5.352702e+000 1.175763e+001 2.500000e-005 vertex 5.031430e+000 1.198259e+001 2.000025e+000 vertex 5.031430e+000 1.198259e+001 2.500000e-005 endloop endfacet facet normal -4.488580e-001 -8.936031e-001 0.000000e+000 outer loop vertex 5.031430e+000 1.198259e+001 2.500000e-005 vertex 5.031430e+000 1.198259e+001 2.000025e+000 vertex 4.675974e+000 1.214834e+001 2.000025e+000 endloop endfacet facet normal -3.960194e-001 -9.182422e-001 0.000000e+000 outer loop vertex 5.031430e+000 1.198259e+001 2.500000e-005 vertex 4.675974e+000 1.214834e+001 2.000025e+000 vertex 4.675974e+000 1.214834e+001 2.500000e-005 endloop endfacet facet normal -2.868663e-001 -9.579706e-001 0.000000e+000 outer loop vertex 4.675974e+000 1.214834e+001 2.500000e-005 vertex 4.675974e+000 1.214834e+001 2.000025e+000 vertex 4.297138e+000 1.224985e+001 2.000025e+000 endloop endfacet facet normal -2.305518e-001 -9.730601e-001 0.000000e+000 outer loop vertex 4.675974e+000 1.214834e+001 2.500000e-005 vertex 4.297138e+000 1.224985e+001 2.000025e+000 vertex 4.297138e+000 1.224985e+001 2.500000e-005 endloop endfacet facet normal -1.161583e-001 -9.932307e-001 0.000000e+000 outer loop vertex 4.297138e+000 1.224985e+001 2.500000e-005 vertex 4.297138e+000 1.224985e+001 2.000025e+000 vertex 3.906429e+000 1.228403e+001 2.000025e+000 endloop endfacet facet normal -5.807913e-002 -9.983119e-001 0.000000e+000 outer loop vertex 4.297138e+000 1.224985e+001 2.500000e-005 vertex 3.906429e+000 1.228403e+001 2.000025e+000 vertex 3.906429e+000 1.228403e+001 2.500000e-005 endloop endfacet facet normal 5.807913e-002 -9.983119e-001 0.000000e+000 outer loop vertex 3.906429e+000 1.228403e+001 2.500000e-005 vertex 3.906429e+000 1.228403e+001 2.000025e+000 vertex 3.515721e+000 1.224985e+001 2.000025e+000 endloop endfacet facet normal 1.161583e-001 -9.932307e-001 0.000000e+000 outer loop vertex 3.906429e+000 1.228403e+001 2.500000e-005 vertex 3.515721e+000 1.224985e+001 2.000025e+000 vertex 3.515721e+000 1.224985e+001 2.500000e-005 endloop endfacet facet normal 2.305518e-001 -9.730601e-001 0.000000e+000 outer loop vertex 3.515721e+000 1.224985e+001 2.500000e-005 vertex 3.515721e+000 1.224985e+001 2.000025e+000 vertex 3.136884e+000 1.214834e+001 2.000025e+000 endloop endfacet facet normal 2.868663e-001 -9.579706e-001 0.000000e+000 outer loop vertex 3.515721e+000 1.224985e+001 2.500000e-005 vertex 3.136884e+000 1.214834e+001 2.000025e+000 vertex 3.136884e+000 1.214834e+001 2.500000e-005 endloop endfacet facet normal 3.960194e-001 -9.182422e-001 0.000000e+000 outer loop vertex 3.136884e+000 1.214834e+001 2.500000e-005 vertex 3.136884e+000 1.214834e+001 2.000025e+000 vertex 2.781430e+000 1.198259e+001 2.000025e+000 endloop endfacet facet normal 4.488580e-001 -8.936031e-001 0.000000e+000 outer loop vertex 3.136884e+000 1.214834e+001 2.500000e-005 vertex 2.781430e+000 1.198259e+001 2.000025e+000 vertex 2.781430e+000 1.198259e+001 2.500000e-005 endloop endfacet facet normal 5.494540e-001 -8.355240e-001 0.000000e+000 outer loop vertex 2.781430e+000 1.198259e+001 2.500000e-005 vertex 2.781430e+000 1.198259e+001 2.000025e+000 vertex 2.460157e+000 1.175763e+001 2.000025e+000 endloop endfacet facet normal 5.972114e-001 -8.020838e-001 0.000000e+000 outer loop vertex 2.781430e+000 1.198259e+001 2.500000e-005 vertex 2.460157e+000 1.175763e+001 2.000025e+000 vertex 2.460157e+000 1.175763e+001 2.500000e-005 endloop endfacet facet normal 6.861938e-001 -7.274188e-001 0.000000e+000 outer loop vertex 2.460157e+000 1.175763e+001 2.500000e-005 vertex 2.460157e+000 1.175763e+001 2.000025e+000 vertex 2.182829e+000 1.148030e+001 2.000025e+000 endloop endfacet facet normal 7.274188e-001 -6.861938e-001 0.000000e+000 outer loop vertex 2.460157e+000 1.175763e+001 2.500000e-005 vertex 2.182829e+000 1.148030e+001 2.000025e+000 vertex 2.182829e+000 1.148030e+001 2.500000e-005 endloop endfacet facet normal 8.020838e-001 -5.972114e-001 0.000000e+000 outer loop vertex 2.182829e+000 1.148030e+001 2.500000e-005 vertex 2.182829e+000 1.148030e+001 2.000025e+000 vertex 1.957872e+000 1.115903e+001 2.000025e+000 endloop endfacet facet normal 8.355240e-001 -5.494540e-001 0.000000e+000 outer loop vertex 2.182829e+000 1.148030e+001 2.500000e-005 vertex 1.957872e+000 1.115903e+001 2.000025e+000 vertex 1.957872e+000 1.115903e+001 2.500000e-005 endloop endfacet facet normal 8.936031e-001 -4.488580e-001 0.000000e+000 outer loop vertex 1.957872e+000 1.115903e+001 2.500000e-005 vertex 1.957872e+000 1.115903e+001 2.000025e+000 vertex 1.792121e+000 1.080358e+001 2.000025e+000 endloop endfacet facet normal 9.182422e-001 -3.960194e-001 0.000000e+000 outer loop vertex 1.957872e+000 1.115903e+001 2.500000e-005 vertex 1.792121e+000 1.080358e+001 2.000025e+000 vertex 1.792121e+000 1.080358e+001 2.500000e-005 endloop endfacet facet normal 9.579706e-001 -2.868663e-001 0.000000e+000 outer loop vertex 1.792121e+000 1.080358e+001 2.500000e-005 vertex 1.792121e+000 1.080358e+001 2.000025e+000 vertex 1.690612e+000 1.042474e+001 2.000025e+000 endloop endfacet facet normal 9.730601e-001 -2.305518e-001 0.000000e+000 outer loop vertex 1.792121e+000 1.080358e+001 2.500000e-005 vertex 1.690612e+000 1.042474e+001 2.000025e+000 vertex 1.690612e+000 1.042474e+001 2.500000e-005 endloop endfacet facet normal 9.932307e-001 -1.161583e-001 0.000000e+000 outer loop vertex 1.690612e+000 1.042474e+001 2.500000e-005 vertex 1.690612e+000 1.042474e+001 2.000025e+000 vertex 1.656430e+000 1.003403e+001 2.000025e+000 endloop endfacet facet normal 9.983119e-001 -5.807913e-002 0.000000e+000 outer loop vertex 1.690612e+000 1.042474e+001 2.500000e-005 vertex 1.656430e+000 1.003403e+001 2.000025e+000 vertex 1.656430e+000 1.003403e+001 2.500000e-005 endloop endfacet facet normal 9.983119e-001 5.807913e-002 0.000000e+000 outer loop vertex 1.656430e+000 1.003403e+001 2.500000e-005 vertex 1.656430e+000 1.003403e+001 2.000025e+000 vertex 1.690612e+000 9.643323e+000 2.000025e+000 endloop endfacet facet normal 9.932307e-001 1.161583e-001 0.000000e+000 outer loop vertex 1.656430e+000 1.003403e+001 2.500000e-005 vertex 1.690612e+000 9.643323e+000 2.000025e+000 vertex 1.690612e+000 9.643323e+000 2.500000e-005 endloop endfacet facet normal 9.730601e-001 2.305518e-001 0.000000e+000 outer loop vertex 1.690612e+000 9.643323e+000 2.500000e-005 vertex 1.690612e+000 9.643323e+000 2.000025e+000 vertex 1.792121e+000 9.264486e+000 2.000025e+000 endloop endfacet facet normal 9.579706e-001 2.868663e-001 0.000000e+000 outer loop vertex 1.690612e+000 9.643323e+000 2.500000e-005 vertex 1.792121e+000 9.264486e+000 2.000025e+000 vertex 1.792121e+000 9.264486e+000 2.500000e-005 endloop endfacet facet normal 9.182422e-001 3.960194e-001 0.000000e+000 outer loop vertex 1.792121e+000 9.264486e+000 2.500000e-005 vertex 1.792121e+000 9.264486e+000 2.000025e+000 vertex 1.957872e+000 8.909031e+000 2.000025e+000 endloop endfacet facet normal 8.936031e-001 4.488580e-001 0.000000e+000 outer loop vertex 1.792121e+000 9.264486e+000 2.500000e-005 vertex 1.957872e+000 8.909031e+000 2.000025e+000 vertex 1.957872e+000 8.909031e+000 2.500000e-005 endloop endfacet facet normal 8.355240e-001 5.494540e-001 0.000000e+000 outer loop vertex 1.957872e+000 8.909031e+000 2.500000e-005 vertex 1.957872e+000 8.909031e+000 2.000025e+000 vertex 2.182829e+000 8.587759e+000 2.000025e+000 endloop endfacet facet normal 8.020838e-001 5.972114e-001 0.000000e+000 outer loop vertex 1.957872e+000 8.909031e+000 2.500000e-005 vertex 2.182829e+000 8.587759e+000 2.000025e+000 vertex 2.182829e+000 8.587759e+000 2.500000e-005 endloop endfacet facet normal 7.274188e-001 6.861938e-001 0.000000e+000 outer loop vertex 2.182829e+000 8.587759e+000 2.500000e-005 vertex 2.182829e+000 8.587759e+000 2.000025e+000 vertex 2.460157e+000 8.310431e+000 2.000025e+000 endloop endfacet facet normal 6.861938e-001 7.274188e-001 0.000000e+000 outer loop vertex 2.182829e+000 8.587759e+000 2.500000e-005 vertex 2.460157e+000 8.310431e+000 2.000025e+000 vertex 2.460157e+000 8.310431e+000 2.500000e-005 endloop endfacet facet normal 5.972114e-001 8.020838e-001 0.000000e+000 outer loop vertex 2.460157e+000 8.310431e+000 2.500000e-005 vertex 2.460157e+000 8.310431e+000 2.000025e+000 vertex 2.781430e+000 8.085474e+000 2.000025e+000 endloop endfacet facet normal 5.494540e-001 8.355240e-001 0.000000e+000 outer loop vertex 2.460157e+000 8.310431e+000 2.500000e-005 vertex 2.781430e+000 8.085474e+000 2.000025e+000 vertex 2.781430e+000 8.085474e+000 2.500000e-005 endloop endfacet facet normal 4.488580e-001 8.936031e-001 0.000000e+000 outer loop vertex 2.781430e+000 8.085474e+000 2.500000e-005 vertex 2.781430e+000 8.085474e+000 2.000025e+000 vertex 3.136884e+000 7.919722e+000 2.000025e+000 endloop endfacet facet normal 3.960194e-001 9.182422e-001 0.000000e+000 outer loop vertex 2.781430e+000 8.085474e+000 2.500000e-005 vertex 3.136884e+000 7.919722e+000 2.000025e+000 vertex 3.136884e+000 7.919722e+000 2.500000e-005 endloop endfacet facet normal 2.868663e-001 9.579706e-001 0.000000e+000 outer loop vertex 3.136884e+000 7.919722e+000 2.500000e-005 vertex 3.136884e+000 7.919722e+000 2.000025e+000 vertex 3.515721e+000 7.818213e+000 2.000025e+000 endloop endfacet facet normal 2.305518e-001 9.730601e-001 0.000000e+000 outer loop vertex 3.136884e+000 7.919722e+000 2.500000e-005 vertex 3.515721e+000 7.818213e+000 2.000025e+000 vertex 3.515721e+000 7.818213e+000 2.500000e-005 endloop endfacet facet normal 1.161583e-001 9.932307e-001 0.000000e+000 outer loop vertex 3.515721e+000 7.818213e+000 2.500000e-005 vertex 3.515721e+000 7.818213e+000 2.000025e+000 vertex 3.906429e+000 7.784031e+000 2.000025e+000 endloop endfacet facet normal 5.807913e-002 9.983119e-001 0.000000e+000 outer loop vertex 3.515721e+000 7.818213e+000 2.500000e-005 vertex 3.906429e+000 7.784031e+000 2.000025e+000 vertex 3.906429e+000 7.784031e+000 2.500000e-005 endloop endfacet facet normal -5.807913e-002 9.983119e-001 0.000000e+000 outer loop vertex 3.906429e+000 7.784031e+000 2.500000e-005 vertex 3.906429e+000 7.784031e+000 2.000025e+000 vertex 4.297138e+000 7.818213e+000 2.000025e+000 endloop endfacet facet normal -1.161583e-001 9.932307e-001 0.000000e+000 outer loop vertex 3.906429e+000 7.784031e+000 2.500000e-005 vertex 4.297138e+000 7.818213e+000 2.000025e+000 vertex 4.297138e+000 7.818213e+000 2.500000e-005 endloop endfacet facet normal -2.305518e-001 9.730601e-001 0.000000e+000 outer loop vertex 4.297138e+000 7.818213e+000 2.500000e-005 vertex 4.297138e+000 7.818213e+000 2.000025e+000 vertex 4.675974e+000 7.919722e+000 2.000025e+000 endloop endfacet facet normal -2.868663e-001 9.579706e-001 0.000000e+000 outer loop vertex 4.297138e+000 7.818213e+000 2.500000e-005 vertex 4.675974e+000 7.919722e+000 2.000025e+000 vertex 4.675974e+000 7.919722e+000 2.500000e-005 endloop endfacet facet normal -3.960194e-001 9.182422e-001 0.000000e+000 outer loop vertex 4.675974e+000 7.919722e+000 2.500000e-005 vertex 4.675974e+000 7.919722e+000 2.000025e+000 vertex 5.031430e+000 8.085474e+000 2.000025e+000 endloop endfacet facet normal -4.488580e-001 8.936031e-001 0.000000e+000 outer loop vertex 4.675974e+000 7.919722e+000 2.500000e-005 vertex 5.031430e+000 8.085474e+000 2.000025e+000 vertex 5.031430e+000 8.085474e+000 2.500000e-005 endloop endfacet facet normal -5.494540e-001 8.355240e-001 0.000000e+000 outer loop vertex 5.031430e+000 8.085474e+000 2.500000e-005 vertex 5.031430e+000 8.085474e+000 2.000025e+000 vertex 5.352702e+000 8.310431e+000 2.000025e+000 endloop endfacet facet normal -5.972114e-001 8.020838e-001 0.000000e+000 outer loop vertex 5.031430e+000 8.085474e+000 2.500000e-005 vertex 5.352702e+000 8.310431e+000 2.000025e+000 vertex 5.352702e+000 8.310431e+000 2.500000e-005 endloop endfacet facet normal -6.861938e-001 7.274188e-001 0.000000e+000 outer loop vertex 5.352702e+000 8.310431e+000 2.500000e-005 vertex 5.352702e+000 8.310431e+000 2.000025e+000 vertex 5.630029e+000 8.587759e+000 2.000025e+000 endloop endfacet facet normal -7.274188e-001 6.861938e-001 0.000000e+000 outer loop vertex 5.352702e+000 8.310431e+000 2.500000e-005 vertex 5.630029e+000 8.587759e+000 2.000025e+000 vertex 5.630029e+000 8.587759e+000 2.500000e-005 endloop endfacet facet normal -8.020838e-001 5.972114e-001 0.000000e+000 outer loop vertex 5.630029e+000 8.587759e+000 2.500000e-005 vertex 5.630029e+000 8.587759e+000 2.000025e+000 vertex 5.854987e+000 8.909031e+000 2.000025e+000 endloop endfacet facet normal -8.355240e-001 5.494540e-001 0.000000e+000 outer loop vertex 5.630029e+000 8.587759e+000 2.500000e-005 vertex 5.854987e+000 8.909031e+000 2.000025e+000 vertex 5.854987e+000 8.909031e+000 2.500000e-005 endloop endfacet facet normal -8.936031e-001 4.488580e-001 0.000000e+000 outer loop vertex 5.854987e+000 8.909031e+000 2.500000e-005 vertex 5.854987e+000 8.909031e+000 2.000025e+000 vertex 6.020738e+000 9.264486e+000 2.000025e+000 endloop endfacet facet normal -9.182422e-001 3.960194e-001 0.000000e+000 outer loop vertex 5.854987e+000 8.909031e+000 2.500000e-005 vertex 6.020738e+000 9.264486e+000 2.000025e+000 vertex 6.020738e+000 9.264486e+000 2.500000e-005 endloop endfacet facet normal -9.579706e-001 2.868663e-001 0.000000e+000 outer loop vertex 6.020738e+000 9.264486e+000 2.500000e-005 vertex 6.020738e+000 9.264486e+000 2.000025e+000 vertex 6.122247e+000 9.643323e+000 2.000025e+000 endloop endfacet facet normal -9.730601e-001 2.305518e-001 0.000000e+000 outer loop vertex 6.020738e+000 9.264486e+000 2.500000e-005 vertex 6.122247e+000 9.643323e+000 2.000025e+000 vertex 6.122247e+000 9.643323e+000 2.500000e-005 endloop endfacet facet normal -9.932307e-001 1.161583e-001 0.000000e+000 outer loop vertex 6.122247e+000 9.643323e+000 2.500000e-005 vertex 6.122247e+000 9.643323e+000 2.000025e+000 vertex 6.156430e+000 1.003403e+001 2.000025e+000 endloop endfacet facet normal 5.000000e-001 8.660254e-001 0.000000e+000 outer loop vertex 5.322232e+001 3.254457e+000 2.000025e+000 vertex 5.322232e+001 3.254457e+000 2.500000e-005 vertex 4.997232e+001 5.130845e+000 2.000025e+000 endloop endfacet facet normal 5.000000e-001 8.660254e-001 0.000000e+000 outer loop vertex 4.997232e+001 5.130845e+000 2.000025e+000 vertex 5.322232e+001 3.254457e+000 2.500000e-005 vertex 4.997232e+001 5.130845e+000 2.500000e-005 endloop endfacet facet normal 1.000000e+000 1.849003e-015 0.000000e+000 outer loop vertex 4.997232e+001 5.130845e+000 2.000025e+000 vertex 4.997232e+001 5.130845e+000 2.500000e-005 vertex 4.997232e+001 8.883622e+000 2.000025e+000 endloop endfacet facet normal 1.000000e+000 1.849003e-015 0.000000e+000 outer loop vertex 4.997232e+001 8.883622e+000 2.000025e+000 vertex 4.997232e+001 5.130845e+000 2.500000e-005 vertex 4.997232e+001 8.883622e+000 2.500000e-005 endloop endfacet facet normal 5.000000e-001 -8.660254e-001 0.000000e+000 outer loop vertex 4.997232e+001 8.883622e+000 2.000025e+000 vertex 4.997232e+001 8.883622e+000 2.500000e-005 vertex 5.322232e+001 1.076001e+001 2.000025e+000 endloop endfacet facet normal 5.000000e-001 -8.660254e-001 0.000000e+000 outer loop vertex 5.322232e+001 1.076001e+001 2.000025e+000 vertex 4.997232e+001 8.883622e+000 2.500000e-005 vertex 5.322232e+001 1.076001e+001 2.500000e-005 endloop endfacet facet normal -5.000000e-001 -8.660254e-001 0.000000e+000 outer loop vertex 5.322232e+001 1.076001e+001 2.000025e+000 vertex 5.322232e+001 1.076001e+001 2.500000e-005 vertex 5.647232e+001 8.883622e+000 2.000025e+000 endloop endfacet facet normal -5.000000e-001 -8.660254e-001 0.000000e+000 outer loop vertex 5.647232e+001 8.883622e+000 2.000025e+000 vertex 5.322232e+001 1.076001e+001 2.500000e-005 vertex 5.647232e+001 8.883622e+000 2.500000e-005 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 5.647232e+001 8.883622e+000 2.000025e+000 vertex 5.647232e+001 8.883622e+000 2.500000e-005 vertex 5.647232e+001 5.130845e+000 2.000025e+000 endloop endfacet facet normal -1.000000e+000 0.000000e+000 0.000000e+000 outer loop vertex 5.647232e+001 5.130845e+000 2.000025e+000 vertex 5.647232e+001 8.883622e+000 2.500000e-005 vertex 5.647232e+001 5.130845e+000 2.500000e-005 endloop endfacet facet normal -5.000000e-001 8.660254e-001 0.000000e+000 outer loop vertex 5.647232e+001 5.130845e+000 2.000025e+000 vertex 5.647232e+001 5.130845e+000 2.500000e-005 vertex 5.322232e+001 3.254457e+000 2.000025e+000 endloop endfacet facet normal -5.000000e-001 8.660254e-001 0.000000e+000 outer loop vertex 5.322232e+001 3.254457e+000 2.000025e+000 vertex 5.647232e+001 5.130845e+000 2.500000e-005 vertex 5.322232e+001 3.254457e+000 2.500000e-005 endloop endfacet facet normal -9.983119e-001 5.807913e-002 0.000000e+000 outer loop vertex 6.082822e+000 6.037057e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 2.000025e+000 vertex 6.037245e+000 5.516113e+000 6.800025e+000 endloop endfacet facet normal -9.983119e-001 -5.807913e-002 0.000000e+000 outer loop vertex 6.037245e+000 5.516113e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 2.000025e+000 vertex 6.082822e+000 4.995169e+000 2.000025e+000 endloop endfacet facet normal -9.932307e-001 -1.161583e-001 0.000000e+000 outer loop vertex 6.037245e+000 5.516113e+000 6.800025e+000 vertex 6.082822e+000 4.995169e+000 2.000025e+000 vertex 6.082822e+000 4.995169e+000 6.800025e+000 endloop endfacet facet normal -9.730601e-001 -2.305518e-001 0.000000e+000 outer loop vertex 6.082822e+000 4.995169e+000 6.800025e+000 vertex 6.082822e+000 4.995169e+000 2.000025e+000 vertex 6.218167e+000 4.490052e+000 2.000025e+000 endloop endfacet facet normal -9.579706e-001 -2.868663e-001 0.000000e+000 outer loop vertex 6.082822e+000 4.995169e+000 6.800025e+000 vertex 6.218167e+000 4.490052e+000 2.000025e+000 vertex 6.218167e+000 4.490052e+000 6.800025e+000 endloop endfacet facet normal -9.182422e-001 -3.960194e-001 0.000000e+000 outer loop vertex 6.218167e+000 4.490052e+000 6.800025e+000 vertex 6.218167e+000 4.490052e+000 2.000025e+000 vertex 6.439169e+000 4.016113e+000 2.000025e+000 endloop endfacet facet normal -8.936031e-001 -4.488580e-001 0.000000e+000 outer loop vertex 6.218167e+000 4.490052e+000 6.800025e+000 vertex 6.439169e+000 4.016113e+000 2.000025e+000 vertex 6.439169e+000 4.016113e+000 6.800025e+000 endloop endfacet facet normal -8.355240e-001 -5.494540e-001 0.000000e+000 outer loop vertex 6.439169e+000 4.016113e+000 6.800025e+000 vertex 6.439169e+000 4.016113e+000 2.000025e+000 vertex 6.739111e+000 3.587750e+000 2.000025e+000 endloop endfacet facet normal -8.020838e-001 -5.972114e-001 0.000000e+000 outer loop vertex 6.439169e+000 4.016113e+000 6.800025e+000 vertex 6.739111e+000 3.587750e+000 2.000025e+000 vertex 6.739111e+000 3.587750e+000 6.800025e+000 endloop endfacet facet normal -7.274188e-001 -6.861938e-001 0.000000e+000 outer loop vertex 6.739111e+000 3.587750e+000 6.800025e+000 vertex 6.739111e+000 3.587750e+000 2.000025e+000 vertex 7.108882e+000 3.217980e+000 2.000025e+000 endloop endfacet facet normal -6.861938e-001 -7.274188e-001 0.000000e+000 outer loop vertex 6.739111e+000 3.587750e+000 6.800025e+000 vertex 7.108882e+000 3.217980e+000 2.000025e+000 vertex 7.108882e+000 3.217980e+000 6.800025e+000 endloop endfacet facet normal -5.972114e-001 -8.020838e-001 0.000000e+000 outer loop vertex 7.108882e+000 3.217980e+000 6.800025e+000 vertex 7.108882e+000 3.217980e+000 2.000025e+000 vertex 7.537245e+000 2.918037e+000 2.000025e+000 endloop endfacet facet normal -5.494540e-001 -8.355240e-001 0.000000e+000 outer loop vertex 7.108882e+000 3.217980e+000 6.800025e+000 vertex 7.537245e+000 2.918037e+000 2.000025e+000 vertex 7.537245e+000 2.918037e+000 6.800025e+000 endloop endfacet facet normal -4.488580e-001 -8.936031e-001 0.000000e+000 outer loop vertex 7.537245e+000 2.918037e+000 6.800025e+000 vertex 7.537245e+000 2.918037e+000 2.000025e+000 vertex 8.011185e+000 2.697035e+000 2.000025e+000 endloop endfacet facet normal -3.960194e-001 -9.182422e-001 0.000000e+000 outer loop vertex 7.537245e+000 2.918037e+000 6.800025e+000 vertex 8.011185e+000 2.697035e+000 2.000025e+000 vertex 8.011185e+000 2.697035e+000 6.800025e+000 endloop endfacet facet normal -2.868663e-001 -9.579706e-001 0.000000e+000 outer loop vertex 8.011185e+000 2.697035e+000 6.800025e+000 vertex 8.011185e+000 2.697035e+000 2.000025e+000 vertex 8.516300e+000 2.561690e+000 2.000025e+000 endloop endfacet facet normal -2.305518e-001 -9.730601e-001 0.000000e+000 outer loop vertex 8.011185e+000 2.697035e+000 6.800025e+000 vertex 8.516300e+000 2.561690e+000 2.000025e+000 vertex 8.516300e+000 2.561690e+000 6.800025e+000 endloop endfacet facet normal -1.161583e-001 -9.932307e-001 0.000000e+000 outer loop vertex 8.516300e+000 2.561690e+000 6.800025e+000 vertex 8.516300e+000 2.561690e+000 2.000025e+000 vertex 9.037245e+000 2.516113e+000 2.000025e+000 endloop endfacet facet normal -5.807913e-002 -9.983119e-001 0.000000e+000 outer loop vertex 8.516300e+000 2.561690e+000 6.800025e+000 vertex 9.037245e+000 2.516113e+000 2.000025e+000 vertex 9.037245e+000 2.516113e+000 6.800025e+000 endloop endfacet facet normal 5.807913e-002 -9.983119e-001 0.000000e+000 outer loop vertex 9.037245e+000 2.516113e+000 6.800025e+000 vertex 9.037245e+000 2.516113e+000 2.000025e+000 vertex 9.558189e+000 2.561690e+000 2.000025e+000 endloop endfacet facet normal 1.161583e-001 -9.932307e-001 0.000000e+000 outer loop vertex 9.037245e+000 2.516113e+000 6.800025e+000 vertex 9.558189e+000 2.561690e+000 2.000025e+000 vertex 9.558189e+000 2.561690e+000 6.800025e+000 endloop endfacet facet normal 2.305518e-001 -9.730601e-001 0.000000e+000 outer loop vertex 9.558189e+000 2.561690e+000 6.800025e+000 vertex 9.558189e+000 2.561690e+000 2.000025e+000 vertex 1.006331e+001 2.697035e+000 2.000025e+000 endloop endfacet facet normal 2.868663e-001 -9.579706e-001 0.000000e+000 outer loop vertex 9.558189e+000 2.561690e+000 6.800025e+000 vertex 1.006331e+001 2.697035e+000 2.000025e+000 vertex 1.006331e+001 2.697035e+000 6.800025e+000 endloop endfacet facet normal 3.960194e-001 -9.182422e-001 0.000000e+000 outer loop vertex 1.006331e+001 2.697035e+000 6.800025e+000 vertex 1.006331e+001 2.697035e+000 2.000025e+000 vertex 1.053725e+001 2.918037e+000 2.000025e+000 endloop endfacet facet normal 4.488580e-001 -8.936031e-001 0.000000e+000 outer loop vertex 1.006331e+001 2.697035e+000 6.800025e+000 vertex 1.053725e+001 2.918037e+000 2.000025e+000 vertex 1.053725e+001 2.918037e+000 6.800025e+000 endloop endfacet facet normal 5.494540e-001 -8.355240e-001 0.000000e+000 outer loop vertex 1.053725e+001 2.918037e+000 6.800025e+000 vertex 1.053725e+001 2.918037e+000 2.000025e+000 vertex 1.096561e+001 3.217980e+000 2.000025e+000 endloop endfacet facet normal 5.972114e-001 -8.020838e-001 0.000000e+000 outer loop vertex 1.053725e+001 2.918037e+000 6.800025e+000 vertex 1.096561e+001 3.217980e+000 2.000025e+000 vertex 1.096561e+001 3.217980e+000 6.800025e+000 endloop endfacet facet normal 6.861938e-001 -7.274188e-001 0.000000e+000 outer loop vertex 1.096561e+001 3.217980e+000 6.800025e+000 vertex 1.096561e+001 3.217980e+000 2.000025e+000 vertex 1.133538e+001 3.587750e+000 2.000025e+000 endloop endfacet facet normal 7.274188e-001 -6.861938e-001 0.000000e+000 outer loop vertex 1.096561e+001 3.217980e+000 6.800025e+000 vertex 1.133538e+001 3.587750e+000 2.000025e+000 vertex 1.133538e+001 3.587750e+000 6.800025e+000 endloop endfacet facet normal 8.020838e-001 -5.972114e-001 0.000000e+000 outer loop vertex 1.133538e+001 3.587750e+000 6.800025e+000 vertex 1.133538e+001 3.587750e+000 2.000025e+000 vertex 1.163532e+001 4.016113e+000 2.000025e+000 endloop endfacet facet normal 8.355240e-001 -5.494540e-001 0.000000e+000 outer loop vertex 1.133538e+001 3.587750e+000 6.800025e+000 vertex 1.163532e+001 4.016113e+000 2.000025e+000 vertex 1.163532e+001 4.016113e+000 6.800025e+000 endloop endfacet facet normal 8.936031e-001 -4.488580e-001 0.000000e+000 outer loop vertex 1.163532e+001 4.016113e+000 6.800025e+000 vertex 1.163532e+001 4.016113e+000 2.000025e+000 vertex 1.185632e+001 4.490052e+000 2.000025e+000 endloop endfacet facet normal 9.182422e-001 -3.960194e-001 0.000000e+000 outer loop vertex 1.163532e+001 4.016113e+000 6.800025e+000 vertex 1.185632e+001 4.490052e+000 2.000025e+000 vertex 1.185632e+001 4.490052e+000 6.800025e+000 endloop endfacet facet normal 9.579706e-001 -2.868663e-001 0.000000e+000 outer loop vertex 1.185632e+001 4.490052e+000 6.800025e+000 vertex 1.185632e+001 4.490052e+000 2.000025e+000 vertex 1.199167e+001 4.995169e+000 2.000025e+000 endloop endfacet facet normal 9.730601e-001 -2.305518e-001 0.000000e+000 outer loop vertex 1.185632e+001 4.490052e+000 6.800025e+000 vertex 1.199167e+001 4.995169e+000 2.000025e+000 vertex 1.199167e+001 4.995169e+000 6.800025e+000 endloop endfacet facet normal 9.932307e-001 -1.161583e-001 0.000000e+000 outer loop vertex 1.199167e+001 4.995169e+000 6.800025e+000 vertex 1.199167e+001 4.995169e+000 2.000025e+000 vertex 1.203724e+001 5.516113e+000 2.000025e+000 endloop endfacet facet normal 9.983119e-001 -5.807913e-002 0.000000e+000 outer loop vertex 1.199167e+001 4.995169e+000 6.800025e+000 vertex 1.203724e+001 5.516113e+000 2.000025e+000 vertex 1.203724e+001 5.516113e+000 6.800025e+000 endloop endfacet facet normal 9.983119e-001 5.807913e-002 0.000000e+000 outer loop vertex 1.203724e+001 5.516113e+000 6.800025e+000 vertex 1.203724e+001 5.516113e+000 2.000025e+000 vertex 1.199167e+001 6.037057e+000 2.000025e+000 endloop endfacet facet normal 9.932307e-001 1.161583e-001 0.000000e+000 outer loop vertex 1.203724e+001 5.516113e+000 6.800025e+000 vertex 1.199167e+001 6.037057e+000 2.000025e+000 vertex 1.199167e+001 6.037057e+000 6.800025e+000 endloop endfacet facet normal 9.730601e-001 2.305518e-001 0.000000e+000 outer loop vertex 1.199167e+001 6.037057e+000 6.800025e+000 vertex 1.199167e+001 6.037057e+000 2.000025e+000 vertex 1.185632e+001 6.542173e+000 2.000025e+000 endloop endfacet facet normal 9.579706e-001 2.868663e-001 0.000000e+000 outer loop vertex 1.199167e+001 6.037057e+000 6.800025e+000 vertex 1.185632e+001 6.542173e+000 2.000025e+000 vertex 1.185632e+001 6.542173e+000 6.800025e+000 endloop endfacet facet normal 9.182422e-001 3.960194e-001 0.000000e+000 outer loop vertex 1.185632e+001 6.542173e+000 6.800025e+000 vertex 1.185632e+001 6.542173e+000 2.000025e+000 vertex 1.163532e+001 7.016113e+000 2.000025e+000 endloop endfacet facet normal 8.936031e-001 4.488580e-001 0.000000e+000 outer loop vertex 1.185632e+001 6.542173e+000 6.800025e+000 vertex 1.163532e+001 7.016113e+000 2.000025e+000 vertex 1.163532e+001 7.016113e+000 6.800025e+000 endloop endfacet facet normal 8.355240e-001 5.494540e-001 0.000000e+000 outer loop vertex 1.163532e+001 7.016113e+000 6.800025e+000 vertex 1.163532e+001 7.016113e+000 2.000025e+000 vertex 1.133538e+001 7.444476e+000 2.000025e+000 endloop endfacet facet normal 8.020838e-001 5.972114e-001 0.000000e+000 outer loop vertex 1.163532e+001 7.016113e+000 6.800025e+000 vertex 1.133538e+001 7.444476e+000 2.000025e+000 vertex 1.133538e+001 7.444476e+000 6.800025e+000 endloop endfacet facet normal 7.274188e-001 6.861938e-001 0.000000e+000 outer loop vertex 1.133538e+001 7.444476e+000 6.800025e+000 vertex 1.133538e+001 7.444476e+000 2.000025e+000 vertex 1.096561e+001 7.814246e+000 2.000025e+000 endloop endfacet facet normal 6.861938e-001 7.274188e-001 0.000000e+000 outer loop vertex 1.133538e+001 7.444476e+000 6.800025e+000 vertex 1.096561e+001 7.814246e+000 2.000025e+000 vertex 1.096561e+001 7.814246e+000 6.800025e+000 endloop endfacet facet normal 5.972114e-001 8.020838e-001 0.000000e+000 outer loop vertex 1.096561e+001 7.814246e+000 6.800025e+000 vertex 1.096561e+001 7.814246e+000 2.000025e+000 vertex 1.053725e+001 8.114189e+000 2.000025e+000 endloop endfacet facet normal 5.494540e-001 8.355240e-001 0.000000e+000 outer loop vertex 1.096561e+001 7.814246e+000 6.800025e+000 vertex 1.053725e+001 8.114189e+000 2.000025e+000 vertex 1.053725e+001 8.114189e+000 6.800025e+000 endloop endfacet facet normal 4.488580e-001 8.936031e-001 0.000000e+000 outer loop vertex 1.053725e+001 8.114189e+000 6.800025e+000 vertex 1.053725e+001 8.114189e+000 2.000025e+000 vertex 1.006331e+001 8.335191e+000 2.000025e+000 endloop endfacet facet normal 3.960194e-001 9.182422e-001 0.000000e+000 outer loop vertex 1.053725e+001 8.114189e+000 6.800025e+000 vertex 1.006331e+001 8.335191e+000 2.000025e+000 vertex 1.006331e+001 8.335191e+000 6.800025e+000 endloop endfacet facet normal 2.868663e-001 9.579706e-001 0.000000e+000 outer loop vertex 1.006331e+001 8.335191e+000 6.800025e+000 vertex 1.006331e+001 8.335191e+000 2.000025e+000 vertex 9.558189e+000 8.470536e+000 2.000025e+000 endloop endfacet facet normal 2.305518e-001 9.730601e-001 0.000000e+000 outer loop vertex 1.006331e+001 8.335191e+000 6.800025e+000 vertex 9.558189e+000 8.470536e+000 2.000025e+000 vertex 9.558189e+000 8.470536e+000 6.800025e+000 endloop endfacet facet normal 1.161583e-001 9.932307e-001 0.000000e+000 outer loop vertex 9.558189e+000 8.470536e+000 6.800025e+000 vertex 9.558189e+000 8.470536e+000 2.000025e+000 vertex 9.037245e+000 8.516113e+000 2.000025e+000 endloop endfacet facet normal 5.807913e-002 9.983119e-001 0.000000e+000 outer loop vertex 9.558189e+000 8.470536e+000 6.800025e+000 vertex 9.037245e+000 8.516113e+000 2.000025e+000 vertex 9.037245e+000 8.516113e+000 6.800025e+000 endloop endfacet facet normal -5.807913e-002 9.983119e-001 0.000000e+000 outer loop vertex 9.037245e+000 8.516113e+000 6.800025e+000 vertex 9.037245e+000 8.516113e+000 2.000025e+000 vertex 8.516300e+000 8.470536e+000 2.000025e+000 endloop endfacet facet normal -1.161583e-001 9.932307e-001 0.000000e+000 outer loop vertex 9.037245e+000 8.516113e+000 6.800025e+000 vertex 8.516300e+000 8.470536e+000 2.000025e+000 vertex 8.516300e+000 8.470536e+000 6.800025e+000 endloop endfacet facet normal -2.305518e-001 9.730601e-001 0.000000e+000 outer loop vertex 8.516300e+000 8.470536e+000 6.800025e+000 vertex 8.516300e+000 8.470536e+000 2.000025e+000 vertex 8.011185e+000 8.335191e+000 2.000025e+000 endloop endfacet facet normal -2.868663e-001 9.579706e-001 0.000000e+000 outer loop vertex 8.516300e+000 8.470536e+000 6.800025e+000 vertex 8.011185e+000 8.335191e+000 2.000025e+000 vertex 8.011185e+000 8.335191e+000 6.800025e+000 endloop endfacet facet normal -3.960194e-001 9.182422e-001 0.000000e+000 outer loop vertex 8.011185e+000 8.335191e+000 6.800025e+000 vertex 8.011185e+000 8.335191e+000 2.000025e+000 vertex 7.537245e+000 8.114189e+000 2.000025e+000 endloop endfacet facet normal -4.488580e-001 8.936031e-001 0.000000e+000 outer loop vertex 8.011185e+000 8.335191e+000 6.800025e+000 vertex 7.537245e+000 8.114189e+000 2.000025e+000 vertex 7.537245e+000 8.114189e+000 6.800025e+000 endloop endfacet facet normal -5.494540e-001 8.355240e-001 0.000000e+000 outer loop vertex 7.537245e+000 8.114189e+000 6.800025e+000 vertex 7.537245e+000 8.114189e+000 2.000025e+000 vertex 7.108882e+000 7.814246e+000 2.000025e+000 endloop endfacet facet normal -5.972114e-001 8.020838e-001 0.000000e+000 outer loop vertex 7.537245e+000 8.114189e+000 6.800025e+000 vertex 7.108882e+000 7.814246e+000 2.000025e+000 vertex 7.108882e+000 7.814246e+000 6.800025e+000 endloop endfacet facet normal -6.861938e-001 7.274188e-001 0.000000e+000 outer loop vertex 7.108882e+000 7.814246e+000 6.800025e+000 vertex 7.108882e+000 7.814246e+000 2.000025e+000 vertex 6.739111e+000 7.444476e+000 2.000025e+000 endloop endfacet facet normal -7.274188e-001 6.861938e-001 0.000000e+000 outer loop vertex 7.108882e+000 7.814246e+000 6.800025e+000 vertex 6.739111e+000 7.444476e+000 2.000025e+000 vertex 6.739111e+000 7.444476e+000 6.800025e+000 endloop endfacet facet normal -8.020838e-001 5.972114e-001 0.000000e+000 outer loop vertex 6.739111e+000 7.444476e+000 6.800025e+000 vertex 6.739111e+000 7.444476e+000 2.000025e+000 vertex 6.439169e+000 7.016113e+000 2.000025e+000 endloop endfacet facet normal -8.355240e-001 5.494540e-001 0.000000e+000 outer loop vertex 6.739111e+000 7.444476e+000 6.800025e+000 vertex 6.439169e+000 7.016113e+000 2.000025e+000 vertex 6.439169e+000 7.016113e+000 6.800025e+000 endloop endfacet facet normal -8.936031e-001 4.488580e-001 0.000000e+000 outer loop vertex 6.439169e+000 7.016113e+000 6.800025e+000 vertex 6.439169e+000 7.016113e+000 2.000025e+000 vertex 6.218167e+000 6.542173e+000 2.000025e+000 endloop endfacet facet normal -9.182422e-001 3.960194e-001 0.000000e+000 outer loop vertex 6.439169e+000 7.016113e+000 6.800025e+000 vertex 6.218167e+000 6.542173e+000 2.000025e+000 vertex 6.218167e+000 6.542173e+000 6.800025e+000 endloop endfacet facet normal -9.579706e-001 2.868663e-001 0.000000e+000 outer loop vertex 6.218167e+000 6.542173e+000 6.800025e+000 vertex 6.218167e+000 6.542173e+000 2.000025e+000 vertex 6.082822e+000 6.037057e+000 2.000025e+000 endloop endfacet facet normal -9.730601e-001 2.305518e-001 0.000000e+000 outer loop vertex 6.218167e+000 6.542173e+000 6.800025e+000 vertex 6.082822e+000 6.037057e+000 2.000025e+000 vertex 6.082822e+000 6.037057e+000 6.800025e+000 endloop endfacet facet normal -9.932307e-001 1.161583e-001 0.000000e+000 outer loop vertex 6.082822e+000 6.037057e+000 6.800025e+000 vertex 6.082822e+000 6.037057e+000 2.000025e+000 vertex 6.037245e+000 5.516113e+000 2.000025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.185632e+001 4.490052e+000 6.800025e+000 vertex 1.199167e+001 4.995169e+000 6.800025e+000 vertex 1.203724e+001 5.516113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.006331e+001 2.697035e+000 6.800025e+000 vertex 1.053725e+001 2.918037e+000 6.800025e+000 vertex 1.096561e+001 3.217980e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.011185e+000 8.335191e+000 6.800025e+000 vertex 7.537245e+000 8.114189e+000 6.800025e+000 vertex 7.108882e+000 7.814246e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.739111e+000 3.587750e+000 6.800025e+000 vertex 7.108882e+000 3.217980e+000 6.800025e+000 vertex 7.537245e+000 2.918037e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.163532e+001 4.016113e+000 6.800025e+000 vertex 1.185632e+001 4.490052e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.006331e+001 8.335191e+000 6.800025e+000 vertex 7.108882e+000 7.814246e+000 6.800025e+000 vertex 6.739111e+000 7.444476e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.133538e+001 3.587750e+000 6.800025e+000 vertex 1.163532e+001 4.016113e+000 6.800025e+000 vertex 1.096561e+001 3.217980e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.096561e+001 3.217980e+000 6.800025e+000 vertex 1.163532e+001 4.016113e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.096561e+001 3.217980e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 6.800025e+000 vertex 6.082822e+000 4.995169e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.185632e+001 4.490052e+000 6.800025e+000 vertex 1.203724e+001 5.516113e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.037245e+000 5.516113e+000 6.800025e+000 vertex 1.203724e+001 5.516113e+000 6.800025e+000 vertex 1.199167e+001 6.037057e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.037245e+000 5.516113e+000 6.800025e+000 vertex 1.199167e+001 6.037057e+000 6.800025e+000 vertex 1.185632e+001 6.542173e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.053725e+001 8.114189e+000 6.800025e+000 vertex 1.006331e+001 8.335191e+000 6.800025e+000 vertex 1.096561e+001 7.814246e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.096561e+001 7.814246e+000 6.800025e+000 vertex 1.006331e+001 8.335191e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.096561e+001 7.814246e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 6.800025e+000 vertex 1.133538e+001 7.444476e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.133538e+001 7.444476e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 6.800025e+000 vertex 1.185632e+001 6.542173e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.133538e+001 7.444476e+000 6.800025e+000 vertex 1.185632e+001 6.542173e+000 6.800025e+000 vertex 1.163532e+001 7.016113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.006331e+001 8.335191e+000 6.800025e+000 vertex 9.558189e+000 8.470536e+000 6.800025e+000 vertex 9.037245e+000 8.516113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 7.108882e+000 7.814246e+000 6.800025e+000 vertex 1.006331e+001 8.335191e+000 6.800025e+000 vertex 8.011185e+000 8.335191e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.011185e+000 8.335191e+000 6.800025e+000 vertex 1.006331e+001 8.335191e+000 6.800025e+000 vertex 9.037245e+000 8.516113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.011185e+000 8.335191e+000 6.800025e+000 vertex 9.037245e+000 8.516113e+000 6.800025e+000 vertex 8.516300e+000 8.470536e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.082822e+000 6.037057e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 6.800025e+000 vertex 6.218167e+000 6.542173e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.218167e+000 6.542173e+000 6.800025e+000 vertex 6.037245e+000 5.516113e+000 6.800025e+000 vertex 1.006331e+001 8.335191e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.218167e+000 6.542173e+000 6.800025e+000 vertex 1.006331e+001 8.335191e+000 6.800025e+000 vertex 6.439169e+000 7.016113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.439169e+000 7.016113e+000 6.800025e+000 vertex 1.006331e+001 8.335191e+000 6.800025e+000 vertex 6.739111e+000 7.444476e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.082822e+000 4.995169e+000 6.800025e+000 vertex 6.218167e+000 4.490052e+000 6.800025e+000 vertex 1.096561e+001 3.217980e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.096561e+001 3.217980e+000 6.800025e+000 vertex 6.218167e+000 4.490052e+000 6.800025e+000 vertex 6.439169e+000 4.016113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.096561e+001 3.217980e+000 6.800025e+000 vertex 6.439169e+000 4.016113e+000 6.800025e+000 vertex 6.739111e+000 3.587750e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 8.011185e+000 2.697035e+000 6.800025e+000 vertex 8.516300e+000 2.561690e+000 6.800025e+000 vertex 9.037245e+000 2.516113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 6.739111e+000 3.587750e+000 6.800025e+000 vertex 7.537245e+000 2.918037e+000 6.800025e+000 vertex 1.096561e+001 3.217980e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.096561e+001 3.217980e+000 6.800025e+000 vertex 7.537245e+000 2.918037e+000 6.800025e+000 vertex 8.011185e+000 2.697035e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.096561e+001 3.217980e+000 6.800025e+000 vertex 8.011185e+000 2.697035e+000 6.800025e+000 vertex 1.006331e+001 2.697035e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.006331e+001 2.697035e+000 6.800025e+000 vertex 8.011185e+000 2.697035e+000 6.800025e+000 vertex 9.037245e+000 2.516113e+000 6.800025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 1.006331e+001 2.697035e+000 6.800025e+000 vertex 9.037245e+000 2.516113e+000 6.800025e+000 vertex 9.558189e+000 2.561690e+000 6.800025e+000 endloop endfacet facet normal 9.991224e-001 4.188516e-002 0.000000e+000 outer loop vertex 2.282083e+001 5.876099e+000 5.200025e+000 vertex 2.282083e+001 5.876099e+000 3.200025e+000 vertex 2.281837e+001 5.934666e+000 3.200025e+000 endloop endfacet facet normal 9.982564e-001 5.902546e-002 0.000000e+000 outer loop vertex 2.282083e+001 5.876099e+000 5.200025e+000 vertex 2.281837e+001 5.934666e+000 3.200025e+000 vertex 2.281837e+001 5.934666e+000 5.200025e+000 endloop endfacet facet normal 9.915403e-001 1.297995e-001 0.000000e+000 outer loop vertex 2.281837e+001 5.934666e+000 5.200025e+000 vertex 2.281837e+001 5.934666e+000 3.200025e+000 vertex 2.280476e+001 6.019302e+000 3.200025e+000 endloop endfacet facet normal 9.830695e-001 1.832332e-001 0.000000e+000 outer loop vertex 2.281837e+001 5.934666e+000 5.200025e+000 vertex 2.280476e+001 6.019302e+000 3.200025e+000 vertex 2.280476e+001 6.019302e+000 5.200025e+000 endloop endfacet facet normal 9.580261e-001 2.866813e-001 0.000000e+000 outer loop vertex 2.280476e+001 6.019302e+000 5.200025e+000 vertex 2.280476e+001 6.019302e+000 3.200025e+000 vertex 2.277458e+001 6.110955e+000 3.200025e+000 endloop endfacet facet normal 9.416007e-001 3.367315e-001 0.000000e+000 outer loop vertex 2.280476e+001 6.019302e+000 5.200025e+000 vertex 2.277458e+001 6.110955e+000 3.200025e+000 vertex 2.277458e+001 6.110955e+000 5.200025e+000 endloop endfacet facet normal 9.008085e-001 4.342168e-001 0.000000e+000 outer loop vertex 2.277458e+001 6.110955e+000 5.200025e+000 vertex 2.277458e+001 6.110955e+000 3.200025e+000 vertex 2.273219e+001 6.193780e+000 3.200025e+000 endloop endfacet facet normal 8.763774e-001 4.816251e-001 0.000000e+000 outer loop vertex 2.277458e+001 6.110955e+000 5.200025e+000 vertex 2.273219e+001 6.193780e+000 3.200025e+000 vertex 2.273219e+001 6.193780e+000 5.200025e+000 endloop endfacet facet normal 8.232309e-001 5.677066e-001 0.000000e+000 outer loop vertex 2.273219e+001 6.193780e+000 5.200025e+000 vertex 2.273219e+001 6.193780e+000 3.200025e+000 vertex 2.267049e+001 6.277335e+000 3.200025e+000 endloop endfacet facet normal 7.949631e-001 6.066577e-001 0.000000e+000 outer loop vertex 2.273219e+001 6.193780e+000 5.200025e+000 vertex 2.267049e+001 6.277335e+000 3.200025e+000 vertex 2.267049e+001 6.277335e+000 5.200025e+000 endloop endfacet facet normal 7.360649e-001 6.769109e-001 0.000000e+000 outer loop vertex 2.267049e+001 6.277335e+000 5.200025e+000 vertex 2.267049e+001 6.277335e+000 3.200025e+000 vertex 2.258687e+001 6.361741e+000 3.200025e+000 endloop endfacet facet normal 7.057405e-001 7.084705e-001 0.000000e+000 outer loop vertex 2.267049e+001 6.277335e+000 5.200025e+000 vertex 2.258687e+001 6.361741e+000 3.200025e+000 vertex 2.258687e+001 6.361741e+000 5.200025e+000 endloop endfacet facet normal 6.202572e-001 7.843985e-001 0.000000e+000 outer loop vertex 2.258687e+001 6.361741e+000 5.200025e+000 vertex 2.258687e+001 6.361741e+000 3.200025e+000 vertex 2.252559e+001 6.410197e+000 3.200025e+000 endloop endfacet facet normal 6.061446e-001 7.953544e-001 0.000000e+000 outer loop vertex 2.258687e+001 6.361741e+000 5.200025e+000 vertex 2.252559e+001 6.410197e+000 3.200025e+000 vertex 2.252559e+001 6.410197e+000 5.200025e+000 endloop endfacet facet normal 5.480802e-001 8.364257e-001 0.000000e+000 outer loop vertex 2.252559e+001 6.410197e+000 5.200025e+000 vertex 2.252559e+001 6.410197e+000 3.200025e+000 vertex 2.242289e+001 6.473251e+000 3.200025e+000 endloop endfacet facet normal 5.026307e-001 8.645013e-001 0.000000e+000 outer loop vertex 2.252559e+001 6.410197e+000 5.200025e+000 vertex 2.242289e+001 6.473251e+000 3.200025e+000 vertex 2.242289e+001 6.473251e+000 5.200025e+000 endloop endfacet facet normal 4.056769e-001 9.140165e-001 0.000000e+000 outer loop vertex 2.242289e+001 6.473251e+000 5.200025e+000 vertex 2.242289e+001 6.473251e+000 3.200025e+000 vertex 2.231094e+001 6.520463e+000 3.200025e+000 endloop endfacet facet normal 3.540542e-001 9.352249e-001 0.000000e+000 outer loop vertex 2.242289e+001 6.473251e+000 5.200025e+000 vertex 2.231094e+001 6.520463e+000 3.200025e+000 vertex 2.231094e+001 6.520463e+000 5.200025e+000 endloop endfacet facet normal 2.544051e-001 9.670978e-001 0.000000e+000 outer loop vertex 2.231094e+001 6.520463e+000 5.200025e+000 vertex 2.231094e+001 6.520463e+000 3.200025e+000 vertex 2.220584e+001 6.545606e+000 3.200025e+000 endloop endfacet facet normal 2.065890e-001 9.784278e-001 0.000000e+000 outer loop vertex 2.231094e+001 6.520463e+000 5.200025e+000 vertex 2.220584e+001 6.545606e+000 3.200025e+000 vertex 2.220584e+001 6.545606e+000 5.200025e+000 endloop endfacet facet normal 1.167792e-001 9.931579e-001 0.000000e+000 outer loop vertex 2.220584e+001 6.545606e+000 5.200025e+000 vertex 2.220584e+001 6.545606e+000 3.200025e+000 vertex 2.207505e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 7.488728e-002 9.971920e-001 0.000000e+000 outer loop vertex 2.220584e+001 6.545606e+000 5.200025e+000 vertex 2.207505e+001 6.555998e+000 3.200025e+000 vertex 2.207505e+001 6.555998e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.137995e+001 6.555998e+000 5.200025e+000 vertex 2.207505e+001 6.555998e+000 5.200025e+000 vertex 2.137995e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.137995e+001 6.555998e+000 3.200025e+000 vertex 2.207505e+001 6.555998e+000 5.200025e+000 vertex 2.207505e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal -1.351927e-002 9.999086e-001 0.000000e+000 outer loop vertex 2.137995e+001 6.555998e+000 5.200025e+000 vertex 2.137995e+001 6.555998e+000 3.200025e+000 vertex 2.128266e+001 6.554683e+000 3.200025e+000 endloop endfacet facet normal -1.522511e-002 9.998841e-001 0.000000e+000 outer loop vertex 2.137995e+001 6.555998e+000 5.200025e+000 vertex 2.128266e+001 6.554683e+000 3.200025e+000 vertex 2.128266e+001 6.554683e+000 5.200025e+000 endloop endfacet facet normal -6.607155e-002 9.978149e-001 0.000000e+000 outer loop vertex 2.128266e+001 6.554683e+000 5.200025e+000 vertex 2.128266e+001 6.554683e+000 3.200025e+000 vertex 2.070188e+001 6.506922e+000 3.200025e+000 endloop endfacet facet normal -1.151711e-001 9.933457e-001 0.000000e+000 outer loop vertex 2.128266e+001 6.554683e+000 5.200025e+000 vertex 2.070188e+001 6.506922e+000 3.200025e+000 vertex 2.070188e+001 6.506922e+000 5.200025e+000 endloop endfacet facet normal -2.157017e-001 9.764593e-001 0.000000e+000 outer loop vertex 2.070188e+001 6.506922e+000 5.200025e+000 vertex 2.070188e+001 6.506922e+000 3.200025e+000 vertex 2.034992e+001 6.421170e+000 3.200025e+000 endloop endfacet facet normal -2.670720e-001 9.636766e-001 0.000000e+000 outer loop vertex 2.070188e+001 6.506922e+000 5.200025e+000 vertex 2.034992e+001 6.421170e+000 3.200025e+000 vertex 2.034992e+001 6.421170e+000 5.200025e+000 endloop endfacet facet normal -3.443886e-001 9.388272e-001 0.000000e+000 outer loop vertex 2.034992e+001 6.421170e+000 5.200025e+000 vertex 2.034992e+001 6.421170e+000 3.200025e+000 vertex 2.022012e+001 6.371653e+000 3.200025e+000 endloop endfacet facet normal -3.709664e-001 9.286463e-001 0.000000e+000 outer loop vertex 2.034992e+001 6.421170e+000 5.200025e+000 vertex 2.022012e+001 6.371653e+000 3.200025e+000 vertex 2.022012e+001 6.371653e+000 5.200025e+000 endloop endfacet facet normal -4.456854e-001 8.951897e-001 0.000000e+000 outer loop vertex 2.022012e+001 6.371653e+000 5.200025e+000 vertex 2.022012e+001 6.371653e+000 3.200025e+000 vertex 2.003585e+001 6.274529e+000 3.200025e+000 endloop endfacet facet normal -4.930086e-001 8.700244e-001 0.000000e+000 outer loop vertex 2.022012e+001 6.371653e+000 5.200025e+000 vertex 2.003585e+001 6.274529e+000 3.200025e+000 vertex 2.003585e+001 6.274529e+000 5.200025e+000 endloop endfacet facet normal -5.799621e-001 8.146434e-001 0.000000e+000 outer loop vertex 2.003585e+001 6.274529e+000 5.200025e+000 vertex 2.003585e+001 6.274529e+000 3.200025e+000 vertex 1.992107e+001 6.188916e+000 3.200025e+000 endloop endfacet facet normal -6.198032e-001 7.847573e-001 0.000000e+000 outer loop vertex 2.003585e+001 6.274529e+000 5.200025e+000 vertex 1.992107e+001 6.188916e+000 3.200025e+000 vertex 1.992107e+001 6.188916e+000 5.200025e+000 endloop endfacet facet normal -6.980899e-001 7.160102e-001 0.000000e+000 outer loop vertex 1.992107e+001 6.188916e+000 5.200025e+000 vertex 1.992107e+001 6.188916e+000 3.200025e+000 vertex 1.982245e+001 6.087405e+000 3.200025e+000 endloop endfacet facet normal -7.361993e-001 6.767648e-001 0.000000e+000 outer loop vertex 1.992107e+001 6.188916e+000 5.200025e+000 vertex 1.982245e+001 6.087405e+000 3.200025e+000 vertex 1.982245e+001 6.087405e+000 5.200025e+000 endloop endfacet facet normal -7.868180e-001 6.171852e-001 0.000000e+000 outer loop vertex 1.982245e+001 6.087405e+000 5.200025e+000 vertex 1.982245e+001 6.087405e+000 3.200025e+000 vertex 1.978541e+001 6.039046e+000 3.200025e+000 endloop endfacet facet normal -8.012018e-001 5.983943e-001 0.000000e+000 outer loop vertex 1.982245e+001 6.087405e+000 5.200025e+000 vertex 1.978541e+001 6.039046e+000 3.200025e+000 vertex 1.978541e+001 6.039046e+000 5.200025e+000 endloop endfacet facet normal -8.446460e-001 5.353252e-001 0.000000e+000 outer loop vertex 1.978541e+001 6.039046e+000 5.200025e+000 vertex 1.978541e+001 6.039046e+000 3.200025e+000 vertex 1.972443e+001 5.937308e+000 3.200025e+000 endloop endfacet facet normal -8.718683e-001 4.897404e-001 0.000000e+000 outer loop vertex 1.978541e+001 6.039046e+000 5.200025e+000 vertex 1.972443e+001 5.937308e+000 3.200025e+000 vertex 1.972443e+001 5.937308e+000 5.200025e+000 endloop endfacet facet normal -9.189408e-001 3.943954e-001 0.000000e+000 outer loop vertex 1.972443e+001 5.937308e+000 5.200025e+000 vertex 1.972443e+001 5.937308e+000 3.200025e+000 vertex 1.967211e+001 5.804854e+000 3.200025e+000 endloop endfacet facet normal -9.387451e-001 3.446124e-001 0.000000e+000 outer loop vertex 1.972443e+001 5.937308e+000 5.200025e+000 vertex 1.967211e+001 5.804854e+000 3.200025e+000 vertex 1.967211e+001 5.804854e+000 5.200025e+000 endloop endfacet facet normal -9.703479e-001 2.417122e-001 0.000000e+000 outer loop vertex 1.967211e+001 5.804854e+000 5.200025e+000 vertex 1.967211e+001 5.804854e+000 3.200025e+000 vertex 1.964198e+001 5.668105e+000 3.200025e+000 endloop endfacet facet normal -9.820601e-001 1.885684e-001 0.000000e+000 outer loop vertex 1.967211e+001 5.804854e+000 5.200025e+000 vertex 1.964198e+001 5.668105e+000 3.200025e+000 vertex 1.964198e+001 5.668105e+000 5.200025e+000 endloop endfacet facet normal -9.949916e-001 9.995858e-002 0.000000e+000 outer loop vertex 1.964198e+001 5.668105e+000 5.200025e+000 vertex 1.964198e+001 5.668105e+000 3.200025e+000 vertex 1.963164e+001 5.511234e+000 3.200025e+000 endloop endfacet facet normal -9.979033e-001 6.472310e-002 0.000000e+000 outer loop vertex 1.964198e+001 5.668105e+000 5.200025e+000 vertex 1.963164e+001 5.511234e+000 3.200025e+000 vertex 1.963164e+001 5.511234e+000 5.200025e+000 endloop endfacet facet normal -9.966881e-001 -8.131968e-002 0.000000e+000 outer loop vertex 1.963164e+001 5.511234e+000 5.200025e+000 vertex 1.963164e+001 5.511234e+000 3.200025e+000 vertex 1.966306e+001 5.228972e+000 3.200025e+000 endloop endfacet facet normal -9.905221e-001 -1.373528e-001 0.000000e+000 outer loop vertex 1.963164e+001 5.511234e+000 5.200025e+000 vertex 1.966306e+001 5.228972e+000 3.200025e+000 vertex 1.966306e+001 5.228972e+000 5.200025e+000 endloop endfacet facet normal -9.699386e-001 -2.433499e-001 0.000000e+000 outer loop vertex 1.966306e+001 5.228972e+000 5.200025e+000 vertex 1.966306e+001 5.228972e+000 3.200025e+000 vertex 1.986816e+001 4.556346e+000 3.200025e+000 endloop endfacet facet normal -9.559880e-001 -2.934056e-001 0.000000e+000 outer loop vertex 1.966306e+001 5.228972e+000 5.200025e+000 vertex 1.986816e+001 4.556346e+000 3.200025e+000 vertex 1.986816e+001 4.556346e+000 5.200025e+000 endloop endfacet facet normal -9.557078e-001 -2.943169e-001 0.000000e+000 outer loop vertex 1.986816e+001 4.556346e+000 5.200025e+000 vertex 1.986816e+001 4.556346e+000 3.200025e+000 vertex 2.003253e+001 4.000062e+000 3.200025e+000 endloop endfacet facet normal -9.694709e-001 -2.452062e-001 0.000000e+000 outer loop vertex 1.986816e+001 4.556346e+000 5.200025e+000 vertex 2.003253e+001 4.000062e+000 3.200025e+000 vertex 2.003253e+001 4.000062e+000 5.200025e+000 endloop endfacet facet normal -9.901677e-001 -1.398855e-001 0.000000e+000 outer loop vertex 2.003253e+001 4.000062e+000 5.200025e+000 vertex 2.003253e+001 4.000062e+000 3.200025e+000 vertex 2.006407e+001 3.724917e+000 3.200025e+000 endloop endfacet facet normal -9.965031e-001 -8.355613e-002 0.000000e+000 outer loop vertex 2.003253e+001 4.000062e+000 5.200025e+000 vertex 2.006407e+001 3.724917e+000 3.200025e+000 vertex 2.006407e+001 3.724917e+000 5.200025e+000 endloop endfacet facet normal -9.990410e-001 4.378431e-002 0.000000e+000 outer loop vertex 2.006407e+001 3.724917e+000 5.200025e+000 vertex 2.006407e+001 3.724917e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 endloop endfacet facet normal -9.982981e-001 5.831718e-002 0.000000e+000 outer loop vertex 2.006407e+001 3.724917e+000 5.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 vertex 2.006042e+001 3.641685e+000 5.200025e+000 endloop endfacet facet normal -9.924292e-001 1.228183e-001 0.000000e+000 outer loop vertex 2.006042e+001 3.641685e+000 5.200025e+000 vertex 2.006042e+001 3.641685e+000 3.200025e+000 vertex 2.004197e+001 3.519632e+000 3.200025e+000 endloop endfacet facet normal -9.849890e-001 1.726175e-001 0.000000e+000 outer loop vertex 2.006042e+001 3.641685e+000 5.200025e+000 vertex 2.004197e+001 3.519632e+000 3.200025e+000 vertex 2.004197e+001 3.519632e+000 5.200025e+000 endloop endfacet facet normal -9.605756e-001 2.780191e-001 0.000000e+000 outer loop vertex 2.004197e+001 3.519632e+000 5.200025e+000 vertex 2.004197e+001 3.519632e+000 3.200025e+000 vertex 2.000307e+001 3.395886e+000 3.200025e+000 endloop endfacet facet normal -9.427738e-001 3.334331e-001 0.000000e+000 outer loop vertex 2.004197e+001 3.519632e+000 5.200025e+000 vertex 2.000307e+001 3.395886e+000 3.200025e+000 vertex 2.000307e+001 3.395886e+000 5.200025e+000 endloop endfacet facet normal -9.020504e-001 4.316307e-001 0.000000e+000 outer loop vertex 2.000307e+001 3.395886e+000 5.200025e+000 vertex 2.000307e+001 3.395886e+000 3.200025e+000 vertex 1.995123e+001 3.294544e+000 3.200025e+000 endloop endfacet facet normal -8.800849e-001 4.748162e-001 0.000000e+000 outer loop vertex 2.000307e+001 3.395886e+000 5.200025e+000 vertex 1.995123e+001 3.294544e+000 3.200025e+000 vertex 1.995123e+001 3.294544e+000 5.200025e+000 endloop endfacet facet normal -8.270720e-001 5.620961e-001 0.000000e+000 outer loop vertex 1.995123e+001 3.294544e+000 5.200025e+000 vertex 1.995123e+001 3.294544e+000 3.200025e+000 vertex 1.988647e+001 3.204496e+000 3.200025e+000 endloop endfacet facet normal -7.955415e-001 6.058991e-001 0.000000e+000 outer loop vertex 1.995123e+001 3.294544e+000 5.200025e+000 vertex 1.988647e+001 3.204496e+000 3.200025e+000 vertex 1.988647e+001 3.204496e+000 5.200025e+000 endloop endfacet facet normal -7.294812e-001 6.840010e-001 0.000000e+000 outer loop vertex 1.988647e+001 3.204496e+000 5.200025e+000 vertex 1.988647e+001 3.204496e+000 3.200025e+000 vertex 1.980193e+001 3.118547e+000 3.200025e+000 endloop endfacet facet normal -6.953677e-001 7.186542e-001 0.000000e+000 outer loop vertex 1.988647e+001 3.204496e+000 5.200025e+000 vertex 1.980193e+001 3.118547e+000 3.200025e+000 vertex 1.980193e+001 3.118547e+000 5.200025e+000 endloop endfacet facet normal -6.287342e-001 7.776203e-001 0.000000e+000 outer loop vertex 1.980193e+001 3.118547e+000 5.200025e+000 vertex 1.980193e+001 3.118547e+000 3.200025e+000 vertex 1.968991e+001 3.034883e+000 3.200025e+000 endloop endfacet facet normal -5.966883e-001 8.024731e-001 0.000000e+000 outer loop vertex 1.980193e+001 3.118547e+000 5.200025e+000 vertex 1.968991e+001 3.034883e+000 3.200025e+000 vertex 1.968991e+001 3.034883e+000 5.200025e+000 endloop endfacet facet normal -5.060359e-001 8.625124e-001 0.000000e+000 outer loop vertex 1.968991e+001 3.034883e+000 5.200025e+000 vertex 1.968991e+001 3.034883e+000 3.200025e+000 vertex 1.959893e+001 2.981532e+000 3.200025e+000 endloop endfacet facet normal -4.852286e-001 8.743873e-001 0.000000e+000 outer loop vertex 1.968991e+001 3.034883e+000 5.200025e+000 vertex 1.959893e+001 2.981532e+000 3.200025e+000 vertex 1.959893e+001 2.981532e+000 5.200025e+000 endloop endfacet facet normal -4.140031e-001 9.102755e-001 0.000000e+000 outer loop vertex 1.959893e+001 2.981532e+000 5.200025e+000 vertex 1.959893e+001 2.981532e+000 3.200025e+000 vertex 1.941135e+001 2.902604e+000 3.200025e+000 endloop endfacet facet normal -3.623980e-001 9.320234e-001 0.000000e+000 outer loop vertex 1.959893e+001 2.981532e+000 5.200025e+000 vertex 1.941135e+001 2.902604e+000 3.200025e+000 vertex 1.941135e+001 2.902604e+000 5.200025e+000 endloop endfacet facet normal -2.633361e-001 9.647042e-001 0.000000e+000 outer loop vertex 1.941135e+001 2.902604e+000 5.200025e+000 vertex 1.941135e+001 2.902604e+000 3.200025e+000 vertex 1.919246e+001 2.850029e+000 3.200025e+000 endloop endfacet facet normal -2.161173e-001 9.763674e-001 0.000000e+000 outer loop vertex 1.941135e+001 2.902604e+000 5.200025e+000 vertex 1.919246e+001 2.850029e+000 3.200025e+000 vertex 1.919246e+001 2.850029e+000 5.200025e+000 endloop endfacet facet normal -1.186856e-001 9.929318e-001 0.000000e+000 outer loop vertex 1.919246e+001 2.850029e+000 5.200025e+000 vertex 1.919246e+001 2.850029e+000 3.200025e+000 vertex 1.888586e+001 2.826268e+000 3.200025e+000 endloop endfacet facet normal -6.844212e-002 9.976550e-001 0.000000e+000 outer loop vertex 1.919246e+001 2.850029e+000 5.200025e+000 vertex 1.888586e+001 2.826268e+000 3.200025e+000 vertex 1.888586e+001 2.826268e+000 5.200025e+000 endloop endfacet facet normal 4.076267e-002 9.991689e-001 0.000000e+000 outer loop vertex 1.888586e+001 2.826268e+000 5.200025e+000 vertex 1.888586e+001 2.826268e+000 3.200025e+000 vertex 1.874229e+001 2.832124e+000 3.200025e+000 endloop endfacet facet normal 5.310328e-002 9.985890e-001 0.000000e+000 outer loop vertex 1.888586e+001 2.826268e+000 5.200025e+000 vertex 1.874229e+001 2.832124e+000 3.200025e+000 vertex 1.874229e+001 2.832124e+000 5.200025e+000 endloop endfacet facet normal 1.197937e-001 9.927988e-001 0.000000e+000 outer loop vertex 1.874229e+001 2.832124e+000 5.200025e+000 vertex 1.874229e+001 2.832124e+000 3.200025e+000 vertex 1.846527e+001 2.873987e+000 3.200025e+000 endloop endfacet facet normal 1.739576e-001 9.847531e-001 0.000000e+000 outer loop vertex 1.874229e+001 2.832124e+000 5.200025e+000 vertex 1.846527e+001 2.873987e+000 3.200025e+000 vertex 1.846527e+001 2.873987e+000 5.200025e+000 endloop endfacet facet normal 2.773883e-001 9.607579e-001 0.000000e+000 outer loop vertex 1.846527e+001 2.873987e+000 5.200025e+000 vertex 1.846527e+001 2.873987e+000 3.200025e+000 vertex 1.817218e+001 2.972383e+000 3.200025e+000 endloop endfacet facet normal 3.267275e-001 9.451185e-001 0.000000e+000 outer loop vertex 1.846527e+001 2.873987e+000 5.200025e+000 vertex 1.817218e+001 2.972383e+000 3.200025e+000 vertex 1.817218e+001 2.972383e+000 5.200025e+000 endloop endfacet facet normal 4.302116e-001 9.027281e-001 0.000000e+000 outer loop vertex 1.817218e+001 2.972383e+000 5.200025e+000 vertex 1.817218e+001 2.972383e+000 3.200025e+000 vertex 1.810614e+001 3.003853e+000 3.200025e+000 endloop endfacet facet normal 4.381675e-001 8.988934e-001 0.000000e+000 outer loop vertex 1.817218e+001 2.972383e+000 5.200025e+000 vertex 1.810614e+001 3.003853e+000 3.200025e+000 vertex 1.810614e+001 3.003853e+000 5.200025e+000 endloop endfacet facet normal 4.879041e-001 8.728972e-001 0.000000e+000 outer loop vertex 1.810614e+001 3.003853e+000 5.200025e+000 vertex 1.810614e+001 3.003853e+000 3.200025e+000 vertex 1.799337e+001 3.069825e+000 3.200025e+000 endloop endfacet facet normal 5.287186e-001 8.487972e-001 0.000000e+000 outer loop vertex 1.810614e+001 3.003853e+000 5.200025e+000 vertex 1.799337e+001 3.069825e+000 3.200025e+000 vertex 1.799337e+001 3.069825e+000 5.200025e+000 endloop endfacet facet normal 6.120465e-001 7.908218e-001 0.000000e+000 outer loop vertex 1.799337e+001 3.069825e+000 5.200025e+000 vertex 1.799337e+001 3.069825e+000 3.200025e+000 vertex 1.789379e+001 3.151021e+000 3.200025e+000 endloop endfacet facet normal 6.541553e-001 7.563603e-001 0.000000e+000 outer loop vertex 1.799337e+001 3.069825e+000 5.200025e+000 vertex 1.789379e+001 3.151021e+000 3.200025e+000 vertex 1.789379e+001 3.151021e+000 5.200025e+000 endloop endfacet facet normal 7.305741e-001 6.828334e-001 0.000000e+000 outer loop vertex 1.789379e+001 3.151021e+000 5.200025e+000 vertex 1.789379e+001 3.151021e+000 3.200025e+000 vertex 1.783493e+001 3.216788e+000 3.200025e+000 endloop endfacet facet normal 7.650638e-001 6.439545e-001 0.000000e+000 outer loop vertex 1.789379e+001 3.151021e+000 5.200025e+000 vertex 1.783493e+001 3.216788e+000 3.200025e+000 vertex 1.783493e+001 3.216788e+000 5.200025e+000 endloop endfacet facet normal 8.293992e-001 5.586565e-001 0.000000e+000 outer loop vertex 1.783493e+001 3.216788e+000 5.200025e+000 vertex 1.783493e+001 3.216788e+000 3.200025e+000 vertex 1.779280e+001 3.283037e+000 3.200025e+000 endloop endfacet facet normal 8.589686e-001 5.120284e-001 0.000000e+000 outer loop vertex 1.783493e+001 3.216788e+000 5.200025e+000 vertex 1.779280e+001 3.283037e+000 3.200025e+000 vertex 1.779280e+001 3.283037e+000 5.200025e+000 endloop endfacet facet normal 9.075900e-001 4.198575e-001 0.000000e+000 outer loop vertex 1.779280e+001 3.283037e+000 5.200025e+000 vertex 1.779280e+001 3.283037e+000 3.200025e+000 vertex 1.776498e+001 3.347373e+000 3.200025e+000 endloop endfacet facet normal 9.271865e-001 3.745999e-001 0.000000e+000 outer loop vertex 1.779280e+001 3.283037e+000 5.200025e+000 vertex 1.776498e+001 3.347373e+000 3.200025e+000 vertex 1.776498e+001 3.347373e+000 5.200025e+000 endloop endfacet facet normal 9.611733e-001 2.759453e-001 0.000000e+000 outer loop vertex 1.776498e+001 3.347373e+000 5.200025e+000 vertex 1.776498e+001 3.347373e+000 3.200025e+000 vertex 1.774729e+001 3.415194e+000 3.200025e+000 endloop endfacet facet normal 9.749689e-001 2.223416e-001 0.000000e+000 outer loop vertex 1.776498e+001 3.347373e+000 5.200025e+000 vertex 1.774729e+001 3.415194e+000 3.200025e+000 vertex 1.774729e+001 3.415194e+000 5.200025e+000 endloop endfacet facet normal 9.918312e-001 1.275573e-001 0.000000e+000 outer loop vertex 1.774729e+001 3.415194e+000 5.200025e+000 vertex 1.774729e+001 3.415194e+000 3.200025e+000 vertex 1.773974e+001 3.501944e+000 3.200025e+000 endloop endfacet facet normal 9.962426e-001 8.660615e-002 0.000000e+000 outer loop vertex 1.774729e+001 3.415194e+000 5.200025e+000 vertex 1.773974e+001 3.501944e+000 3.200025e+000 vertex 1.773974e+001 3.501944e+000 5.200025e+000 endloop endfacet facet normal 9.987100e-001 -5.077673e-002 0.000000e+000 outer loop vertex 1.773974e+001 3.501944e+000 5.200025e+000 vertex 1.773974e+001 3.501944e+000 3.200025e+000 vertex 1.774192e+001 3.544773e+000 3.200025e+000 endloop endfacet facet normal 9.981527e-001 -6.075483e-002 0.000000e+000 outer loop vertex 1.773974e+001 3.501944e+000 5.200025e+000 vertex 1.774192e+001 3.544773e+000 3.200025e+000 vertex 1.774192e+001 3.544773e+000 5.200025e+000 endloop endfacet facet normal 9.925501e-001 -1.218371e-001 0.000000e+000 outer loop vertex 1.774192e+001 3.544773e+000 5.200025e+000 vertex 1.774192e+001 3.544773e+000 3.200025e+000 vertex 1.775203e+001 3.615100e+000 3.200025e+000 endloop endfacet facet normal 9.849638e-001 -1.727611e-001 0.000000e+000 outer loop vertex 1.774192e+001 3.544773e+000 5.200025e+000 vertex 1.775203e+001 3.615100e+000 3.200025e+000 vertex 1.775203e+001 3.615100e+000 5.200025e+000 endloop endfacet facet normal 9.618220e-001 -2.736758e-001 0.000000e+000 outer loop vertex 1.775203e+001 3.615100e+000 5.200025e+000 vertex 1.775203e+001 3.615100e+000 3.200025e+000 vertex 1.777220e+001 3.679322e+000 3.200025e+000 endloop endfacet facet normal 9.461781e-001 -3.236462e-001 0.000000e+000 outer loop vertex 1.775203e+001 3.615100e+000 5.200025e+000 vertex 1.777220e+001 3.679322e+000 3.200025e+000 vertex 1.777220e+001 3.679322e+000 5.200025e+000 endloop endfacet facet normal 9.080523e-001 -4.188567e-001 0.000000e+000 outer loop vertex 1.777220e+001 3.679322e+000 5.200025e+000 vertex 1.777220e+001 3.679322e+000 3.200025e+000 vertex 1.780268e+001 3.741352e+000 3.200025e+000 endloop endfacet facet normal 8.857474e-001 -4.641676e-001 0.000000e+000 outer loop vertex 1.777220e+001 3.679322e+000 5.200025e+000 vertex 1.780268e+001 3.741352e+000 3.200025e+000 vertex 1.780268e+001 3.741352e+000 5.200025e+000 endloop endfacet facet normal 8.320678e-001 -5.546739e-001 0.000000e+000 outer loop vertex 1.780268e+001 3.741352e+000 5.200025e+000 vertex 1.780268e+001 3.741352e+000 3.200025e+000 vertex 1.784237e+001 3.797465e+000 3.200025e+000 endloop endfacet facet normal 8.002806e-001 -5.996258e-001 0.000000e+000 outer loop vertex 1.780268e+001 3.741352e+000 5.200025e+000 vertex 1.784237e+001 3.797465e+000 3.200025e+000 vertex 1.784237e+001 3.797465e+000 5.200025e+000 endloop endfacet facet normal 7.326506e-001 -6.806049e-001 0.000000e+000 outer loop vertex 1.784237e+001 3.797465e+000 5.200025e+000 vertex 1.784237e+001 3.797465e+000 3.200025e+000 vertex 1.789301e+001 3.848914e+000 3.200025e+000 endloop endfacet facet normal 6.971534e-001 -7.169219e-001 0.000000e+000 outer loop vertex 1.784237e+001 3.797465e+000 5.200025e+000 vertex 1.789301e+001 3.848914e+000 3.200025e+000 vertex 1.789301e+001 3.848914e+000 5.200025e+000 endloop endfacet facet normal 6.258441e-001 -7.799482e-001 0.000000e+000 outer loop vertex 1.789301e+001 3.848914e+000 5.200025e+000 vertex 1.789301e+001 3.848914e+000 3.200025e+000 vertex 1.796161e+001 3.901403e+000 3.200025e+000 endloop endfacet facet normal 5.904183e-001 -8.070974e-001 0.000000e+000 outer loop vertex 1.789301e+001 3.848914e+000 5.200025e+000 vertex 1.796161e+001 3.901403e+000 3.200025e+000 vertex 1.796161e+001 3.901403e+000 5.200025e+000 endloop endfacet facet normal 5.256945e-001 -8.506734e-001 0.000000e+000 outer loop vertex 1.796161e+001 3.901403e+000 5.200025e+000 vertex 1.796161e+001 3.901403e+000 3.200025e+000 vertex 1.805140e+001 3.952957e+000 3.200025e+000 endloop endfacet facet normal 4.968762e-001 -8.678215e-001 0.000000e+000 outer loop vertex 1.796161e+001 3.901403e+000 5.200025e+000 vertex 1.805140e+001 3.952957e+000 3.200025e+000 vertex 1.805140e+001 3.952957e+000 5.200025e+000 endloop endfacet facet normal 3.810412e-001 -9.245580e-001 0.000000e+000 outer loop vertex 1.805140e+001 3.952957e+000 5.200025e+000 vertex 1.805140e+001 3.952957e+000 3.200025e+000 vertex 1.815991e+001 3.997679e+000 3.200025e+000 endloop endfacet facet normal 3.643372e-001 -9.312671e-001 0.000000e+000 outer loop vertex 1.805140e+001 3.952957e+000 5.200025e+000 vertex 1.815991e+001 3.997679e+000 3.200025e+000 vertex 1.815991e+001 3.997679e+000 5.200025e+000 endloop endfacet facet normal 2.962035e-001 -9.551249e-001 0.000000e+000 outer loop vertex 1.815991e+001 3.997679e+000 5.200025e+000 vertex 1.815991e+001 3.997679e+000 3.200025e+000 vertex 1.832537e+001 4.043572e+000 3.200025e+000 endloop endfacet facet normal 2.438608e-001 -9.698102e-001 0.000000e+000 outer loop vertex 1.815991e+001 3.997679e+000 5.200025e+000 vertex 1.832537e+001 4.043572e+000 3.200025e+000 vertex 1.832537e+001 4.043572e+000 5.200025e+000 endloop endfacet facet normal 1.374697e-001 -9.905060e-001 0.000000e+000 outer loop vertex 1.832537e+001 4.043572e+000 5.200025e+000 vertex 1.832537e+001 4.043572e+000 3.200025e+000 vertex 1.861306e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 8.342099e-002 -9.965144e-001 0.000000e+000 outer loop vertex 1.832537e+001 4.043572e+000 5.200025e+000 vertex 1.861306e+001 4.069511e+000 3.200025e+000 vertex 1.861306e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 1.946947e+001 4.069511e+000 5.200025e+000 vertex 1.861306e+001 4.069511e+000 5.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 1.946947e+001 4.069511e+000 3.200025e+000 vertex 1.861306e+001 4.069511e+000 5.200025e+000 vertex 1.861306e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 9.020448e-001 4.316425e-001 0.000000e+000 outer loop vertex 1.926255e+001 4.501944e+000 5.200025e+000 vertex 1.946947e+001 4.069511e+000 5.200025e+000 vertex 1.926255e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 9.020448e-001 4.316425e-001 0.000000e+000 outer loop vertex 1.926255e+001 4.501944e+000 3.200025e+000 vertex 1.946947e+001 4.069511e+000 5.200025e+000 vertex 1.946947e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 1.818062e+001 4.501944e+000 5.200025e+000 vertex 1.926255e+001 4.501944e+000 5.200025e+000 vertex 1.818062e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 1.818062e+001 4.501944e+000 3.200025e+000 vertex 1.926255e+001 4.501944e+000 5.200025e+000 vertex 1.926255e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal -5.065971e-002 9.987160e-001 0.000000e+000 outer loop vertex 1.818062e+001 4.501944e+000 5.200025e+000 vertex 1.818062e+001 4.501944e+000 3.200025e+000 vertex 1.764915e+001 4.469552e+000 3.200025e+000 endloop endfacet facet normal -9.276488e-002 9.956880e-001 0.000000e+000 outer loop vertex 1.818062e+001 4.501944e+000 5.200025e+000 vertex 1.764915e+001 4.469552e+000 3.200025e+000 vertex 1.764915e+001 4.469552e+000 5.200025e+000 endloop endfacet facet normal -1.847166e-001 9.827918e-001 0.000000e+000 outer loop vertex 1.764915e+001 4.469552e+000 5.200025e+000 vertex 1.764915e+001 4.469552e+000 3.200025e+000 vertex 1.731359e+001 4.400511e+000 3.200025e+000 endloop endfacet facet normal -2.344550e-001 9.721270e-001 0.000000e+000 outer loop vertex 1.764915e+001 4.469552e+000 5.200025e+000 vertex 1.731359e+001 4.400511e+000 3.200025e+000 vertex 1.731359e+001 4.400511e+000 5.200025e+000 endloop endfacet facet normal -3.312091e-001 9.435574e-001 0.000000e+000 outer loop vertex 1.731359e+001 4.400511e+000 5.200025e+000 vertex 1.731359e+001 4.400511e+000 3.200025e+000 vertex 1.709907e+001 4.321096e+000 3.200025e+000 endloop endfacet facet normal -3.782410e-001 9.257072e-001 0.000000e+000 outer loop vertex 1.731359e+001 4.400511e+000 5.200025e+000 vertex 1.709907e+001 4.321096e+000 3.200025e+000 vertex 1.709907e+001 4.321096e+000 5.200025e+000 endloop endfacet facet normal -4.737846e-001 8.806407e-001 0.000000e+000 outer loop vertex 1.709907e+001 4.321096e+000 5.200025e+000 vertex 1.709907e+001 4.321096e+000 3.200025e+000 vertex 1.693494e+001 4.227113e+000 3.200025e+000 endloop endfacet facet normal -5.220559e-001 8.529113e-001 0.000000e+000 outer loop vertex 1.709907e+001 4.321096e+000 5.200025e+000 vertex 1.693494e+001 4.227113e+000 3.200025e+000 vertex 1.693494e+001 4.227113e+000 5.200025e+000 endloop endfacet facet normal -6.085090e-001 7.935470e-001 0.000000e+000 outer loop vertex 1.693494e+001 4.227113e+000 5.200025e+000 vertex 1.693494e+001 4.227113e+000 3.200025e+000 vertex 1.684071e+001 4.151348e+000 3.200025e+000 endloop endfacet facet normal -6.470569e-001 7.624417e-001 0.000000e+000 outer loop vertex 1.693494e+001 4.227113e+000 5.200025e+000 vertex 1.684071e+001 4.151348e+000 3.200025e+000 vertex 1.684071e+001 4.151348e+000 5.200025e+000 endloop endfacet facet normal -7.202287e-001 6.937367e-001 0.000000e+000 outer loop vertex 1.684071e+001 4.151348e+000 5.200025e+000 vertex 1.684071e+001 4.151348e+000 3.200025e+000 vertex 1.676508e+001 4.068985e+000 3.200025e+000 endloop endfacet facet normal -7.547431e-001 6.560205e-001 0.000000e+000 outer loop vertex 1.684071e+001 4.151348e+000 5.200025e+000 vertex 1.676508e+001 4.068985e+000 3.200025e+000 vertex 1.676508e+001 4.068985e+000 5.200025e+000 endloop endfacet facet normal -7.956098e-001 6.058095e-001 0.000000e+000 outer loop vertex 1.676508e+001 4.068985e+000 5.200025e+000 vertex 1.676508e+001 4.068985e+000 3.200025e+000 vertex 1.674828e+001 4.046607e+000 3.200025e+000 endloop endfacet facet normal -8.038678e-001 5.948079e-001 0.000000e+000 outer loop vertex 1.676508e+001 4.068985e+000 5.200025e+000 vertex 1.674828e+001 4.046607e+000 3.200025e+000 vertex 1.674828e+001 4.046607e+000 5.200025e+000 endloop endfacet facet normal -8.436589e-001 5.368795e-001 0.000000e+000 outer loop vertex 1.674828e+001 4.046607e+000 5.200025e+000 vertex 1.674828e+001 4.046607e+000 3.200025e+000 vertex 1.668431e+001 3.939104e+000 3.200025e+000 endloop endfacet facet normal -8.727381e-001 4.881888e-001 0.000000e+000 outer loop vertex 1.674828e+001 4.046607e+000 5.200025e+000 vertex 1.668431e+001 3.939104e+000 3.200025e+000 vertex 1.668431e+001 3.939104e+000 5.200025e+000 endloop endfacet facet normal -9.206166e-001 3.904678e-001 0.000000e+000 outer loop vertex 1.668431e+001 3.939104e+000 5.200025e+000 vertex 1.668431e+001 3.939104e+000 3.200025e+000 vertex 1.664092e+001 3.828664e+000 3.200025e+000 endloop endfacet facet normal -9.398310e-001 3.416398e-001 0.000000e+000 outer loop vertex 1.668431e+001 3.939104e+000 5.200025e+000 vertex 1.664092e+001 3.828664e+000 3.200025e+000 vertex 1.664092e+001 3.828664e+000 5.200025e+000 endloop endfacet facet normal -9.701862e-001 2.423605e-001 0.000000e+000 outer loop vertex 1.664092e+001 3.828664e+000 5.200025e+000 vertex 1.664092e+001 3.828664e+000 3.200025e+000 vertex 1.661395e+001 3.707921e+000 3.200025e+000 endloop endfacet facet normal -9.814078e-001 1.919340e-001 0.000000e+000 outer loop vertex 1.664092e+001 3.828664e+000 5.200025e+000 vertex 1.661395e+001 3.707921e+000 3.200025e+000 vertex 1.661395e+001 3.707921e+000 5.200025e+000 endloop endfacet facet normal -9.946787e-001 1.030253e-001 0.000000e+000 outer loop vertex 1.661395e+001 3.707921e+000 5.200025e+000 vertex 1.661395e+001 3.707921e+000 3.200025e+000 vertex 1.660461e+001 3.566978e+000 3.200025e+000 endloop endfacet facet normal -9.979041e-001 6.471089e-002 0.000000e+000 outer loop vertex 1.661395e+001 3.707921e+000 5.200025e+000 vertex 1.660461e+001 3.566978e+000 3.200025e+000 vertex 1.660461e+001 3.566978e+000 5.200025e+000 endloop endfacet facet normal -9.970961e-001 -7.615354e-002 0.000000e+000 outer loop vertex 1.660461e+001 3.566978e+000 5.200025e+000 vertex 1.660461e+001 3.566978e+000 3.200025e+000 vertex 1.661873e+001 3.408270e+000 3.200025e+000 endloop endfacet facet normal -9.916326e-001 -1.290919e-001 0.000000e+000 outer loop vertex 1.660461e+001 3.566978e+000 5.200025e+000 vertex 1.661873e+001 3.408270e+000 3.200025e+000 vertex 1.661873e+001 3.408270e+000 5.200025e+000 endloop endfacet facet normal -9.723833e-001 -2.333898e-001 0.000000e+000 outer loop vertex 1.661873e+001 3.408270e+000 5.200025e+000 vertex 1.661873e+001 3.408270e+000 3.200025e+000 vertex 1.665080e+001 3.287392e+000 3.200025e+000 endloop endfacet facet normal -9.586018e-001 -2.847502e-001 0.000000e+000 outer loop vertex 1.661873e+001 3.408270e+000 5.200025e+000 vertex 1.665080e+001 3.287392e+000 3.200025e+000 vertex 1.665080e+001 3.287392e+000 5.200025e+000 endloop endfacet facet normal -9.240387e-001 -3.822989e-001 0.000000e+000 outer loop vertex 1.665080e+001 3.287392e+000 5.200025e+000 vertex 1.665080e+001 3.287392e+000 3.200025e+000 vertex 1.670302e+001 3.170838e+000 3.200025e+000 endloop endfacet facet normal -9.035059e-001 -4.285757e-001 0.000000e+000 outer loop vertex 1.665080e+001 3.287392e+000 5.200025e+000 vertex 1.670302e+001 3.170838e+000 3.200025e+000 vertex 1.670302e+001 3.170838e+000 5.200025e+000 endloop endfacet facet normal -8.536287e-001 -5.208820e-001 0.000000e+000 outer loop vertex 1.670302e+001 3.170838e+000 5.200025e+000 vertex 1.670302e+001 3.170838e+000 3.200025e+000 vertex 1.677189e+001 3.065296e+000 3.200025e+000 endloop endfacet facet normal -8.239152e-001 -5.667131e-001 0.000000e+000 outer loop vertex 1.670302e+001 3.170838e+000 5.200025e+000 vertex 1.677189e+001 3.065296e+000 3.200025e+000 vertex 1.677189e+001 3.065296e+000 5.200025e+000 endloop endfacet facet normal -7.599650e-001 -6.499640e-001 0.000000e+000 outer loop vertex 1.677189e+001 3.065296e+000 5.200025e+000 vertex 1.677189e+001 3.065296e+000 3.200025e+000 vertex 1.687265e+001 2.954101e+000 3.200025e+000 endloop endfacet facet normal -7.260555e-001 -6.876361e-001 0.000000e+000 outer loop vertex 1.677189e+001 3.065296e+000 5.200025e+000 vertex 1.687265e+001 2.954101e+000 3.200025e+000 vertex 1.687265e+001 2.954101e+000 5.200025e+000 endloop endfacet facet normal -6.479832e-001 -7.616546e-001 0.000000e+000 outer loop vertex 1.687265e+001 2.954101e+000 5.200025e+000 vertex 1.687265e+001 2.954101e+000 3.200025e+000 vertex 1.703224e+001 2.826606e+000 3.200025e+000 endloop endfacet facet normal -6.033326e-001 -7.974897e-001 0.000000e+000 outer loop vertex 1.687265e+001 2.954101e+000 5.200025e+000 vertex 1.703224e+001 2.826606e+000 3.200025e+000 vertex 1.703224e+001 2.826606e+000 5.200025e+000 endloop endfacet facet normal -5.181997e-001 -8.552596e-001 0.000000e+000 outer loop vertex 1.703224e+001 2.826606e+000 5.200025e+000 vertex 1.703224e+001 2.826606e+000 3.200025e+000 vertex 1.721914e+001 2.718450e+000 3.200025e+000 endloop endfacet facet normal -4.783654e-001 -8.781609e-001 0.000000e+000 outer loop vertex 1.703224e+001 2.826606e+000 5.200025e+000 vertex 1.721914e+001 2.718450e+000 3.200025e+000 vertex 1.721914e+001 2.718450e+000 5.200025e+000 endloop endfacet facet normal -4.061978e-001 -9.137852e-001 0.000000e+000 outer loop vertex 1.721914e+001 2.718450e+000 5.200025e+000 vertex 1.721914e+001 2.718450e+000 3.200025e+000 vertex 1.746610e+001 2.614275e+000 3.200025e+000 endloop endfacet facet normal -3.742613e-001 -9.273233e-001 0.000000e+000 outer loop vertex 1.721914e+001 2.718450e+000 5.200025e+000 vertex 1.746610e+001 2.614275e+000 3.200025e+000 vertex 1.746610e+001 2.614275e+000 5.200025e+000 endloop endfacet facet normal -3.187949e-001 -9.478237e-001 0.000000e+000 outer loop vertex 1.746610e+001 2.614275e+000 5.200025e+000 vertex 1.746610e+001 2.614275e+000 3.200025e+000 vertex 1.756545e+001 2.580856e+000 3.200025e+000 endloop endfacet facet normal -3.149365e-001 -9.491128e-001 0.000000e+000 outer loop vertex 1.746610e+001 2.614275e+000 5.200025e+000 vertex 1.756545e+001 2.580856e+000 3.200025e+000 vertex 1.756545e+001 2.580856e+000 5.200025e+000 endloop endfacet facet normal -2.561716e-001 -9.666314e-001 0.000000e+000 outer loop vertex 1.756545e+001 2.580856e+000 5.200025e+000 vertex 1.756545e+001 2.580856e+000 3.200025e+000 vertex 1.815905e+001 2.443472e+000 3.200025e+000 endloop endfacet facet normal -2.002455e-001 -9.797457e-001 0.000000e+000 outer loop vertex 1.756545e+001 2.580856e+000 5.200025e+000 vertex 1.815905e+001 2.443472e+000 3.200025e+000 vertex 1.815905e+001 2.443472e+000 5.200025e+000 endloop endfacet facet normal -9.949169e-002 -9.950384e-001 0.000000e+000 outer loop vertex 1.815905e+001 2.443472e+000 5.200025e+000 vertex 1.815905e+001 2.443472e+000 3.200025e+000 vertex 1.887150e+001 2.393836e+000 3.200025e+000 endloop endfacet facet normal -5.484978e-002 -9.984947e-001 0.000000e+000 outer loop vertex 1.815905e+001 2.443472e+000 5.200025e+000 vertex 1.887150e+001 2.393836e+000 3.200025e+000 vertex 1.887150e+001 2.393836e+000 5.200025e+000 endloop endfacet facet normal 3.675729e-002 -9.993242e-001 0.000000e+000 outer loop vertex 1.887150e+001 2.393836e+000 5.200025e+000 vertex 1.887150e+001 2.393836e+000 3.200025e+000 vertex 1.929369e+001 2.411791e+000 3.200025e+000 endloop endfacet facet normal 6.348281e-002 -9.979829e-001 0.000000e+000 outer loop vertex 1.887150e+001 2.393836e+000 5.200025e+000 vertex 1.929369e+001 2.411791e+000 3.200025e+000 vertex 1.929369e+001 2.411791e+000 5.200025e+000 endloop endfacet facet normal 1.382148e-001 -9.904023e-001 0.000000e+000 outer loop vertex 1.929369e+001 2.411791e+000 5.200025e+000 vertex 1.929369e+001 2.411791e+000 3.200025e+000 vertex 1.985567e+001 2.503588e+000 3.200025e+000 endloop endfacet facet normal 1.860739e-001 -9.825358e-001 0.000000e+000 outer loop vertex 1.929369e+001 2.411791e+000 5.200025e+000 vertex 1.985567e+001 2.503588e+000 3.200025e+000 vertex 1.985567e+001 2.503588e+000 5.200025e+000 endloop endfacet facet normal 2.857718e-001 -9.582977e-001 0.000000e+000 outer loop vertex 1.985567e+001 2.503588e+000 5.200025e+000 vertex 1.985567e+001 2.503588e+000 3.200025e+000 vertex 2.038586e+001 2.682687e+000 3.200025e+000 endloop endfacet facet normal 3.374692e-001 -9.413366e-001 0.000000e+000 outer loop vertex 1.985567e+001 2.503588e+000 5.200025e+000 vertex 2.038586e+001 2.682687e+000 3.200025e+000 vertex 2.038586e+001 2.682687e+000 5.200025e+000 endloop endfacet facet normal 4.357744e-001 -9.000559e-001 0.000000e+000 outer loop vertex 2.038586e+001 2.682687e+000 5.200025e+000 vertex 2.038586e+001 2.682687e+000 3.200025e+000 vertex 2.049224e+001 2.734193e+000 3.200025e+000 endloop endfacet facet normal 4.426808e-001 -8.966793e-001 0.000000e+000 outer loop vertex 2.038586e+001 2.682687e+000 5.200025e+000 vertex 2.049224e+001 2.734193e+000 3.200025e+000 vertex 2.049224e+001 2.734193e+000 5.200025e+000 endloop endfacet facet normal 4.971292e-001 -8.676765e-001 0.000000e+000 outer loop vertex 2.049224e+001 2.734193e+000 5.200025e+000 vertex 2.049224e+001 2.734193e+000 3.200025e+000 vertex 2.074987e+001 2.891915e+000 3.200025e+000 endloop endfacet facet normal 5.433807e-001 -8.394864e-001 0.000000e+000 outer loop vertex 2.049224e+001 2.734193e+000 5.200025e+000 vertex 2.074987e+001 2.891915e+000 3.200025e+000 vertex 2.074987e+001 2.891915e+000 5.200025e+000 endloop endfacet facet normal 6.318894e-001 -7.750585e-001 0.000000e+000 outer loop vertex 2.074987e+001 2.891915e+000 5.200025e+000 vertex 2.074987e+001 2.891915e+000 3.200025e+000 vertex 2.092884e+001 3.046693e+000 3.200025e+000 endloop endfacet facet normal 6.740489e-001 -7.386867e-001 0.000000e+000 outer loop vertex 2.074987e+001 2.891915e+000 5.200025e+000 vertex 2.092884e+001 3.046693e+000 3.200025e+000 vertex 2.092884e+001 3.046693e+000 5.200025e+000 endloop endfacet facet normal 7.505754e-001 -6.607847e-001 0.000000e+000 outer loop vertex 2.092884e+001 3.046693e+000 5.200025e+000 vertex 2.092884e+001 3.046693e+000 3.200025e+000 vertex 2.104632e+001 3.187544e+000 3.200025e+000 endloop endfacet facet normal 7.850821e-001 -6.193917e-001 0.000000e+000 outer loop vertex 2.092884e+001 3.046693e+000 5.200025e+000 vertex 2.104632e+001 3.187544e+000 3.200025e+000 vertex 2.104632e+001 3.187544e+000 5.200025e+000 endloop endfacet facet normal 8.448125e-001 -5.350624e-001 0.000000e+000 outer loop vertex 2.104632e+001 3.187544e+000 5.200025e+000 vertex 2.104632e+001 3.187544e+000 3.200025e+000 vertex 2.113661e+001 3.336027e+000 3.200025e+000 endloop endfacet facet normal 8.703849e-001 -4.923721e-001 0.000000e+000 outer loop vertex 2.104632e+001 3.187544e+000 5.200025e+000 vertex 2.113661e+001 3.336027e+000 3.200025e+000 vertex 2.113661e+001 3.336027e+000 5.200025e+000 endloop endfacet facet normal 9.154238e-001 -4.024915e-001 0.000000e+000 outer loop vertex 2.113661e+001 3.336027e+000 5.200025e+000 vertex 2.113661e+001 3.336027e+000 3.200025e+000 vertex 2.119694e+001 3.484721e+000 3.200025e+000 endloop endfacet facet normal 9.347740e-001 -3.552428e-001 0.000000e+000 outer loop vertex 2.113661e+001 3.336027e+000 5.200025e+000 vertex 2.119694e+001 3.484721e+000 3.200025e+000 vertex 2.119694e+001 3.484721e+000 5.200025e+000 endloop endfacet facet normal 9.663878e-001 -2.570889e-001 0.000000e+000 outer loop vertex 2.119694e+001 3.484721e+000 5.200025e+000 vertex 2.119694e+001 3.484721e+000 3.200025e+000 vertex 2.123813e+001 3.658577e+000 3.200025e+000 endloop endfacet facet normal 9.785221e-001 -2.061418e-001 0.000000e+000 outer loop vertex 2.119694e+001 3.484721e+000 5.200025e+000 vertex 2.123813e+001 3.658577e+000 3.200025e+000 vertex 2.123813e+001 3.658577e+000 5.200025e+000 endloop endfacet facet normal 9.939307e-001 -1.100076e-001 0.000000e+000 outer loop vertex 2.123813e+001 3.658577e+000 5.200025e+000 vertex 2.123813e+001 3.658577e+000 3.200025e+000 vertex 2.125326e+001 3.859207e+000 3.200025e+000 endloop endfacet facet normal 9.978900e-001 -6.492777e-002 0.000000e+000 outer loop vertex 2.123813e+001 3.658577e+000 5.200025e+000 vertex 2.125326e+001 3.859207e+000 3.200025e+000 vertex 2.125326e+001 3.859207e+000 5.200025e+000 endloop endfacet facet normal 9.994057e-001 3.446956e-002 0.000000e+000 outer loop vertex 2.125326e+001 3.859207e+000 5.200025e+000 vertex 2.125326e+001 3.859207e+000 3.200025e+000 vertex 2.125000e+001 3.953780e+000 3.200025e+000 endloop endfacet facet normal 9.986917e-001 5.113651e-002 0.000000e+000 outer loop vertex 2.125326e+001 3.859207e+000 5.200025e+000 vertex 2.125000e+001 3.953780e+000 3.200025e+000 vertex 2.125000e+001 3.953780e+000 5.200025e+000 endloop endfacet facet normal 9.927962e-001 1.198145e-001 0.000000e+000 outer loop vertex 2.125000e+001 3.953780e+000 5.200025e+000 vertex 2.125000e+001 3.953780e+000 3.200025e+000 vertex 2.120317e+001 4.250323e+000 3.200025e+000 endloop endfacet facet normal 9.851565e-001 1.716585e-001 0.000000e+000 outer loop vertex 2.125000e+001 3.953780e+000 5.200025e+000 vertex 2.120317e+001 4.250323e+000 3.200025e+000 vertex 2.120317e+001 4.250323e+000 5.200025e+000 endloop endfacet facet normal 9.741271e-001 2.260013e-001 0.000000e+000 outer loop vertex 2.120317e+001 4.250323e+000 5.200025e+000 vertex 2.120317e+001 4.250323e+000 3.200025e+000 vertex 2.119498e+001 4.285280e+000 3.200025e+000 endloop endfacet facet normal 9.734007e-001 2.291092e-001 0.000000e+000 outer loop vertex 2.120317e+001 4.250323e+000 5.200025e+000 vertex 2.119498e+001 4.285280e+000 3.200025e+000 vertex 2.119498e+001 4.285280e+000 5.200025e+000 endloop endfacet facet normal 9.628728e-001 2.699553e-001 0.000000e+000 outer loop vertex 2.119498e+001 4.285280e+000 5.200025e+000 vertex 2.119498e+001 4.285280e+000 3.200025e+000 vertex 2.098772e+001 4.933215e+000 3.200025e+000 endloop endfacet facet normal 9.515991e-001 3.073420e-001 0.000000e+000 outer loop vertex 2.119498e+001 4.285280e+000 5.200025e+000 vertex 2.098772e+001 4.933215e+000 3.200025e+000 vertex 2.098772e+001 4.933215e+000 5.200025e+000 endloop endfacet facet normal 9.517063e-001 3.070099e-001 0.000000e+000 outer loop vertex 2.098772e+001 4.933215e+000 5.200025e+000 vertex 2.098772e+001 4.933215e+000 3.200025e+000 vertex 2.079131e+001 5.542764e+000 3.200025e+000 endloop endfacet facet normal 9.630615e-001 2.692816e-001 0.000000e+000 outer loop vertex 2.098772e+001 4.933215e+000 5.200025e+000 vertex 2.079131e+001 5.542764e+000 3.200025e+000 vertex 2.079131e+001 5.542764e+000 5.200025e+000 endloop endfacet facet normal 9.845119e-001 1.753180e-001 0.000000e+000 outer loop vertex 2.079131e+001 5.542764e+000 5.200025e+000 vertex 2.079131e+001 5.542764e+000 3.200025e+000 vertex 2.076677e+001 5.706336e+000 3.200025e+000 endloop endfacet facet normal 9.929320e-001 1.186846e-001 0.000000e+000 outer loop vertex 2.079131e+001 5.542764e+000 5.200025e+000 vertex 2.076677e+001 5.706336e+000 3.200025e+000 vertex 2.076677e+001 5.706336e+000 5.200025e+000 endloop endfacet facet normal 9.985574e-001 -5.369433e-002 0.000000e+000 outer loop vertex 2.076677e+001 5.706336e+000 5.200025e+000 vertex 2.076677e+001 5.706336e+000 3.200025e+000 vertex 2.076910e+001 5.749654e+000 3.200025e+000 endloop endfacet facet normal 9.980505e-001 -6.241332e-002 0.000000e+000 outer loop vertex 2.076677e+001 5.706336e+000 5.200025e+000 vertex 2.076910e+001 5.749654e+000 3.200025e+000 vertex 2.076910e+001 5.749654e+000 5.200025e+000 endloop endfacet facet normal 9.926135e-001 -1.213191e-001 0.000000e+000 outer loop vertex 2.076910e+001 5.749654e+000 5.200025e+000 vertex 2.076910e+001 5.749654e+000 3.200025e+000 vertex 2.077898e+001 5.820881e+000 3.200025e+000 endloop endfacet facet normal 9.852137e-001 -1.713298e-001 0.000000e+000 outer loop vertex 2.076910e+001 5.749654e+000 5.200025e+000 vertex 2.077898e+001 5.820881e+000 3.200025e+000 vertex 2.077898e+001 5.820881e+000 5.200025e+000 endloop endfacet facet normal 9.631861e-001 -2.688355e-001 0.000000e+000 outer loop vertex 2.077898e+001 5.820881e+000 5.200025e+000 vertex 2.077898e+001 5.820881e+000 3.200025e+000 vertex 2.079353e+001 5.868840e+000 3.200025e+000 endloop endfacet facet normal 9.486427e-001 -3.163496e-001 0.000000e+000 outer loop vertex 2.077898e+001 5.820881e+000 5.200025e+000 vertex 2.079353e+001 5.868840e+000 3.200025e+000 vertex 2.079353e+001 5.868840e+000 5.200025e+000 endloop endfacet facet normal 9.115970e-001 -4.110850e-001 0.000000e+000 outer loop vertex 2.079353e+001 5.868840e+000 5.200025e+000 vertex 2.079353e+001 5.868840e+000 3.200025e+000 vertex 2.081412e+001 5.911561e+000 3.200025e+000 endloop endfacet facet normal 8.888446e-001 -4.582087e-001 0.000000e+000 outer loop vertex 2.079353e+001 5.868840e+000 5.200025e+000 vertex 2.081412e+001 5.911561e+000 3.200025e+000 vertex 2.081412e+001 5.911561e+000 5.200025e+000 endloop endfacet facet normal 8.361927e-001 -5.484359e-001 0.000000e+000 outer loop vertex 2.081412e+001 5.911561e+000 5.200025e+000 vertex 2.081412e+001 5.911561e+000 3.200025e+000 vertex 2.083975e+001 5.948543e+000 3.200025e+000 endloop endfacet facet normal 8.062813e-001 -5.915324e-001 0.000000e+000 outer loop vertex 2.081412e+001 5.911561e+000 5.200025e+000 vertex 2.083975e+001 5.948543e+000 3.200025e+000 vertex 2.083975e+001 5.948543e+000 5.200025e+000 endloop endfacet facet normal 7.366035e-001 -6.763248e-001 0.000000e+000 outer loop vertex 2.083975e+001 5.948543e+000 5.200025e+000 vertex 2.083975e+001 5.948543e+000 3.200025e+000 vertex 2.087238e+001 5.982143e+000 3.200025e+000 endloop endfacet facet normal 6.963946e-001 -7.176591e-001 0.000000e+000 outer loop vertex 2.083975e+001 5.948543e+000 5.200025e+000 vertex 2.087238e+001 5.982143e+000 3.200025e+000 vertex 2.087238e+001 5.982143e+000 5.200025e+000 endloop endfacet facet normal 6.108910e-001 -7.917147e-001 0.000000e+000 outer loop vertex 2.087238e+001 5.982143e+000 5.200025e+000 vertex 2.087238e+001 5.982143e+000 3.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 endloop endfacet facet normal 5.657297e-001 -8.245907e-001 0.000000e+000 outer loop vertex 2.087238e+001 5.982143e+000 5.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 vertex 2.091064e+001 6.009905e+000 5.200025e+000 endloop endfacet facet normal 4.748310e-001 -8.800770e-001 0.000000e+000 outer loop vertex 2.091064e+001 6.009905e+000 5.200025e+000 vertex 2.091064e+001 6.009905e+000 3.200025e+000 vertex 2.095458e+001 6.032044e+000 3.200025e+000 endloop endfacet facet normal 4.293634e-001 -9.031318e-001 0.000000e+000 outer loop vertex 2.091064e+001 6.009905e+000 5.200025e+000 vertex 2.095458e+001 6.032044e+000 3.200025e+000 vertex 2.095458e+001 6.032044e+000 5.200025e+000 endloop endfacet facet normal 3.375611e-001 -9.413037e-001 0.000000e+000 outer loop vertex 2.095458e+001 6.032044e+000 5.200025e+000 vertex 2.095458e+001 6.032044e+000 3.200025e+000 vertex 2.101403e+001 6.051478e+000 3.200025e+000 endloop endfacet facet normal 2.913123e-001 -9.566280e-001 0.000000e+000 outer loop vertex 2.095458e+001 6.032044e+000 5.200025e+000 vertex 2.101403e+001 6.051478e+000 3.200025e+000 vertex 2.101403e+001 6.051478e+000 5.200025e+000 endloop endfacet facet normal 1.950425e-001 -9.807948e-001 0.000000e+000 outer loop vertex 2.101403e+001 6.051478e+000 5.200025e+000 vertex 2.101403e+001 6.051478e+000 3.200025e+000 vertex 2.109454e+001 6.065140e+000 3.200025e+000 endloop endfacet facet normal 1.449706e-001 -9.894360e-001 0.000000e+000 outer loop vertex 2.101403e+001 6.051478e+000 5.200025e+000 vertex 2.109454e+001 6.065140e+000 3.200025e+000 vertex 2.109454e+001 6.065140e+000 5.200025e+000 endloop endfacet facet normal 7.429833e-002 -9.972361e-001 0.000000e+000 outer loop vertex 2.109454e+001 6.065140e+000 5.200025e+000 vertex 2.109454e+001 6.065140e+000 3.200025e+000 vertex 2.117556e+001 6.069511e+000 3.200025e+000 endloop endfacet facet normal 5.390254e-002 -9.985462e-001 0.000000e+000 outer loop vertex 2.109454e+001 6.065140e+000 5.200025e+000 vertex 2.117556e+001 6.069511e+000 3.200025e+000 vertex 2.117556e+001 6.069511e+000 5.200025e+000 endloop endfacet facet normal -5.880820e-002 -9.982693e-001 0.000000e+000 outer loop vertex 2.117556e+001 6.069511e+000 5.200025e+000 vertex 2.117556e+001 6.069511e+000 3.200025e+000 vertex 2.125293e+001 6.064973e+000 3.200025e+000 endloop endfacet facet normal -7.967159e-002 -9.968212e-001 0.000000e+000 outer loop vertex 2.117556e+001 6.069511e+000 5.200025e+000 vertex 2.125293e+001 6.064973e+000 3.200025e+000 vertex 2.125293e+001 6.064973e+000 5.200025e+000 endloop endfacet facet normal -9.541638e-002 -9.954374e-001 0.000000e+000 outer loop vertex 2.125293e+001 6.064973e+000 5.200025e+000 vertex 2.125293e+001 6.064973e+000 3.200025e+000 vertex 2.133012e+001 6.057687e+000 3.200025e+000 endloop endfacet facet normal -9.033913e-002 -9.959111e-001 0.000000e+000 outer loop vertex 2.125293e+001 6.064973e+000 5.200025e+000 vertex 2.133012e+001 6.057687e+000 3.200025e+000 vertex 2.133012e+001 6.057687e+000 5.200025e+000 endloop endfacet facet normal -9.836949e-001 1.798452e-001 0.000000e+000 outer loop vertex 2.133012e+001 6.057687e+000 5.200025e+000 vertex 2.133012e+001 6.057687e+000 3.200025e+000 vertex 2.131461e+001 5.972906e+000 3.200025e+000 endloop endfacet facet normal -9.873282e-001 1.586916e-001 0.000000e+000 outer loop vertex 2.133012e+001 6.057687e+000 5.200025e+000 vertex 2.131461e+001 5.972906e+000 3.200025e+000 vertex 2.131461e+001 5.972906e+000 5.200025e+000 endloop endfacet facet normal -9.938371e-001 1.108507e-001 0.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 5.200025e+000 vertex 2.131461e+001 5.972906e+000 3.200025e+000 vertex 2.130731e+001 5.887079e+000 3.200025e+000 endloop endfacet facet normal -9.964550e-001 8.412769e-002 0.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 5.200025e+000 vertex 2.130731e+001 5.887079e+000 3.200025e+000 vertex 2.130731e+001 5.887079e+000 5.200025e+000 endloop endfacet facet normal -9.976127e-001 -6.905733e-002 0.000000e+000 outer loop vertex 2.130731e+001 5.887079e+000 5.200025e+000 vertex 2.130731e+001 5.887079e+000 3.200025e+000 vertex 2.131480e+001 5.783948e+000 3.200025e+000 endloop endfacet facet normal -9.939240e-001 -1.100691e-001 0.000000e+000 outer loop vertex 2.130731e+001 5.887079e+000 5.200025e+000 vertex 2.131480e+001 5.783948e+000 3.200025e+000 vertex 2.131480e+001 5.783948e+000 5.200025e+000 endloop endfacet facet normal -9.793428e-001 -2.022071e-001 0.000000e+000 outer loop vertex 2.131480e+001 5.783948e+000 5.200025e+000 vertex 2.131480e+001 5.783948e+000 3.200025e+000 vertex 2.133514e+001 5.697336e+000 3.200025e+000 endloop endfacet facet normal -9.674202e-001 -2.531762e-001 0.000000e+000 outer loop vertex 2.131480e+001 5.783948e+000 5.200025e+000 vertex 2.133514e+001 5.697336e+000 3.200025e+000 vertex 2.133514e+001 5.697336e+000 5.200025e+000 endloop endfacet facet normal -9.372860e-001 -3.485612e-001 0.000000e+000 outer loop vertex 2.133514e+001 5.697336e+000 5.200025e+000 vertex 2.133514e+001 5.697336e+000 3.200025e+000 vertex 2.137114e+001 5.608021e+000 3.200025e+000 endloop endfacet facet normal -9.194915e-001 -3.931100e-001 0.000000e+000 outer loop vertex 2.133514e+001 5.697336e+000 5.200025e+000 vertex 2.137114e+001 5.608021e+000 3.200025e+000 vertex 2.137114e+001 5.608021e+000 5.200025e+000 endloop endfacet facet normal -8.742332e-001 -4.855062e-001 0.000000e+000 outer loop vertex 2.137114e+001 5.608021e+000 5.200025e+000 vertex 2.137114e+001 5.608021e+000 3.200025e+000 vertex 2.141991e+001 5.525266e+000 3.200025e+000 endloop endfacet facet normal -8.460978e-001 -5.330277e-001 0.000000e+000 outer loop vertex 2.137114e+001 5.608021e+000 5.200025e+000 vertex 2.141991e+001 5.525266e+000 3.200025e+000 vertex 2.141991e+001 5.525266e+000 5.200025e+000 endloop endfacet facet normal -7.827671e-001 -6.223149e-001 0.000000e+000 outer loop vertex 2.141991e+001 5.525266e+000 5.200025e+000 vertex 2.141991e+001 5.525266e+000 3.200025e+000 vertex 2.150039e+001 5.431047e+000 3.200025e+000 endloop endfacet facet normal -7.476265e-001 -6.641194e-001 0.000000e+000 outer loop vertex 2.141991e+001 5.525266e+000 5.200025e+000 vertex 2.150039e+001 5.431047e+000 3.200025e+000 vertex 2.150039e+001 5.431047e+000 5.200025e+000 endloop endfacet facet normal -6.700522e-001 -7.423140e-001 0.000000e+000 outer loop vertex 2.150039e+001 5.431047e+000 5.200025e+000 vertex 2.150039e+001 5.431047e+000 3.200025e+000 vertex 2.159562e+001 5.349894e+000 3.200025e+000 endloop endfacet facet normal -6.275167e-001 -7.786031e-001 0.000000e+000 outer loop vertex 2.150039e+001 5.431047e+000 5.200025e+000 vertex 2.159562e+001 5.349894e+000 3.200025e+000 vertex 2.159562e+001 5.349894e+000 5.200025e+000 endloop endfacet facet normal -5.411766e-001 -8.409089e-001 0.000000e+000 outer loop vertex 2.159562e+001 5.349894e+000 5.200025e+000 vertex 2.159562e+001 5.349894e+000 3.200025e+000 vertex 2.169907e+001 5.286629e+000 3.200025e+000 endloop endfacet facet normal -4.976832e-001 -8.673589e-001 0.000000e+000 outer loop vertex 2.159562e+001 5.349894e+000 5.200025e+000 vertex 2.169907e+001 5.286629e+000 3.200025e+000 vertex 2.169907e+001 5.286629e+000 5.200025e+000 endloop endfacet facet normal -4.060884e-001 -9.138338e-001 0.000000e+000 outer loop vertex 2.169907e+001 5.286629e+000 5.200025e+000 vertex 2.169907e+001 5.286629e+000 3.200025e+000 vertex 2.180478e+001 5.243255e+000 3.200025e+000 endloop endfacet facet normal -3.579307e-001 -9.337481e-001 0.000000e+000 outer loop vertex 2.169907e+001 5.286629e+000 5.200025e+000 vertex 2.180478e+001 5.243255e+000 3.200025e+000 vertex 2.180478e+001 5.243255e+000 5.200025e+000 endloop endfacet facet normal -2.584190e-001 -9.660329e-001 0.000000e+000 outer loop vertex 2.180478e+001 5.243255e+000 5.200025e+000 vertex 2.180478e+001 5.243255e+000 3.200025e+000 vertex 2.192347e+001 5.215448e+000 3.200025e+000 endloop endfacet facet normal -2.070418e-001 -9.783321e-001 0.000000e+000 outer loop vertex 2.180478e+001 5.243255e+000 5.200025e+000 vertex 2.192347e+001 5.215448e+000 3.200025e+000 vertex 2.192347e+001 5.215448e+000 5.200025e+000 endloop endfacet facet normal -1.124702e-001 -9.936551e-001 0.000000e+000 outer loop vertex 2.192347e+001 5.215448e+000 5.200025e+000 vertex 2.192347e+001 5.215448e+000 3.200025e+000 vertex 2.206238e+001 5.204647e+000 3.200025e+000 endloop endfacet facet normal -6.941876e-002 -9.975876e-001 0.000000e+000 outer loop vertex 2.192347e+001 5.215448e+000 5.200025e+000 vertex 2.206238e+001 5.204647e+000 3.200025e+000 vertex 2.206238e+001 5.204647e+000 5.200025e+000 endloop endfacet facet normal 4.175248e-002 -9.991280e-001 0.000000e+000 outer loop vertex 2.206238e+001 5.204647e+000 5.200025e+000 vertex 2.206238e+001 5.204647e+000 3.200025e+000 vertex 2.213434e+001 5.207653e+000 3.200025e+000 endloop endfacet facet normal 5.714317e-002 -9.983659e-001 0.000000e+000 outer loop vertex 2.206238e+001 5.204647e+000 5.200025e+000 vertex 2.213434e+001 5.207653e+000 3.200025e+000 vertex 2.213434e+001 5.207653e+000 5.200025e+000 endloop endfacet facet normal 1.291830e-001 -9.916208e-001 0.000000e+000 outer loop vertex 2.213434e+001 5.207653e+000 5.200025e+000 vertex 2.213434e+001 5.207653e+000 3.200025e+000 vertex 2.227851e+001 5.231004e+000 3.200025e+000 endloop endfacet facet normal 1.856129e-001 -9.826230e-001 0.000000e+000 outer loop vertex 2.213434e+001 5.207653e+000 5.200025e+000 vertex 2.227851e+001 5.231004e+000 3.200025e+000 vertex 2.227851e+001 5.231004e+000 5.200025e+000 endloop endfacet facet normal 2.931087e-001 -9.560791e-001 0.000000e+000 outer loop vertex 2.227851e+001 5.231004e+000 5.200025e+000 vertex 2.227851e+001 5.231004e+000 3.200025e+000 vertex 2.238523e+001 5.266520e+000 3.200025e+000 endloop endfacet facet normal 3.442595e-001 -9.388745e-001 0.000000e+000 outer loop vertex 2.227851e+001 5.231004e+000 5.200025e+000 vertex 2.238523e+001 5.266520e+000 3.200025e+000 vertex 2.238523e+001 5.266520e+000 5.200025e+000 endloop endfacet facet normal 4.434745e-001 -8.962870e-001 0.000000e+000 outer loop vertex 2.238523e+001 5.266520e+000 5.200025e+000 vertex 2.238523e+001 5.266520e+000 3.200025e+000 vertex 2.250027e+001 5.327528e+000 3.200025e+000 endloop endfacet facet normal 4.915221e-001 -8.708651e-001 0.000000e+000 outer loop vertex 2.238523e+001 5.266520e+000 5.200025e+000 vertex 2.250027e+001 5.327528e+000 3.200025e+000 vertex 2.250027e+001 5.327528e+000 5.200025e+000 endloop endfacet facet normal 5.854415e-001 -8.107147e-001 0.000000e+000 outer loop vertex 2.250027e+001 5.327528e+000 5.200025e+000 vertex 2.250027e+001 5.327528e+000 3.200025e+000 vertex 2.260748e+001 5.410102e+000 3.200025e+000 endloop endfacet facet normal 6.311207e-001 -7.756847e-001 0.000000e+000 outer loop vertex 2.250027e+001 5.327528e+000 5.200025e+000 vertex 2.260748e+001 5.410102e+000 3.200025e+000 vertex 2.260748e+001 5.410102e+000 5.200025e+000 endloop endfacet facet normal 7.134382e-001 -7.007182e-001 0.000000e+000 outer loop vertex 2.260748e+001 5.410102e+000 5.200025e+000 vertex 2.260748e+001 5.410102e+000 3.200025e+000 vertex 2.269183e+001 5.500207e+000 3.200025e+000 endloop endfacet facet normal 7.503318e-001 -6.610613e-001 0.000000e+000 outer loop vertex 2.260748e+001 5.410102e+000 5.200025e+000 vertex 2.269183e+001 5.500207e+000 3.200025e+000 vertex 2.269183e+001 5.500207e+000 5.200025e+000 endloop endfacet facet normal 8.179095e-001 -5.753469e-001 0.000000e+000 outer loop vertex 2.269183e+001 5.500207e+000 5.200025e+000 vertex 2.269183e+001 5.500207e+000 3.200025e+000 vertex 2.274731e+001 5.583439e+000 3.200025e+000 endloop endfacet facet normal 8.484916e-001 -5.292088e-001 0.000000e+000 outer loop vertex 2.269183e+001 5.500207e+000 5.200025e+000 vertex 2.274731e+001 5.583439e+000 3.200025e+000 vertex 2.274731e+001 5.583439e+000 5.200025e+000 endloop endfacet facet normal 9.004661e-001 -4.349260e-001 0.000000e+000 outer loop vertex 2.274731e+001 5.583439e+000 5.200025e+000 vertex 2.274731e+001 5.583439e+000 3.200025e+000 vertex 2.278642e+001 5.670285e+000 3.200025e+000 endloop endfacet facet normal 9.221128e-001 -3.869211e-001 0.000000e+000 outer loop vertex 2.274731e+001 5.583439e+000 5.200025e+000 vertex 2.278642e+001 5.670285e+000 3.200025e+000 vertex 2.278642e+001 5.670285e+000 5.200025e+000 endloop endfacet facet normal 9.577931e-001 -2.874586e-001 0.000000e+000 outer loop vertex 2.278642e+001 5.670285e+000 5.200025e+000 vertex 2.278642e+001 5.670285e+000 3.200025e+000 vertex 2.281060e+001 5.758884e+000 3.200025e+000 endloop endfacet facet normal 9.717587e-001 -2.359767e-001 0.000000e+000 outer loop vertex 2.278642e+001 5.670285e+000 5.200025e+000 vertex 2.281060e+001 5.758884e+000 3.200025e+000 vertex 2.281060e+001 5.758884e+000 5.200025e+000 endloop endfacet facet normal 9.912230e-001 -1.322004e-001 0.000000e+000 outer loop vertex 2.281060e+001 5.758884e+000 5.200025e+000 vertex 2.281060e+001 5.758884e+000 3.200025e+000 vertex 2.282083e+001 5.876099e+000 3.200025e+000 endloop endfacet facet normal 9.968012e-001 -7.992079e-002 0.000000e+000 outer loop vertex 2.281060e+001 5.758884e+000 5.200025e+000 vertex 2.282083e+001 5.876099e+000 3.200025e+000 vertex 2.282083e+001 5.876099e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.282083e+001 5.876099e+000 5.200025e+000 vertex 2.281837e+001 5.934666e+000 5.200025e+000 vertex 2.131461e+001 5.972906e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.213434e+001 5.207653e+000 5.200025e+000 vertex 2.131461e+001 5.972906e+000 5.200025e+000 vertex 2.206238e+001 5.204647e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.206238e+001 5.204647e+000 5.200025e+000 vertex 2.131461e+001 5.972906e+000 5.200025e+000 vertex 2.130731e+001 5.887079e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.206238e+001 5.204647e+000 5.200025e+000 vertex 2.130731e+001 5.887079e+000 5.200025e+000 vertex 2.192347e+001 5.215448e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.192347e+001 5.215448e+000 5.200025e+000 vertex 2.130731e+001 5.887079e+000 5.200025e+000 vertex 2.131480e+001 5.783948e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.192347e+001 5.215448e+000 5.200025e+000 vertex 2.131480e+001 5.783948e+000 5.200025e+000 vertex 2.180478e+001 5.243255e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.180478e+001 5.243255e+000 5.200025e+000 vertex 2.131480e+001 5.783948e+000 5.200025e+000 vertex 2.133514e+001 5.697336e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.180478e+001 5.243255e+000 5.200025e+000 vertex 2.133514e+001 5.697336e+000 5.200025e+000 vertex 2.169907e+001 5.286629e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.169907e+001 5.286629e+000 5.200025e+000 vertex 2.133514e+001 5.697336e+000 5.200025e+000 vertex 2.137114e+001 5.608021e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.169907e+001 5.286629e+000 5.200025e+000 vertex 2.137114e+001 5.608021e+000 5.200025e+000 vertex 2.159562e+001 5.349894e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.159562e+001 5.349894e+000 5.200025e+000 vertex 2.137114e+001 5.608021e+000 5.200025e+000 vertex 2.141991e+001 5.525266e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.159562e+001 5.349894e+000 5.200025e+000 vertex 2.141991e+001 5.525266e+000 5.200025e+000 vertex 2.150039e+001 5.431047e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.250027e+001 5.327528e+000 5.200025e+000 vertex 2.260748e+001 5.410102e+000 5.200025e+000 vertex 2.238523e+001 5.266520e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.238523e+001 5.266520e+000 5.200025e+000 vertex 2.260748e+001 5.410102e+000 5.200025e+000 vertex 2.269183e+001 5.500207e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.238523e+001 5.266520e+000 5.200025e+000 vertex 2.269183e+001 5.500207e+000 5.200025e+000 vertex 2.227851e+001 5.231004e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.227851e+001 5.231004e+000 5.200025e+000 vertex 2.269183e+001 5.500207e+000 5.200025e+000 vertex 2.274731e+001 5.583439e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.227851e+001 5.231004e+000 5.200025e+000 vertex 2.274731e+001 5.583439e+000 5.200025e+000 vertex 2.213434e+001 5.207653e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.213434e+001 5.207653e+000 5.200025e+000 vertex 2.274731e+001 5.583439e+000 5.200025e+000 vertex 2.278642e+001 5.670285e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.213434e+001 5.207653e+000 5.200025e+000 vertex 2.278642e+001 5.670285e+000 5.200025e+000 vertex 2.131461e+001 5.972906e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 5.200025e+000 vertex 2.278642e+001 5.670285e+000 5.200025e+000 vertex 2.281060e+001 5.758884e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 5.200025e+000 vertex 2.281060e+001 5.758884e+000 5.200025e+000 vertex 2.282083e+001 5.876099e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.946947e+001 4.069511e+000 5.200025e+000 vertex 1.926255e+001 4.501944e+000 5.200025e+000 vertex 1.861306e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.861306e+001 4.069511e+000 5.200025e+000 vertex 1.926255e+001 4.501944e+000 5.200025e+000 vertex 1.818062e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.861306e+001 4.069511e+000 5.200025e+000 vertex 1.818062e+001 4.501944e+000 5.200025e+000 vertex 1.832537e+001 4.043572e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.277458e+001 6.110955e+000 5.200025e+000 vertex 2.273219e+001 6.193780e+000 5.200025e+000 vertex 2.280476e+001 6.019302e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.280476e+001 6.019302e+000 5.200025e+000 vertex 2.273219e+001 6.193780e+000 5.200025e+000 vertex 2.267049e+001 6.277335e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.280476e+001 6.019302e+000 5.200025e+000 vertex 2.267049e+001 6.277335e+000 5.200025e+000 vertex 2.281837e+001 5.934666e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.281837e+001 5.934666e+000 5.200025e+000 vertex 2.267049e+001 6.277335e+000 5.200025e+000 vertex 2.258687e+001 6.361741e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.281837e+001 5.934666e+000 5.200025e+000 vertex 2.258687e+001 6.361741e+000 5.200025e+000 vertex 2.131461e+001 5.972906e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 5.200025e+000 vertex 2.258687e+001 6.361741e+000 5.200025e+000 vertex 2.252559e+001 6.410197e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 5.200025e+000 vertex 2.252559e+001 6.410197e+000 5.200025e+000 vertex 2.242289e+001 6.473251e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.780268e+001 3.741352e+000 5.200025e+000 vertex 1.784237e+001 3.797465e+000 5.200025e+000 vertex 1.709907e+001 4.321096e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.959893e+001 2.981532e+000 5.200025e+000 vertex 1.941135e+001 2.902604e+000 5.200025e+000 vertex 1.985567e+001 2.503588e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.774192e+001 3.544773e+000 5.200025e+000 vertex 1.775203e+001 3.615100e+000 5.200025e+000 vertex 1.664092e+001 3.828664e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.242289e+001 6.473251e+000 5.200025e+000 vertex 2.231094e+001 6.520463e+000 5.200025e+000 vertex 2.131461e+001 5.972906e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 5.200025e+000 vertex 2.231094e+001 6.520463e+000 5.200025e+000 vertex 2.220584e+001 6.545606e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.131461e+001 5.972906e+000 5.200025e+000 vertex 2.220584e+001 6.545606e+000 5.200025e+000 vertex 2.133012e+001 6.057687e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.709907e+001 4.321096e+000 5.200025e+000 vertex 1.784237e+001 3.797465e+000 5.200025e+000 vertex 1.731359e+001 4.400511e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.731359e+001 4.400511e+000 5.200025e+000 vertex 1.784237e+001 3.797465e+000 5.200025e+000 vertex 1.789301e+001 3.848914e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.731359e+001 4.400511e+000 5.200025e+000 vertex 1.789301e+001 3.848914e+000 5.200025e+000 vertex 1.764915e+001 4.469552e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.077898e+001 5.820881e+000 5.200025e+000 vertex 1.972443e+001 5.937308e+000 5.200025e+000 vertex 2.076910e+001 5.749654e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.076910e+001 5.749654e+000 5.200025e+000 vertex 1.972443e+001 5.937308e+000 5.200025e+000 vertex 1.967211e+001 5.804854e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.076910e+001 5.749654e+000 5.200025e+000 vertex 1.967211e+001 5.804854e+000 5.200025e+000 vertex 2.076677e+001 5.706336e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.079353e+001 5.868840e+000 5.200025e+000 vertex 1.982245e+001 6.087405e+000 5.200025e+000 vertex 2.077898e+001 5.820881e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.077898e+001 5.820881e+000 5.200025e+000 vertex 1.982245e+001 6.087405e+000 5.200025e+000 vertex 1.978541e+001 6.039046e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.077898e+001 5.820881e+000 5.200025e+000 vertex 1.978541e+001 6.039046e+000 5.200025e+000 vertex 1.972443e+001 5.937308e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.091064e+001 6.009905e+000 5.200025e+000 vertex 2.070188e+001 6.506922e+000 5.200025e+000 vertex 2.087238e+001 5.982143e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.087238e+001 5.982143e+000 5.200025e+000 vertex 2.070188e+001 6.506922e+000 5.200025e+000 vertex 2.034992e+001 6.421170e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.087238e+001 5.982143e+000 5.200025e+000 vertex 2.034992e+001 6.421170e+000 5.200025e+000 vertex 2.083975e+001 5.948543e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.083975e+001 5.948543e+000 5.200025e+000 vertex 2.034992e+001 6.421170e+000 5.200025e+000 vertex 2.022012e+001 6.371653e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.083975e+001 5.948543e+000 5.200025e+000 vertex 2.022012e+001 6.371653e+000 5.200025e+000 vertex 2.081412e+001 5.911561e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.081412e+001 5.911561e+000 5.200025e+000 vertex 2.022012e+001 6.371653e+000 5.200025e+000 vertex 2.003585e+001 6.274529e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.081412e+001 5.911561e+000 5.200025e+000 vertex 2.003585e+001 6.274529e+000 5.200025e+000 vertex 2.079353e+001 5.868840e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.079353e+001 5.868840e+000 5.200025e+000 vertex 2.003585e+001 6.274529e+000 5.200025e+000 vertex 1.992107e+001 6.188916e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.079353e+001 5.868840e+000 5.200025e+000 vertex 1.992107e+001 6.188916e+000 5.200025e+000 vertex 1.982245e+001 6.087405e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.091064e+001 6.009905e+000 5.200025e+000 vertex 2.095458e+001 6.032044e+000 5.200025e+000 vertex 2.070188e+001 6.506922e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.070188e+001 6.506922e+000 5.200025e+000 vertex 2.095458e+001 6.032044e+000 5.200025e+000 vertex 2.101403e+001 6.051478e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.070188e+001 6.506922e+000 5.200025e+000 vertex 2.101403e+001 6.051478e+000 5.200025e+000 vertex 2.128266e+001 6.554683e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.128266e+001 6.554683e+000 5.200025e+000 vertex 2.101403e+001 6.051478e+000 5.200025e+000 vertex 2.109454e+001 6.065140e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.967211e+001 5.804854e+000 5.200025e+000 vertex 1.964198e+001 5.668105e+000 5.200025e+000 vertex 2.076677e+001 5.706336e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.076677e+001 5.706336e+000 5.200025e+000 vertex 1.964198e+001 5.668105e+000 5.200025e+000 vertex 1.963164e+001 5.511234e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.076677e+001 5.706336e+000 5.200025e+000 vertex 1.963164e+001 5.511234e+000 5.200025e+000 vertex 2.079131e+001 5.542764e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.079131e+001 5.542764e+000 5.200025e+000 vertex 1.963164e+001 5.511234e+000 5.200025e+000 vertex 1.966306e+001 5.228972e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.079131e+001 5.542764e+000 5.200025e+000 vertex 1.966306e+001 5.228972e+000 5.200025e+000 vertex 2.098772e+001 4.933215e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.098772e+001 4.933215e+000 5.200025e+000 vertex 1.966306e+001 5.228972e+000 5.200025e+000 vertex 1.986816e+001 4.556346e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.098772e+001 4.933215e+000 5.200025e+000 vertex 1.986816e+001 4.556346e+000 5.200025e+000 vertex 2.119498e+001 4.285280e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.119498e+001 4.285280e+000 5.200025e+000 vertex 1.986816e+001 4.556346e+000 5.200025e+000 vertex 2.003253e+001 4.000062e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.006407e+001 3.724917e+000 5.200025e+000 vertex 2.125000e+001 3.953780e+000 5.200025e+000 vertex 2.003253e+001 4.000062e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.003253e+001 4.000062e+000 5.200025e+000 vertex 2.125000e+001 3.953780e+000 5.200025e+000 vertex 2.120317e+001 4.250323e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.003253e+001 4.000062e+000 5.200025e+000 vertex 2.120317e+001 4.250323e+000 5.200025e+000 vertex 2.119498e+001 4.285280e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.000307e+001 3.395886e+000 5.200025e+000 vertex 2.092884e+001 3.046693e+000 5.200025e+000 vertex 2.104632e+001 3.187544e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.985567e+001 2.503588e+000 5.200025e+000 vertex 1.941135e+001 2.902604e+000 5.200025e+000 vertex 1.929369e+001 2.411791e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.929369e+001 2.411791e+000 5.200025e+000 vertex 1.941135e+001 2.902604e+000 5.200025e+000 vertex 1.919246e+001 2.850029e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.929369e+001 2.411791e+000 5.200025e+000 vertex 1.919246e+001 2.850029e+000 5.200025e+000 vertex 1.887150e+001 2.393836e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.006042e+001 3.641685e+000 5.200025e+000 vertex 2.123813e+001 3.658577e+000 5.200025e+000 vertex 2.006407e+001 3.724917e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.006407e+001 3.724917e+000 5.200025e+000 vertex 2.123813e+001 3.658577e+000 5.200025e+000 vertex 2.125326e+001 3.859207e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.006407e+001 3.724917e+000 5.200025e+000 vertex 2.125326e+001 3.859207e+000 5.200025e+000 vertex 2.125000e+001 3.953780e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.000307e+001 3.395886e+000 5.200025e+000 vertex 2.104632e+001 3.187544e+000 5.200025e+000 vertex 2.004197e+001 3.519632e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.004197e+001 3.519632e+000 5.200025e+000 vertex 2.104632e+001 3.187544e+000 5.200025e+000 vertex 2.113661e+001 3.336027e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.004197e+001 3.519632e+000 5.200025e+000 vertex 2.113661e+001 3.336027e+000 5.200025e+000 vertex 2.006042e+001 3.641685e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.006042e+001 3.641685e+000 5.200025e+000 vertex 2.113661e+001 3.336027e+000 5.200025e+000 vertex 2.119694e+001 3.484721e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.006042e+001 3.641685e+000 5.200025e+000 vertex 2.119694e+001 3.484721e+000 5.200025e+000 vertex 2.123813e+001 3.658577e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.756545e+001 2.580856e+000 5.200025e+000 vertex 1.815905e+001 2.443472e+000 5.200025e+000 vertex 1.817218e+001 2.972383e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.776498e+001 3.347373e+000 5.200025e+000 vertex 1.774729e+001 3.415194e+000 5.200025e+000 vertex 1.670302e+001 3.170838e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.919246e+001 2.850029e+000 5.200025e+000 vertex 1.888586e+001 2.826268e+000 5.200025e+000 vertex 1.887150e+001 2.393836e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.887150e+001 2.393836e+000 5.200025e+000 vertex 1.888586e+001 2.826268e+000 5.200025e+000 vertex 1.874229e+001 2.832124e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.887150e+001 2.393836e+000 5.200025e+000 vertex 1.874229e+001 2.832124e+000 5.200025e+000 vertex 1.815905e+001 2.443472e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.815905e+001 2.443472e+000 5.200025e+000 vertex 1.874229e+001 2.832124e+000 5.200025e+000 vertex 1.846527e+001 2.873987e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.815905e+001 2.443472e+000 5.200025e+000 vertex 1.846527e+001 2.873987e+000 5.200025e+000 vertex 1.817218e+001 2.972383e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.670302e+001 3.170838e+000 5.200025e+000 vertex 1.677189e+001 3.065296e+000 5.200025e+000 vertex 1.776498e+001 3.347373e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.776498e+001 3.347373e+000 5.200025e+000 vertex 1.677189e+001 3.065296e+000 5.200025e+000 vertex 1.687265e+001 2.954101e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.776498e+001 3.347373e+000 5.200025e+000 vertex 1.687265e+001 2.954101e+000 5.200025e+000 vertex 1.779280e+001 3.283037e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.779280e+001 3.283037e+000 5.200025e+000 vertex 1.687265e+001 2.954101e+000 5.200025e+000 vertex 1.703224e+001 2.826606e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.779280e+001 3.283037e+000 5.200025e+000 vertex 1.703224e+001 2.826606e+000 5.200025e+000 vertex 1.783493e+001 3.216788e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.783493e+001 3.216788e+000 5.200025e+000 vertex 1.703224e+001 2.826606e+000 5.200025e+000 vertex 1.721914e+001 2.718450e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.783493e+001 3.216788e+000 5.200025e+000 vertex 1.721914e+001 2.718450e+000 5.200025e+000 vertex 1.789379e+001 3.151021e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.789379e+001 3.151021e+000 5.200025e+000 vertex 1.721914e+001 2.718450e+000 5.200025e+000 vertex 1.746610e+001 2.614275e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.789379e+001 3.151021e+000 5.200025e+000 vertex 1.746610e+001 2.614275e+000 5.200025e+000 vertex 1.799337e+001 3.069825e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.799337e+001 3.069825e+000 5.200025e+000 vertex 1.746610e+001 2.614275e+000 5.200025e+000 vertex 1.756545e+001 2.580856e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.799337e+001 3.069825e+000 5.200025e+000 vertex 1.756545e+001 2.580856e+000 5.200025e+000 vertex 1.810614e+001 3.003853e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.810614e+001 3.003853e+000 5.200025e+000 vertex 1.756545e+001 2.580856e+000 5.200025e+000 vertex 1.817218e+001 2.972383e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.664092e+001 3.828664e+000 5.200025e+000 vertex 1.661395e+001 3.707921e+000 5.200025e+000 vertex 1.774192e+001 3.544773e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.774192e+001 3.544773e+000 5.200025e+000 vertex 1.661395e+001 3.707921e+000 5.200025e+000 vertex 1.660461e+001 3.566978e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.774192e+001 3.544773e+000 5.200025e+000 vertex 1.660461e+001 3.566978e+000 5.200025e+000 vertex 1.773974e+001 3.501944e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.773974e+001 3.501944e+000 5.200025e+000 vertex 1.660461e+001 3.566978e+000 5.200025e+000 vertex 1.661873e+001 3.408270e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.773974e+001 3.501944e+000 5.200025e+000 vertex 1.661873e+001 3.408270e+000 5.200025e+000 vertex 1.774729e+001 3.415194e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.774729e+001 3.415194e+000 5.200025e+000 vertex 1.661873e+001 3.408270e+000 5.200025e+000 vertex 1.665080e+001 3.287392e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.774729e+001 3.415194e+000 5.200025e+000 vertex 1.665080e+001 3.287392e+000 5.200025e+000 vertex 1.670302e+001 3.170838e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.668431e+001 3.939104e+000 5.200025e+000 vertex 1.664092e+001 3.828664e+000 5.200025e+000 vertex 1.674828e+001 4.046607e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.674828e+001 4.046607e+000 5.200025e+000 vertex 1.664092e+001 3.828664e+000 5.200025e+000 vertex 1.775203e+001 3.615100e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.674828e+001 4.046607e+000 5.200025e+000 vertex 1.775203e+001 3.615100e+000 5.200025e+000 vertex 1.676508e+001 4.068985e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.676508e+001 4.068985e+000 5.200025e+000 vertex 1.775203e+001 3.615100e+000 5.200025e+000 vertex 1.777220e+001 3.679322e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.676508e+001 4.068985e+000 5.200025e+000 vertex 1.777220e+001 3.679322e+000 5.200025e+000 vertex 1.684071e+001 4.151348e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.684071e+001 4.151348e+000 5.200025e+000 vertex 1.777220e+001 3.679322e+000 5.200025e+000 vertex 1.780268e+001 3.741352e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.684071e+001 4.151348e+000 5.200025e+000 vertex 1.780268e+001 3.741352e+000 5.200025e+000 vertex 1.693494e+001 4.227113e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.693494e+001 4.227113e+000 5.200025e+000 vertex 1.780268e+001 3.741352e+000 5.200025e+000 vertex 1.709907e+001 4.321096e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.789301e+001 3.848914e+000 5.200025e+000 vertex 1.796161e+001 3.901403e+000 5.200025e+000 vertex 1.764915e+001 4.469552e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.764915e+001 4.469552e+000 5.200025e+000 vertex 1.796161e+001 3.901403e+000 5.200025e+000 vertex 1.805140e+001 3.952957e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.764915e+001 4.469552e+000 5.200025e+000 vertex 1.805140e+001 3.952957e+000 5.200025e+000 vertex 1.818062e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.818062e+001 4.501944e+000 5.200025e+000 vertex 1.805140e+001 3.952957e+000 5.200025e+000 vertex 1.815991e+001 3.997679e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.818062e+001 4.501944e+000 5.200025e+000 vertex 1.815991e+001 3.997679e+000 5.200025e+000 vertex 1.832537e+001 4.043572e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.109454e+001 6.065140e+000 5.200025e+000 vertex 2.117556e+001 6.069511e+000 5.200025e+000 vertex 2.128266e+001 6.554683e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.128266e+001 6.554683e+000 5.200025e+000 vertex 2.117556e+001 6.069511e+000 5.200025e+000 vertex 2.125293e+001 6.064973e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.128266e+001 6.554683e+000 5.200025e+000 vertex 2.125293e+001 6.064973e+000 5.200025e+000 vertex 2.137995e+001 6.555998e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.137995e+001 6.555998e+000 5.200025e+000 vertex 2.125293e+001 6.064973e+000 5.200025e+000 vertex 2.133012e+001 6.057687e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.137995e+001 6.555998e+000 5.200025e+000 vertex 2.133012e+001 6.057687e+000 5.200025e+000 vertex 2.207505e+001 6.555998e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.207505e+001 6.555998e+000 5.200025e+000 vertex 2.133012e+001 6.057687e+000 5.200025e+000 vertex 2.220584e+001 6.545606e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.092884e+001 3.046693e+000 5.200025e+000 vertex 2.000307e+001 3.395886e+000 5.200025e+000 vertex 2.074987e+001 2.891915e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.074987e+001 2.891915e+000 5.200025e+000 vertex 2.000307e+001 3.395886e+000 5.200025e+000 vertex 1.995123e+001 3.294544e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.074987e+001 2.891915e+000 5.200025e+000 vertex 1.995123e+001 3.294544e+000 5.200025e+000 vertex 2.049224e+001 2.734193e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.049224e+001 2.734193e+000 5.200025e+000 vertex 1.995123e+001 3.294544e+000 5.200025e+000 vertex 1.988647e+001 3.204496e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.049224e+001 2.734193e+000 5.200025e+000 vertex 1.988647e+001 3.204496e+000 5.200025e+000 vertex 2.038586e+001 2.682687e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.038586e+001 2.682687e+000 5.200025e+000 vertex 1.988647e+001 3.204496e+000 5.200025e+000 vertex 1.980193e+001 3.118547e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 2.038586e+001 2.682687e+000 5.200025e+000 vertex 1.980193e+001 3.118547e+000 5.200025e+000 vertex 1.985567e+001 2.503588e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.985567e+001 2.503588e+000 5.200025e+000 vertex 1.980193e+001 3.118547e+000 5.200025e+000 vertex 1.968991e+001 3.034883e+000 5.200025e+000 endloop endfacet facet normal 1.001843e-013 8.435607e-014 1.000000e+000 outer loop vertex 1.985567e+001 2.503588e+000 5.200025e+000 vertex 1.968991e+001 3.034883e+000 5.200025e+000 vertex 1.959893e+001 2.981532e+000 5.200025e+000 endloop endfacet facet normal 2.616428e-002 -9.996577e-001 0.000000e+000 outer loop vertex 2.554971e+001 4.069511e+000 5.200025e+000 vertex 2.554971e+001 4.069511e+000 3.200025e+000 vertex 2.561042e+001 4.071100e+000 3.200025e+000 endloop endfacet facet normal 2.970619e-002 -9.995587e-001 0.000000e+000 outer loop vertex 2.554971e+001 4.069511e+000 5.200025e+000 vertex 2.561042e+001 4.071100e+000 3.200025e+000 vertex 2.561042e+001 4.071100e+000 5.200025e+000 endloop endfacet facet normal 4.388228e-002 -9.990367e-001 0.000000e+000 outer loop vertex 2.561042e+001 4.071100e+000 5.200025e+000 vertex 2.561042e+001 4.071100e+000 3.200025e+000 vertex 2.567104e+001 4.073978e+000 3.200025e+000 endloop endfacet facet normal 5.451311e-002 -9.985130e-001 0.000000e+000 outer loop vertex 2.561042e+001 4.071100e+000 5.200025e+000 vertex 2.567104e+001 4.073978e+000 3.200025e+000 vertex 2.567104e+001 4.073978e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 5.200025e+000 vertex 2.997032e+001 6.555998e+000 5.200025e+000 vertex 3.020765e+001 6.091471e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.020765e+001 6.091471e+000 5.200025e+000 vertex 2.997032e+001 6.555998e+000 5.200025e+000 vertex 2.829887e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.222623e+001 1.853295e+000 5.200025e+000 vertex 2.187403e+001 1.420863e+000 5.200025e+000 vertex 2.200705e+001 1.423892e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.313931e+001 3.258176e+000 5.200025e+000 vertex 2.314515e+001 3.170863e+000 5.200025e+000 vertex 2.388682e+001 3.571214e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.067640e+001 4.501944e+000 5.200025e+000 vertex 2.860208e+001 4.069511e+000 5.200025e+000 vertex 3.173466e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.173466e+001 4.501944e+000 5.200025e+000 vertex 2.860208e+001 4.069511e+000 5.200025e+000 vertex 2.949903e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 5.200025e+000 vertex 3.020765e+001 6.091471e+000 5.200025e+000 vertex 3.067640e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.067640e+001 4.501944e+000 5.200025e+000 vertex 3.020765e+001 6.091471e+000 5.200025e+000 vertex 2.962995e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.067640e+001 4.501944e+000 5.200025e+000 vertex 2.962995e+001 4.501944e+000 5.200025e+000 vertex 2.860208e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.487749e+001 2.724321e+000 5.200025e+000 vertex 2.491925e+001 2.650554e+000 5.200025e+000 vertex 2.602125e+001 3.048951e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.388682e+001 3.571214e+000 5.200025e+000 vertex 2.314515e+001 3.170863e+000 5.200025e+000 vertex 2.390364e+001 3.294121e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.390364e+001 3.294121e+000 5.200025e+000 vertex 2.314515e+001 3.170863e+000 5.200025e+000 vertex 2.312220e+001 2.972271e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.390364e+001 3.294121e+000 5.200025e+000 vertex 2.312220e+001 2.972271e+000 5.200025e+000 vertex 2.390191e+001 3.211403e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.624589e+001 4.302198e+000 5.200025e+000 vertex 2.617619e+001 4.280954e+000 5.200025e+000 vertex 2.567104e+001 4.073978e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.897623e+001 4.501944e+000 5.200025e+000 vertex 2.792640e+001 4.069511e+000 5.200025e+000 vertex 2.758600e+001 3.662999e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.617619e+001 4.280954e+000 5.200025e+000 vertex 2.561042e+001 4.071100e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.561042e+001 4.071100e+000 5.200025e+000 vertex 2.617619e+001 4.280954e+000 5.200025e+000 vertex 2.366542e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.561042e+001 4.071100e+000 5.200025e+000 vertex 2.366542e+001 4.069511e+000 5.200025e+000 vertex 2.554971e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.620843e+001 4.323749e+000 5.200025e+000 vertex 2.624228e+001 4.384831e+000 5.200025e+000 vertex 2.628028e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.411812e+001 6.015457e+000 5.200025e+000 vertex 2.309110e+001 6.015457e+000 5.200025e+000 vertex 2.346356e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.346356e+001 4.501944e+000 5.200025e+000 vertex 2.309110e+001 6.015457e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.537339e+001 6.544735e+000 5.200025e+000 vertex 3.446525e+001 6.069511e+000 5.200025e+000 vertex 3.547242e+001 6.518541e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.547242e+001 6.518541e+000 5.200025e+000 vertex 3.446525e+001 6.069511e+000 5.200025e+000 vertex 3.444749e+001 5.985519e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.547242e+001 6.518541e+000 5.200025e+000 vertex 3.444749e+001 5.985519e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.444749e+001 5.985519e+000 5.200025e+000 vertex 3.444245e+001 5.899748e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.444245e+001 5.899748e+000 5.200025e+000 vertex 3.444469e+001 5.840539e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.386987e+001 2.957672e+000 5.200025e+000 vertex 2.390191e+001 3.211403e+000 5.200025e+000 vertex 2.380128e+001 2.735877e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.380128e+001 2.735877e+000 5.200025e+000 vertex 2.390191e+001 3.211403e+000 5.200025e+000 vertex 2.312220e+001 2.972271e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.380128e+001 2.735877e+000 5.200025e+000 vertex 2.312220e+001 2.972271e+000 5.200025e+000 vertex 2.369053e+001 2.513875e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.369053e+001 2.513875e+000 5.200025e+000 vertex 2.312220e+001 2.972271e+000 5.200025e+000 vertex 2.306745e+001 2.779815e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.369053e+001 2.513875e+000 5.200025e+000 vertex 2.306745e+001 2.779815e+000 5.200025e+000 vertex 2.351545e+001 2.271196e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.306745e+001 2.779815e+000 5.200025e+000 vertex 2.302143e+001 2.672723e+000 5.200025e+000 vertex 2.351545e+001 2.271196e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.351545e+001 2.271196e+000 5.200025e+000 vertex 2.302143e+001 2.672723e+000 5.200025e+000 vertex 2.292390e+001 2.510384e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.351545e+001 2.271196e+000 5.200025e+000 vertex 2.292390e+001 2.510384e+000 5.200025e+000 vertex 2.325911e+001 2.015348e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.325911e+001 2.015348e+000 5.200025e+000 vertex 2.292390e+001 2.510384e+000 5.200025e+000 vertex 2.273214e+001 2.272214e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.325911e+001 2.015348e+000 5.200025e+000 vertex 2.273214e+001 2.272214e+000 5.200025e+000 vertex 2.314008e+001 1.917484e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.314008e+001 1.917484e+000 5.200025e+000 vertex 2.273214e+001 2.272214e+000 5.200025e+000 vertex 2.268718e+001 2.223361e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.314008e+001 1.917484e+000 5.200025e+000 vertex 2.268718e+001 2.223361e+000 5.200025e+000 vertex 2.276652e+001 1.666767e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.276652e+001 1.666767e+000 5.200025e+000 vertex 2.268718e+001 2.223361e+000 5.200025e+000 vertex 2.244634e+001 1.997951e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.276652e+001 1.666767e+000 5.200025e+000 vertex 2.244634e+001 1.997951e+000 5.200025e+000 vertex 2.248483e+001 1.533015e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.248483e+001 1.533015e+000 5.200025e+000 vertex 2.244634e+001 1.997951e+000 5.200025e+000 vertex 2.222623e+001 1.853295e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.248483e+001 1.533015e+000 5.200025e+000 vertex 2.222623e+001 1.853295e+000 5.200025e+000 vertex 2.222927e+001 1.455257e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.222927e+001 1.455257e+000 5.200025e+000 vertex 2.222623e+001 1.853295e+000 5.200025e+000 vertex 2.200705e+001 1.423892e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.897623e+001 4.501944e+000 5.200025e+000 vertex 3.020765e+001 6.091471e+000 5.200025e+000 vertex 2.792640e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.792640e+001 4.069511e+000 5.200025e+000 vertex 3.020765e+001 6.091471e+000 5.200025e+000 vertex 2.829887e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.792640e+001 4.069511e+000 5.200025e+000 vertex 2.829887e+001 4.501944e+000 5.200025e+000 vertex 2.712552e+001 4.011939e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.712552e+001 4.011939e+000 5.200025e+000 vertex 2.829887e+001 4.501944e+000 5.200025e+000 vertex 2.683557e+001 3.948704e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.196043e+001 4.238191e+000 5.200025e+000 vertex 2.197223e+001 4.181031e+000 5.200025e+000 vertex 2.195596e+001 4.295863e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.195596e+001 4.295863e+000 5.200025e+000 vertex 2.197223e+001 4.181031e+000 5.200025e+000 vertex 2.199379e+001 4.123733e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.195596e+001 4.295863e+000 5.200025e+000 vertex 2.199379e+001 4.123733e+000 5.200025e+000 vertex 2.196850e+001 4.401275e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.196850e+001 4.401275e+000 5.200025e+000 vertex 2.199379e+001 4.123733e+000 5.200025e+000 vertex 2.202447e+001 4.068987e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.196850e+001 4.401275e+000 5.200025e+000 vertex 2.202447e+001 4.068987e+000 5.200025e+000 vertex 2.200241e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 5.200025e+000 vertex 2.202447e+001 4.068987e+000 5.200025e+000 vertex 2.207336e+001 4.007856e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 5.200025e+000 vertex 2.207336e+001 4.007856e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.620843e+001 4.323749e+000 5.200025e+000 vertex 2.628028e+001 4.501944e+000 5.200025e+000 vertex 2.617619e+001 4.280954e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.617619e+001 4.280954e+000 5.200025e+000 vertex 2.628028e+001 4.501944e+000 5.200025e+000 vertex 2.346356e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.617619e+001 4.280954e+000 5.200025e+000 vertex 2.346356e+001 4.501944e+000 5.200025e+000 vertex 2.366542e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.366542e+001 4.069511e+000 5.200025e+000 vertex 2.346356e+001 4.501944e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.366542e+001 4.069511e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 5.200025e+000 vertex 2.298383e+001 3.528971e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.298383e+001 3.528971e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 5.200025e+000 vertex 2.232674e+001 3.853295e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.298383e+001 3.528971e+000 5.200025e+000 vertex 2.232674e+001 3.853295e+000 5.200025e+000 vertex 2.260892e+001 2.689378e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.260892e+001 2.689378e+000 5.200025e+000 vertex 2.232674e+001 3.853295e+000 5.200025e+000 vertex 2.159785e+001 1.821201e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.260892e+001 2.689378e+000 5.200025e+000 vertex 2.159785e+001 1.821201e+000 5.200025e+000 vertex 2.222623e+001 1.853295e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.222623e+001 1.853295e+000 5.200025e+000 vertex 2.159785e+001 1.821201e+000 5.200025e+000 vertex 2.158293e+001 1.772760e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.222623e+001 1.853295e+000 5.200025e+000 vertex 2.158293e+001 1.772760e+000 5.200025e+000 vertex 2.187403e+001 1.420863e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.187403e+001 1.420863e+000 5.200025e+000 vertex 2.158293e+001 1.772760e+000 5.200025e+000 vertex 2.157758e+001 1.722383e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.187403e+001 1.420863e+000 5.200025e+000 vertex 2.157758e+001 1.722383e+000 5.200025e+000 vertex 2.181840e+001 1.427426e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.181840e+001 1.427426e+000 5.200025e+000 vertex 2.157758e+001 1.722383e+000 5.200025e+000 vertex 2.157923e+001 1.697007e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.181840e+001 1.427426e+000 5.200025e+000 vertex 2.157923e+001 1.697007e+000 5.200025e+000 vertex 2.177628e+001 1.439914e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.177628e+001 1.439914e+000 5.200025e+000 vertex 2.157923e+001 1.697007e+000 5.200025e+000 vertex 2.158555e+001 1.653413e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.177628e+001 1.439914e+000 5.200025e+000 vertex 2.158555e+001 1.653413e+000 5.200025e+000 vertex 2.173006e+001 1.462375e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.173006e+001 1.462375e+000 5.200025e+000 vertex 2.158555e+001 1.653413e+000 5.200025e+000 vertex 2.159803e+001 1.614061e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.173006e+001 1.462375e+000 5.200025e+000 vertex 2.159803e+001 1.614061e+000 5.200025e+000 vertex 2.168871e+001 1.492140e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.168871e+001 1.492140e+000 5.200025e+000 vertex 2.159803e+001 1.614061e+000 5.200025e+000 vertex 2.161900e+001 1.571960e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.168871e+001 1.492140e+000 5.200025e+000 vertex 2.161900e+001 1.571960e+000 5.200025e+000 vertex 2.164507e+001 1.535839e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.899397e+001 2.555998e+000 5.200025e+000 vertex 3.001002e+001 2.555998e+000 5.200025e+000 vertex 2.949903e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.949903e+001 4.069511e+000 5.200025e+000 vertex 3.001002e+001 2.555998e+000 5.200025e+000 vertex 3.052775e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.949903e+001 4.069511e+000 5.200025e+000 vertex 3.052775e+001 4.069511e+000 5.200025e+000 vertex 3.173466e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.173466e+001 4.501944e+000 5.200025e+000 vertex 3.052775e+001 4.069511e+000 5.200025e+000 vertex 3.168638e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.173466e+001 4.501944e+000 5.200025e+000 vertex 3.168638e+001 4.069511e+000 5.200025e+000 vertex 3.182188e+001 4.771779e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.471583e+001 5.365334e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.467555e+001 5.397214e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.467555e+001 5.397214e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.444469e+001 5.840539e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.467555e+001 5.397214e+000 5.200025e+000 vertex 3.444469e+001 5.840539e+000 5.200025e+000 vertex 3.459350e+001 5.479983e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.459350e+001 5.479983e+000 5.200025e+000 vertex 3.444469e+001 5.840539e+000 5.200025e+000 vertex 3.445865e+001 5.748045e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.459350e+001 5.479983e+000 5.200025e+000 vertex 3.445865e+001 5.748045e+000 5.200025e+000 vertex 3.453214e+001 5.566125e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.453214e+001 5.566125e+000 5.200025e+000 vertex 3.445865e+001 5.748045e+000 5.200025e+000 vertex 3.448911e+001 5.652171e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.520174e+001 5.204647e+000 5.200025e+000 vertex 3.526373e+001 5.206391e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.576385e+001 5.429909e+000 5.200025e+000 vertex 3.583331e+001 5.508509e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.595596e+001 5.882011e+000 5.200025e+000 vertex 3.595133e+001 5.958773e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.223761e+001 3.885249e+000 5.200025e+000 vertex 2.232674e+001 3.853295e+000 5.200025e+000 vertex 2.217411e+001 3.920629e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.217411e+001 3.920629e+000 5.200025e+000 vertex 2.232674e+001 3.853295e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.217411e+001 3.920629e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 5.200025e+000 vertex 2.211550e+001 3.966825e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.211550e+001 3.966825e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 5.200025e+000 vertex 2.207336e+001 4.007856e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.298383e+001 3.528971e+000 5.200025e+000 vertex 2.300212e+001 3.514563e+000 5.200025e+000 vertex 2.366542e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.366542e+001 4.069511e+000 5.200025e+000 vertex 2.300212e+001 3.514563e+000 5.200025e+000 vertex 2.304059e+001 3.478963e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.366542e+001 4.069511e+000 5.200025e+000 vertex 2.304059e+001 3.478963e+000 5.200025e+000 vertex 2.373908e+001 3.985847e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.373908e+001 3.985847e+000 5.200025e+000 vertex 2.304059e+001 3.478963e+000 5.200025e+000 vertex 2.307066e+001 3.440160e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.373908e+001 3.985847e+000 5.200025e+000 vertex 2.307066e+001 3.440160e+000 5.200025e+000 vertex 2.379199e+001 3.897038e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.413707e+001 6.512548e+000 5.200025e+000 vertex 3.368468e+001 5.773034e+000 5.200025e+000 vertex 3.389362e+001 5.914418e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.505911e+001 5.216029e+000 5.200025e+000 vertex 3.520174e+001 5.204647e+000 5.200025e+000 vertex 3.494287e+001 5.244747e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.494287e+001 5.244747e+000 5.200025e+000 vertex 3.520174e+001 5.204647e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.494287e+001 5.244747e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.482317e+001 5.295907e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.482317e+001 5.295907e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.471583e+001 5.365334e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.576385e+001 5.429909e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.572285e+001 5.392146e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.572285e+001 5.392146e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.526373e+001 5.206391e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.572285e+001 5.392146e+000 5.200025e+000 vertex 3.526373e+001 5.206391e+000 5.200025e+000 vertex 3.561232e+001 5.313697e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.561232e+001 5.313697e+000 5.200025e+000 vertex 3.526373e+001 5.206391e+000 5.200025e+000 vertex 3.538346e+001 5.223536e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.561232e+001 5.313697e+000 5.200025e+000 vertex 3.538346e+001 5.223536e+000 5.200025e+000 vertex 3.549575e+001 5.257381e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.661934e+001 2.435870e+000 5.200025e+000 vertex 2.641702e+001 2.894977e+000 5.200025e+000 vertex 2.638799e+001 2.361197e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.638799e+001 2.361197e+000 5.200025e+000 vertex 2.641702e+001 2.894977e+000 5.200025e+000 vertex 2.627522e+001 2.880322e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.638799e+001 2.361197e+000 5.200025e+000 vertex 2.627522e+001 2.880322e+000 5.200025e+000 vertex 2.606751e+001 2.299473e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.602125e+001 3.048951e+000 5.200025e+000 vertex 2.491925e+001 2.650554e+000 5.200025e+000 vertex 2.603515e+001 3.007836e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.558199e+001 4.025043e+000 5.200025e+000 vertex 2.602125e+001 3.048951e+000 5.200025e+000 vertex 2.567104e+001 4.073978e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.602125e+001 3.048951e+000 5.200025e+000 vertex 2.601267e+001 3.097160e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.601267e+001 3.097160e+000 5.200025e+000 vertex 2.601001e+001 3.146369e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.601001e+001 3.146369e+000 5.200025e+000 vertex 2.601945e+001 3.245797e+000 5.200025e+000 vertex 2.567104e+001 4.073978e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.601945e+001 3.245797e+000 5.200025e+000 vertex 2.604041e+001 3.323305e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.604041e+001 3.323305e+000 5.200025e+000 vertex 2.607772e+001 3.407592e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.607772e+001 3.407592e+000 5.200025e+000 vertex 2.614034e+001 3.505764e+000 5.200025e+000 vertex 2.567104e+001 4.073978e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.614034e+001 3.505764e+000 5.200025e+000 vertex 2.623308e+001 3.611141e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.623308e+001 3.611141e+000 5.200025e+000 vertex 2.637826e+001 3.735896e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.702711e+001 4.460593e+000 5.200025e+000 vertex 2.631576e+001 4.322890e+000 5.200025e+000 vertex 2.775072e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.775072e+001 4.501944e+000 5.200025e+000 vertex 2.631576e+001 4.322890e+000 5.200025e+000 vertex 2.624589e+001 4.302198e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.775072e+001 4.501944e+000 5.200025e+000 vertex 2.624589e+001 4.302198e+000 5.200025e+000 vertex 2.829887e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.829887e+001 4.501944e+000 5.200025e+000 vertex 2.624589e+001 4.302198e+000 5.200025e+000 vertex 2.567104e+001 4.073978e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.829887e+001 4.501944e+000 5.200025e+000 vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.683557e+001 3.948704e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.379199e+001 3.897038e+000 5.200025e+000 vertex 2.307066e+001 3.440160e+000 5.200025e+000 vertex 2.384816e+001 3.755558e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.384816e+001 3.755558e+000 5.200025e+000 vertex 2.307066e+001 3.440160e+000 5.200025e+000 vertex 2.310262e+001 3.384567e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.384816e+001 3.755558e+000 5.200025e+000 vertex 2.310262e+001 3.384567e+000 5.200025e+000 vertex 2.388682e+001 3.571214e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.388682e+001 3.571214e+000 5.200025e+000 vertex 2.310262e+001 3.384567e+000 5.200025e+000 vertex 2.312376e+001 3.328368e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.388682e+001 3.571214e+000 5.200025e+000 vertex 2.312376e+001 3.328368e+000 5.200025e+000 vertex 2.313931e+001 3.258176e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.424180e+001 2.992802e+000 5.200025e+000 vertex 3.384801e+001 3.038748e+000 5.200025e+000 vertex 3.410799e+001 2.555998e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.537339e+001 6.544735e+000 5.200025e+000 vertex 3.524650e+001 6.555998e+000 5.200025e+000 vertex 3.446525e+001 6.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.446525e+001 6.069511e+000 5.200025e+000 vertex 3.524650e+001 6.555998e+000 5.200025e+000 vertex 3.467893e+001 6.555998e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.446525e+001 6.069511e+000 5.200025e+000 vertex 3.467893e+001 6.555998e+000 5.200025e+000 vertex 3.425444e+001 6.048870e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.425444e+001 6.048870e+000 5.200025e+000 vertex 3.467893e+001 6.555998e+000 5.200025e+000 vertex 3.413707e+001 6.512548e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.425444e+001 6.048870e+000 5.200025e+000 vertex 3.413707e+001 6.512548e+000 5.200025e+000 vertex 3.407401e+001 5.998157e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.407401e+001 5.998157e+000 5.200025e+000 vertex 3.413707e+001 6.512548e+000 5.200025e+000 vertex 3.389362e+001 5.914418e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.594813e+001 5.776505e+000 5.200025e+000 vertex 3.595596e+001 5.882011e+000 5.200025e+000 vertex 3.592517e+001 5.683188e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.592517e+001 5.683188e+000 5.200025e+000 vertex 3.595596e+001 5.882011e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.592517e+001 5.683188e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.588581e+001 5.590718e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.588581e+001 5.590718e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.583331e+001 5.508509e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.567940e+001 6.403383e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.577528e+001 6.314840e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.577528e+001 6.314840e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.595133e+001 5.958773e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.577528e+001 6.314840e+000 5.200025e+000 vertex 3.595133e+001 5.958773e+000 5.200025e+000 vertex 3.585004e+001 6.222932e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.585004e+001 6.222932e+000 5.200025e+000 vertex 3.595133e+001 5.958773e+000 5.200025e+000 vertex 3.593454e+001 6.042812e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.585004e+001 6.222932e+000 5.200025e+000 vertex 3.593454e+001 6.042812e+000 5.200025e+000 vertex 3.589819e+001 6.139915e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.962995e+001 4.501944e+000 5.200025e+000 vertex 2.897623e+001 4.501944e+000 5.200025e+000 vertex 2.860208e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.860208e+001 4.069511e+000 5.200025e+000 vertex 2.897623e+001 4.501944e+000 5.200025e+000 vertex 2.758600e+001 3.662999e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.860208e+001 4.069511e+000 5.200025e+000 vertex 2.758600e+001 3.662999e+000 5.200025e+000 vertex 2.791843e+001 3.310633e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.791843e+001 3.310633e+000 5.200025e+000 vertex 2.758600e+001 3.662999e+000 5.200025e+000 vertex 2.718738e+001 3.312755e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.791843e+001 3.310633e+000 5.200025e+000 vertex 2.718738e+001 3.312755e+000 5.200025e+000 vertex 2.750514e+001 2.949922e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.750514e+001 2.949922e+000 5.200025e+000 vertex 2.718738e+001 3.312755e+000 5.200025e+000 vertex 2.711975e+001 3.261054e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.750514e+001 2.949922e+000 5.200025e+000 vertex 2.711975e+001 3.261054e+000 5.200025e+000 vertex 2.702461e+001 2.626600e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.702461e+001 2.626600e+000 5.200025e+000 vertex 2.711975e+001 3.261054e+000 5.200025e+000 vertex 2.678301e+001 3.038524e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.702461e+001 2.626600e+000 5.200025e+000 vertex 2.678301e+001 3.038524e+000 5.200025e+000 vertex 2.661934e+001 2.435870e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.661934e+001 2.435870e+000 5.200025e+000 vertex 2.678301e+001 3.038524e+000 5.200025e+000 vertex 2.656557e+001 2.937940e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.661934e+001 2.435870e+000 5.200025e+000 vertex 2.656557e+001 2.937940e+000 5.200025e+000 vertex 2.641702e+001 2.894977e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.627522e+001 2.880322e+000 5.200025e+000 vertex 2.624462e+001 2.881522e+000 5.200025e+000 vertex 2.606751e+001 2.299473e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.606751e+001 2.299473e+000 5.200025e+000 vertex 2.624462e+001 2.881522e+000 5.200025e+000 vertex 2.619372e+001 2.887917e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.606751e+001 2.299473e+000 5.200025e+000 vertex 2.619372e+001 2.887917e+000 5.200025e+000 vertex 2.582674e+001 2.285728e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.637826e+001 3.735896e+000 5.200025e+000 vertex 2.643037e+001 3.771226e+000 5.200025e+000 vertex 2.567104e+001 4.073978e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.643037e+001 3.771226e+000 5.200025e+000 vertex 2.659707e+001 3.863054e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.659707e+001 3.863054e+000 5.200025e+000 vertex 2.683557e+001 3.948704e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.226681e+001 5.490809e+000 5.200025e+000 vertex 3.198890e+001 5.105829e+000 5.200025e+000 vertex 3.257662e+001 5.796973e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.257662e+001 5.796973e+000 5.200025e+000 vertex 3.198890e+001 5.105829e+000 5.200025e+000 vertex 3.182188e+001 4.771779e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.257662e+001 5.796973e+000 5.200025e+000 vertex 3.182188e+001 4.771779e+000 5.200025e+000 vertex 3.295127e+001 6.067502e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.295127e+001 6.067502e+000 5.200025e+000 vertex 3.182188e+001 4.771779e+000 5.200025e+000 vertex 3.168638e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.295127e+001 6.067502e+000 5.200025e+000 vertex 3.168638e+001 4.069511e+000 5.200025e+000 vertex 3.314093e+001 6.175086e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.314093e+001 6.175086e+000 5.200025e+000 vertex 3.168638e+001 4.069511e+000 5.200025e+000 vertex 3.413707e+001 6.512548e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.314093e+001 6.175086e+000 5.200025e+000 vertex 3.413707e+001 6.512548e+000 5.200025e+000 vertex 3.365337e+001 6.393368e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.410799e+001 2.555998e+000 5.200025e+000 vertex 3.384801e+001 3.038748e+000 5.200025e+000 vertex 3.329603e+001 2.613956e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.491925e+001 2.650554e+000 5.200025e+000 vertex 2.498601e+001 2.568571e+000 5.200025e+000 vertex 2.603515e+001 3.007836e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.603515e+001 3.007836e+000 5.200025e+000 vertex 2.498601e+001 2.568571e+000 5.200025e+000 vertex 2.506216e+001 2.501009e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.603515e+001 3.007836e+000 5.200025e+000 vertex 2.506216e+001 2.501009e+000 5.200025e+000 vertex 2.604864e+001 2.981828e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.604864e+001 2.981828e+000 5.200025e+000 vertex 2.506216e+001 2.501009e+000 5.200025e+000 vertex 2.516204e+001 2.436065e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.604864e+001 2.981828e+000 5.200025e+000 vertex 2.516204e+001 2.436065e+000 5.200025e+000 vertex 2.606749e+001 2.956850e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.606749e+001 2.956850e+000 5.200025e+000 vertex 2.516204e+001 2.436065e+000 5.200025e+000 vertex 2.532370e+001 2.363159e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.606749e+001 2.956850e+000 5.200025e+000 vertex 2.532370e+001 2.363159e+000 5.200025e+000 vertex 2.609461e+001 2.930993e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.609461e+001 2.930993e+000 5.200025e+000 vertex 2.532370e+001 2.363159e+000 5.200025e+000 vertex 2.553387e+001 2.309567e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.609461e+001 2.930993e+000 5.200025e+000 vertex 2.553387e+001 2.309567e+000 5.200025e+000 vertex 2.611779e+001 2.915203e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.611779e+001 2.915203e+000 5.200025e+000 vertex 2.553387e+001 2.309567e+000 5.200025e+000 vertex 2.582674e+001 2.285728e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.611779e+001 2.915203e+000 5.200025e+000 vertex 2.582674e+001 2.285728e+000 5.200025e+000 vertex 2.614441e+001 2.902653e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.614441e+001 2.902653e+000 5.200025e+000 vertex 2.582674e+001 2.285728e+000 5.200025e+000 vertex 2.619372e+001 2.887917e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.558199e+001 4.025043e+000 5.200025e+000 vertex 2.530402e+001 3.833575e+000 5.200025e+000 vertex 2.507505e+001 3.610052e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.558199e+001 4.025043e+000 5.200025e+000 vertex 2.507505e+001 3.610052e+000 5.200025e+000 vertex 2.602125e+001 3.048951e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.602125e+001 3.048951e+000 5.200025e+000 vertex 2.507505e+001 3.610052e+000 5.200025e+000 vertex 2.502317e+001 3.545587e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.602125e+001 3.048951e+000 5.200025e+000 vertex 2.502317e+001 3.545587e+000 5.200025e+000 vertex 2.492107e+001 3.383970e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.384801e+001 3.038748e+000 5.200025e+000 vertex 3.357499e+001 3.114775e+000 5.200025e+000 vertex 3.329603e+001 2.613956e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.329603e+001 2.613956e+000 5.200025e+000 vertex 3.357499e+001 3.114775e+000 5.200025e+000 vertex 3.341020e+001 3.189356e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.329603e+001 2.613956e+000 5.200025e+000 vertex 3.341020e+001 3.189356e+000 5.200025e+000 vertex 3.280565e+001 2.728420e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.280565e+001 2.728420e+000 5.200025e+000 vertex 3.341020e+001 3.189356e+000 5.200025e+000 vertex 3.326696e+001 3.281403e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.280565e+001 2.728420e+000 5.200025e+000 vertex 3.326696e+001 3.281403e+000 5.200025e+000 vertex 3.251593e+001 2.840626e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.251593e+001 2.840626e+000 5.200025e+000 vertex 3.326696e+001 3.281403e+000 5.200025e+000 vertex 3.315278e+001 3.384182e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.251593e+001 2.840626e+000 5.200025e+000 vertex 3.315278e+001 3.384182e+000 5.200025e+000 vertex 3.229612e+001 2.960717e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.229612e+001 2.960717e+000 5.200025e+000 vertex 3.315278e+001 3.384182e+000 5.200025e+000 vertex 3.305370e+001 3.508620e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.229612e+001 2.960717e+000 5.200025e+000 vertex 3.305370e+001 3.508620e+000 5.200025e+000 vertex 3.211307e+001 3.097985e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.211307e+001 3.097985e+000 5.200025e+000 vertex 3.305370e+001 3.508620e+000 5.200025e+000 vertex 3.298082e+001 3.639853e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.211307e+001 3.097985e+000 5.200025e+000 vertex 3.298082e+001 3.639853e+000 5.200025e+000 vertex 3.197369e+001 3.240942e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.197369e+001 3.240942e+000 5.200025e+000 vertex 3.298082e+001 3.639853e+000 5.200025e+000 vertex 3.185274e+001 3.414602e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.185274e+001 3.414602e+000 5.200025e+000 vertex 3.298082e+001 3.639853e+000 5.200025e+000 vertex 3.292393e+001 3.795351e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.185274e+001 3.414602e+000 5.200025e+000 vertex 3.292393e+001 3.795351e+000 5.200025e+000 vertex 3.177435e+001 3.582894e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.177435e+001 3.582894e+000 5.200025e+000 vertex 3.292393e+001 3.795351e+000 5.200025e+000 vertex 3.288729e+001 3.976790e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.177435e+001 3.582894e+000 5.200025e+000 vertex 3.288729e+001 3.976790e+000 5.200025e+000 vertex 3.171952e+001 3.769147e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.171952e+001 3.769147e+000 5.200025e+000 vertex 3.288729e+001 3.976790e+000 5.200025e+000 vertex 3.169009e+001 3.974148e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.169009e+001 3.974148e+000 5.200025e+000 vertex 3.288729e+001 3.976790e+000 5.200025e+000 vertex 3.287488e+001 4.185221e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.169009e+001 3.974148e+000 5.200025e+000 vertex 3.287488e+001 4.185221e+000 5.200025e+000 vertex 3.168638e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.168638e+001 4.069511e+000 5.200025e+000 vertex 3.287488e+001 4.185221e+000 5.200025e+000 vertex 3.290936e+001 4.526751e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.168638e+001 4.069511e+000 5.200025e+000 vertex 3.290936e+001 4.526751e+000 5.200025e+000 vertex 3.299145e+001 4.809980e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.299145e+001 4.809980e+000 5.200025e+000 vertex 3.312604e+001 5.097305e+000 5.200025e+000 vertex 3.168638e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.168638e+001 4.069511e+000 5.200025e+000 vertex 3.312604e+001 5.097305e+000 5.200025e+000 vertex 3.334701e+001 5.425931e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.168638e+001 4.069511e+000 5.200025e+000 vertex 3.334701e+001 5.425931e+000 5.200025e+000 vertex 3.413707e+001 6.512548e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.413707e+001 6.512548e+000 5.200025e+000 vertex 3.334701e+001 5.425931e+000 5.200025e+000 vertex 3.346085e+001 5.560289e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.413707e+001 6.512548e+000 5.200025e+000 vertex 3.346085e+001 5.560289e+000 5.200025e+000 vertex 3.368468e+001 5.773034e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.484638e+001 2.806348e+000 5.200025e+000 vertex 2.487749e+001 2.724321e+000 5.200025e+000 vertex 2.482629e+001 2.903027e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.482629e+001 2.903027e+000 5.200025e+000 vertex 2.487749e+001 2.724321e+000 5.200025e+000 vertex 2.602125e+001 3.048951e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.482629e+001 2.903027e+000 5.200025e+000 vertex 2.602125e+001 3.048951e+000 5.200025e+000 vertex 2.482083e+001 2.996032e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.482083e+001 2.996032e+000 5.200025e+000 vertex 2.602125e+001 3.048951e+000 5.200025e+000 vertex 2.492107e+001 3.383970e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.482083e+001 2.996032e+000 5.200025e+000 vertex 2.492107e+001 3.383970e+000 5.200025e+000 vertex 2.483340e+001 3.134158e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 2.483340e+001 3.134158e+000 5.200025e+000 vertex 2.492107e+001 3.383970e+000 5.200025e+000 vertex 2.486559e+001 3.258564e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.424180e+001 2.992802e+000 5.200025e+000 vertex 3.410799e+001 2.555998e+000 5.200025e+000 vertex 3.441289e+001 2.988430e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.441289e+001 2.988430e+000 5.200025e+000 vertex 3.410799e+001 2.555998e+000 5.200025e+000 vertex 3.515697e+001 2.555998e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.441289e+001 2.988430e+000 5.200025e+000 vertex 3.515697e+001 2.555998e+000 5.200025e+000 vertex 3.530741e+001 2.563509e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.584785e+001 2.988430e+000 5.200025e+000 vertex 3.441289e+001 2.988430e+000 5.200025e+000 vertex 3.582179e+001 2.898758e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.582179e+001 2.898758e+000 5.200025e+000 vertex 3.441289e+001 2.988430e+000 5.200025e+000 vertex 3.530741e+001 2.563509e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.582179e+001 2.898758e+000 5.200025e+000 vertex 3.530741e+001 2.563509e+000 5.200025e+000 vertex 3.579260e+001 2.833500e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.579260e+001 2.833500e+000 5.200025e+000 vertex 3.530741e+001 2.563509e+000 5.200025e+000 vertex 3.545889e+001 2.591131e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.579260e+001 2.833500e+000 5.200025e+000 vertex 3.545889e+001 2.591131e+000 5.200025e+000 vertex 3.575074e+001 2.770387e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.575074e+001 2.770387e+000 5.200025e+000 vertex 3.545889e+001 2.591131e+000 5.200025e+000 vertex 3.556581e+001 2.628944e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.575074e+001 2.770387e+000 5.200025e+000 vertex 3.556581e+001 2.628944e+000 5.200025e+000 vertex 3.570092e+001 2.717005e+000 5.200025e+000 endloop endfacet facet normal 7.619259e-014 -3.264371e-014 1.000000e+000 outer loop vertex 3.570092e+001 2.717005e+000 5.200025e+000 vertex 3.556581e+001 2.628944e+000 5.200025e+000 vertex 3.564011e+001 2.669571e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.346356e+001 4.501944e+000 5.200025e+000 vertex 2.628028e+001 4.501944e+000 5.200025e+000 vertex 2.346356e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.346356e+001 4.501944e+000 3.200025e+000 vertex 2.628028e+001 4.501944e+000 5.200025e+000 vertex 2.628028e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 9.178419e-001 -3.969461e-001 0.000000e+000 outer loop vertex 2.411812e+001 6.015457e+000 5.200025e+000 vertex 2.346356e+001 4.501944e+000 5.200025e+000 vertex 2.411812e+001 6.015457e+000 3.200025e+000 endloop endfacet facet normal 9.178419e-001 -3.969461e-001 0.000000e+000 outer loop vertex 2.411812e+001 6.015457e+000 3.200025e+000 vertex 2.346356e+001 4.501944e+000 5.200025e+000 vertex 2.346356e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.309110e+001 6.015457e+000 5.200025e+000 vertex 2.411812e+001 6.015457e+000 5.200025e+000 vertex 2.309110e+001 6.015457e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.309110e+001 6.015457e+000 3.200025e+000 vertex 2.411812e+001 6.015457e+000 5.200025e+000 vertex 2.411812e+001 6.015457e+000 3.200025e+000 endloop endfacet facet normal -9.420745e-001 3.354037e-001 0.000000e+000 outer loop vertex 2.255224e+001 4.501944e+000 5.200025e+000 vertex 2.309110e+001 6.015457e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal -9.420745e-001 3.354037e-001 0.000000e+000 outer loop vertex 2.255224e+001 4.501944e+000 3.200025e+000 vertex 2.309110e+001 6.015457e+000 5.200025e+000 vertex 2.309110e+001 6.015457e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 5.200025e+000 vertex 2.200241e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.255224e+001 4.501944e+000 5.200025e+000 vertex 2.255224e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal -9.478112e-001 3.188320e-001 0.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 5.200025e+000 vertex 2.200241e+001 4.501944e+000 3.200025e+000 vertex 2.196850e+001 4.401275e+000 3.200025e+000 endloop endfacet facet normal -9.625385e-001 2.711449e-001 0.000000e+000 outer loop vertex 2.200241e+001 4.501944e+000 5.200025e+000 vertex 2.196850e+001 4.401275e+000 3.200025e+000 vertex 2.196850e+001 4.401275e+000 5.200025e+000 endloop endfacet facet normal -9.852704e-001 1.710033e-001 0.000000e+000 outer loop vertex 2.196850e+001 4.401275e+000 5.200025e+000 vertex 2.196850e+001 4.401275e+000 3.200025e+000 vertex 2.195596e+001 4.295863e+000 3.200025e+000 endloop endfacet facet normal -9.929569e-001 1.184760e-001 0.000000e+000 outer loop vertex 2.196850e+001 4.401275e+000 5.200025e+000 vertex 2.195596e+001 4.295863e+000 3.200025e+000 vertex 2.195596e+001 4.295863e+000 5.200025e+000 endloop endfacet facet normal -9.970003e-001 -7.739806e-002 0.000000e+000 outer loop vertex 2.195596e+001 4.295863e+000 5.200025e+000 vertex 2.195596e+001 4.295863e+000 3.200025e+000 vertex 2.196043e+001 4.238191e+000 3.200025e+000 endloop endfacet facet normal -9.950550e-001 -9.932577e-002 0.000000e+000 outer loop vertex 2.195596e+001 4.295863e+000 5.200025e+000 vertex 2.196043e+001 4.238191e+000 3.200025e+000 vertex 2.196043e+001 4.238191e+000 5.200025e+000 endloop endfacet facet normal -9.844645e-001 -1.755835e-001 0.000000e+000 outer loop vertex 2.196043e+001 4.238191e+000 5.200025e+000 vertex 2.196043e+001 4.238191e+000 3.200025e+000 vertex 2.197223e+001 4.181031e+000 3.200025e+000 endloop endfacet facet normal -9.732841e-001 -2.296039e-001 0.000000e+000 outer loop vertex 2.196043e+001 4.238191e+000 5.200025e+000 vertex 2.197223e+001 4.181031e+000 3.200025e+000 vertex 2.197223e+001 4.181031e+000 5.200025e+000 endloop endfacet facet normal -9.446811e-001 -3.279902e-001 0.000000e+000 outer loop vertex 2.197223e+001 4.181031e+000 5.200025e+000 vertex 2.197223e+001 4.181031e+000 3.200025e+000 vertex 2.199379e+001 4.123733e+000 3.200025e+000 endloop endfacet facet normal -9.280019e-001 -3.725753e-001 0.000000e+000 outer loop vertex 2.197223e+001 4.181031e+000 5.200025e+000 vertex 2.199379e+001 4.123733e+000 3.200025e+000 vertex 2.199379e+001 4.123733e+000 5.200025e+000 endloop endfacet facet normal -8.841821e-001 -4.671424e-001 0.000000e+000 outer loop vertex 2.199379e+001 4.123733e+000 5.200025e+000 vertex 2.199379e+001 4.123733e+000 3.200025e+000 vertex 2.202447e+001 4.068987e+000 3.200025e+000 endloop endfacet facet normal -8.561553e-001 -5.167187e-001 0.000000e+000 outer loop vertex 2.199379e+001 4.123733e+000 5.200025e+000 vertex 2.202447e+001 4.068987e+000 3.200025e+000 vertex 2.202447e+001 4.068987e+000 5.200025e+000 endloop endfacet facet normal -8.038245e-001 -5.948665e-001 0.000000e+000 outer loop vertex 2.202447e+001 4.068987e+000 5.200025e+000 vertex 2.202447e+001 4.068987e+000 3.200025e+000 vertex 2.207336e+001 4.007856e+000 3.200025e+000 endloop endfacet facet normal -7.810422e-001 -6.244783e-001 0.000000e+000 outer loop vertex 2.202447e+001 4.068987e+000 5.200025e+000 vertex 2.207336e+001 4.007856e+000 3.200025e+000 vertex 2.207336e+001 4.007856e+000 5.200025e+000 endloop endfacet facet normal -6.976216e-001 -7.164663e-001 0.000000e+000 outer loop vertex 2.207336e+001 4.007856e+000 5.200025e+000 vertex 2.207336e+001 4.007856e+000 3.200025e+000 vertex 2.211550e+001 3.966825e+000 3.200025e+000 endloop endfacet facet normal -6.864337e-001 -7.271924e-001 0.000000e+000 outer loop vertex 2.207336e+001 4.007856e+000 5.200025e+000 vertex 2.211550e+001 3.966825e+000 3.200025e+000 vertex 2.211550e+001 3.966825e+000 5.200025e+000 endloop endfacet facet normal -6.368110e-001 -7.710200e-001 0.000000e+000 outer loop vertex 2.211550e+001 3.966825e+000 5.200025e+000 vertex 2.211550e+001 3.966825e+000 3.200025e+000 vertex 2.217411e+001 3.920629e+000 3.200025e+000 endloop endfacet facet normal -5.967951e-001 -8.023936e-001 0.000000e+000 outer loop vertex 2.211550e+001 3.966825e+000 5.200025e+000 vertex 2.217411e+001 3.920629e+000 3.200025e+000 vertex 2.217411e+001 3.920629e+000 5.200025e+000 endloop endfacet facet normal -5.099006e-001 -8.602334e-001 0.000000e+000 outer loop vertex 2.217411e+001 3.920629e+000 5.200025e+000 vertex 2.217411e+001 3.920629e+000 3.200025e+000 vertex 2.223761e+001 3.885249e+000 3.200025e+000 endloop endfacet facet normal -4.628473e-001 -8.864380e-001 0.000000e+000 outer loop vertex 2.217411e+001 3.920629e+000 5.200025e+000 vertex 2.223761e+001 3.885249e+000 3.200025e+000 vertex 2.223761e+001 3.885249e+000 5.200025e+000 endloop endfacet facet normal -3.757479e-001 -9.267219e-001 0.000000e+000 outer loop vertex 2.223761e+001 3.885249e+000 5.200025e+000 vertex 2.223761e+001 3.885249e+000 3.200025e+000 vertex 2.232674e+001 3.853295e+000 3.200025e+000 endloop endfacet facet normal -3.361592e-001 -9.418051e-001 0.000000e+000 outer loop vertex 2.223761e+001 3.885249e+000 5.200025e+000 vertex 2.232674e+001 3.853295e+000 3.200025e+000 vertex 2.232674e+001 3.853295e+000 5.200025e+000 endloop endfacet facet normal -9.412808e-001 3.376248e-001 0.000000e+000 outer loop vertex 2.159785e+001 1.821201e+000 5.200025e+000 vertex 2.232674e+001 3.853295e+000 5.200025e+000 vertex 2.159785e+001 1.821201e+000 3.200025e+000 endloop endfacet facet normal -9.412808e-001 3.376248e-001 0.000000e+000 outer loop vertex 2.159785e+001 1.821201e+000 3.200025e+000 vertex 2.232674e+001 3.853295e+000 5.200025e+000 vertex 2.232674e+001 3.853295e+000 3.200025e+000 endloop endfacet facet normal -9.557949e-001 2.940342e-001 0.000000e+000 outer loop vertex 2.159785e+001 1.821201e+000 5.200025e+000 vertex 2.159785e+001 1.821201e+000 3.200025e+000 vertex 2.158293e+001 1.772760e+000 3.200025e+000 endloop endfacet facet normal -9.685059e-001 2.489906e-001 0.000000e+000 outer loop vertex 2.159785e+001 1.821201e+000 5.200025e+000 vertex 2.158293e+001 1.772760e+000 3.200025e+000 vertex 2.158293e+001 1.772760e+000 5.200025e+000 endloop endfacet facet normal -9.879239e-001 1.549403e-001 0.000000e+000 outer loop vertex 2.158293e+001 1.772760e+000 5.200025e+000 vertex 2.158293e+001 1.772760e+000 3.200025e+000 vertex 2.157758e+001 1.722383e+000 3.200025e+000 endloop endfacet facet normal -9.943787e-001 1.058812e-001 0.000000e+000 outer loop vertex 2.158293e+001 1.772760e+000 5.200025e+000 vertex 2.157758e+001 1.722383e+000 3.200025e+000 vertex 2.157758e+001 1.722383e+000 5.200025e+000 endloop endfacet facet normal -9.978865e-001 -6.498186e-002 0.000000e+000 outer loop vertex 2.157758e+001 1.722383e+000 5.200025e+000 vertex 2.157758e+001 1.722383e+000 3.200025e+000 vertex 2.157923e+001 1.697007e+000 3.200025e+000 endloop endfacet facet normal -9.973561e-001 -7.266870e-002 0.000000e+000 outer loop vertex 2.157758e+001 1.722383e+000 5.200025e+000 vertex 2.157923e+001 1.697007e+000 3.200025e+000 vertex 2.157923e+001 1.697007e+000 5.200025e+000 endloop endfacet facet normal -9.916509e-001 -1.289514e-001 0.000000e+000 outer loop vertex 2.157923e+001 1.697007e+000 5.200025e+000 vertex 2.157923e+001 1.697007e+000 3.200025e+000 vertex 2.158555e+001 1.653413e+000 3.200025e+000 endloop endfacet facet normal -9.841461e-001 -1.773595e-001 0.000000e+000 outer loop vertex 2.157923e+001 1.697007e+000 5.200025e+000 vertex 2.158555e+001 1.653413e+000 3.200025e+000 vertex 2.158555e+001 1.653413e+000 5.200025e+000 endloop endfacet facet normal -9.614099e-001 -2.751199e-001 0.000000e+000 outer loop vertex 2.158555e+001 1.653413e+000 5.200025e+000 vertex 2.158555e+001 1.653413e+000 3.200025e+000 vertex 2.159803e+001 1.614061e+000 3.200025e+000 endloop endfacet facet normal -9.459160e-001 -3.244117e-001 0.000000e+000 outer loop vertex 2.158555e+001 1.653413e+000 5.200025e+000 vertex 2.159803e+001 1.614061e+000 3.200025e+000 vertex 2.159803e+001 1.614061e+000 5.200025e+000 endloop endfacet facet normal -9.064272e-001 -4.223621e-001 0.000000e+000 outer loop vertex 2.159803e+001 1.614061e+000 5.200025e+000 vertex 2.159803e+001 1.614061e+000 3.200025e+000 vertex 2.161900e+001 1.571960e+000 3.200025e+000 endloop endfacet facet normal -8.821769e-001 -4.709181e-001 0.000000e+000 outer loop vertex 2.159803e+001 1.614061e+000 5.200025e+000 vertex 2.161900e+001 1.571960e+000 3.200025e+000 vertex 2.161900e+001 1.571960e+000 5.200025e+000 endloop endfacet facet normal -8.271294e-001 -5.620115e-001 0.000000e+000 outer loop vertex 2.161900e+001 1.571960e+000 5.200025e+000 vertex 2.161900e+001 1.571960e+000 3.200025e+000 vertex 2.164507e+001 1.535839e+000 3.200025e+000 endloop endfacet facet normal -7.964937e-001 -6.046468e-001 0.000000e+000 outer loop vertex 2.161900e+001 1.571960e+000 5.200025e+000 vertex 2.164507e+001 1.535839e+000 3.200025e+000 vertex 2.164507e+001 1.535839e+000 5.200025e+000 endloop endfacet facet normal -7.275544e-001 -6.860501e-001 0.000000e+000 outer loop vertex 2.164507e+001 1.535839e+000 5.200025e+000 vertex 2.164507e+001 1.535839e+000 3.200025e+000 vertex 2.168871e+001 1.492140e+000 3.200025e+000 endloop endfacet facet normal -6.890863e-001 -7.246793e-001 0.000000e+000 outer loop vertex 2.164507e+001 1.535839e+000 5.200025e+000 vertex 2.168871e+001 1.492140e+000 3.200025e+000 vertex 2.168871e+001 1.492140e+000 5.200025e+000 endloop endfacet facet normal -6.047888e-001 -7.963859e-001 0.000000e+000 outer loop vertex 2.168871e+001 1.492140e+000 5.200025e+000 vertex 2.168871e+001 1.492140e+000 3.200025e+000 vertex 2.173006e+001 1.462375e+000 3.200025e+000 endloop endfacet facet normal -5.588141e-001 -8.292930e-001 0.000000e+000 outer loop vertex 2.168871e+001 1.492140e+000 5.200025e+000 vertex 2.173006e+001 1.462375e+000 3.200025e+000 vertex 2.173006e+001 1.462375e+000 5.200025e+000 endloop endfacet facet normal -4.627131e-001 -8.865081e-001 0.000000e+000 outer loop vertex 2.173006e+001 1.462375e+000 5.200025e+000 vertex 2.173006e+001 1.462375e+000 3.200025e+000 vertex 2.177628e+001 1.439914e+000 3.200025e+000 endloop endfacet facet normal -4.126348e-001 -9.108965e-001 0.000000e+000 outer loop vertex 2.173006e+001 1.462375e+000 5.200025e+000 vertex 2.177628e+001 1.439914e+000 3.200025e+000 vertex 2.177628e+001 1.439914e+000 5.200025e+000 endloop endfacet facet normal -3.077320e-001 -9.514731e-001 0.000000e+000 outer loop vertex 2.177628e+001 1.439914e+000 5.200025e+000 vertex 2.177628e+001 1.439914e+000 3.200025e+000 vertex 2.181840e+001 1.427426e+000 3.200025e+000 endloop endfacet facet normal -2.528477e-001 -9.675061e-001 0.000000e+000 outer loop vertex 2.177628e+001 1.439914e+000 5.200025e+000 vertex 2.181840e+001 1.427426e+000 3.200025e+000 vertex 2.181840e+001 1.427426e+000 5.200025e+000 endloop endfacet facet normal -1.574658e-001 -9.875244e-001 0.000000e+000 outer loop vertex 2.181840e+001 1.427426e+000 5.200025e+000 vertex 2.181840e+001 1.427426e+000 3.200025e+000 vertex 2.187403e+001 1.420863e+000 3.200025e+000 endloop endfacet facet normal -1.172880e-001 -9.930980e-001 0.000000e+000 outer loop vertex 2.181840e+001 1.427426e+000 5.200025e+000 vertex 2.187403e+001 1.420863e+000 3.200025e+000 vertex 2.187403e+001 1.420863e+000 5.200025e+000 endloop endfacet facet normal 2.278424e-002 -9.997404e-001 0.000000e+000 outer loop vertex 2.187403e+001 1.420863e+000 5.200025e+000 vertex 2.187403e+001 1.420863e+000 3.200025e+000 vertex 2.200705e+001 1.423892e+000 3.200025e+000 endloop endfacet facet normal 3.905552e-002 -9.992371e-001 0.000000e+000 outer loop vertex 2.187403e+001 1.420863e+000 5.200025e+000 vertex 2.200705e+001 1.423892e+000 3.200025e+000 vertex 2.200705e+001 1.423892e+000 5.200025e+000 endloop endfacet facet normal 1.087345e-001 -9.940708e-001 0.000000e+000 outer loop vertex 2.200705e+001 1.423892e+000 5.200025e+000 vertex 2.200705e+001 1.423892e+000 3.200025e+000 vertex 2.222927e+001 1.455257e+000 3.200025e+000 endloop endfacet facet normal 1.619973e-001 -9.867911e-001 0.000000e+000 outer loop vertex 2.200705e+001 1.423892e+000 5.200025e+000 vertex 2.222927e+001 1.455257e+000 3.200025e+000 vertex 2.222927e+001 1.455257e+000 5.200025e+000 endloop endfacet facet normal 2.639149e-001 -9.645460e-001 0.000000e+000 outer loop vertex 2.222927e+001 1.455257e+000 5.200025e+000 vertex 2.222927e+001 1.455257e+000 3.200025e+000 vertex 2.248483e+001 1.533015e+000 3.200025e+000 endloop endfacet facet normal 3.126340e-001 -9.498736e-001 0.000000e+000 outer loop vertex 2.222927e+001 1.455257e+000 5.200025e+000 vertex 2.248483e+001 1.533015e+000 3.200025e+000 vertex 2.248483e+001 1.533015e+000 5.200025e+000 endloop endfacet facet normal 4.046802e-001 -9.144583e-001 0.000000e+000 outer loop vertex 2.248483e+001 1.533015e+000 5.200025e+000 vertex 2.248483e+001 1.533015e+000 3.200025e+000 vertex 2.276652e+001 1.666767e+000 3.200025e+000 endloop endfacet facet normal 4.481091e-001 -8.939788e-001 0.000000e+000 outer loop vertex 2.248483e+001 1.533015e+000 5.200025e+000 vertex 2.276652e+001 1.666767e+000 3.200025e+000 vertex 2.276652e+001 1.666767e+000 5.200025e+000 endloop endfacet facet normal 5.285131e-001 -8.489251e-001 0.000000e+000 outer loop vertex 2.276652e+001 1.666767e+000 5.200025e+000 vertex 2.276652e+001 1.666767e+000 3.200025e+000 vertex 2.314008e+001 1.917484e+000 3.200025e+000 endloop endfacet facet normal 5.656528e-001 -8.246435e-001 0.000000e+000 outer loop vertex 2.276652e+001 1.666767e+000 5.200025e+000 vertex 2.314008e+001 1.917484e+000 3.200025e+000 vertex 2.314008e+001 1.917484e+000 5.200025e+000 endloop endfacet facet normal 6.350900e-001 -7.724382e-001 0.000000e+000 outer loop vertex 2.314008e+001 1.917484e+000 5.200025e+000 vertex 2.314008e+001 1.917484e+000 3.200025e+000 vertex 2.325911e+001 2.015348e+000 3.200025e+000 endloop endfacet facet normal 6.415651e-001 -7.670687e-001 0.000000e+000 outer loop vertex 2.314008e+001 1.917484e+000 5.200025e+000 vertex 2.325911e+001 2.015348e+000 3.200025e+000 vertex 2.325911e+001 2.015348e+000 5.200025e+000 endloop endfacet facet normal 6.880280e-001 -7.256842e-001 0.000000e+000 outer loop vertex 2.325911e+001 2.015348e+000 5.200025e+000 vertex 2.325911e+001 2.015348e+000 3.200025e+000 vertex 2.351545e+001 2.271196e+000 3.200025e+000 endloop endfacet facet normal 7.261769e-001 -6.875079e-001 0.000000e+000 outer loop vertex 2.325911e+001 2.015348e+000 5.200025e+000 vertex 2.351545e+001 2.271196e+000 3.200025e+000 vertex 2.351545e+001 2.271196e+000 5.200025e+000 endloop endfacet facet normal 7.960309e-001 -6.052561e-001 0.000000e+000 outer loop vertex 2.351545e+001 2.271196e+000 5.200025e+000 vertex 2.351545e+001 2.271196e+000 3.200025e+000 vertex 2.369053e+001 2.513875e+000 3.200025e+000 endloop endfacet facet normal 8.277089e-001 -5.611578e-001 0.000000e+000 outer loop vertex 2.351545e+001 2.271196e+000 5.200025e+000 vertex 2.369053e+001 2.513875e+000 3.200025e+000 vertex 2.369053e+001 2.513875e+000 5.200025e+000 endloop endfacet facet normal 8.839755e-001 -4.675332e-001 0.000000e+000 outer loop vertex 2.369053e+001 2.513875e+000 5.200025e+000 vertex 2.369053e+001 2.513875e+000 3.200025e+000 vertex 2.380128e+001 2.735877e+000 3.200025e+000 endloop endfacet facet normal 9.084699e-001 -4.179503e-001 0.000000e+000 outer loop vertex 2.369053e+001 2.513875e+000 5.200025e+000 vertex 2.380128e+001 2.735877e+000 3.200025e+000 vertex 2.380128e+001 2.735877e+000 5.200025e+000 endloop endfacet facet normal 9.478195e-001 -3.188075e-001 0.000000e+000 outer loop vertex 2.380128e+001 2.735877e+000 5.200025e+000 vertex 2.380128e+001 2.735877e+000 3.200025e+000 vertex 2.386987e+001 2.957672e+000 3.200025e+000 endloop endfacet facet normal 9.630316e-001 -2.693883e-001 0.000000e+000 outer loop vertex 2.380128e+001 2.735877e+000 5.200025e+000 vertex 2.386987e+001 2.957672e+000 3.200025e+000 vertex 2.386987e+001 2.957672e+000 5.200025e+000 endloop endfacet facet normal 9.854131e-001 -1.701791e-001 0.000000e+000 outer loop vertex 2.386987e+001 2.957672e+000 5.200025e+000 vertex 2.386987e+001 2.957672e+000 3.200025e+000 vertex 2.390191e+001 3.211403e+000 3.200025e+000 endloop endfacet facet normal 9.927229e-001 -1.204206e-001 0.000000e+000 outer loop vertex 2.386987e+001 2.957672e+000 5.200025e+000 vertex 2.390191e+001 3.211403e+000 3.200025e+000 vertex 2.390191e+001 3.211403e+000 5.200025e+000 endloop endfacet facet normal 9.997811e-001 -2.092126e-002 0.000000e+000 outer loop vertex 2.390191e+001 3.211403e+000 5.200025e+000 vertex 2.390191e+001 3.211403e+000 3.200025e+000 vertex 2.390364e+001 3.294121e+000 3.200025e+000 endloop endfacet facet normal 9.998624e-001 -1.659215e-002 0.000000e+000 outer loop vertex 2.390191e+001 3.211403e+000 5.200025e+000 vertex 2.390364e+001 3.294121e+000 3.200025e+000 vertex 2.390364e+001 3.294121e+000 5.200025e+000 endloop endfacet facet normal 9.992281e-001 3.928505e-002 0.000000e+000 outer loop vertex 2.390364e+001 3.294121e+000 5.200025e+000 vertex 2.390364e+001 3.294121e+000 3.200025e+000 vertex 2.388682e+001 3.571214e+000 3.200025e+000 endloop endfacet facet normal 9.958631e-001 9.086565e-002 0.000000e+000 outer loop vertex 2.390364e+001 3.294121e+000 5.200025e+000 vertex 2.388682e+001 3.571214e+000 3.200025e+000 vertex 2.388682e+001 3.571214e+000 5.200025e+000 endloop endfacet facet normal 9.812911e-001 1.925299e-001 0.000000e+000 outer loop vertex 2.388682e+001 3.571214e+000 5.200025e+000 vertex 2.388682e+001 3.571214e+000 3.200025e+000 vertex 2.384816e+001 3.755558e+000 3.200025e+000 endloop endfacet facet normal 9.701216e-001 2.426191e-001 0.000000e+000 outer loop vertex 2.388682e+001 3.571214e+000 5.200025e+000 vertex 2.384816e+001 3.755558e+000 3.200025e+000 vertex 2.384816e+001 3.755558e+000 5.200025e+000 endloop endfacet facet normal 9.388645e-001 3.442869e-001 0.000000e+000 outer loop vertex 2.384816e+001 3.755558e+000 5.200025e+000 vertex 2.384816e+001 3.755558e+000 3.200025e+000 vertex 2.379199e+001 3.897038e+000 3.200025e+000 endloop endfacet facet normal 9.183630e-001 3.957392e-001 0.000000e+000 outer loop vertex 2.384816e+001 3.755558e+000 5.200025e+000 vertex 2.379199e+001 3.897038e+000 3.200025e+000 vertex 2.379199e+001 3.897038e+000 5.200025e+000 endloop endfacet facet normal 8.693968e-001 4.941146e-001 0.000000e+000 outer loop vertex 2.379199e+001 3.897038e+000 5.200025e+000 vertex 2.379199e+001 3.897038e+000 3.200025e+000 vertex 2.373908e+001 3.985847e+000 3.200025e+000 endloop endfacet facet normal 8.409823e-001 5.410626e-001 0.000000e+000 outer loop vertex 2.379199e+001 3.897038e+000 5.200025e+000 vertex 2.373908e+001 3.985847e+000 3.200025e+000 vertex 2.373908e+001 3.985847e+000 5.200025e+000 endloop endfacet facet normal 7.806446e-001 6.249753e-001 0.000000e+000 outer loop vertex 2.373908e+001 3.985847e+000 5.200025e+000 vertex 2.373908e+001 3.985847e+000 3.200025e+000 vertex 2.366542e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 7.492310e-001 6.623088e-001 0.000000e+000 outer loop vertex 2.373908e+001 3.985847e+000 5.200025e+000 vertex 2.366542e+001 4.069511e+000 3.200025e+000 vertex 2.366542e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.554971e+001 4.069511e+000 5.200025e+000 vertex 2.366542e+001 4.069511e+000 5.200025e+000 vertex 2.554971e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.554971e+001 4.069511e+000 3.200025e+000 vertex 2.366542e+001 4.069511e+000 5.200025e+000 vertex 2.366542e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 7.867855e-001 -6.172265e-001 0.000000e+000 outer loop vertex 2.617619e+001 4.280954e+000 5.200025e+000 vertex 2.617619e+001 4.280954e+000 3.200025e+000 vertex 2.620843e+001 4.323749e+000 3.200025e+000 endloop endfacet facet normal 8.107034e-001 -5.854571e-001 0.000000e+000 outer loop vertex 2.617619e+001 4.280954e+000 5.200025e+000 vertex 2.620843e+001 4.323749e+000 3.200025e+000 vertex 2.620843e+001 4.323749e+000 5.200025e+000 endloop endfacet facet normal 8.616599e-001 -5.074862e-001 0.000000e+000 outer loop vertex 2.620843e+001 4.323749e+000 5.200025e+000 vertex 2.620843e+001 4.323749e+000 3.200025e+000 vertex 2.624228e+001 4.384831e+000 3.200025e+000 endloop endfacet facet normal 8.876228e-001 -4.605711e-001 0.000000e+000 outer loop vertex 2.620843e+001 4.323749e+000 5.200025e+000 vertex 2.624228e+001 4.384831e+000 3.200025e+000 vertex 2.624228e+001 4.384831e+000 5.200025e+000 endloop endfacet facet normal 9.326648e-001 -3.607441e-001 0.000000e+000 outer loop vertex 2.624228e+001 4.384831e+000 5.200025e+000 vertex 2.624228e+001 4.384831e+000 3.200025e+000 vertex 2.628028e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 9.514794e-001 -3.077126e-001 0.000000e+000 outer loop vertex 2.624228e+001 4.384831e+000 5.200025e+000 vertex 2.628028e+001 4.501944e+000 3.200025e+000 vertex 2.628028e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal -9.187567e-001 3.948242e-001 0.000000e+000 outer loop vertex 2.306745e+001 2.779815e+000 5.200025e+000 vertex 2.306745e+001 2.779815e+000 3.200025e+000 vertex 2.302143e+001 2.672723e+000 3.200025e+000 endloop endfacet facet normal -9.096024e-001 4.154798e-001 0.000000e+000 outer loop vertex 2.306745e+001 2.779815e+000 5.200025e+000 vertex 2.302143e+001 2.672723e+000 3.200025e+000 vertex 2.302143e+001 2.672723e+000 5.200025e+000 endloop endfacet facet normal -8.768432e-001 4.807765e-001 0.000000e+000 outer loop vertex 2.302143e+001 2.672723e+000 5.200025e+000 vertex 2.302143e+001 2.672723e+000 3.200025e+000 vertex 2.292390e+001 2.510384e+000 3.200025e+000 endloop endfacet facet normal -8.513951e-001 5.245249e-001 0.000000e+000 outer loop vertex 2.302143e+001 2.672723e+000 5.200025e+000 vertex 2.292390e+001 2.510384e+000 3.200025e+000 vertex 2.292390e+001 2.510384e+000 5.200025e+000 endloop endfacet facet normal -8.001236e-001 5.998352e-001 0.000000e+000 outer loop vertex 2.292390e+001 2.510384e+000 5.200025e+000 vertex 2.292390e+001 2.510384e+000 3.200025e+000 vertex 2.273214e+001 2.272214e+000 3.200025e+000 endloop endfacet facet normal -7.750431e-001 6.319084e-001 0.000000e+000 outer loop vertex 2.292390e+001 2.510384e+000 5.200025e+000 vertex 2.273214e+001 2.272214e+000 3.200025e+000 vertex 2.273214e+001 2.272214e+000 5.200025e+000 endloop endfacet facet normal -9.954394e-001 9.539549e-002 0.000000e+000 outer loop vertex 2.314515e+001 3.170863e+000 5.200025e+000 vertex 2.314515e+001 3.170863e+000 3.200025e+000 vertex 2.312220e+001 2.972271e+000 3.200025e+000 endloop endfacet facet normal -9.882593e-001 1.527860e-001 0.000000e+000 outer loop vertex 2.314515e+001 3.170863e+000 5.200025e+000 vertex 2.312220e+001 2.972271e+000 3.200025e+000 vertex 2.312220e+001 2.972271e+000 5.200025e+000 endloop endfacet facet normal -9.698512e-001 2.436979e-001 0.000000e+000 outer loop vertex 2.312220e+001 2.972271e+000 5.200025e+000 vertex 2.312220e+001 2.972271e+000 3.200025e+000 vertex 2.306745e+001 2.779815e+000 3.200025e+000 endloop endfacet facet normal -9.606795e-001 2.776597e-001 0.000000e+000 outer loop vertex 2.312220e+001 2.972271e+000 5.200025e+000 vertex 2.306745e+001 2.779815e+000 3.200025e+000 vertex 2.306745e+001 2.779815e+000 5.200025e+000 endloop endfacet facet normal -6.188936e-001 -7.854748e-001 0.000000e+000 outer loop vertex 2.298383e+001 3.528971e+000 5.200025e+000 vertex 2.298383e+001 3.528971e+000 3.200025e+000 vertex 2.300212e+001 3.514563e+000 3.200025e+000 endloop endfacet facet normal -6.235873e-001 -7.817537e-001 0.000000e+000 outer loop vertex 2.298383e+001 3.528971e+000 5.200025e+000 vertex 2.300212e+001 3.514563e+000 3.200025e+000 vertex 2.300212e+001 3.514563e+000 5.200025e+000 endloop endfacet facet normal -6.664197e-001 -7.455768e-001 0.000000e+000 outer loop vertex 2.300212e+001 3.514563e+000 5.200025e+000 vertex 2.300212e+001 3.514563e+000 3.200025e+000 vertex 2.304059e+001 3.478963e+000 3.200025e+000 endloop endfacet facet normal -7.029994e-001 -7.111903e-001 0.000000e+000 outer loop vertex 2.300212e+001 3.514563e+000 5.200025e+000 vertex 2.304059e+001 3.478963e+000 3.200025e+000 vertex 2.304059e+001 3.478963e+000 5.200025e+000 endloop endfacet facet normal -7.715968e-001 -6.361119e-001 0.000000e+000 outer loop vertex 2.304059e+001 3.478963e+000 5.200025e+000 vertex 2.304059e+001 3.478963e+000 3.200025e+000 vertex 2.307066e+001 3.440160e+000 3.200025e+000 endloop endfacet facet normal -8.034955e-001 -5.953107e-001 0.000000e+000 outer loop vertex 2.304059e+001 3.478963e+000 5.200025e+000 vertex 2.307066e+001 3.440160e+000 3.200025e+000 vertex 2.307066e+001 3.440160e+000 5.200025e+000 endloop endfacet facet normal -8.581570e-001 -5.133873e-001 0.000000e+000 outer loop vertex 2.307066e+001 3.440160e+000 5.200025e+000 vertex 2.307066e+001 3.440160e+000 3.200025e+000 vertex 2.310262e+001 3.384567e+000 3.200025e+000 endloop endfacet facet normal -8.813158e-001 -4.725277e-001 0.000000e+000 outer loop vertex 2.307066e+001 3.440160e+000 5.200025e+000 vertex 2.310262e+001 3.384567e+000 3.200025e+000 vertex 2.310262e+001 3.384567e+000 5.200025e+000 endloop endfacet facet normal -9.235264e-001 -3.835348e-001 0.000000e+000 outer loop vertex 2.310262e+001 3.384567e+000 5.200025e+000 vertex 2.310262e+001 3.384567e+000 3.200025e+000 vertex 2.312376e+001 3.328368e+000 3.200025e+000 endloop endfacet facet normal -9.421484e-001 -3.351961e-001 0.000000e+000 outer loop vertex 2.310262e+001 3.384567e+000 5.200025e+000 vertex 2.312376e+001 3.328368e+000 3.200025e+000 vertex 2.312376e+001 3.328368e+000 5.200025e+000 endloop endfacet facet normal -9.710232e-001 -2.389852e-001 0.000000e+000 outer loop vertex 2.312376e+001 3.328368e+000 5.200025e+000 vertex 2.312376e+001 3.328368e+000 3.200025e+000 vertex 2.313931e+001 3.258176e+000 3.200025e+000 endloop endfacet facet normal -9.815520e-001 -1.911953e-001 0.000000e+000 outer loop vertex 2.312376e+001 3.328368e+000 5.200025e+000 vertex 2.313931e+001 3.258176e+000 3.200025e+000 vertex 2.313931e+001 3.258176e+000 5.200025e+000 endloop endfacet facet normal -9.946417e-001 -1.033826e-001 0.000000e+000 outer loop vertex 2.313931e+001 3.258176e+000 5.200025e+000 vertex 2.313931e+001 3.258176e+000 3.200025e+000 vertex 2.314515e+001 3.170863e+000 3.200025e+000 endloop endfacet facet normal -9.979836e-001 -6.347276e-002 0.000000e+000 outer loop vertex 2.313931e+001 3.258176e+000 5.200025e+000 vertex 2.314515e+001 3.170863e+000 3.200025e+000 vertex 2.314515e+001 3.170863e+000 5.200025e+000 endloop endfacet facet normal 9.097010e-001 -4.152639e-001 0.000000e+000 outer loop vertex 2.222623e+001 1.853295e+000 5.200025e+000 vertex 2.222623e+001 1.853295e+000 3.200025e+000 vertex 2.260892e+001 2.689378e+000 3.200025e+000 endloop endfacet facet normal 9.105328e-001 -4.134368e-001 0.000000e+000 outer loop vertex 2.222623e+001 1.853295e+000 5.200025e+000 vertex 2.260892e+001 2.689378e+000 3.200025e+000 vertex 2.260892e+001 2.689378e+000 5.200025e+000 endloop endfacet facet normal 9.131434e-001 -4.076385e-001 0.000000e+000 outer loop vertex 2.260892e+001 2.689378e+000 5.200025e+000 vertex 2.260892e+001 2.689378e+000 3.200025e+000 vertex 2.298383e+001 3.528971e+000 3.200025e+000 endloop endfacet facet normal 9.149086e-001 -4.036612e-001 0.000000e+000 outer loop vertex 2.260892e+001 2.689378e+000 5.200025e+000 vertex 2.298383e+001 3.528971e+000 3.200025e+000 vertex 2.298383e+001 3.528971e+000 5.200025e+000 endloop endfacet facet normal -7.357821e-001 6.772183e-001 0.000000e+000 outer loop vertex 2.273214e+001 2.272214e+000 5.200025e+000 vertex 2.273214e+001 2.272214e+000 3.200025e+000 vertex 2.268718e+001 2.223361e+000 3.200025e+000 endloop endfacet facet normal -7.342504e-001 6.788787e-001 0.000000e+000 outer loop vertex 2.273214e+001 2.272214e+000 5.200025e+000 vertex 2.268718e+001 2.223361e+000 3.200025e+000 vertex 2.268718e+001 2.223361e+000 5.200025e+000 endloop endfacet facet normal -6.994054e-001 7.147252e-001 0.000000e+000 outer loop vertex 2.268718e+001 2.223361e+000 5.200025e+000 vertex 2.268718e+001 2.223361e+000 3.200025e+000 vertex 2.244634e+001 1.997951e+000 3.200025e+000 endloop endfacet facet normal -6.644207e-001 7.473587e-001 0.000000e+000 outer loop vertex 2.268718e+001 2.223361e+000 5.200025e+000 vertex 2.244634e+001 1.997951e+000 3.200025e+000 vertex 2.244634e+001 1.997951e+000 5.200025e+000 endloop endfacet facet normal -5.827749e-001 8.126337e-001 0.000000e+000 outer loop vertex 2.244634e+001 1.997951e+000 5.200025e+000 vertex 2.244634e+001 1.997951e+000 3.200025e+000 vertex 2.222623e+001 1.853295e+000 3.200025e+000 endloop endfacet facet normal -5.355110e-001 8.445283e-001 0.000000e+000 outer loop vertex 2.244634e+001 1.997951e+000 5.200025e+000 vertex 2.222623e+001 1.853295e+000 3.200025e+000 vertex 2.222623e+001 1.853295e+000 5.200025e+000 endloop endfacet facet normal -4.756666e-001 8.796256e-001 0.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.567104e+001 4.073978e+000 3.200025e+000 vertex 2.558199e+001 4.025043e+000 3.200025e+000 endloop endfacet facet normal -4.890141e-001 8.722759e-001 0.000000e+000 outer loop vertex 2.567104e+001 4.073978e+000 5.200025e+000 vertex 2.558199e+001 4.025043e+000 3.200025e+000 vertex 2.558199e+001 4.025043e+000 5.200025e+000 endloop endfacet facet normal -5.462206e-001 8.376414e-001 0.000000e+000 outer loop vertex 2.558199e+001 4.025043e+000 5.200025e+000 vertex 2.558199e+001 4.025043e+000 3.200025e+000 vertex 2.530402e+001 3.833575e+000 3.200025e+000 endloop endfacet facet normal -5.888510e-001 8.082415e-001 0.000000e+000 outer loop vertex 2.558199e+001 4.025043e+000 5.200025e+000 vertex 2.530402e+001 3.833575e+000 3.200025e+000 vertex 2.530402e+001 3.833575e+000 5.200025e+000 endloop endfacet facet normal -6.695504e-001 7.427666e-001 0.000000e+000 outer loop vertex 2.530402e+001 3.833575e+000 5.200025e+000 vertex 2.530402e+001 3.833575e+000 3.200025e+000 vertex 2.507505e+001 3.610052e+000 3.200025e+000 endloop endfacet facet normal -7.075756e-001 7.066377e-001 0.000000e+000 outer loop vertex 2.530402e+001 3.833575e+000 5.200025e+000 vertex 2.507505e+001 3.610052e+000 3.200025e+000 vertex 2.507505e+001 3.610052e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.067640e+001 4.501944e+000 3.200025e+000 vertex 3.067640e+001 4.501944e+000 5.200025e+000 vertex 3.173466e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.173466e+001 4.501944e+000 3.200025e+000 vertex 3.067640e+001 4.501944e+000 5.200025e+000 vertex 3.173466e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal 9.450877e-001 -3.268169e-001 0.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 5.200025e+000 vertex 3.067640e+001 4.501944e+000 5.200025e+000 vertex 3.138670e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 9.450877e-001 -3.268169e-001 0.000000e+000 outer loop vertex 3.138670e+001 6.555998e+000 3.200025e+000 vertex 3.067640e+001 4.501944e+000 5.200025e+000 vertex 3.067640e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.997032e+001 6.555998e+000 5.200025e+000 vertex 3.138670e+001 6.555998e+000 5.200025e+000 vertex 2.997032e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.997032e+001 6.555998e+000 3.200025e+000 vertex 3.138670e+001 6.555998e+000 5.200025e+000 vertex 3.138670e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal -7.756456e-001 6.311688e-001 0.000000e+000 outer loop vertex 2.829887e+001 4.501944e+000 5.200025e+000 vertex 2.997032e+001 6.555998e+000 5.200025e+000 vertex 2.829887e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal -7.756456e-001 6.311688e-001 0.000000e+000 outer loop vertex 2.829887e+001 4.501944e+000 3.200025e+000 vertex 2.997032e+001 6.555998e+000 5.200025e+000 vertex 2.997032e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.775072e+001 4.501944e+000 5.200025e+000 vertex 2.829887e+001 4.501944e+000 5.200025e+000 vertex 2.775072e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.775072e+001 4.501944e+000 3.200025e+000 vertex 2.829887e+001 4.501944e+000 5.200025e+000 vertex 2.829887e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal -4.365902e-002 9.990465e-001 0.000000e+000 outer loop vertex 2.775072e+001 4.501944e+000 5.200025e+000 vertex 2.775072e+001 4.501944e+000 3.200025e+000 vertex 2.702711e+001 4.460593e+000 3.200025e+000 endloop endfacet facet normal -8.079561e-002 9.967307e-001 0.000000e+000 outer loop vertex 2.775072e+001 4.501944e+000 5.200025e+000 vertex 2.702711e+001 4.460593e+000 3.200025e+000 vertex 2.702711e+001 4.460593e+000 5.200025e+000 endloop endfacet facet normal -1.643360e-001 9.864044e-001 0.000000e+000 outer loop vertex 2.702711e+001 4.460593e+000 5.200025e+000 vertex 2.702711e+001 4.460593e+000 3.200025e+000 vertex 2.631576e+001 4.322890e+000 3.200025e+000 endloop endfacet facet normal -2.106414e-001 9.775634e-001 0.000000e+000 outer loop vertex 2.702711e+001 4.460593e+000 5.200025e+000 vertex 2.631576e+001 4.322890e+000 3.200025e+000 vertex 2.631576e+001 4.322890e+000 5.200025e+000 endloop endfacet facet normal -2.839510e-001 9.588388e-001 0.000000e+000 outer loop vertex 2.631576e+001 4.322890e+000 5.200025e+000 vertex 2.631576e+001 4.322890e+000 3.200025e+000 vertex 2.624589e+001 4.302198e+000 3.200025e+000 endloop endfacet facet normal -2.852200e-001 9.584621e-001 0.000000e+000 outer loop vertex 2.631576e+001 4.322890e+000 5.200025e+000 vertex 2.624589e+001 4.302198e+000 3.200025e+000 vertex 2.624589e+001 4.302198e+000 5.200025e+000 endloop endfacet facet normal -2.902918e-001 9.569382e-001 0.000000e+000 outer loop vertex 2.624589e+001 4.302198e+000 5.200025e+000 vertex 2.624589e+001 4.302198e+000 3.200025e+000 vertex 2.617619e+001 4.280954e+000 3.200025e+000 endloop endfacet facet normal -2.940906e-001 9.557776e-001 0.000000e+000 outer loop vertex 2.624589e+001 4.302198e+000 5.200025e+000 vertex 2.617619e+001 4.280954e+000 3.200025e+000 vertex 2.617619e+001 4.280954e+000 5.200025e+000 endloop endfacet facet normal -7.790819e-001 6.269221e-001 0.000000e+000 outer loop vertex 2.507505e+001 3.610052e+000 5.200025e+000 vertex 2.507505e+001 3.610052e+000 3.200025e+000 vertex 2.502317e+001 3.545587e+000 3.200025e+000 endloop endfacet facet normal -7.865905e-001 6.174751e-001 0.000000e+000 outer loop vertex 2.507505e+001 3.610052e+000 5.200025e+000 vertex 2.502317e+001 3.545587e+000 3.200025e+000 vertex 2.502317e+001 3.545587e+000 5.200025e+000 endloop endfacet facet normal -8.271237e-001 5.620199e-001 0.000000e+000 outer loop vertex 2.502317e+001 3.545587e+000 5.200025e+000 vertex 2.502317e+001 3.545587e+000 3.200025e+000 vertex 2.492107e+001 3.383970e+000 3.200025e+000 endloop endfacet facet normal -8.577055e-001 5.141413e-001 0.000000e+000 outer loop vertex 2.502317e+001 3.545587e+000 5.200025e+000 vertex 2.492107e+001 3.383970e+000 3.200025e+000 vertex 2.492107e+001 3.383970e+000 5.200025e+000 endloop endfacet facet normal -9.074520e-001 4.201559e-001 0.000000e+000 outer loop vertex 2.492107e+001 3.383970e+000 5.200025e+000 vertex 2.492107e+001 3.383970e+000 3.200025e+000 vertex 2.486559e+001 3.258564e+000 3.200025e+000 endloop endfacet facet normal -9.272704e-001 3.743924e-001 0.000000e+000 outer loop vertex 2.492107e+001 3.383970e+000 5.200025e+000 vertex 2.486559e+001 3.258564e+000 3.200025e+000 vertex 2.486559e+001 3.258564e+000 5.200025e+000 endloop endfacet facet normal -9.604161e-001 2.785695e-001 0.000000e+000 outer loop vertex 2.486559e+001 3.258564e+000 5.200025e+000 vertex 2.486559e+001 3.258564e+000 3.200025e+000 vertex 2.483340e+001 3.134158e+000 3.200025e+000 endloop endfacet facet normal -9.735568e-001 2.284453e-001 0.000000e+000 outer loop vertex 2.486559e+001 3.258564e+000 5.200025e+000 vertex 2.483340e+001 3.134158e+000 3.200025e+000 vertex 2.483340e+001 3.134158e+000 5.200025e+000 endloop endfacet facet normal -9.915389e-001 1.298095e-001 0.000000e+000 outer loop vertex 2.483340e+001 3.134158e+000 5.200025e+000 vertex 2.483340e+001 3.134158e+000 3.200025e+000 vertex 2.482083e+001 2.996032e+000 3.200025e+000 endloop endfacet facet normal -9.966853e-001 8.135293e-002 0.000000e+000 outer loop vertex 2.483340e+001 3.134158e+000 5.200025e+000 vertex 2.482083e+001 2.996032e+000 3.200025e+000 vertex 2.482083e+001 2.996032e+000 5.200025e+000 endloop endfacet facet normal -9.982774e-001 -5.867029e-002 0.000000e+000 outer loop vertex 2.482083e+001 2.996032e+000 5.200025e+000 vertex 2.482083e+001 2.996032e+000 3.200025e+000 vertex 2.482629e+001 2.903027e+000 3.200025e+000 endloop endfacet facet normal -9.961082e-001 -8.813871e-002 0.000000e+000 outer loop vertex 2.482083e+001 2.996032e+000 5.200025e+000 vertex 2.482629e+001 2.903027e+000 3.200025e+000 vertex 2.482629e+001 2.903027e+000 5.200025e+000 endloop endfacet facet normal -9.847482e-001 -1.739855e-001 0.000000e+000 outer loop vertex 2.482629e+001 2.903027e+000 5.200025e+000 vertex 2.482629e+001 2.903027e+000 3.200025e+000 vertex 2.484638e+001 2.806348e+000 3.200025e+000 endloop endfacet facet normal -9.731714e-001 -2.300816e-001 0.000000e+000 outer loop vertex 2.482629e+001 2.903027e+000 5.200025e+000 vertex 2.484638e+001 2.806348e+000 3.200025e+000 vertex 2.484638e+001 2.806348e+000 5.200025e+000 endloop endfacet facet normal -9.433390e-001 -3.318306e-001 0.000000e+000 outer loop vertex 2.484638e+001 2.806348e+000 5.200025e+000 vertex 2.484638e+001 2.806348e+000 3.200025e+000 vertex 2.487749e+001 2.724321e+000 3.200025e+000 endloop endfacet facet normal -9.259154e-001 -3.777311e-001 0.000000e+000 outer loop vertex 2.484638e+001 2.806348e+000 5.200025e+000 vertex 2.487749e+001 2.724321e+000 3.200025e+000 vertex 2.487749e+001 2.724321e+000 5.200025e+000 endloop endfacet facet normal -8.824971e-001 -4.703177e-001 0.000000e+000 outer loop vertex 2.487749e+001 2.724321e+000 5.200025e+000 vertex 2.487749e+001 2.724321e+000 3.200025e+000 vertex 2.491925e+001 2.650554e+000 3.200025e+000 endloop endfacet facet normal -8.560972e-001 -5.168148e-001 0.000000e+000 outer loop vertex 2.487749e+001 2.724321e+000 5.200025e+000 vertex 2.491925e+001 2.650554e+000 3.200025e+000 vertex 2.491925e+001 2.650554e+000 5.200025e+000 endloop endfacet facet normal -7.945591e-001 -6.071868e-001 0.000000e+000 outer loop vertex 2.491925e+001 2.650554e+000 5.200025e+000 vertex 2.491925e+001 2.650554e+000 3.200025e+000 vertex 2.498601e+001 2.568571e+000 3.200025e+000 endloop endfacet facet normal -7.591705e-001 -6.508918e-001 0.000000e+000 outer loop vertex 2.491925e+001 2.650554e+000 5.200025e+000 vertex 2.498601e+001 2.568571e+000 3.200025e+000 vertex 2.498601e+001 2.568571e+000 5.200025e+000 endloop endfacet facet normal -6.837164e-001 -7.297478e-001 0.000000e+000 outer loop vertex 2.498601e+001 2.568571e+000 5.200025e+000 vertex 2.498601e+001 2.568571e+000 3.200025e+000 vertex 2.506216e+001 2.501009e+000 3.200025e+000 endloop endfacet facet normal -6.438844e-001 -7.651228e-001 0.000000e+000 outer loop vertex 2.498601e+001 2.568571e+000 5.200025e+000 vertex 2.506216e+001 2.501009e+000 3.200025e+000 vertex 2.506216e+001 2.501009e+000 5.200025e+000 endloop endfacet facet normal -5.736420e-001 -8.191061e-001 0.000000e+000 outer loop vertex 2.506216e+001 2.501009e+000 5.200025e+000 vertex 2.506216e+001 2.501009e+000 3.200025e+000 vertex 2.516204e+001 2.436065e+000 3.200025e+000 endloop endfacet facet normal -5.441787e-001 -8.389693e-001 0.000000e+000 outer loop vertex 2.506216e+001 2.501009e+000 5.200025e+000 vertex 2.516204e+001 2.436065e+000 3.200025e+000 vertex 2.516204e+001 2.436065e+000 5.200025e+000 endloop endfacet facet normal -4.116980e-001 -9.113203e-001 0.000000e+000 outer loop vertex 2.516204e+001 2.436065e+000 5.200025e+000 vertex 2.516204e+001 2.436065e+000 3.200025e+000 vertex 2.532370e+001 2.363159e+000 3.200025e+000 endloop endfacet facet normal -3.746496e-001 -9.271665e-001 0.000000e+000 outer loop vertex 2.516204e+001 2.436065e+000 5.200025e+000 vertex 2.532370e+001 2.363159e+000 3.200025e+000 vertex 2.532370e+001 2.363159e+000 5.200025e+000 endloop endfacet facet normal -2.840914e-001 -9.587972e-001 0.000000e+000 outer loop vertex 2.532370e+001 2.363159e+000 5.200025e+000 vertex 2.532370e+001 2.363159e+000 3.200025e+000 vertex 2.553387e+001 2.309567e+000 3.200025e+000 endloop endfacet facet normal -2.300772e-001 -9.731724e-001 0.000000e+000 outer loop vertex 2.532370e+001 2.363159e+000 5.200025e+000 vertex 2.553387e+001 2.309567e+000 3.200025e+000 vertex 2.553387e+001 2.309567e+000 5.200025e+000 endloop endfacet facet normal -1.252504e-001 -9.921252e-001 0.000000e+000 outer loop vertex 2.553387e+001 2.309567e+000 5.200025e+000 vertex 2.553387e+001 2.309567e+000 3.200025e+000 vertex 2.582674e+001 2.285728e+000 3.200025e+000 endloop endfacet facet normal -7.452975e-002 -9.972188e-001 0.000000e+000 outer loop vertex 2.553387e+001 2.309567e+000 5.200025e+000 vertex 2.582674e+001 2.285728e+000 3.200025e+000 vertex 2.582674e+001 2.285728e+000 5.200025e+000 endloop endfacet facet normal 5.374902e-002 -9.985545e-001 0.000000e+000 outer loop vertex 2.582674e+001 2.285728e+000 5.200025e+000 vertex 2.582674e+001 2.285728e+000 3.200025e+000 vertex 2.606751e+001 2.299473e+000 3.200025e+000 endloop endfacet facet normal 8.599414e-002 -9.962956e-001 0.000000e+000 outer loop vertex 2.582674e+001 2.285728e+000 5.200025e+000 vertex 2.606751e+001 2.299473e+000 3.200025e+000 vertex 2.606751e+001 2.299473e+000 5.200025e+000 endloop endfacet facet normal 1.663728e-001 -9.860629e-001 0.000000e+000 outer loop vertex 2.606751e+001 2.299473e+000 5.200025e+000 vertex 2.606751e+001 2.299473e+000 3.200025e+000 vertex 2.638799e+001 2.361197e+000 3.200025e+000 endloop endfacet facet normal 2.143479e-001 -9.767574e-001 0.000000e+000 outer loop vertex 2.606751e+001 2.299473e+000 5.200025e+000 vertex 2.638799e+001 2.361197e+000 3.200025e+000 vertex 2.638799e+001 2.361197e+000 5.200025e+000 endloop endfacet facet normal 2.913408e-001 -9.566193e-001 0.000000e+000 outer loop vertex 2.638799e+001 2.361197e+000 5.200025e+000 vertex 2.638799e+001 2.361197e+000 3.200025e+000 vertex 2.661934e+001 2.435870e+000 3.200025e+000 endloop endfacet facet normal 3.207335e-001 -9.471694e-001 0.000000e+000 outer loop vertex 2.638799e+001 2.361197e+000 5.200025e+000 vertex 2.661934e+001 2.435870e+000 3.200025e+000 vertex 2.661934e+001 2.435870e+000 5.200025e+000 endloop endfacet facet normal 3.976820e-001 -9.175233e-001 0.000000e+000 outer loop vertex 2.661934e+001 2.435870e+000 5.200025e+000 vertex 2.661934e+001 2.435870e+000 3.200025e+000 vertex 2.702461e+001 2.626600e+000 3.200025e+000 endloop endfacet facet normal 4.446347e-001 -8.957120e-001 0.000000e+000 outer loop vertex 2.661934e+001 2.435870e+000 5.200025e+000 vertex 2.702461e+001 2.626600e+000 3.200025e+000 vertex 2.702461e+001 2.626600e+000 5.200025e+000 endloop endfacet facet normal 5.337380e-001 -8.456499e-001 0.000000e+000 outer loop vertex 2.702461e+001 2.626600e+000 5.200025e+000 vertex 2.702461e+001 2.626600e+000 3.200025e+000 vertex 2.750514e+001 2.949922e+000 3.200025e+000 endloop endfacet facet normal 5.759407e-001 -8.174915e-001 0.000000e+000 outer loop vertex 2.702461e+001 2.626600e+000 5.200025e+000 vertex 2.750514e+001 2.949922e+000 3.200025e+000 vertex 2.750514e+001 2.949922e+000 5.200025e+000 endloop endfacet facet normal 6.431000e-001 -7.657822e-001 0.000000e+000 outer loop vertex 2.750514e+001 2.949922e+000 5.200025e+000 vertex 2.750514e+001 2.949922e+000 3.200025e+000 vertex 2.791843e+001 3.310633e+000 3.200025e+000 endloop endfacet facet normal 6.689203e-001 -7.433341e-001 0.000000e+000 outer loop vertex 2.750514e+001 2.949922e+000 5.200025e+000 vertex 2.791843e+001 3.310633e+000 3.200025e+000 vertex 2.791843e+001 3.310633e+000 5.200025e+000 endloop endfacet facet normal 7.229618e-001 -6.908880e-001 0.000000e+000 outer loop vertex 2.791843e+001 3.310633e+000 5.200025e+000 vertex 2.791843e+001 3.310633e+000 3.200025e+000 vertex 2.860208e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 7.508170e-001 -6.605102e-001 0.000000e+000 outer loop vertex 2.791843e+001 3.310633e+000 5.200025e+000 vertex 2.860208e+001 4.069511e+000 3.200025e+000 vertex 2.860208e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.949903e+001 4.069511e+000 5.200025e+000 vertex 2.860208e+001 4.069511e+000 5.200025e+000 vertex 2.949903e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 2.949903e+001 4.069511e+000 3.200025e+000 vertex 2.860208e+001 4.069511e+000 5.200025e+000 vertex 2.860208e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal -9.485774e-001 3.165453e-001 0.000000e+000 outer loop vertex 2.899397e+001 2.555998e+000 5.200025e+000 vertex 2.949903e+001 4.069511e+000 5.200025e+000 vertex 2.899397e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal -9.485774e-001 3.165453e-001 0.000000e+000 outer loop vertex 2.899397e+001 2.555998e+000 3.200025e+000 vertex 2.949903e+001 4.069511e+000 5.200025e+000 vertex 2.949903e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.001002e+001 2.555998e+000 5.200025e+000 vertex 2.899397e+001 2.555998e+000 5.200025e+000 vertex 3.001002e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.001002e+001 2.555998e+000 3.200025e+000 vertex 2.899397e+001 2.555998e+000 5.200025e+000 vertex 2.899397e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 9.461725e-001 -3.236628e-001 0.000000e+000 outer loop vertex 3.052775e+001 4.069511e+000 5.200025e+000 vertex 3.001002e+001 2.555998e+000 5.200025e+000 vertex 3.052775e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 9.461725e-001 -3.236628e-001 0.000000e+000 outer loop vertex 3.052775e+001 4.069511e+000 3.200025e+000 vertex 3.001002e+001 2.555998e+000 5.200025e+000 vertex 3.001002e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.052775e+001 4.069511e+000 5.200025e+000 vertex 3.052775e+001 4.069511e+000 3.200025e+000 vertex 3.168638e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.168638e+001 4.069511e+000 5.200025e+000 vertex 3.052775e+001 4.069511e+000 3.200025e+000 vertex 3.168638e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal -9.398518e-001 3.415827e-001 0.000000e+000 outer loop vertex 2.962995e+001 4.501944e+000 5.200025e+000 vertex 3.020765e+001 6.091471e+000 5.200025e+000 vertex 2.962995e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal -9.398518e-001 3.415827e-001 0.000000e+000 outer loop vertex 2.962995e+001 4.501944e+000 3.200025e+000 vertex 3.020765e+001 6.091471e+000 5.200025e+000 vertex 3.020765e+001 6.091471e+000 3.200025e+000 endloop endfacet facet normal 7.905269e-001 -6.124273e-001 0.000000e+000 outer loop vertex 3.020765e+001 6.091471e+000 5.200025e+000 vertex 2.897623e+001 4.501944e+000 5.200025e+000 vertex 3.020765e+001 6.091471e+000 3.200025e+000 endloop endfacet facet normal 7.905269e-001 -6.124273e-001 0.000000e+000 outer loop vertex 3.020765e+001 6.091471e+000 3.200025e+000 vertex 2.897623e+001 4.501944e+000 5.200025e+000 vertex 2.897623e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.897623e+001 4.501944e+000 5.200025e+000 vertex 2.962995e+001 4.501944e+000 5.200025e+000 vertex 2.897623e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 2.897623e+001 4.501944e+000 3.200025e+000 vertex 2.962995e+001 4.501944e+000 5.200025e+000 vertex 2.962995e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal -7.833727e-001 6.215522e-001 0.000000e+000 outer loop vertex 2.792640e+001 4.069511e+000 5.200025e+000 vertex 2.792640e+001 4.069511e+000 3.200025e+000 vertex 2.758600e+001 3.662999e+000 3.200025e+000 endloop endfacet facet normal -7.458798e-001 6.660807e-001 0.000000e+000 outer loop vertex 2.792640e+001 4.069511e+000 5.200025e+000 vertex 2.758600e+001 3.662999e+000 3.200025e+000 vertex 2.758600e+001 3.662999e+000 5.200025e+000 endloop endfacet facet normal -6.791131e-001 7.340336e-001 0.000000e+000 outer loop vertex 2.758600e+001 3.662999e+000 5.200025e+000 vertex 2.758600e+001 3.662999e+000 3.200025e+000 vertex 2.718738e+001 3.312755e+000 3.200025e+000 endloop endfacet facet normal -6.512446e-001 7.588679e-001 0.000000e+000 outer loop vertex 2.758600e+001 3.662999e+000 5.200025e+000 vertex 2.718738e+001 3.312755e+000 3.200025e+000 vertex 2.718738e+001 3.312755e+000 5.200025e+000 endloop endfacet facet normal 5.611562e-001 -8.277099e-001 0.000000e+000 outer loop vertex 2.637826e+001 3.735896e+000 5.200025e+000 vertex 2.637826e+001 3.735896e+000 3.200025e+000 vertex 2.643037e+001 3.771226e+000 3.200025e+000 endloop endfacet facet normal 5.568535e-001 -8.306108e-001 0.000000e+000 outer loop vertex 2.637826e+001 3.735896e+000 5.200025e+000 vertex 2.643037e+001 3.771226e+000 3.200025e+000 vertex 2.643037e+001 3.771226e+000 5.200025e+000 endloop endfacet facet normal 5.049704e-001 -8.631366e-001 0.000000e+000 outer loop vertex 2.643037e+001 3.771226e+000 5.200025e+000 vertex 2.643037e+001 3.771226e+000 3.200025e+000 vertex 2.659707e+001 3.863054e+000 3.200025e+000 endloop endfacet facet normal 4.556609e-001 -8.901534e-001 0.000000e+000 outer loop vertex 2.643037e+001 3.771226e+000 5.200025e+000 vertex 2.659707e+001 3.863054e+000 3.200025e+000 vertex 2.659707e+001 3.863054e+000 5.200025e+000 endloop endfacet facet normal 3.617236e-001 -9.322854e-001 0.000000e+000 outer loop vertex 2.659707e+001 3.863054e+000 5.200025e+000 vertex 2.659707e+001 3.863054e+000 3.200025e+000 vertex 2.683557e+001 3.948704e+000 3.200025e+000 endloop endfacet facet normal 3.174790e-001 -9.482654e-001 0.000000e+000 outer loop vertex 2.659707e+001 3.863054e+000 5.200025e+000 vertex 2.683557e+001 3.948704e+000 3.200025e+000 vertex 2.683557e+001 3.948704e+000 5.200025e+000 endloop endfacet facet normal 2.365100e-001 -9.716290e-001 0.000000e+000 outer loop vertex 2.683557e+001 3.948704e+000 5.200025e+000 vertex 2.683557e+001 3.948704e+000 3.200025e+000 vertex 2.712552e+001 4.011939e+000 3.200025e+000 endloop endfacet facet normal 2.000073e-001 -9.797944e-001 0.000000e+000 outer loop vertex 2.683557e+001 3.948704e+000 5.200025e+000 vertex 2.712552e+001 4.011939e+000 3.200025e+000 vertex 2.712552e+001 4.011939e+000 5.200025e+000 endloop endfacet facet normal 1.121893e-001 -9.936869e-001 0.000000e+000 outer loop vertex 2.712552e+001 4.011939e+000 5.200025e+000 vertex 2.712552e+001 4.011939e+000 3.200025e+000 vertex 2.792640e+001 4.069511e+000 3.200025e+000 endloop endfacet facet normal 6.066618e-002 -9.981582e-001 0.000000e+000 outer loop vertex 2.712552e+001 4.011939e+000 5.200025e+000 vertex 2.792640e+001 4.069511e+000 3.200025e+000 vertex 2.792640e+001 4.069511e+000 5.200025e+000 endloop endfacet facet normal 9.957419e-001 -9.218541e-002 0.000000e+000 outer loop vertex 2.601001e+001 3.146369e+000 5.200025e+000 vertex 2.601001e+001 3.146369e+000 3.200025e+000 vertex 2.601945e+001 3.245797e+000 3.200025e+000 endloop endfacet facet normal 9.903961e-001 -1.382586e-001 0.000000e+000 outer loop vertex 2.601001e+001 3.146369e+000 5.200025e+000 vertex 2.601945e+001 3.245797e+000 3.200025e+000 vertex 2.601945e+001 3.245797e+000 5.200025e+000 endloop endfacet facet normal 9.723318e-001 -2.336043e-001 0.000000e+000 outer loop vertex 2.601945e+001 3.245797e+000 5.200025e+000 vertex 2.601945e+001 3.245797e+000 3.200025e+000 vertex 2.604041e+001 3.323305e+000 3.200025e+000 endloop endfacet facet normal 9.591801e-001 -2.827957e-001 0.000000e+000 outer loop vertex 2.601945e+001 3.245797e+000 5.200025e+000 vertex 2.604041e+001 3.323305e+000 3.200025e+000 vertex 2.604041e+001 3.323305e+000 5.200025e+000 endloop endfacet facet normal 9.252856e-001 -3.792711e-001 0.000000e+000 outer loop vertex 2.604041e+001 3.323305e+000 5.200025e+000 vertex 2.604041e+001 3.323305e+000 3.200025e+000 vertex 2.607772e+001 3.407592e+000 3.200025e+000 endloop endfacet facet normal 9.044731e-001 -4.265306e-001 0.000000e+000 outer loop vertex 2.604041e+001 3.323305e+000 5.200025e+000 vertex 2.607772e+001 3.407592e+000 3.200025e+000 vertex 2.607772e+001 3.407592e+000 5.200025e+000 endloop endfacet facet normal 8.569838e-001 -5.153433e-001 0.000000e+000 outer loop vertex 2.607772e+001 3.407592e+000 5.200025e+000 vertex 2.607772e+001 3.407592e+000 3.200025e+000 vertex 2.614034e+001 3.505764e+000 3.200025e+000 endloop endfacet facet normal 8.305092e-001 -5.570049e-001 0.000000e+000 outer loop vertex 2.607772e+001 3.407592e+000 5.200025e+000 vertex 2.614034e+001 3.505764e+000 3.200025e+000 vertex 2.614034e+001 3.505764e+000 5.200025e+000 endloop endfacet facet normal 7.712108e-001 -6.365799e-001 0.000000e+000 outer loop vertex 2.614034e+001 3.505764e+000 5.200025e+000 vertex 2.614034e+001 3.505764e+000 3.200025e+000 vertex 2.623308e+001 3.611141e+000 3.200025e+000 endloop endfacet facet normal 7.383239e-001 -6.744463e-001 0.000000e+000 outer loop vertex 2.614034e+001 3.505764e+000 5.200025e+000 vertex 2.623308e+001 3.611141e+000 3.200025e+000 vertex 2.623308e+001 3.611141e+000 5.200025e+000 endloop endfacet facet normal 6.764964e-001 -7.364460e-001 0.000000e+000 outer loop vertex 2.623308e+001 3.611141e+000 5.200025e+000 vertex 2.623308e+001 3.611141e+000 3.200025e+000 vertex 2.637826e+001 3.735896e+000 3.200025e+000 endloop endfacet facet normal 6.483293e-001 -7.613600e-001 0.000000e+000 outer loop vertex 2.623308e+001 3.611141e+000 5.200025e+000 vertex 2.637826e+001 3.735896e+000 3.200025e+000 vertex 2.637826e+001 3.735896e+000 5.200025e+000 endloop endfacet facet normal 3.920680e-002 9.992312e-001 0.000000e+000 outer loop vertex 2.627522e+001 2.880322e+000 5.200025e+000 vertex 2.627522e+001 2.880322e+000 3.200025e+000 vertex 2.624462e+001 2.881522e+000 3.200025e+000 endloop endfacet facet normal 4.801081e-002 9.988468e-001 0.000000e+000 outer loop vertex 2.627522e+001 2.880322e+000 5.200025e+000 vertex 2.624462e+001 2.881522e+000 3.200025e+000 vertex 2.624462e+001 2.881522e+000 5.200025e+000 endloop endfacet facet normal 1.071857e-001 9.942390e-001 0.000000e+000 outer loop vertex 2.624462e+001 2.881522e+000 5.200025e+000 vertex 2.624462e+001 2.881522e+000 3.200025e+000 vertex 2.619372e+001 2.887917e+000 3.200025e+000 endloop endfacet facet normal 1.574152e-001 9.875325e-001 0.000000e+000 outer loop vertex 2.624462e+001 2.881522e+000 5.200025e+000 vertex 2.619372e+001 2.887917e+000 3.200025e+000 vertex 2.619372e+001 2.887917e+000 5.200025e+000 endloop endfacet facet normal 2.607381e-001 9.654096e-001 0.000000e+000 outer loop vertex 2.619372e+001 2.887917e+000 5.200025e+000 vertex 2.619372e+001 2.887917e+000 3.200025e+000 vertex 2.614441e+001 2.902653e+000 3.200025e+000 endloop endfacet facet normal 3.137297e-001 9.495123e-001 0.000000e+000 outer loop vertex 2.619372e+001 2.887917e+000 5.200025e+000 vertex 2.614441e+001 2.902653e+000 3.200025e+000 vertex 2.614441e+001 2.902653e+000 5.200025e+000 endloop endfacet facet normal 4.092559e-001 9.124197e-001 0.000000e+000 outer loop vertex 2.614441e+001 2.902653e+000 5.200025e+000 vertex 2.614441e+001 2.902653e+000 3.200025e+000 vertex 2.611779e+001 2.915203e+000 3.200025e+000 endloop endfacet facet normal 4.520853e-001 8.919747e-001 0.000000e+000 outer loop vertex 2.614441e+001 2.902653e+000 5.200025e+000 vertex 2.611779e+001 2.915203e+000 3.200025e+000 vertex 2.611779e+001 2.915203e+000 5.200025e+000 endloop endfacet facet normal 5.388928e-001 8.423743e-001 0.000000e+000 outer loop vertex 2.611779e+001 2.915203e+000 5.200025e+000 vertex 2.611779e+001 2.915203e+000 3.200025e+000 vertex 2.609461e+001 2.930993e+000 3.200025e+000 endloop endfacet facet normal 5.826069e-001 8.127541e-001 0.000000e+000 outer loop vertex 2.611779e+001 2.915203e+000 5.200025e+000 vertex 2.609461e+001 2.930993e+000 3.200025e+000 vertex 2.609461e+001 2.930993e+000 5.200025e+000 endloop endfacet facet normal 6.678530e-001 7.442932e-001 0.000000e+000 outer loop vertex 2.609461e+001 2.930993e+000 5.200025e+000 vertex 2.609461e+001 2.930993e+000 3.200025e+000 vertex 2.606749e+001 2.956850e+000 3.200025e+000 endloop endfacet facet normal 7.091052e-001 7.051027e-001 0.000000e+000 outer loop vertex 2.609461e+001 2.930993e+000 5.200025e+000 vertex 2.606749e+001 2.956850e+000 3.200025e+000 vertex 2.606749e+001 2.956850e+000 5.200025e+000 endloop endfacet facet normal 7.833601e-001 6.215682e-001 0.000000e+000 outer loop vertex 2.606749e+001 2.956850e+000 5.200025e+000 vertex 2.606749e+001 2.956850e+000 3.200025e+000 vertex 2.604864e+001 2.981828e+000 3.200025e+000 endloop endfacet facet normal 8.164997e-001 5.773458e-001 0.000000e+000 outer loop vertex 2.606749e+001 2.956850e+000 5.200025e+000 vertex 2.604864e+001 2.981828e+000 3.200025e+000 vertex 2.604864e+001 2.981828e+000 5.200025e+000 endloop endfacet facet normal 8.733938e-001 4.870147e-001 0.000000e+000 outer loop vertex 2.604864e+001 2.981828e+000 5.200025e+000 vertex 2.604864e+001 2.981828e+000 3.200025e+000 vertex 2.603515e+001 3.007836e+000 3.200025e+000 endloop endfacet facet normal 8.974579e-001 4.411002e-001 0.000000e+000 outer loop vertex 2.604864e+001 2.981828e+000 5.200025e+000 vertex 2.603515e+001 3.007836e+000 3.200025e+000 vertex 2.603515e+001 3.007836e+000 5.200025e+000 endloop endfacet facet normal 9.374716e-001 3.480618e-001 0.000000e+000 outer loop vertex 2.603515e+001 3.007836e+000 5.200025e+000 vertex 2.603515e+001 3.007836e+000 3.200025e+000 vertex 2.602125e+001 3.048951e+000 3.200025e+000 endloop endfacet facet normal 9.536172e-001 3.010218e-001 0.000000e+000 outer loop vertex 2.603515e+001 3.007836e+000 5.200025e+000 vertex 2.602125e+001 3.048951e+000 3.200025e+000 vertex 2.602125e+001 3.048951e+000 5.200025e+000 endloop endfacet facet normal 9.793758e-001 2.020472e-001 0.000000e+000 outer loop vertex 2.602125e+001 3.048951e+000 5.200025e+000 vertex 2.602125e+001 3.048951e+000 3.200025e+000 vertex 2.601267e+001 3.097160e+000 3.200025e+000 endloop endfacet facet normal 9.886811e-001 1.500320e-001 0.000000e+000 outer loop vertex 2.602125e+001 3.048951e+000 5.200025e+000 vertex 2.601267e+001 3.097160e+000 3.200025e+000 vertex 2.601267e+001 3.097160e+000 5.200025e+000 endloop endfacet facet normal 9.971196e-001 7.584519e-002 0.000000e+000 outer loop vertex 2.601267e+001 3.097160e+000 5.200025e+000 vertex 2.601267e+001 3.097160e+000 3.200025e+000 vertex 2.601001e+001 3.146369e+000 3.200025e+000 endloop endfacet facet normal 9.985464e-001 5.389884e-002 0.000000e+000 outer loop vertex 2.601267e+001 3.097160e+000 5.200025e+000 vertex 2.601001e+001 3.146369e+000 3.200025e+000 vertex 2.601001e+001 3.146369e+000 5.200025e+000 endloop endfacet facet normal -6.073642e-001 7.944235e-001 0.000000e+000 outer loop vertex 2.718738e+001 3.312755e+000 5.200025e+000 vertex 2.718738e+001 3.312755e+000 3.200025e+000 vertex 2.711975e+001 3.261054e+000 3.200025e+000 endloop endfacet facet normal -6.056615e-001 7.957225e-001 0.000000e+000 outer loop vertex 2.718738e+001 3.312755e+000 5.200025e+000 vertex 2.711975e+001 3.261054e+000 3.200025e+000 vertex 2.711975e+001 3.261054e+000 5.200025e+000 endloop endfacet facet normal -5.648199e-001 8.252142e-001 0.000000e+000 outer loop vertex 2.711975e+001 3.261054e+000 5.200025e+000 vertex 2.711975e+001 3.261054e+000 3.200025e+000 vertex 2.678301e+001 3.038524e+000 3.200025e+000 endloop endfacet facet normal -5.242738e-001 8.515498e-001 0.000000e+000 outer loop vertex 2.711975e+001 3.261054e+000 5.200025e+000 vertex 2.678301e+001 3.038524e+000 3.200025e+000 vertex 2.678301e+001 3.038524e+000 5.200025e+000 endloop endfacet facet normal -4.374166e-001 8.992590e-001 0.000000e+000 outer loop vertex 2.678301e+001 3.038524e+000 5.200025e+000 vertex 2.678301e+001 3.038524e+000 3.200025e+000 vertex 2.656557e+001 2.937940e+000 3.200025e+000 endloop endfacet facet normal -3.909776e-001 9.204002e-001 0.000000e+000 outer loop vertex 2.678301e+001 3.038524e+000 5.200025e+000 vertex 2.656557e+001 2.937940e+000 3.200025e+000 vertex 2.656557e+001 2.937940e+000 5.200025e+000 endloop endfacet facet normal -2.955793e-001 9.553182e-001 0.000000e+000 outer loop vertex 2.656557e+001 2.937940e+000 5.200025e+000 vertex 2.656557e+001 2.937940e+000 3.200025e+000 vertex 2.641702e+001 2.894977e+000 3.200025e+000 endloop endfacet facet normal -2.466260e-001 9.691108e-001 0.000000e+000 outer loop vertex 2.656557e+001 2.937940e+000 5.200025e+000 vertex 2.641702e+001 2.894977e+000 3.200025e+000 vertex 2.641702e+001 2.894977e+000 5.200025e+000 endloop endfacet facet normal -1.470411e-001 9.891304e-001 0.000000e+000 outer loop vertex 2.641702e+001 2.894977e+000 5.200025e+000 vertex 2.641702e+001 2.894977e+000 3.200025e+000 vertex 2.627522e+001 2.880322e+000 3.200025e+000 endloop endfacet facet normal -9.640652e-002 9.953420e-001 0.000000e+000 outer loop vertex 2.641702e+001 2.894977e+000 5.200025e+000 vertex 2.627522e+001 2.880322e+000 3.200025e+000 vertex 2.627522e+001 2.880322e+000 5.200025e+000 endloop endfacet facet normal 9.982258e-001 5.954128e-002 0.000000e+000 outer loop vertex 3.595596e+001 5.882011e+000 5.200025e+000 vertex 3.595596e+001 5.882011e+000 3.200025e+000 vertex 3.595133e+001 5.958773e+000 3.200025e+000 endloop endfacet facet normal 9.960761e-001 8.850101e-002 0.000000e+000 outer loop vertex 3.595596e+001 5.882011e+000 5.200025e+000 vertex 3.595133e+001 5.958773e+000 3.200025e+000 vertex 3.595133e+001 5.958773e+000 5.200025e+000 endloop endfacet facet normal 9.856780e-001 1.686385e-001 0.000000e+000 outer loop vertex 3.595133e+001 5.958773e+000 5.200025e+000 vertex 3.595133e+001 5.958773e+000 3.200025e+000 vertex 3.593454e+001 6.042812e+000 3.200025e+000 endloop endfacet facet normal 9.755902e-001 2.195989e-001 0.000000e+000 outer loop vertex 3.595133e+001 5.958773e+000 5.200025e+000 vertex 3.593454e+001 6.042812e+000 3.200025e+000 vertex 3.593454e+001 6.042812e+000 5.200025e+000 endloop endfacet facet normal 9.457080e-001 3.250175e-001 0.000000e+000 outer loop vertex 3.593454e+001 6.042812e+000 5.200025e+000 vertex 3.593454e+001 6.042812e+000 3.200025e+000 vertex 3.589819e+001 6.139915e+000 3.200025e+000 endloop endfacet facet normal 9.252751e-001 3.792968e-001 0.000000e+000 outer loop vertex 3.593454e+001 6.042812e+000 5.200025e+000 vertex 3.589819e+001 6.139915e+000 3.200025e+000 vertex 3.589819e+001 6.139915e+000 5.200025e+000 endloop endfacet facet normal 8.785946e-001 4.775684e-001 0.000000e+000 outer loop vertex 3.589819e+001 6.139915e+000 5.200025e+000 vertex 3.589819e+001 6.139915e+000 3.200025e+000 vertex 3.585004e+001 6.222932e+000 3.200025e+000 endloop endfacet facet normal 8.530176e-001 5.218821e-001 0.000000e+000 outer loop vertex 3.589819e+001 6.139915e+000 5.200025e+000 vertex 3.585004e+001 6.222932e+000 3.200025e+000 vertex 3.585004e+001 6.222932e+000 5.200025e+000 endloop endfacet facet normal 7.954938e-001 6.059617e-001 0.000000e+000 outer loop vertex 3.585004e+001 6.222932e+000 5.200025e+000 vertex 3.585004e+001 6.222932e+000 3.200025e+000 vertex 3.577528e+001 6.314840e+000 3.200025e+000 endloop endfacet facet normal 7.635602e-001 6.457366e-001 0.000000e+000 outer loop vertex 3.585004e+001 6.222932e+000 5.200025e+000 vertex 3.577528e+001 6.314840e+000 3.200025e+000 vertex 3.577528e+001 6.314840e+000 5.200025e+000 endloop endfacet facet normal 6.938754e-001 7.200950e-001 0.000000e+000 outer loop vertex 3.577528e+001 6.314840e+000 5.200025e+000 vertex 3.577528e+001 6.314840e+000 3.200025e+000 vertex 3.567940e+001 6.403383e+000 3.200025e+000 endloop endfacet facet normal 6.561100e-001 7.546653e-001 0.000000e+000 outer loop vertex 3.577528e+001 6.314840e+000 5.200025e+000 vertex 3.567940e+001 6.403383e+000 3.200025e+000 vertex 3.567940e+001 6.403383e+000 5.200025e+000 endloop endfacet facet normal 5.708773e-001 8.210354e-001 0.000000e+000 outer loop vertex 3.567940e+001 6.403383e+000 5.200025e+000 vertex 3.567940e+001 6.403383e+000 3.200025e+000 vertex 3.556422e+001 6.477963e+000 3.200025e+000 endloop endfacet facet normal 5.230109e-001 8.523260e-001 0.000000e+000 outer loop vertex 3.567940e+001 6.403383e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 3.200025e+000 vertex 3.556422e+001 6.477963e+000 5.200025e+000 endloop endfacet facet normal 4.246256e-001 9.053690e-001 0.000000e+000 outer loop vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.556422e+001 6.477963e+000 3.200025e+000 vertex 3.547242e+001 6.518541e+000 3.200025e+000 endloop endfacet facet normal 3.742234e-001 9.273385e-001 0.000000e+000 outer loop vertex 3.556422e+001 6.477963e+000 5.200025e+000 vertex 3.547242e+001 6.518541e+000 3.200025e+000 vertex 3.547242e+001 6.518541e+000 5.200025e+000 endloop endfacet facet normal 2.759858e-001 9.611617e-001 0.000000e+000 outer loop vertex 3.547242e+001 6.518541e+000 5.200025e+000 vertex 3.547242e+001 6.518541e+000 3.200025e+000 vertex 3.537339e+001 6.544735e+000 3.200025e+000 endloop endfacet facet normal 2.283432e-001 9.735807e-001 0.000000e+000 outer loop vertex 3.547242e+001 6.518541e+000 5.200025e+000 vertex 3.537339e+001 6.544735e+000 3.200025e+000 vertex 3.537339e+001 6.544735e+000 5.200025e+000 endloop endfacet facet normal 1.313726e-001 9.913330e-001 0.000000e+000 outer loop vertex 3.537339e+001 6.544735e+000 5.200025e+000 vertex 3.537339e+001 6.544735e+000 3.200025e+000 vertex 3.524650e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 8.203778e-002 9.966292e-001 0.000000e+000 outer loop vertex 3.537339e+001 6.544735e+000 5.200025e+000 vertex 3.524650e+001 6.555998e+000 3.200025e+000 vertex 3.524650e+001 6.555998e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.467893e+001 6.555998e+000 5.200025e+000 vertex 3.524650e+001 6.555998e+000 5.200025e+000 vertex 3.467893e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.467893e+001 6.555998e+000 3.200025e+000 vertex 3.524650e+001 6.555998e+000 5.200025e+000 vertex 3.524650e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal -6.505903e-002 9.978814e-001 0.000000e+000 outer loop vertex 3.467893e+001 6.555998e+000 5.200025e+000 vertex 3.467893e+001 6.555998e+000 3.200025e+000 vertex 3.413707e+001 6.512548e+000 3.200025e+000 endloop endfacet facet normal -1.134921e-001 9.935389e-001 0.000000e+000 outer loop vertex 3.467893e+001 6.555998e+000 5.200025e+000 vertex 3.413707e+001 6.512548e+000 3.200025e+000 vertex 3.413707e+001 6.512548e+000 5.200025e+000 endloop endfacet facet normal -2.132087e-001 9.770067e-001 0.000000e+000 outer loop vertex 3.413707e+001 6.512548e+000 5.200025e+000 vertex 3.413707e+001 6.512548e+000 3.200025e+000 vertex 3.365337e+001 6.393368e+000 3.200025e+000 endloop endfacet facet normal -2.644249e-001 9.644063e-001 0.000000e+000 outer loop vertex 3.413707e+001 6.512548e+000 5.200025e+000 vertex 3.365337e+001 6.393368e+000 3.200025e+000 vertex 3.365337e+001 6.393368e+000 5.200025e+000 endloop endfacet facet normal -3.616829e-001 9.323012e-001 0.000000e+000 outer loop vertex 3.365337e+001 6.393368e+000 5.200025e+000 vertex 3.365337e+001 6.393368e+000 3.200025e+000 vertex 3.314093e+001 6.175086e+000 3.200025e+000 endloop endfacet facet normal -4.078138e-001 9.130651e-001 0.000000e+000 outer loop vertex 3.365337e+001 6.393368e+000 5.200025e+000 vertex 3.314093e+001 6.175086e+000 3.200025e+000 vertex 3.314093e+001 6.175086e+000 5.200025e+000 endloop endfacet facet normal -4.933795e-001 8.698142e-001 0.000000e+000 outer loop vertex 3.314093e+001 6.175086e+000 5.200025e+000 vertex 3.314093e+001 6.175086e+000 3.200025e+000 vertex 3.295127e+001 6.067502e+000 3.200025e+000 endloop endfacet facet normal -5.063874e-001 8.623061e-001 0.000000e+000 outer loop vertex 3.314093e+001 6.175086e+000 5.200025e+000 vertex 3.295127e+001 6.067502e+000 3.200025e+000 vertex 3.295127e+001 6.067502e+000 5.200025e+000 endloop endfacet facet normal -5.640959e-001 8.257093e-001 0.000000e+000 outer loop vertex 3.295127e+001 6.067502e+000 5.200025e+000 vertex 3.295127e+001 6.067502e+000 3.200025e+000 vertex 3.257662e+001 5.796973e+000 3.200025e+000 endloop endfacet facet normal -6.074306e-001 7.943727e-001 0.000000e+000 outer loop vertex 3.295127e+001 6.067502e+000 5.200025e+000 vertex 3.257662e+001 5.796973e+000 3.200025e+000 vertex 3.257662e+001 5.796973e+000 5.200025e+000 endloop endfacet facet normal -6.875762e-001 7.261121e-001 0.000000e+000 outer loop vertex 3.257662e+001 5.796973e+000 5.200025e+000 vertex 3.257662e+001 5.796973e+000 3.200025e+000 vertex 3.226681e+001 5.490809e+000 3.200025e+000 endloop endfacet facet normal -7.244795e-001 6.892964e-001 0.000000e+000 outer loop vertex 3.257662e+001 5.796973e+000 5.200025e+000 vertex 3.226681e+001 5.490809e+000 3.200025e+000 vertex 3.226681e+001 5.490809e+000 5.200025e+000 endloop endfacet facet normal -7.899370e-001 6.131880e-001 0.000000e+000 outer loop vertex 3.226681e+001 5.490809e+000 5.200025e+000 vertex 3.226681e+001 5.490809e+000 3.200025e+000 vertex 3.198890e+001 5.105829e+000 3.200025e+000 endloop endfacet facet normal -8.187644e-001 5.741296e-001 0.000000e+000 outer loop vertex 3.226681e+001 5.490809e+000 5.200025e+000 vertex 3.198890e+001 5.105829e+000 3.200025e+000 vertex 3.198890e+001 5.105829e+000 5.200025e+000 endloop endfacet facet normal -8.854957e-001 4.646476e-001 0.000000e+000 outer loop vertex 3.198890e+001 5.105829e+000 5.200025e+000 vertex 3.198890e+001 5.105829e+000 3.200025e+000 vertex 3.182188e+001 4.771779e+000 3.200025e+000 endloop endfacet facet normal -9.071285e-001 4.208538e-001 0.000000e+000 outer loop vertex 3.198890e+001 5.105829e+000 5.200025e+000 vertex 3.182188e+001 4.771779e+000 3.200025e+000 vertex 3.182188e+001 4.771779e+000 5.200025e+000 endloop endfacet facet normal -9.444647e-001 3.286129e-001 0.000000e+000 outer loop vertex 3.182188e+001 4.771779e+000 5.200025e+000 vertex 3.182188e+001 4.771779e+000 3.200025e+000 vertex 3.173466e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal -9.599746e-001 2.800872e-001 0.000000e+000 outer loop vertex 3.182188e+001 4.771779e+000 5.200025e+000 vertex 3.173466e+001 4.501944e+000 3.200025e+000 vertex 3.173466e+001 4.501944e+000 5.200025e+000 endloop endfacet facet normal -9.994065e-001 -3.444941e-002 0.000000e+000 outer loop vertex 3.168638e+001 4.069511e+000 5.200025e+000 vertex 3.168638e+001 4.069511e+000 3.200025e+000 vertex 3.169009e+001 3.974148e+000 3.200025e+000 endloop endfacet facet normal -9.987322e-001 -5.033978e-002 0.000000e+000 outer loop vertex 3.168638e+001 4.069511e+000 5.200025e+000 vertex 3.169009e+001 3.974148e+000 3.200025e+000 vertex 3.169009e+001 3.974148e+000 5.200025e+000 endloop endfacet facet normal -9.934652e-001 -1.141356e-001 0.000000e+000 outer loop vertex 3.169009e+001 3.974148e+000 5.200025e+000 vertex 3.169009e+001 3.974148e+000 3.200025e+000 vertex 3.171952e+001 3.769147e+000 3.200025e+000 endloop endfacet facet normal -9.868066e-001 -1.619039e-001 0.000000e+000 outer loop vertex 3.169009e+001 3.974148e+000 5.200025e+000 vertex 3.171952e+001 3.769147e+000 3.200025e+000 vertex 3.171952e+001 3.769147e+000 5.200025e+000 endloop endfacet facet normal -9.657534e-001 -2.594618e-001 0.000000e+000 outer loop vertex 3.171952e+001 3.769147e+000 5.200025e+000 vertex 3.171952e+001 3.769147e+000 3.200025e+000 vertex 3.177435e+001 3.582894e+000 3.200025e+000 endloop endfacet facet normal -9.510050e-001 -3.091757e-001 0.000000e+000 outer loop vertex 3.171952e+001 3.769147e+000 5.200025e+000 vertex 3.177435e+001 3.582894e+000 3.200025e+000 vertex 3.177435e+001 3.582894e+000 5.200025e+000 endloop endfacet facet normal -9.135801e-001 -4.066588e-001 0.000000e+000 outer loop vertex 3.177435e+001 3.582894e+000 5.200025e+000 vertex 3.177435e+001 3.582894e+000 3.200025e+000 vertex 3.185274e+001 3.414602e+000 3.200025e+000 endloop endfacet facet normal -8.908031e-001 -4.543895e-001 0.000000e+000 outer loop vertex 3.177435e+001 3.582894e+000 5.200025e+000 vertex 3.185274e+001 3.414602e+000 3.200025e+000 vertex 3.185274e+001 3.414602e+000 5.200025e+000 endloop endfacet facet normal -8.363901e-001 -5.481346e-001 0.000000e+000 outer loop vertex 3.185274e+001 3.414602e+000 5.200025e+000 vertex 3.185274e+001 3.414602e+000 3.200025e+000 vertex 3.197369e+001 3.240942e+000 3.200025e+000 endloop endfacet facet normal -8.044744e-001 -5.939873e-001 0.000000e+000 outer loop vertex 3.185274e+001 3.414602e+000 5.200025e+000 vertex 3.197369e+001 3.240942e+000 3.200025e+000 vertex 3.197369e+001 3.240942e+000 5.200025e+000 endloop endfacet facet normal -7.363222e-001 -6.766310e-001 0.000000e+000 outer loop vertex 3.197369e+001 3.240942e+000 5.200025e+000 vertex 3.197369e+001 3.240942e+000 3.200025e+000 vertex 3.211307e+001 3.097985e+000 3.200025e+000 endloop endfacet facet normal -7.004378e-001 -7.137135e-001 0.000000e+000 outer loop vertex 3.197369e+001 3.240942e+000 5.200025e+000 vertex 3.211307e+001 3.097985e+000 3.200025e+000 vertex 3.211307e+001 3.097985e+000 5.200025e+000 endloop endfacet facet normal -6.235467e-001 -7.817862e-001 0.000000e+000 outer loop vertex 3.211307e+001 3.097985e+000 5.200025e+000 vertex 3.211307e+001 3.097985e+000 3.200025e+000 vertex 3.229612e+001 2.960717e+000 3.200025e+000 endloop endfacet facet normal -5.825539e-001 -8.127921e-001 0.000000e+000 outer loop vertex 3.211307e+001 3.097985e+000 5.200025e+000 vertex 3.229612e+001 2.960717e+000 3.200025e+000 vertex 3.229612e+001 2.960717e+000 5.200025e+000 endloop endfacet facet normal -5.063331e-001 -8.623380e-001 0.000000e+000 outer loop vertex 3.229612e+001 2.960717e+000 5.200025e+000 vertex 3.229612e+001 2.960717e+000 3.200025e+000 vertex 3.251593e+001 2.840626e+000 3.200025e+000 endloop endfacet facet normal -4.716782e-001 -8.817707e-001 0.000000e+000 outer loop vertex 3.229612e+001 2.960717e+000 5.200025e+000 vertex 3.251593e+001 2.840626e+000 3.200025e+000 vertex 3.251593e+001 2.840626e+000 5.200025e+000 endloop endfacet facet normal -3.683648e-001 -9.296813e-001 0.000000e+000 outer loop vertex 3.251593e+001 2.840626e+000 5.200025e+000 vertex 3.251593e+001 2.840626e+000 3.200025e+000 vertex 3.280565e+001 2.728420e+000 3.200025e+000 endloop endfacet facet normal -3.347622e-001 -9.423026e-001 0.000000e+000 outer loop vertex 3.251593e+001 2.840626e+000 5.200025e+000 vertex 3.280565e+001 2.728420e+000 3.200025e+000 vertex 3.280565e+001 2.728420e+000 5.200025e+000 endloop endfacet facet normal -2.534612e-001 -9.673455e-001 0.000000e+000 outer loop vertex 3.280565e+001 2.728420e+000 5.200025e+000 vertex 3.280565e+001 2.728420e+000 3.200025e+000 vertex 3.329603e+001 2.613956e+000 3.200025e+000 endloop endfacet facet normal -2.054182e-001 -9.786742e-001 0.000000e+000 outer loop vertex 3.280565e+001 2.728420e+000 5.200025e+000 vertex 3.329603e+001 2.613956e+000 3.200025e+000 vertex 3.329603e+001 2.613956e+000 5.200025e+000 endloop endfacet facet normal -1.078165e-001 -9.941708e-001 0.000000e+000 outer loop vertex 3.329603e+001 2.613956e+000 5.200025e+000 vertex 3.329603e+001 2.613956e+000 3.200025e+000 vertex 3.410799e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal -5.825177e-002 -9.983019e-001 0.000000e+000 outer loop vertex 3.329603e+001 2.613956e+000 5.200025e+000 vertex 3.410799e+001 2.555998e+000 3.200025e+000 vertex 3.410799e+001 2.555998e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.515697e+001 2.555998e+000 5.200025e+000 vertex 3.410799e+001 2.555998e+000 5.200025e+000 vertex 3.515697e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.515697e+001 2.555998e+000 3.200025e+000 vertex 3.410799e+001 2.555998e+000 5.200025e+000 vertex 3.410799e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 4.981948e-002 -9.987583e-001 0.000000e+000 outer loop vertex 3.515697e+001 2.555998e+000 5.200025e+000 vertex 3.515697e+001 2.555998e+000 3.200025e+000 vertex 3.530741e+001 2.563509e+000 3.200025e+000 endloop endfacet facet normal 7.556289e-002 -9.971410e-001 0.000000e+000 outer loop vertex 3.515697e+001 2.555998e+000 5.200025e+000 vertex 3.530741e+001 2.563509e+000 3.200025e+000 vertex 3.530741e+001 2.563509e+000 5.200025e+000 endloop endfacet facet normal 1.549202e-001 -9.879270e-001 0.000000e+000 outer loop vertex 3.530741e+001 2.563509e+000 5.200025e+000 vertex 3.530741e+001 2.563509e+000 3.200025e+000 vertex 3.545889e+001 2.591131e+000 3.200025e+000 endloop endfacet facet normal 2.083035e-001 -9.780642e-001 0.000000e+000 outer loop vertex 3.530741e+001 2.563509e+000 5.200025e+000 vertex 3.545889e+001 2.591131e+000 3.200025e+000 vertex 3.545889e+001 2.591131e+000 5.200025e+000 endloop endfacet facet normal 3.119895e-001 -9.500855e-001 0.000000e+000 outer loop vertex 3.545889e+001 2.591131e+000 5.200025e+000 vertex 3.545889e+001 2.591131e+000 3.200025e+000 vertex 3.556581e+001 2.628944e+000 3.200025e+000 endloop endfacet facet normal 3.623154e-001 -9.320555e-001 0.000000e+000 outer loop vertex 3.545889e+001 2.591131e+000 5.200025e+000 vertex 3.556581e+001 2.628944e+000 3.200025e+000 vertex 3.556581e+001 2.628944e+000 5.200025e+000 endloop endfacet facet normal 4.591014e-001 -8.883839e-001 0.000000e+000 outer loop vertex 3.556581e+001 2.628944e+000 5.200025e+000 vertex 3.556581e+001 2.628944e+000 3.200025e+000 vertex 3.564011e+001 2.669571e+000 3.200025e+000 endloop endfacet facet normal 5.055787e-001 -8.627805e-001 0.000000e+000 outer loop vertex 3.556581e+001 2.628944e+000 5.200025e+000 vertex 3.564011e+001 2.669571e+000 3.200025e+000 vertex 3.564011e+001 2.669571e+000 5.200025e+000 endloop endfacet facet normal 5.940297e-001 -8.044431e-001 0.000000e+000 outer loop vertex 3.564011e+001 2.669571e+000 5.200025e+000 vertex 3.564011e+001 2.669571e+000 3.200025e+000 vertex 3.570092e+001 2.717005e+000 3.200025e+000 endloop endfacet facet normal 6.359935e-001 -7.716945e-001 0.000000e+000 outer loop vertex 3.564011e+001 2.669571e+000 5.200025e+000 vertex 3.570092e+001 2.717005e+000 3.200025e+000 vertex 3.570092e+001 2.717005e+000 5.200025e+000 endloop endfacet facet normal 7.135836e-001 -7.005700e-001 0.000000e+000 outer loop vertex 3.570092e+001 2.717005e+000 5.200025e+000 vertex 3.570092e+001 2.717005e+000 3.200025e+000 vertex 3.575074e+001 2.770387e+000 3.200025e+000 endloop endfacet facet normal 7.492722e-001 -6.622621e-001 0.000000e+000 outer loop vertex 3.570092e+001 2.717005e+000 5.200025e+000 vertex 3.575074e+001 2.770387e+000 3.200025e+000 vertex 3.575074e+001 2.770387e+000 5.200025e+000 endloop endfacet facet normal 8.171390e-001 -5.764406e-001 0.000000e+000 outer loop vertex 3.575074e+001 2.770387e+000 5.200025e+000 vertex 3.575074e+001 2.770387e+000 3.200025e+000 vertex 3.579260e+001 2.833500e+000 3.200025e+000 endloop endfacet facet normal 8.488826e-001 -5.285813e-001 0.000000e+000 outer loop vertex 3.575074e+001 2.770387e+000 5.200025e+000 vertex 3.579260e+001 2.833500e+000 3.200025e+000 vertex 3.579260e+001 2.833500e+000 5.200025e+000 endloop endfacet facet normal 9.014991e-001 -4.327810e-001 0.000000e+000 outer loop vertex 3.579260e+001 2.833500e+000 5.200025e+000 vertex 3.579260e+001 2.833500e+000 3.200025e+000 vertex 3.582179e+001 2.898758e+000 3.200025e+000 endloop endfacet facet normal 9.228700e-001 -3.851116e-001 0.000000e+000 outer loop vertex 3.579260e+001 2.833500e+000 5.200025e+000 vertex 3.582179e+001 2.898758e+000 3.200025e+000 vertex 3.582179e+001 2.898758e+000 5.200025e+000 endloop endfacet facet normal 9.513863e-001 -3.080001e-001 0.000000e+000 outer loop vertex 3.582179e+001 2.898758e+000 5.200025e+000 vertex 3.582179e+001 2.898758e+000 3.200025e+000 vertex 3.584785e+001 2.988430e+000 3.200025e+000 endloop endfacet facet normal 9.602420e-001 -2.791691e-001 0.000000e+000 outer loop vertex 3.582179e+001 2.898758e+000 5.200025e+000 vertex 3.584785e+001 2.988430e+000 3.200025e+000 vertex 3.584785e+001 2.988430e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.441289e+001 2.988430e+000 5.200025e+000 vertex 3.584785e+001 2.988430e+000 5.200025e+000 vertex 3.441289e+001 2.988430e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.441289e+001 2.988430e+000 3.200025e+000 vertex 3.584785e+001 2.988430e+000 5.200025e+000 vertex 3.584785e+001 2.988430e+000 3.200025e+000 endloop endfacet facet normal 2.554560e-002 9.996737e-001 0.000000e+000 outer loop vertex 3.441289e+001 2.988430e+000 5.200025e+000 vertex 3.441289e+001 2.988430e+000 3.200025e+000 vertex 3.424180e+001 2.992802e+000 3.200025e+000 endloop endfacet facet normal 3.391676e-002 9.994246e-001 0.000000e+000 outer loop vertex 3.441289e+001 2.988430e+000 5.200025e+000 vertex 3.424180e+001 2.992802e+000 3.200025e+000 vertex 3.424180e+001 2.992802e+000 5.200025e+000 endloop endfacet facet normal 9.456359e-002 9.955188e-001 0.000000e+000 outer loop vertex 3.424180e+001 2.992802e+000 5.200025e+000 vertex 3.424180e+001 2.992802e+000 3.200025e+000 vertex 3.384801e+001 3.038748e+000 3.200025e+000 endloop endfacet facet normal 1.467256e-001 9.891772e-001 0.000000e+000 outer loop vertex 3.424180e+001 2.992802e+000 5.200025e+000 vertex 3.384801e+001 3.038748e+000 3.200025e+000 vertex 3.384801e+001 3.038748e+000 5.200025e+000 endloop endfacet facet normal 2.494189e-001 9.683957e-001 0.000000e+000 outer loop vertex 3.384801e+001 3.038748e+000 5.200025e+000 vertex 3.384801e+001 3.038748e+000 3.200025e+000 vertex 3.357499e+001 3.114775e+000 3.200025e+000 endloop endfacet facet normal 2.999500e-001 9.539549e-001 0.000000e+000 outer loop vertex 3.384801e+001 3.038748e+000 5.200025e+000 vertex 3.357499e+001 3.114775e+000 3.200025e+000 vertex 3.357499e+001 3.114775e+000 5.200025e+000 endloop endfacet facet normal 3.926216e-001 9.197001e-001 0.000000e+000 outer loop vertex 3.357499e+001 3.114775e+000 5.200025e+000 vertex 3.357499e+001 3.114775e+000 3.200025e+000 vertex 3.341020e+001 3.189356e+000 3.200025e+000 endloop endfacet facet normal 4.349705e-001 9.004447e-001 0.000000e+000 outer loop vertex 3.357499e+001 3.114775e+000 5.200025e+000 vertex 3.341020e+001 3.189356e+000 3.200025e+000 vertex 3.341020e+001 3.189356e+000 5.200025e+000 endloop endfacet facet normal 5.212851e-001 8.533826e-001 0.000000e+000 outer loop vertex 3.341020e+001 3.189356e+000 5.200025e+000 vertex 3.341020e+001 3.189356e+000 3.200025e+000 vertex 3.326696e+001 3.281403e+000 3.200025e+000 endloop endfacet facet normal 5.649911e-001 8.250970e-001 0.000000e+000 outer loop vertex 3.341020e+001 3.189356e+000 5.200025e+000 vertex 3.326696e+001 3.281403e+000 3.200025e+000 vertex 3.326696e+001 3.281403e+000 5.200025e+000 endloop endfacet facet normal 6.486706e-001 7.610694e-001 0.000000e+000 outer loop vertex 3.326696e+001 3.281403e+000 5.200025e+000 vertex 3.326696e+001 3.281403e+000 3.200025e+000 vertex 3.315278e+001 3.384182e+000 3.200025e+000 endloop endfacet facet normal 6.885431e-001 7.251954e-001 0.000000e+000 outer loop vertex 3.326696e+001 3.281403e+000 5.200025e+000 vertex 3.315278e+001 3.384182e+000 3.200025e+000 vertex 3.315278e+001 3.384182e+000 5.200025e+000 endloop endfacet facet normal 7.644140e-001 6.447257e-001 0.000000e+000 outer loop vertex 3.315278e+001 3.384182e+000 5.200025e+000 vertex 3.315278e+001 3.384182e+000 3.200025e+000 vertex 3.305370e+001 3.508620e+000 3.200025e+000 endloop endfacet facet normal 8.001142e-001 5.998477e-001 0.000000e+000 outer loop vertex 3.315278e+001 3.384182e+000 5.200025e+000 vertex 3.305370e+001 3.508620e+000 3.200025e+000 vertex 3.305370e+001 3.508620e+000 5.200025e+000 endloop endfacet facet normal 8.607276e-001 5.090659e-001 0.000000e+000 outer loop vertex 3.305370e+001 3.508620e+000 5.200025e+000 vertex 3.305370e+001 3.508620e+000 3.200025e+000 vertex 3.298082e+001 3.639853e+000 3.200025e+000 endloop endfacet facet normal 8.861106e-001 4.634738e-001 0.000000e+000 outer loop vertex 3.305370e+001 3.508620e+000 5.200025e+000 vertex 3.298082e+001 3.639853e+000 3.200025e+000 vertex 3.298082e+001 3.639853e+000 5.200025e+000 endloop endfacet facet normal 9.292989e-001 3.693286e-001 0.000000e+000 outer loop vertex 3.298082e+001 3.639853e+000 5.200025e+000 vertex 3.298082e+001 3.639853e+000 3.200025e+000 vertex 3.292393e+001 3.795351e+000 3.200025e+000 endloop endfacet facet normal 9.471484e-001 3.207957e-001 0.000000e+000 outer loop vertex 3.298082e+001 3.639853e+000 5.200025e+000 vertex 3.292393e+001 3.795351e+000 3.200025e+000 vertex 3.292393e+001 3.795351e+000 5.200025e+000 endloop endfacet facet normal 9.746434e-001 2.237637e-001 0.000000e+000 outer loop vertex 3.292393e+001 3.795351e+000 5.200025e+000 vertex 3.292393e+001 3.795351e+000 3.200025e+000 vertex 3.288729e+001 3.976790e+000 3.200025e+000 endloop endfacet facet normal 9.845102e-001 1.753270e-001 0.000000e+000 outer loop vertex 3.292393e+001 3.795351e+000 5.200025e+000 vertex 3.288729e+001 3.976790e+000 3.200025e+000 vertex 3.288729e+001 3.976790e+000 5.200025e+000 endloop endfacet facet normal 9.957744e-001 9.183280e-002 0.000000e+000 outer loop vertex 3.288729e+001 3.976790e+000 5.200025e+000 vertex 3.288729e+001 3.976790e+000 3.200025e+000 vertex 3.287488e+001 4.185221e+000 3.200025e+000 endloop endfacet facet normal 9.983782e-001 5.692931e-002 0.000000e+000 outer loop vertex 3.288729e+001 3.976790e+000 5.200025e+000 vertex 3.287488e+001 4.185221e+000 3.200025e+000 vertex 3.287488e+001 4.185221e+000 5.200025e+000 endloop endfacet facet normal 9.962124e-001 -8.695291e-002 0.000000e+000 outer loop vertex 3.287488e+001 4.185221e+000 5.200025e+000 vertex 3.287488e+001 4.185221e+000 3.200025e+000 vertex 3.290936e+001 4.526751e+000 3.200025e+000 endloop endfacet facet normal 9.894901e-001 -1.446007e-001 0.000000e+000 outer loop vertex 3.287488e+001 4.185221e+000 5.200025e+000 vertex 3.290936e+001 4.526751e+000 3.200025e+000 vertex 3.290936e+001 4.526751e+000 5.200025e+000 endloop endfacet facet normal 9.677919e-001 -2.517519e-001 0.000000e+000 outer loop vertex 3.290936e+001 4.526751e+000 5.200025e+000 vertex 3.290936e+001 4.526751e+000 3.200025e+000 vertex 3.299145e+001 4.809980e+000 3.200025e+000 endloop endfacet facet normal 9.534991e-001 -3.013960e-001 0.000000e+000 outer loop vertex 3.290936e+001 4.526751e+000 5.200025e+000 vertex 3.299145e+001 4.809980e+000 3.200025e+000 vertex 3.299145e+001 4.809980e+000 5.200025e+000 endloop endfacet facet normal 9.172655e-001 -3.982763e-001 0.000000e+000 outer loop vertex 3.299145e+001 4.809980e+000 5.200025e+000 vertex 3.299145e+001 4.809980e+000 3.200025e+000 vertex 3.312604e+001 5.097305e+000 3.200025e+000 endloop endfacet facet normal 8.952834e-001 -4.454971e-001 0.000000e+000 outer loop vertex 3.299145e+001 4.809980e+000 5.200025e+000 vertex 3.312604e+001 5.097305e+000 3.200025e+000 vertex 3.312604e+001 5.097305e+000 5.200025e+000 endloop endfacet facet normal 8.483390e-001 -5.294534e-001 0.000000e+000 outer loop vertex 3.312604e+001 5.097305e+000 5.200025e+000 vertex 3.312604e+001 5.097305e+000 3.200025e+000 vertex 3.334701e+001 5.425931e+000 3.200025e+000 endloop endfacet facet normal 8.240245e-001 -5.665542e-001 0.000000e+000 outer loop vertex 3.312604e+001 5.097305e+000 5.200025e+000 vertex 3.334701e+001 5.425931e+000 3.200025e+000 vertex 3.334701e+001 5.425931e+000 5.200025e+000 endloop endfacet facet normal 7.629534e-001 -6.464534e-001 0.000000e+000 outer loop vertex 3.334701e+001 5.425931e+000 5.200025e+000 vertex 3.334701e+001 5.425931e+000 3.200025e+000 vertex 3.346085e+001 5.560289e+000 3.200025e+000 endloop endfacet facet normal 7.539849e-001 -6.568918e-001 0.000000e+000 outer loop vertex 3.334701e+001 5.425931e+000 5.200025e+000 vertex 3.346085e+001 5.560289e+000 3.200025e+000 vertex 3.346085e+001 5.560289e+000 5.200025e+000 endloop endfacet facet normal 7.072872e-001 -7.069263e-001 0.000000e+000 outer loop vertex 3.346085e+001 5.560289e+000 5.200025e+000 vertex 3.346085e+001 5.560289e+000 3.200025e+000 vertex 3.368468e+001 5.773034e+000 3.200025e+000 endloop endfacet facet normal 6.674614e-001 -7.446444e-001 0.000000e+000 outer loop vertex 3.346085e+001 5.560289e+000 5.200025e+000 vertex 3.368468e+001 5.773034e+000 3.200025e+000 vertex 3.368468e+001 5.773034e+000 5.200025e+000 endloop endfacet facet normal 5.822974e-001 -8.129759e-001 0.000000e+000 outer loop vertex 3.368468e+001 5.773034e+000 5.200025e+000 vertex 3.368468e+001 5.773034e+000 3.200025e+000 vertex 3.389362e+001 5.914418e+000 3.200025e+000 endloop endfacet facet normal 5.369692e-001 -8.436018e-001 0.000000e+000 outer loop vertex 3.368468e+001 5.773034e+000 5.200025e+000 vertex 3.389362e+001 5.914418e+000 3.200025e+000 vertex 3.389362e+001 5.914418e+000 5.200025e+000 endloop endfacet facet normal 4.423262e-001 -8.968543e-001 0.000000e+000 outer loop vertex 3.389362e+001 5.914418e+000 5.200025e+000 vertex 3.389362e+001 5.914418e+000 3.200025e+000 vertex 3.407401e+001 5.998157e+000 3.200025e+000 endloop endfacet facet normal 3.930353e-001 -9.195234e-001 0.000000e+000 outer loop vertex 3.389362e+001 5.914418e+000 5.200025e+000 vertex 3.407401e+001 5.998157e+000 3.200025e+000 vertex 3.407401e+001 5.998157e+000 5.200025e+000 endloop endfacet facet normal 2.935072e-001 -9.559569e-001 0.000000e+000 outer loop vertex 3.407401e+001 5.998157e+000 5.200025e+000 vertex 3.407401e+001 5.998157e+000 3.200025e+000 vertex 3.425444e+001 6.048870e+000 3.200025e+000 endloop endfacet facet normal 2.433494e-001 -9.699387e-001 0.000000e+000 outer loop vertex 3.407401e+001 5.998157e+000 5.200025e+000 vertex 3.425444e+001 6.048870e+000 3.200025e+000 vertex 3.425444e+001 6.048870e+000 5.200025e+000 endloop endfacet facet normal 1.431578e-001 -9.896999e-001 0.000000e+000 outer loop vertex 3.425444e+001 6.048870e+000 5.200025e+000 vertex 3.425444e+001 6.048870e+000 3.200025e+000 vertex 3.446525e+001 6.069511e+000 3.200025e+000 endloop endfacet facet normal 9.315778e-002 -9.956514e-001 0.000000e+000 outer loop vertex 3.425444e+001 6.048870e+000 5.200025e+000 vertex 3.446525e+001 6.069511e+000 3.200025e+000 vertex 3.446525e+001 6.069511e+000 5.200025e+000 endloop endfacet facet normal -9.783311e-001 2.070464e-001 0.000000e+000 outer loop vertex 3.446525e+001 6.069511e+000 5.200025e+000 vertex 3.446525e+001 6.069511e+000 3.200025e+000 vertex 3.444749e+001 5.985519e+000 3.200025e+000 endloop endfacet facet normal -9.858350e-001 1.677182e-001 0.000000e+000 outer loop vertex 3.446525e+001 6.069511e+000 5.200025e+000 vertex 3.444749e+001 5.985519e+000 3.200025e+000 vertex 3.444749e+001 5.985519e+000 5.200025e+000 endloop endfacet facet normal -9.956077e-001 9.362358e-002 0.000000e+000 outer loop vertex 3.444749e+001 5.985519e+000 5.200025e+000 vertex 3.444749e+001 5.985519e+000 3.200025e+000 vertex 3.444245e+001 5.899748e+000 3.200025e+000 endloop endfacet facet normal -9.982635e-001 5.890721e-002 0.000000e+000 outer loop vertex 3.444749e+001 5.985519e+000 5.200025e+000 vertex 3.444245e+001 5.899748e+000 3.200025e+000 vertex 3.444245e+001 5.899748e+000 5.200025e+000 endloop endfacet facet normal -9.992808e-001 -3.791938e-002 0.000000e+000 outer loop vertex 3.444245e+001 5.899748e+000 5.200025e+000 vertex 3.444245e+001 5.899748e+000 3.200025e+000 vertex 3.444469e+001 5.840539e+000 3.200025e+000 endloop endfacet facet normal -9.986094e-001 -5.271946e-002 0.000000e+000 outer loop vertex 3.444245e+001 5.899748e+000 5.200025e+000 vertex 3.444469e+001 5.840539e+000 3.200025e+000 vertex 3.444469e+001 5.840539e+000 5.200025e+000 endloop endfacet facet normal -9.925880e-001 -1.215273e-001 0.000000e+000 outer loop vertex 3.444469e+001 5.840539e+000 5.200025e+000 vertex 3.444469e+001 5.840539e+000 3.200025e+000 vertex 3.445865e+001 5.748045e+000 3.200025e+000 endloop endfacet facet normal -9.845061e-001 -1.753502e-001 0.000000e+000 outer loop vertex 3.444469e+001 5.840539e+000 5.200025e+000 vertex 3.445865e+001 5.748045e+000 3.200025e+000 vertex 3.445865e+001 5.748045e+000 5.200025e+000 endloop endfacet facet normal -9.606684e-001 -2.776982e-001 0.000000e+000 outer loop vertex 3.445865e+001 5.748045e+000 5.200025e+000 vertex 3.445865e+001 5.748045e+000 3.200025e+000 vertex 3.448911e+001 5.652171e+000 3.200025e+000 endloop endfacet facet normal -9.452643e-001 -3.263057e-001 0.000000e+000 outer loop vertex 3.445865e+001 5.748045e+000 5.200025e+000 vertex 3.448911e+001 5.652171e+000 3.200025e+000 vertex 3.448911e+001 5.652171e+000 5.200025e+000 endloop endfacet facet normal -9.064384e-001 -4.223382e-001 0.000000e+000 outer loop vertex 3.448911e+001 5.652171e+000 5.200025e+000 vertex 3.448911e+001 5.652171e+000 3.200025e+000 vertex 3.453214e+001 5.566125e+000 3.200025e+000 endloop endfacet facet normal -8.828321e-001 -4.696888e-001 0.000000e+000 outer loop vertex 3.448911e+001 5.652171e+000 5.200025e+000 vertex 3.453214e+001 5.566125e+000 3.200025e+000 vertex 3.453214e+001 5.566125e+000 5.200025e+000 endloop endfacet facet normal -8.292537e-001 -5.588724e-001 0.000000e+000 outer loop vertex 3.453214e+001 5.566125e+000 5.200025e+000 vertex 3.453214e+001 5.566125e+000 3.200025e+000 vertex 3.459350e+001 5.479983e+000 3.200025e+000 endloop endfacet facet normal -7.994117e-001 -6.007836e-001 0.000000e+000 outer loop vertex 3.453214e+001 5.566125e+000 5.200025e+000 vertex 3.459350e+001 5.479983e+000 3.200025e+000 vertex 3.459350e+001 5.479983e+000 5.200025e+000 endloop endfacet facet normal -7.377801e-001 -6.750411e-001 0.000000e+000 outer loop vertex 3.459350e+001 5.479983e+000 5.200025e+000 vertex 3.459350e+001 5.479983e+000 3.200025e+000 vertex 3.467555e+001 5.397214e+000 3.200025e+000 endloop endfacet facet normal -7.064456e-001 -7.077674e-001 0.000000e+000 outer loop vertex 3.459350e+001 5.479983e+000 5.200025e+000 vertex 3.467555e+001 5.397214e+000 3.200025e+000 vertex 3.467555e+001 5.397214e+000 5.200025e+000 endloop endfacet facet normal -6.206257e-001 -7.841069e-001 0.000000e+000 outer loop vertex 3.467555e+001 5.397214e+000 5.200025e+000 vertex 3.467555e+001 5.397214e+000 3.200025e+000 vertex 3.471583e+001 5.365334e+000 3.200025e+000 endloop endfacet facet normal -6.148000e-001 -7.886831e-001 0.000000e+000 outer loop vertex 3.467555e+001 5.397214e+000 5.200025e+000 vertex 3.471583e+001 5.365334e+000 3.200025e+000 vertex 3.471583e+001 5.365334e+000 5.200025e+000 endloop endfacet facet normal -5.630969e-001 -8.263909e-001 0.000000e+000 outer loop vertex 3.471583e+001 5.365334e+000 5.200025e+000 vertex 3.471583e+001 5.365334e+000 3.200025e+000 vertex 3.482317e+001 5.295907e+000 3.200025e+000 endloop endfacet facet normal -5.152937e-001 -8.570136e-001 0.000000e+000 outer loop vertex 3.471583e+001 5.365334e+000 5.200025e+000 vertex 3.482317e+001 5.295907e+000 3.200025e+000 vertex 3.482317e+001 5.295907e+000 5.200025e+000 endloop endfacet facet normal -4.155618e-001 -9.095650e-001 0.000000e+000 outer loop vertex 3.482317e+001 5.295907e+000 5.200025e+000 vertex 3.482317e+001 5.295907e+000 3.200025e+000 vertex 3.494287e+001 5.244747e+000 3.200025e+000 endloop endfacet facet normal -3.636545e-001 -9.315339e-001 0.000000e+000 outer loop vertex 3.482317e+001 5.295907e+000 5.200025e+000 vertex 3.494287e+001 5.244747e+000 3.200025e+000 vertex 3.494287e+001 5.244747e+000 5.200025e+000 endloop endfacet facet normal -2.621806e-001 -9.650189e-001 0.000000e+000 outer loop vertex 3.494287e+001 5.244747e+000 5.200025e+000 vertex 3.494287e+001 5.244747e+000 3.200025e+000 vertex 3.505911e+001 5.216029e+000 3.200025e+000 endloop endfacet facet normal -2.127976e-001 -9.770963e-001 0.000000e+000 outer loop vertex 3.494287e+001 5.244747e+000 5.200025e+000 vertex 3.505911e+001 5.216029e+000 3.200025e+000 vertex 3.505911e+001 5.216029e+000 5.200025e+000 endloop endfacet facet normal -1.193369e-001 -9.928538e-001 0.000000e+000 outer loop vertex 3.505911e+001 5.216029e+000 5.200025e+000 vertex 3.505911e+001 5.216029e+000 3.200025e+000 vertex 3.520174e+001 5.204647e+000 3.200025e+000 endloop endfacet facet normal -7.536206e-002 -9.971562e-001 0.000000e+000 outer loop vertex 3.505911e+001 5.216029e+000 5.200025e+000 vertex 3.520174e+001 5.204647e+000 3.200025e+000 vertex 3.520174e+001 5.204647e+000 5.200025e+000 endloop endfacet facet normal 2.814414e-002 -9.996039e-001 0.000000e+000 outer loop vertex 3.520174e+001 5.204647e+000 5.200025e+000 vertex 3.520174e+001 5.204647e+000 3.200025e+000 vertex 3.526373e+001 5.206391e+000 3.200025e+000 endloop endfacet facet normal 4.374170e-002 -9.990429e-001 0.000000e+000 outer loop vertex 3.520174e+001 5.204647e+000 5.200025e+000 vertex 3.526373e+001 5.206391e+000 3.200025e+000 vertex 3.526373e+001 5.206391e+000 5.200025e+000 endloop endfacet facet normal 1.086212e-001 -9.940832e-001 0.000000e+000 outer loop vertex 3.526373e+001 5.206391e+000 5.200025e+000 vertex 3.526373e+001 5.206391e+000 3.200025e+000 vertex 3.538346e+001 5.223536e+000 3.200025e+000 endloop endfacet facet normal 1.577718e-001 -9.874756e-001 0.000000e+000 outer loop vertex 3.526373e+001 5.206391e+000 5.200025e+000 vertex 3.538346e+001 5.223536e+000 3.200025e+000 vertex 3.538346e+001 5.223536e+000 5.200025e+000 endloop endfacet facet normal 2.584605e-001 -9.660218e-001 0.000000e+000 outer loop vertex 3.538346e+001 5.223536e+000 5.200025e+000 vertex 3.538346e+001 5.223536e+000 3.200025e+000 vertex 3.549575e+001 5.257381e+000 3.200025e+000 endloop endfacet facet normal 3.099119e-001 -9.507653e-001 0.000000e+000 outer loop vertex 3.538346e+001 5.223536e+000 5.200025e+000 vertex 3.549575e+001 5.257381e+000 3.200025e+000 vertex 3.549575e+001 5.257381e+000 5.200025e+000 endloop endfacet facet normal 4.090990e-001 -9.124901e-001 0.000000e+000 outer loop vertex 3.549575e+001 5.257381e+000 5.200025e+000 vertex 3.549575e+001 5.257381e+000 3.200025e+000 vertex 3.561232e+001 5.313697e+000 3.200025e+000 endloop endfacet facet normal 4.568604e-001 -8.895384e-001 0.000000e+000 outer loop vertex 3.549575e+001 5.257381e+000 5.200025e+000 vertex 3.561232e+001 5.313697e+000 3.200025e+000 vertex 3.561232e+001 5.313697e+000 5.200025e+000 endloop endfacet facet normal 5.467092e-001 -8.373225e-001 0.000000e+000 outer loop vertex 3.561232e+001 5.313697e+000 5.200025e+000 vertex 3.561232e+001 5.313697e+000 3.200025e+000 vertex 3.572285e+001 5.392146e+000 3.200025e+000 endloop endfacet facet normal 5.888877e-001 -8.082149e-001 0.000000e+000 outer loop vertex 3.561232e+001 5.313697e+000 5.200025e+000 vertex 3.572285e+001 5.392146e+000 3.200025e+000 vertex 3.572285e+001 5.392146e+000 5.200025e+000 endloop endfacet facet normal 6.774860e-001 -7.355357e-001 0.000000e+000 outer loop vertex 3.572285e+001 5.392146e+000 5.200025e+000 vertex 3.572285e+001 5.392146e+000 3.200025e+000 vertex 3.576385e+001 5.429909e+000 3.200025e+000 endloop endfacet facet normal 6.857578e-001 -7.278298e-001 0.000000e+000 outer loop vertex 3.572285e+001 5.392146e+000 5.200025e+000 vertex 3.576385e+001 5.429909e+000 3.200025e+000 vertex 3.576385e+001 5.429909e+000 5.200025e+000 endloop endfacet facet normal 7.313496e-001 -6.820028e-001 0.000000e+000 outer loop vertex 3.576385e+001 5.429909e+000 5.200025e+000 vertex 3.576385e+001 5.429909e+000 3.200025e+000 vertex 3.583331e+001 5.508509e+000 3.200025e+000 endloop endfacet facet normal 7.667750e-001 -6.419160e-001 0.000000e+000 outer loop vertex 3.576385e+001 5.429909e+000 5.200025e+000 vertex 3.583331e+001 5.508509e+000 3.200025e+000 vertex 3.583331e+001 5.508509e+000 5.200025e+000 endloop endfacet facet normal 8.296230e-001 -5.583240e-001 0.000000e+000 outer loop vertex 3.583331e+001 5.508509e+000 5.200025e+000 vertex 3.583331e+001 5.508509e+000 3.200025e+000 vertex 3.588581e+001 5.590718e+000 3.200025e+000 endloop endfacet facet normal 8.572202e-001 -5.149500e-001 0.000000e+000 outer loop vertex 3.583331e+001 5.508509e+000 5.200025e+000 vertex 3.588581e+001 5.590718e+000 3.200025e+000 vertex 3.588581e+001 5.590718e+000 5.200025e+000 endloop endfacet facet normal 9.078006e-001 -4.194022e-001 0.000000e+000 outer loop vertex 3.588581e+001 5.590718e+000 5.200025e+000 vertex 3.588581e+001 5.590718e+000 3.200025e+000 vertex 3.592517e+001 5.683188e+000 3.200025e+000 endloop endfacet facet normal 9.302442e-001 -3.669410e-001 0.000000e+000 outer loop vertex 3.588581e+001 5.590718e+000 5.200025e+000 vertex 3.592517e+001 5.683188e+000 3.200025e+000 vertex 3.592517e+001 5.683188e+000 5.200025e+000 endloop endfacet facet normal 9.648033e-001 -2.629728e-001 0.000000e+000 outer loop vertex 3.592517e+001 5.683188e+000 5.200025e+000 vertex 3.592517e+001 5.683188e+000 3.200025e+000 vertex 3.594813e+001 5.776505e+000 3.200025e+000 endloop endfacet facet normal 9.773543e-001 -2.116095e-001 0.000000e+000 outer loop vertex 3.592517e+001 5.683188e+000 5.200025e+000 vertex 3.594813e+001 5.776505e+000 3.200025e+000 vertex 3.594813e+001 5.776505e+000 5.200025e+000 endloop endfacet facet normal 9.933872e-001 -1.148124e-001 0.000000e+000 outer loop vertex 3.594813e+001 5.776505e+000 5.200025e+000 vertex 3.594813e+001 5.776505e+000 3.200025e+000 vertex 3.595596e+001 5.882011e+000 3.200025e+000 endloop endfacet facet normal 9.975824e-001 -6.949408e-002 0.000000e+000 outer loop vertex 3.594813e+001 5.776505e+000 5.200025e+000 vertex 3.595596e+001 5.882011e+000 3.200025e+000 vertex 3.595596e+001 5.882011e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.792640e+001 4.069511e+000 3.200025e+000 vertex 2.712552e+001 4.011939e+000 3.200025e+000 vertex 2.758600e+001 3.662999e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.758600e+001 3.662999e+000 3.200025e+000 vertex 2.712552e+001 4.011939e+000 3.200025e+000 vertex 2.683557e+001 3.948704e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.758600e+001 3.662999e+000 3.200025e+000 vertex 2.683557e+001 3.948704e+000 3.200025e+000 vertex 2.718738e+001 3.312755e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.718738e+001 3.312755e+000 3.200025e+000 vertex 2.683557e+001 3.948704e+000 3.200025e+000 vertex 2.659707e+001 3.863054e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.718738e+001 3.312755e+000 3.200025e+000 vertex 2.659707e+001 3.863054e+000 3.200025e+000 vertex 2.711975e+001 3.261054e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.711975e+001 3.261054e+000 3.200025e+000 vertex 2.659707e+001 3.863054e+000 3.200025e+000 vertex 2.643037e+001 3.771226e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.711975e+001 3.261054e+000 3.200025e+000 vertex 2.643037e+001 3.771226e+000 3.200025e+000 vertex 2.678301e+001 3.038524e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.678301e+001 3.038524e+000 3.200025e+000 vertex 2.643037e+001 3.771226e+000 3.200025e+000 vertex 2.637826e+001 3.735896e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.678301e+001 3.038524e+000 3.200025e+000 vertex 2.637826e+001 3.735896e+000 3.200025e+000 vertex 2.656557e+001 2.937940e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.656557e+001 2.937940e+000 3.200025e+000 vertex 2.637826e+001 3.735896e+000 3.200025e+000 vertex 2.623308e+001 3.611141e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.656557e+001 2.937940e+000 3.200025e+000 vertex 2.623308e+001 3.611141e+000 3.200025e+000 vertex 2.641702e+001 2.894977e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.641702e+001 2.894977e+000 3.200025e+000 vertex 2.623308e+001 3.611141e+000 3.200025e+000 vertex 2.614034e+001 3.505764e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.641702e+001 2.894977e+000 3.200025e+000 vertex 2.614034e+001 3.505764e+000 3.200025e+000 vertex 2.627522e+001 2.880322e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.627522e+001 2.880322e+000 3.200025e+000 vertex 2.614034e+001 3.505764e+000 3.200025e+000 vertex 2.607772e+001 3.407592e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.627522e+001 2.880322e+000 3.200025e+000 vertex 2.607772e+001 3.407592e+000 3.200025e+000 vertex 2.624462e+001 2.881522e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.624462e+001 2.881522e+000 3.200025e+000 vertex 2.607772e+001 3.407592e+000 3.200025e+000 vertex 2.604041e+001 3.323305e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.624462e+001 2.881522e+000 3.200025e+000 vertex 2.604041e+001 3.323305e+000 3.200025e+000 vertex 2.619372e+001 2.887917e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.619372e+001 2.887917e+000 3.200025e+000 vertex 2.604041e+001 3.323305e+000 3.200025e+000 vertex 2.601945e+001 3.245797e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.619372e+001 2.887917e+000 3.200025e+000 vertex 2.601945e+001 3.245797e+000 3.200025e+000 vertex 2.614441e+001 2.902653e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.614441e+001 2.902653e+000 3.200025e+000 vertex 2.601945e+001 3.245797e+000 3.200025e+000 vertex 2.601001e+001 3.146369e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.614441e+001 2.902653e+000 3.200025e+000 vertex 2.601001e+001 3.146369e+000 3.200025e+000 vertex 2.611779e+001 2.915203e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.611779e+001 2.915203e+000 3.200025e+000 vertex 2.601001e+001 3.146369e+000 3.200025e+000 vertex 2.601267e+001 3.097160e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.611779e+001 2.915203e+000 3.200025e+000 vertex 2.601267e+001 3.097160e+000 3.200025e+000 vertex 2.609461e+001 2.930993e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.609461e+001 2.930993e+000 3.200025e+000 vertex 2.601267e+001 3.097160e+000 3.200025e+000 vertex 2.602125e+001 3.048951e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.609461e+001 2.930993e+000 3.200025e+000 vertex 2.602125e+001 3.048951e+000 3.200025e+000 vertex 2.606749e+001 2.956850e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.606749e+001 2.956850e+000 3.200025e+000 vertex 2.602125e+001 3.048951e+000 3.200025e+000 vertex 2.603515e+001 3.007836e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.606749e+001 2.956850e+000 3.200025e+000 vertex 2.603515e+001 3.007836e+000 3.200025e+000 vertex 2.604864e+001 2.981828e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 3.020765e+001 6.091471e+000 3.200025e+000 vertex 2.897623e+001 4.501944e+000 3.200025e+000 vertex 2.962995e+001 4.501944e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.300212e+001 3.514563e+000 3.200025e+000 vertex 2.298383e+001 3.528971e+000 3.200025e+000 vertex 2.260892e+001 2.689378e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.304059e+001 3.478963e+000 3.200025e+000 vertex 2.292390e+001 2.510384e+000 3.200025e+000 vertex 2.302143e+001 2.672723e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.304059e+001 3.478963e+000 3.200025e+000 vertex 2.302143e+001 2.672723e+000 3.200025e+000 vertex 2.307066e+001 3.440160e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.307066e+001 3.440160e+000 3.200025e+000 vertex 2.302143e+001 2.672723e+000 3.200025e+000 vertex 2.306745e+001 2.779815e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.307066e+001 3.440160e+000 3.200025e+000 vertex 2.306745e+001 2.779815e+000 3.200025e+000 vertex 2.310262e+001 3.384567e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.310262e+001 3.384567e+000 3.200025e+000 vertex 2.306745e+001 2.779815e+000 3.200025e+000 vertex 2.312220e+001 2.972271e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.310262e+001 3.384567e+000 3.200025e+000 vertex 2.312220e+001 2.972271e+000 3.200025e+000 vertex 2.312376e+001 3.328368e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.312376e+001 3.328368e+000 3.200025e+000 vertex 2.312220e+001 2.972271e+000 3.200025e+000 vertex 2.314515e+001 3.170863e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.312376e+001 3.328368e+000 3.200025e+000 vertex 2.314515e+001 3.170863e+000 3.200025e+000 vertex 2.313931e+001 3.258176e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.304059e+001 3.478963e+000 3.200025e+000 vertex 2.300212e+001 3.514563e+000 3.200025e+000 vertex 2.292390e+001 2.510384e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.292390e+001 2.510384e+000 3.200025e+000 vertex 2.300212e+001 3.514563e+000 3.200025e+000 vertex 2.260892e+001 2.689378e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.292390e+001 2.510384e+000 3.200025e+000 vertex 2.260892e+001 2.689378e+000 3.200025e+000 vertex 2.273214e+001 2.272214e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.273214e+001 2.272214e+000 3.200025e+000 vertex 2.260892e+001 2.689378e+000 3.200025e+000 vertex 2.222623e+001 1.853295e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.273214e+001 2.272214e+000 3.200025e+000 vertex 2.222623e+001 1.853295e+000 3.200025e+000 vertex 2.268718e+001 2.223361e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 0.000000e+000 1.000000e+000 outer loop vertex 2.268718e+001 2.223361e+000 3.200025e+000 vertex 2.222623e+001 1.853295e+000 3.200025e+000 vertex 2.244634e+001 1.997951e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.776762e+001 6.555998e+000 5.200025e+000 vertex 4.146947e+001 6.555998e+000 5.200025e+000 vertex 3.776762e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 1.000000e+000 0.000000e+000 outer loop vertex 3.776762e+001 6.555998e+000 3.200025e+000 vertex 4.146947e+001 6.555998e+000 5.200025e+000 vertex 4.146947e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal -2.948060e-002 9.995654e-001 0.000000e+000 outer loop vertex 3.776762e+001 6.555998e+000 5.200025e+000 vertex 3.776762e+001 6.555998e+000 3.200025e+000 vertex 3.758270e+001 6.550544e+000 3.200025e+000 endloop endfacet facet normal -3.958634e-002 9.992162e-001 0.000000e+000 outer loop vertex 3.776762e+001 6.555998e+000 5.200025e+000 vertex 3.758270e+001 6.550544e+000 3.200025e+000 vertex 3.758270e+001 6.550544e+000 5.200025e+000 endloop endfacet facet normal -1.045854e-001 9.945160e-001 0.000000e+000 outer loop vertex 3.758270e+001 6.550544e+000 5.200025e+000 vertex 3.758270e+001 6.550544e+000 3.200025e+000 vertex 3.714959e+001 6.493544e+000 3.200025e+000 endloop endfacet facet normal -1.593324e-001 9.872250e-001 0.000000e+000 outer loop vertex 3.758270e+001 6.550544e+000 5.200025e+000 vertex 3.714959e+001 6.493544e+000 3.200025e+000 vertex 3.714959e+001 6.493544e+000 5.200025e+000 endloop endfacet facet normal -2.637080e-001 9.646025e-001 0.000000e+000 outer loop vertex 3.714959e+001 6.493544e+000 5.200025e+000 vertex 3.714959e+001 6.493544e+000 3.200025e+000 vertex 3.684798e+001 6.403257e+000 3.200025e+000 endloop endfacet facet normal -3.134122e-001 9.496171e-001 0.000000e+000 outer loop vertex 3.714959e+001 6.493544e+000 5.200025e+000 vertex 3.684798e+001 6.403257e+000 3.200025e+000 vertex 3.684798e+001 6.403257e+000 5.200025e+000 endloop endfacet facet normal -4.127782e-001 9.108316e-001 0.000000e+000 outer loop vertex 3.684798e+001 6.403257e+000 5.200025e+000 vertex 3.684798e+001 6.403257e+000 3.200025e+000 vertex 3.656573e+001 6.266929e+000 3.200025e+000 endloop endfacet facet normal -4.623170e-001 8.867147e-001 0.000000e+000 outer loop vertex 3.684798e+001 6.403257e+000 5.200025e+000 vertex 3.656573e+001 6.266929e+000 3.200025e+000 vertex 3.656573e+001 6.266929e+000 5.200025e+000 endloop endfacet facet normal -5.559050e-001 8.312458e-001 0.000000e+000 outer loop vertex 3.656573e+001 6.266929e+000 5.200025e+000 vertex 3.656573e+001 6.266929e+000 3.200025e+000 vertex 3.631914e+001 6.085559e+000 3.200025e+000 endloop endfacet facet normal -6.000119e-001 7.999911e-001 0.000000e+000 outer loop vertex 3.656573e+001 6.266929e+000 5.200025e+000 vertex 3.631914e+001 6.085559e+000 3.200025e+000 vertex 3.631914e+001 6.085559e+000 5.200025e+000 endloop endfacet facet normal -6.892298e-001 7.245429e-001 0.000000e+000 outer loop vertex 3.631914e+001 6.085559e+000 5.200025e+000 vertex 3.631914e+001 6.085559e+000 3.200025e+000 vertex 3.623904e+001 6.009370e+000 3.200025e+000 endloop endfacet facet normal -6.964645e-001 7.175913e-001 0.000000e+000 outer loop vertex 3.631914e+001 6.085559e+000 5.200025e+000 vertex 3.623904e+001 6.009370e+000 3.200025e+000 vertex 3.623904e+001 6.009370e+000 5.200025e+000 endloop endfacet facet normal -7.388433e-001 6.738772e-001 0.000000e+000 outer loop vertex 3.623904e+001 6.009370e+000 5.200025e+000 vertex 3.623904e+001 6.009370e+000 3.200025e+000 vertex 3.609706e+001 5.845630e+000 3.200025e+000 endloop endfacet facet normal -7.722313e-001 6.353415e-001 0.000000e+000 outer loop vertex 3.623904e+001 6.009370e+000 5.200025e+000 vertex 3.609706e+001 5.845630e+000 3.200025e+000 vertex 3.609706e+001 5.845630e+000 5.200025e+000 endloop endfacet facet normal -8.328856e-001 5.534453e-001 0.000000e+000 outer loop vertex 3.609706e+001 5.845630e+000 5.200025e+000 vertex 3.609706e+001 5.845630e+000 3.200025e+000 vertex 3.599011e+001 5.675723e+000 3.200025e+000 endloop endfacet facet normal -8.601325e-001 5.100707e-001 0.000000e+000 outer loop vertex 3.609706e+001 5.845630e+000 5.200025e+000 vertex 3.599011e+001 5.675723e+000 3.200025e+000 vertex 3.599011e+001 5.675723e+000 5.200025e+000 endloop endfacet facet normal -9.100150e-001 4.145752e-001 0.000000e+000 outer loop vertex 3.599011e+001 5.675723e+000 5.200025e+000 vertex 3.599011e+001 5.675723e+000 3.200025e+000 vertex 3.590902e+001 5.486102e+000 3.200025e+000 endloop endfacet facet normal -9.321117e-001 3.621710e-001 0.000000e+000 outer loop vertex 3.599011e+001 5.675723e+000 5.200025e+000 vertex 3.590902e+001 5.486102e+000 3.200025e+000 vertex 3.590902e+001 5.486102e+000 5.200025e+000 endloop endfacet facet normal -9.654372e-001 2.606356e-001 0.000000e+000 outer loop vertex 3.590902e+001 5.486102e+000 5.200025e+000 vertex 3.590902e+001 5.486102e+000 3.200025e+000 vertex 3.586516e+001 5.303418e+000 3.200025e+000 endloop endfacet facet normal -9.773304e-001 2.117200e-001 0.000000e+000 outer loop vertex 3.590902e+001 5.486102e+000 5.200025e+000 vertex 3.586516e+001 5.303418e+000 3.200025e+000 vertex 3.586516e+001 5.303418e+000 5.200025e+000 endloop endfacet facet normal -9.929234e-001 1.187568e-001 0.000000e+000 outer loop vertex 3.586516e+001 5.303418e+000 5.200025e+000 vertex 3.586516e+001 5.303418e+000 3.200025e+000 vertex 3.584785e+001 5.087248e+000 3.200025e+000 endloop endfacet facet normal -9.971983e-001 7.480383e-002 0.000000e+000 outer loop vertex 3.586516e+001 5.303418e+000 5.200025e+000 vertex 3.584785e+001 5.087248e+000 3.200025e+000 vertex 3.584785e+001 5.087248e+000 5.200025e+000 endloop endfacet facet normal -9.980948e-001 -6.169949e-002 0.000000e+000 outer loop vertex 3.584785e+001 5.087248e+000 5.200025e+000 vertex 3.584785e+001 5.087248e+000 3.200025e+000 vertex 3.585817e+001 4.922856e+000 3.200025e+000 endloop endfacet facet normal -9.958118e-001 -9.142747e-002 0.000000e+000 outer loop vertex 3.584785e+001 5.087248e+000 5.200025e+000 vertex 3.585817e+001 4.922856e+000 3.200025e+000 vertex 3.585817e+001 4.922856e+000 5.200025e+000 endloop endfacet facet normal -9.851014e-001 -1.719746e-001 0.000000e+000 outer loop vertex 3.585817e+001 4.922856e+000 5.200025e+000 vertex 3.585817e+001 4.922856e+000 3.200025e+000 vertex 3.589002e+001 4.763933e+000 3.200025e+000 endloop endfacet facet normal -9.749146e-001 -2.225791e-001 0.000000e+000 outer loop vertex 3.585817e+001 4.922856e+000 5.200025e+000 vertex 3.589002e+001 4.763933e+000 3.200025e+000 vertex 3.589002e+001 4.763933e+000 5.200025e+000 endloop endfacet facet normal -9.455642e-001 -3.254358e-001 0.000000e+000 outer loop vertex 3.589002e+001 4.763933e+000 5.200025e+000 vertex 3.589002e+001 4.763933e+000 3.200025e+000 vertex 3.594708e+001 4.611193e+000 3.200025e+000 endloop endfacet facet normal -9.259813e-001 -3.775692e-001 0.000000e+000 outer loop vertex 3.589002e+001 4.763933e+000 5.200025e+000 vertex 3.594708e+001 4.611193e+000 3.200025e+000 vertex 3.594708e+001 4.611193e+000 5.200025e+000 endloop endfacet facet normal -8.793932e-001 -4.760961e-001 0.000000e+000 outer loop vertex 3.594708e+001 4.611193e+000 5.200025e+000 vertex 3.594708e+001 4.611193e+000 3.200025e+000 vertex 3.602639e+001 4.474357e+000 3.200025e+000 endloop endfacet facet normal -8.525876e-001 -5.225843e-001 0.000000e+000 outer loop vertex 3.594708e+001 4.611193e+000 5.200025e+000 vertex 3.602639e+001 4.474357e+000 3.200025e+000 vertex 3.602639e+001 4.474357e+000 5.200025e+000 endloop endfacet facet normal -7.916470e-001 -6.109788e-001 0.000000e+000 outer loop vertex 3.602639e+001 4.474357e+000 5.200025e+000 vertex 3.602639e+001 4.474357e+000 3.200025e+000 vertex 3.612392e+001 4.354509e+000 3.200025e+000 endloop endfacet facet normal -7.574774e-001 -6.528614e-001 0.000000e+000 outer loop vertex 3.602639e+001 4.474357e+000 5.200025e+000 vertex 3.612392e+001 4.354509e+000 3.200025e+000 vertex 3.612392e+001 4.354509e+000 5.200025e+000 endloop endfacet facet normal -6.920256e-001 -7.218730e-001 0.000000e+000 outer loop vertex 3.612392e+001 4.354509e+000 5.200025e+000 vertex 3.612392e+001 4.354509e+000 3.200025e+000 vertex 3.625664e+001 4.236741e+000 3.200025e+000 endloop endfacet facet normal -6.616173e-001 -7.498416e-001 0.000000e+000 outer loop vertex 3.612392e+001 4.354509e+000 5.200025e+000 vertex 3.625664e+001 4.236741e+000 3.200025e+000 vertex 3.625664e+001 4.236741e+000 5.200025e+000 endloop endfacet facet normal -5.442547e-001 -8.389201e-001 0.000000e+000 outer loop vertex 3.625664e+001 4.236741e+000 5.200025e+000 vertex 3.625664e+001 4.236741e+000 3.200025e+000 vertex 3.645763e+001 4.109829e+000 3.200025e+000 endloop endfacet facet normal -5.011938e-001 -8.653350e-001 0.000000e+000 outer loop vertex 3.625664e+001 4.236741e+000 5.200025e+000 vertex 3.645763e+001 4.109829e+000 3.200025e+000 vertex 3.645763e+001 4.109829e+000 5.200025e+000 endloop endfacet facet normal -4.086026e-001 -9.127124e-001 0.000000e+000 outer loop vertex 3.645763e+001 4.109829e+000 5.200025e+000 vertex 3.645763e+001 4.109829e+000 3.200025e+000 vertex 3.663758e+001 4.035502e+000 3.200025e+000 endloop endfacet facet normal -3.589158e-001 -9.333699e-001 0.000000e+000 outer loop vertex 3.645763e+001 4.109829e+000 5.200025e+000 vertex 3.663758e+001 4.035502e+000 3.200025e+000 vertex 3.663758e+001 4.035502e+000 5.200025e+000 endloop endfacet facet normal -2.596613e-001 -9.656997e-001 0.000000e+000 outer loop vertex 3.663758e+001 4.035502e+000 5.200025e+000 vertex 3.663758e+001 4.035502e+000 3.200025e+000 vertex 3.685820e+001 3.981283e+000 3.200025e+000 endloop endfacet facet normal -2.101873e-001 -9.776611e-001 0.000000e+000 outer loop vertex 3.663758e+001 4.035502e+000 5.200025e+000 vertex 3.685820e+001 3.981283e+000 3.200025e+000 vertex 3.685820e+001 3.981283e+000 5.200025e+000 endloop endfacet facet normal -1.136160e-001 -9.935247e-001 0.000000e+000 outer loop vertex 3.685820e+001 3.981283e+000 5.200025e+000 vertex 3.685820e+001 3.981283e+000 3.200025e+000 vertex 3.711981e+001 3.961403e+000 3.200025e+000 endloop endfacet facet normal -6.657630e-002 -9.977813e-001 0.000000e+000 outer loop vertex 3.685820e+001 3.981283e+000 5.200025e+000 vertex 3.711981e+001 3.961403e+000 3.200025e+000 vertex 3.711981e+001 3.961403e+000 5.200025e+000 endloop endfacet facet normal 1.749194e-002 -9.998470e-001 0.000000e+000 outer loop vertex 3.711981e+001 3.961403e+000 5.200025e+000 vertex 3.711981e+001 3.961403e+000 3.200025e+000 vertex 3.715083e+001 3.961946e+000 3.200025e+000 endloop endfacet facet normal 1.856368e-002 -9.998277e-001 0.000000e+000 outer loop vertex 3.711981e+001 3.961403e+000 5.200025e+000 vertex 3.715083e+001 3.961946e+000 3.200025e+000 vertex 3.715083e+001 3.961946e+000 5.200025e+000 endloop endfacet facet normal 6.970064e-002 -9.975680e-001 0.000000e+000 outer loop vertex 3.715083e+001 3.961946e+000 5.200025e+000 vertex 3.715083e+001 3.961946e+000 3.200025e+000 vertex 3.739110e+001 3.983120e+000 3.200025e+000 endloop endfacet facet normal 1.197164e-001 -9.928082e-001 0.000000e+000 outer loop vertex 3.715083e+001 3.961946e+000 5.200025e+000 vertex 3.739110e+001 3.983120e+000 3.200025e+000 vertex 3.739110e+001 3.983120e+000 5.200025e+000 endloop endfacet facet normal 2.229538e-001 -9.748290e-001 0.000000e+000 outer loop vertex 3.739110e+001 3.983120e+000 5.200025e+000 vertex 3.739110e+001 3.983120e+000 3.200025e+000 vertex 3.757827e+001 4.031086e+000 3.200025e+000 endloop endfacet facet normal 2.760933e-001 -9.611309e-001 0.000000e+000 outer loop vertex 3.739110e+001 3.983120e+000 5.200025e+000 vertex 3.757827e+001 4.031086e+000 3.200025e+000 vertex 3.757827e+001 4.031086e+000 5.200025e+000 endloop endfacet facet normal 3.792086e-001 -9.253112e-001 0.000000e+000 outer loop vertex 3.757827e+001 4.031086e+000 5.200025e+000 vertex 3.757827e+001 4.031086e+000 3.200025e+000 vertex 3.771231e+001 4.090940e+000 3.200025e+000 endloop endfacet facet normal 4.291925e-001 -9.032131e-001 0.000000e+000 outer loop vertex 3.757827e+001 4.031086e+000 5.200025e+000 vertex 3.771231e+001 4.090940e+000 3.200025e+000 vertex 3.771231e+001 4.090940e+000 5.200025e+000 endloop endfacet facet normal 5.267972e-001 -8.499910e-001 0.000000e+000 outer loop vertex 3.771231e+001 4.090940e+000 5.200025e+000 vertex 3.771231e+001 4.090940e+000 3.200025e+000 vertex 3.783687e+001 4.175931e+000 3.200025e+000 endloop endfacet facet normal 5.742979e-001 -8.186464e-001 0.000000e+000 outer loop vertex 3.771231e+001 4.090940e+000 5.200025e+000 vertex 3.783687e+001 4.175931e+000 3.200025e+000 vertex 3.783687e+001 4.175931e+000 5.200025e+000 endloop endfacet facet normal 6.720024e-001 -7.405489e-001 0.000000e+000 outer loop vertex 3.783687e+001 4.175931e+000 5.200025e+000 vertex 3.783687e+001 4.175931e+000 3.200025e+000 vertex 3.789184e+001 4.225810e+000 3.200025e+000 endloop endfacet facet normal 6.886187e-001 -7.251237e-001 0.000000e+000 outer loop vertex 3.783687e+001 4.175931e+000 5.200025e+000 vertex 3.789184e+001 4.225810e+000 3.200025e+000 vertex 3.789184e+001 4.225810e+000 5.200025e+000 endloop endfacet facet normal 7.409771e-001 -6.715303e-001 0.000000e+000 outer loop vertex 3.789184e+001 4.225810e+000 5.200025e+000 vertex 3.789184e+001 4.225810e+000 3.200025e+000 vertex 3.795374e+001 4.298023e+000 3.200025e+000 endloop endfacet facet normal 7.751476e-001 -6.317803e-001 0.000000e+000 outer loop vertex 3.789184e+001 4.225810e+000 5.200025e+000 vertex 3.795374e+001 4.298023e+000 3.200025e+000 vertex 3.795374e+001 4.298023e+000 5.200025e+000 endloop endfacet facet normal 8.362953e-001 -5.482793e-001 0.000000e+000 outer loop vertex 3.795374e+001 4.298023e+000 5.200025e+000 vertex 3.795374e+001 4.298023e+000 3.200025e+000 vertex 3.800050e+001 4.373044e+000 3.200025e+000 endloop endfacet facet normal 8.633584e-001 -5.045912e-001 0.000000e+000 outer loop vertex 3.795374e+001 4.298023e+000 5.200025e+000 vertex 3.800050e+001 4.373044e+000 3.200025e+000 vertex 3.800050e+001 4.373044e+000 5.200025e+000 endloop endfacet facet normal 9.108449e-001 -4.127489e-001 0.000000e+000 outer loop vertex 3.800050e+001 4.373044e+000 5.200025e+000 vertex 3.800050e+001 4.373044e+000 3.200025e+000 vertex 3.803274e+001 4.450180e+000 3.200025e+000 endloop endfacet facet normal 9.311835e-001 -3.645508e-001 0.000000e+000 outer loop vertex 3.800050e+001 4.373044e+000 5.200025e+000 vertex 3.803274e+001 4.450180e+000 3.200025e+000 vertex 3.803274e+001 4.450180e+000 5.200025e+000 endloop endfacet facet normal 9.640149e-001 -2.658480e-001 0.000000e+000 outer loop vertex 3.803274e+001 4.450180e+000 5.200025e+000 vertex 3.803274e+001 4.450180e+000 3.200025e+000 vertex 3.805639e+001 4.545071e+000 3.200025e+000 endloop endfacet facet normal 9.765363e-001 -2.153527e-001 0.000000e+000 outer loop vertex 3.803274e+001 4.450180e+000 5.200025e+000 vertex 3.805639e+001 4.545071e+000 3.200025e+000 vertex 3.805639e+001 4.545071e+000 5.200025e+000 endloop endfacet facet normal 9.930554e-001 -1.176479e-001 0.000000e+000 outer loop vertex 3.805639e+001 4.545071e+000 5.200025e+000 vertex 3.805639e+001 4.545071e+000 3.200025e+000 vertex 3.806407e+001 4.646369e+000 3.200025e+000 endloop endfacet facet normal 9.975107e-001 -7.051475e-002 0.000000e+000 outer loop vertex 3.805639e+001 4.545071e+000 5.200025e+000 vertex 3.806407e+001 4.646369e+000 3.200025e+000 vertex 3.806407e+001 4.646369e+000 5.200025e+000 endloop endfacet facet normal 9.975664e-001 6.972306e-002 0.000000e+000 outer loop vertex 3.806407e+001 4.646369e+000 5.200025e+000 vertex 3.806407e+001 4.646369e+000 3.200025e+000 vertex 3.805677e+001 4.747995e+000 3.200025e+000 endloop endfacet facet normal 9.946117e-001 1.036698e-001 0.000000e+000 outer loop vertex 3.806407e+001 4.646369e+000 5.200025e+000 vertex 3.805677e+001 4.747995e+000 3.200025e+000 vertex 3.805677e+001 4.747995e+000 5.200025e+000 endloop endfacet facet normal 9.818395e-001 1.897133e-001 0.000000e+000 outer loop vertex 3.805677e+001 4.747995e+000 5.200025e+000 vertex 3.805677e+001 4.747995e+000 3.200025e+000 vertex 3.803732e+001 4.835501e+000 3.200025e+000 endloop endfacet facet normal 9.703803e-001 2.415824e-001 0.000000e+000 outer loop vertex 3.805677e+001 4.747995e+000 5.200025e+000 vertex 3.803732e+001 4.835501e+000 3.200025e+000 vertex 3.803732e+001 4.835501e+000 5.200025e+000 endloop endfacet facet normal 9.387521e-001 3.445934e-001 0.000000e+000 outer loop vertex 3.803732e+001 4.835501e+000 5.200025e+000 vertex 3.803732e+001 4.835501e+000 3.200025e+000 vertex 3.799866e+001 4.932467e+000 3.200025e+000 endloop endfacet facet normal 9.183900e-001 3.956763e-001 0.000000e+000 outer loop vertex 3.803732e+001 4.835501e+000 5.200025e+000 vertex 3.799866e+001 4.932467e+000 3.200025e+000 vertex 3.799866e+001 4.932467e+000 5.200025e+000 endloop endfacet facet normal 8.706439e-001 4.919138e-001 0.000000e+000 outer loop vertex 3.799866e+001 4.932467e+000 5.200025e+000 vertex 3.799866e+001 4.932467e+000 3.200025e+000 vertex 3.794726e+001 5.017816e+000 3.200025e+000 endloop endfacet facet normal 8.434716e-001 5.371737e-001 0.000000e+000 outer loop vertex 3.799866e+001 4.932467e+000 5.200025e+000 vertex 3.794726e+001 5.017816e+000 3.200025e+000 vertex 3.794726e+001 5.017816e+000 5.200025e+000 endloop endfacet facet normal 7.881562e-001 6.154753e-001 0.000000e+000 outer loop vertex 3.794726e+001 5.017816e+000 5.200025e+000 vertex 3.794726e+001 5.017816e+000 3.200025e+000 vertex 3.787234e+001 5.106674e+000 3.200025e+000 endloop endfacet facet normal 7.607512e-001 6.490437e-001 0.000000e+000 outer loop vertex 3.794726e+001 5.017816e+000 5.200025e+000 vertex 3.787234e+001 5.106674e+000 3.200025e+000 vertex 3.787234e+001 5.106674e+000 5.200025e+000 endloop endfacet facet normal 6.514645e-001 7.586791e-001 0.000000e+000 outer loop vertex 3.787234e+001 5.106674e+000 5.200025e+000 vertex 3.787234e+001 5.106674e+000 3.200025e+000 vertex 3.778228e+001 5.183082e+000 3.200025e+000 endloop endfacet facet normal 6.152128e-001 7.883611e-001 0.000000e+000 outer loop vertex 3.787234e+001 5.106674e+000 5.200025e+000 vertex 3.778228e+001 5.183082e+000 3.200025e+000 vertex 3.778228e+001 5.183082e+000 5.200025e+000 endloop endfacet facet normal 5.345650e-001 8.451274e-001 0.000000e+000 outer loop vertex 3.778228e+001 5.183082e+000 5.200025e+000 vertex 3.778228e+001 5.183082e+000 3.200025e+000 vertex 3.769533e+001 5.234879e+000 3.200025e+000 endloop endfacet facet normal 4.898731e-001 8.717938e-001 0.000000e+000 outer loop vertex 3.778228e+001 5.183082e+000 5.200025e+000 vertex 3.769533e+001 5.234879e+000 3.200025e+000 vertex 3.769533e+001 5.234879e+000 5.200025e+000 endloop endfacet facet normal 3.969390e-001 9.178450e-001 0.000000e+000 outer loop vertex 3.769533e+001 5.234879e+000 5.200025e+000 vertex 3.769533e+001 5.234879e+000 3.200025e+000 vertex 3.759322e+001 5.275767e+000 3.200025e+000 endloop endfacet facet normal 3.486993e-001 9.372346e-001 0.000000e+000 outer loop vertex 3.769533e+001 5.234879e+000 5.200025e+000 vertex 3.759322e+001 5.275767e+000 3.200025e+000 vertex 3.759322e+001 5.275767e+000 5.200025e+000 endloop endfacet facet normal 2.503683e-001 9.681507e-001 0.000000e+000 outer loop vertex 3.759322e+001 5.275767e+000 5.200025e+000 vertex 3.759322e+001 5.275767e+000 3.200025e+000 vertex 3.747779e+001 5.302271e+000 3.200025e+000 endloop endfacet facet normal 2.002954e-001 9.797356e-001 0.000000e+000 outer loop vertex 3.759322e+001 5.275767e+000 5.200025e+000 vertex 3.747779e+001 5.302271e+000 3.200025e+000 vertex 3.747779e+001 5.302271e+000 5.200025e+000 endloop endfacet facet normal 1.083893e-001 9.941085e-001 0.000000e+000 outer loop vertex 3.747779e+001 5.302271e+000 5.200025e+000 vertex 3.747779e+001 5.302271e+000 3.200025e+000 vertex 3.733265e+001 5.312755e+000 3.200025e+000 endloop endfacet facet normal 6.668909e-002 9.977738e-001 0.000000e+000 outer loop vertex 3.747779e+001 5.302271e+000 5.200025e+000 vertex 3.733265e+001 5.312755e+000 3.200025e+000 vertex 3.733265e+001 5.312755e+000 5.200025e+000 endloop endfacet facet normal -6.735401e-002 9.977291e-001 0.000000e+000 outer loop vertex 3.733265e+001 5.312755e+000 5.200025e+000 vertex 3.733265e+001 5.312755e+000 3.200025e+000 vertex 3.721776e+001 5.305002e+000 3.200025e+000 endloop endfacet facet normal -9.016066e-002 9.959272e-001 0.000000e+000 outer loop vertex 3.733265e+001 5.312755e+000 5.200025e+000 vertex 3.721776e+001 5.305002e+000 3.200025e+000 vertex 3.721776e+001 5.305002e+000 5.200025e+000 endloop endfacet facet normal -1.652374e-001 9.862538e-001 0.000000e+000 outer loop vertex 3.721776e+001 5.305002e+000 5.200025e+000 vertex 3.721776e+001 5.305002e+000 3.200025e+000 vertex 3.710032e+001 5.282188e+000 3.200025e+000 endloop endfacet facet normal -2.172500e-001 9.761160e-001 0.000000e+000 outer loop vertex 3.721776e+001 5.305002e+000 5.200025e+000 vertex 3.710032e+001 5.282188e+000 3.200025e+000 vertex 3.710032e+001 5.282188e+000 5.200025e+000 endloop endfacet facet normal -3.195608e-001 9.475658e-001 0.000000e+000 outer loop vertex 3.710032e+001 5.282188e+000 5.200025e+000 vertex 3.710032e+001 5.282188e+000 3.200025e+000 vertex 3.699149e+001 5.242303e+000 3.200025e+000 endloop endfacet facet normal -3.698427e-001 9.290944e-001 0.000000e+000 outer loop vertex 3.710032e+001 5.282188e+000 5.200025e+000 vertex 3.699149e+001 5.242303e+000 3.200025e+000 vertex 3.699149e+001 5.242303e+000 5.200025e+000 endloop endfacet facet normal -4.564548e-001 8.897467e-001 0.000000e+000 outer loop vertex 3.699149e+001 5.242303e+000 5.200025e+000 vertex 3.699149e+001 5.242303e+000 3.200025e+000 vertex 3.686221e+001 5.169174e+000 3.200025e+000 endloop endfacet facet normal -4.932535e-001 8.698856e-001 0.000000e+000 outer loop vertex 3.699149e+001 5.242303e+000 5.200025e+000 vertex 3.686221e+001 5.169174e+000 3.200025e+000 vertex 3.686221e+001 5.169174e+000 5.200025e+000 endloop endfacet facet normal -6.164027e-001 7.874311e-001 0.000000e+000 outer loop vertex 3.686221e+001 5.169174e+000 5.200025e+000 vertex 3.686221e+001 5.169174e+000 3.200025e+000 vertex 3.682832e+001 5.142647e+000 3.200025e+000 endloop endfacet facet normal -6.193070e-001 7.851490e-001 0.000000e+000 outer loop vertex 3.686221e+001 5.169174e+000 5.200025e+000 vertex 3.682832e+001 5.142647e+000 3.200025e+000 vertex 3.682832e+001 5.142647e+000 5.200025e+000 endloop endfacet facet normal -6.596248e-001 7.515951e-001 0.000000e+000 outer loop vertex 3.682832e+001 5.142647e+000 5.200025e+000 vertex 3.682832e+001 5.142647e+000 3.200025e+000 vertex 3.673830e+001 5.061723e+000 3.200025e+000 endloop endfacet facet normal -6.955621e-001 7.184660e-001 0.000000e+000 outer loop vertex 3.682832e+001 5.142647e+000 5.200025e+000 vertex 3.673830e+001 5.061723e+000 3.200025e+000 vertex 3.673830e+001 5.061723e+000 5.200025e+000 endloop endfacet facet normal -7.637758e-001 6.454817e-001 0.000000e+000 outer loop vertex 3.673830e+001 5.061723e+000 5.200025e+000 vertex 3.673830e+001 5.061723e+000 3.200025e+000 vertex 3.666818e+001 4.973625e+000 3.200025e+000 endloop endfacet facet normal -7.958753e-001 6.054606e-001 0.000000e+000 outer loop vertex 3.673830e+001 5.061723e+000 5.200025e+000 vertex 3.666818e+001 4.973625e+000 3.200025e+000 vertex 3.666818e+001 4.973625e+000 5.200025e+000 endloop endfacet facet normal -8.538891e-001 5.204550e-001 0.000000e+000 outer loop vertex 3.666818e+001 4.973625e+000 5.200025e+000 vertex 3.666818e+001 4.973625e+000 3.200025e+000 vertex 3.660741e+001 4.868336e+000 3.200025e+000 endloop endfacet facet normal -8.797510e-001 4.754347e-001 0.000000e+000 outer loop vertex 3.666818e+001 4.973625e+000 5.200025e+000 vertex 3.660741e+001 4.868336e+000 3.200025e+000 vertex 3.660741e+001 4.868336e+000 5.200025e+000 endloop endfacet facet normal -9.200154e-001 3.918822e-001 0.000000e+000 outer loop vertex 3.660741e+001 4.868336e+000 5.200025e+000 vertex 3.660741e+001 4.868336e+000 3.200025e+000 vertex 3.655056e+001 4.718160e+000 3.200025e+000 endloop endfacet facet normal -9.353277e-001 3.537825e-001 0.000000e+000 outer loop vertex 3.660741e+001 4.868336e+000 5.200025e+000 vertex 3.655056e+001 4.718160e+000 3.200025e+000 vertex 3.655056e+001 4.718160e+000 5.200025e+000 endloop endfacet facet normal 3.080648e-001 9.513654e-001 0.000000e+000 outer loop vertex 3.655056e+001 4.718160e+000 5.200025e+000 vertex 3.655056e+001 4.718160e+000 3.200025e+000 vertex 3.651631e+001 4.729245e+000 3.200025e+000 endloop endfacet facet normal 3.424894e-001 9.395217e-001 0.000000e+000 outer loop vertex 3.655056e+001 4.718160e+000 5.200025e+000 vertex 3.651631e+001 4.729245e+000 3.200025e+000 vertex 3.651631e+001 4.729245e+000 5.200025e+000 endloop endfacet facet normal 4.250745e-001 9.051584e-001 0.000000e+000 outer loop vertex 3.651631e+001 4.729245e+000 5.200025e+000 vertex 3.651631e+001 4.729245e+000 3.200025e+000 vertex 3.649402e+001 4.740480e+000 3.200025e+000 endloop endfacet facet normal 4.726671e-001 8.812410e-001 0.000000e+000 outer loop vertex 3.651631e+001 4.729245e+000 5.200025e+000 vertex 3.649402e+001 4.740480e+000 3.200025e+000 vertex 3.649402e+001 4.740480e+000 5.200025e+000 endloop endfacet facet normal 5.633831e-001 8.261958e-001 0.000000e+000 outer loop vertex 3.649402e+001 4.740480e+000 5.200025e+000 vertex 3.649402e+001 4.740480e+000 3.200025e+000 vertex 3.647124e+001 4.756949e+000 3.200025e+000 endloop endfacet facet normal 6.065110e-001 7.950751e-001 0.000000e+000 outer loop vertex 3.649402e+001 4.740480e+000 5.200025e+000 vertex 3.647124e+001 4.756949e+000 3.200025e+000 vertex 3.647124e+001 4.756949e+000 5.200025e+000 endloop endfacet facet normal 6.870075e-001 7.266504e-001 0.000000e+000 outer loop vertex 3.647124e+001 4.756949e+000 5.200025e+000 vertex 3.647124e+001 4.756949e+000 3.200025e+000 vertex 3.645226e+001 4.775826e+000 3.200025e+000 endloop endfacet facet normal 7.244026e-001 6.893772e-001 0.000000e+000 outer loop vertex 3.647124e+001 4.756949e+000 5.200025e+000 vertex 3.645226e+001 4.775826e+000 3.200025e+000 vertex 3.645226e+001 4.775826e+000 5.200025e+000 endloop endfacet facet normal 7.915173e-001 6.111469e-001 0.000000e+000 outer loop vertex 3.645226e+001 4.775826e+000 5.200025e+000 vertex 3.645226e+001 4.775826e+000 3.200025e+000 vertex 3.643568e+001 4.798648e+000 3.200025e+000 endloop endfacet facet normal 8.214101e-001 5.703381e-001 0.000000e+000 outer loop vertex 3.645226e+001 4.775826e+000 5.200025e+000 vertex 3.643568e+001 4.798648e+000 3.200025e+000 vertex 3.643568e+001 4.798648e+000 5.200025e+000 endloop endfacet facet normal 8.743837e-001 4.852350e-001 0.000000e+000 outer loop vertex 3.643568e+001 4.798648e+000 5.200025e+000 vertex 3.643568e+001 4.798648e+000 3.200025e+000 vertex 3.641783e+001 4.832980e+000 3.200025e+000 endloop endfacet facet normal 8.975195e-001 4.409749e-001 0.000000e+000 outer loop vertex 3.643568e+001 4.798648e+000 5.200025e+000 vertex 3.641783e+001 4.832980e+000 3.200025e+000 vertex 3.641783e+001 4.832980e+000 5.200025e+000 endloop endfacet facet normal 9.388413e-001 3.443501e-001 0.000000e+000 outer loop vertex 3.641783e+001 4.832980e+000 5.200025e+000 vertex 3.641783e+001 4.832980e+000 3.200025e+000 vertex 3.640246e+001 4.879472e+000 3.200025e+000 endloop endfacet facet normal 9.564931e-001 2.917551e-001 0.000000e+000 outer loop vertex 3.641783e+001 4.832980e+000 5.200025e+000 vertex 3.640246e+001 4.879472e+000 3.200025e+000 vertex 3.640246e+001 4.879472e+000 5.200025e+000 endloop endfacet facet normal 9.803663e-001 1.971848e-001 0.000000e+000 outer loop vertex 3.640246e+001 4.879472e+000 5.200025e+000 vertex 3.640246e+001 4.879472e+000 3.200025e+000 vertex 3.639240e+001 4.936398e+000 3.200025e+000 endloop endfacet facet normal 9.878334e-001 1.555155e-001 0.000000e+000 outer loop vertex 3.640246e+001 4.879472e+000 5.200025e+000 vertex 3.639240e+001 4.936398e+000 3.200025e+000 vertex 3.639240e+001 4.936398e+000 5.200025e+000 endloop endfacet facet normal 9.965653e-001 8.281031e-002 0.000000e+000 outer loop vertex 3.639240e+001 4.936398e+000 5.200025e+000 vertex 3.639240e+001 4.936398e+000 3.200025e+000 vertex 3.638839e+001 5.012079e+000 3.200025e+000 endloop endfacet facet normal 9.986539e-001 5.186874e-002 0.000000e+000 outer loop vertex 3.639240e+001 4.936398e+000 5.200025e+000 vertex 3.638839e+001 5.012079e+000 3.200025e+000 vertex 3.638839e+001 5.012079e+000 5.200025e+000 endloop endfacet facet normal 9.974722e-001 -7.105783e-002 0.000000e+000 outer loop vertex 3.638839e+001 5.012079e+000 5.200025e+000 vertex 3.638839e+001 5.012079e+000 3.200025e+000 vertex 3.639725e+001 5.133657e+000 3.200025e+000 endloop endfacet facet normal 9.942322e-001 -1.072491e-001 0.000000e+000 outer loop vertex 3.638839e+001 5.012079e+000 5.200025e+000 vertex 3.639725e+001 5.133657e+000 3.200025e+000 vertex 3.639725e+001 5.133657e+000 5.200025e+000 endloop endfacet facet normal 9.807116e-001 -1.954605e-001 0.000000e+000 outer loop vertex 3.639725e+001 5.133657e+000 5.200025e+000 vertex 3.639725e+001 5.133657e+000 3.200025e+000 vertex 3.642010e+001 5.234116e+000 3.200025e+000 endloop endfacet facet normal 9.689476e-001 -2.472660e-001 0.000000e+000 outer loop vertex 3.639725e+001 5.133657e+000 5.200025e+000 vertex 3.642010e+001 5.234116e+000 3.200025e+000 vertex 3.642010e+001 5.234116e+000 5.200025e+000 endloop endfacet facet normal 9.381226e-001 -3.463034e-001 0.000000e+000 outer loop vertex 3.642010e+001 5.234116e+000 5.200025e+000 vertex 3.642010e+001 5.234116e+000 3.200025e+000 vertex 3.646354e+001 5.343081e+000 3.200025e+000 endloop endfacet facet normal 9.192802e-001 -3.936036e-001 0.000000e+000 outer loop vertex 3.642010e+001 5.234116e+000 5.200025e+000 vertex 3.646354e+001 5.343081e+000 3.200025e+000 vertex 3.646354e+001 5.343081e+000 5.200025e+000 endloop endfacet facet normal 8.735704e-001 -4.866977e-001 0.000000e+000 outer loop vertex 3.646354e+001 5.343081e+000 5.200025e+000 vertex 3.646354e+001 5.343081e+000 3.200025e+000 vertex 3.652083e+001 5.440029e+000 3.200025e+000 endloop endfacet facet normal 8.464983e-001 -5.323914e-001 0.000000e+000 outer loop vertex 3.646354e+001 5.343081e+000 5.200025e+000 vertex 3.652083e+001 5.440029e+000 3.200025e+000 vertex 3.652083e+001 5.440029e+000 5.200025e+000 endloop endfacet facet normal 7.877530e-001 -6.159912e-001 0.000000e+000 outer loop vertex 3.652083e+001 5.440029e+000 5.200025e+000 vertex 3.652083e+001 5.440029e+000 3.200025e+000 vertex 3.659898e+001 5.534632e+000 3.200025e+000 endloop endfacet facet normal 7.563926e-001 -6.541179e-001 0.000000e+000 outer loop vertex 3.652083e+001 5.440029e+000 5.200025e+000 vertex 3.659898e+001 5.534632e+000 3.200025e+000 vertex 3.659898e+001 5.534632e+000 5.200025e+000 endloop endfacet facet normal 6.938108e-001 -7.201574e-001 0.000000e+000 outer loop vertex 3.659898e+001 5.534632e+000 5.200025e+000 vertex 3.659898e+001 5.534632e+000 3.200025e+000 vertex 3.670427e+001 5.628633e+000 3.200025e+000 endloop endfacet facet normal 6.630855e-001 -7.485437e-001 0.000000e+000 outer loop vertex 3.659898e+001 5.534632e+000 5.200025e+000 vertex 3.670427e+001 5.628633e+000 3.200025e+000 vertex 3.670427e+001 5.628633e+000 5.200025e+000 endloop endfacet facet normal 5.513240e-001 -8.342912e-001 0.000000e+000 outer loop vertex 3.670427e+001 5.628633e+000 5.200025e+000 vertex 3.670427e+001 5.628633e+000 3.200025e+000 vertex 3.687299e+001 5.737394e+000 3.200025e+000 endloop endfacet facet normal 5.083891e-001 -8.611275e-001 0.000000e+000 outer loop vertex 3.670427e+001 5.628633e+000 5.200025e+000 vertex 3.687299e+001 5.737394e+000 3.200025e+000 vertex 3.687299e+001 5.737394e+000 5.200025e+000 endloop endfacet facet normal 4.144154e-001 -9.100878e-001 0.000000e+000 outer loop vertex 3.687299e+001 5.737394e+000 5.200025e+000 vertex 3.687299e+001 5.737394e+000 3.200025e+000 vertex 3.702763e+001 5.803219e+000 3.200025e+000 endloop endfacet facet normal 3.631288e-001 -9.317390e-001 0.000000e+000 outer loop vertex 3.687299e+001 5.737394e+000 5.200025e+000 vertex 3.702763e+001 5.803219e+000 3.200025e+000 vertex 3.702763e+001 5.803219e+000 5.200025e+000 endloop endfacet facet normal 2.617325e-001 -9.651405e-001 0.000000e+000 outer loop vertex 3.702763e+001 5.803219e+000 5.200025e+000 vertex 3.702763e+001 5.803219e+000 3.200025e+000 vertex 3.717976e+001 5.839212e+000 3.200025e+000 endloop endfacet facet normal 2.117635e-001 -9.773209e-001 0.000000e+000 outer loop vertex 3.702763e+001 5.803219e+000 5.200025e+000 vertex 3.717976e+001 5.839212e+000 3.200025e+000 vertex 3.717976e+001 5.839212e+000 5.200025e+000 endloop endfacet facet normal 1.139678e-001 -9.934844e-001 0.000000e+000 outer loop vertex 3.717976e+001 5.839212e+000 5.200025e+000 vertex 3.717976e+001 5.839212e+000 3.200025e+000 vertex 3.735376e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 6.619663e-002 -9.978066e-001 0.000000e+000 outer loop vertex 3.717976e+001 5.839212e+000 5.200025e+000 vertex 3.735376e+001 5.853295e+000 3.200025e+000 vertex 3.735376e+001 5.853295e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 5.200025e+000 vertex 3.735376e+001 5.853295e+000 5.200025e+000 vertex 3.898637e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 3.200025e+000 vertex 3.735376e+001 5.853295e+000 5.200025e+000 vertex 3.735376e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal -9.444255e-001 3.287258e-001 0.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 5.200025e+000 vertex 3.898637e+001 5.853295e+000 5.200025e+000 vertex 3.798890e+001 2.987586e+000 3.200025e+000 endloop endfacet facet normal -9.444255e-001 3.287258e-001 0.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 3.200025e+000 vertex 3.898637e+001 5.853295e+000 5.200025e+000 vertex 3.898637e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 1.549440e-001 9.879233e-001 0.000000e+000 outer loop vertex 3.664262e+001 3.198734e+000 5.200025e+000 vertex 3.798890e+001 2.987586e+000 5.200025e+000 vertex 3.664262e+001 3.198734e+000 3.200025e+000 endloop endfacet facet normal 1.549440e-001 9.879233e-001 0.000000e+000 outer loop vertex 3.664262e+001 3.198734e+000 3.200025e+000 vertex 3.798890e+001 2.987586e+000 5.200025e+000 vertex 3.798890e+001 2.987586e+000 3.200025e+000 endloop endfacet facet normal 1.137289e-001 9.935118e-001 0.000000e+000 outer loop vertex 3.664262e+001 3.198734e+000 5.200025e+000 vertex 3.664262e+001 3.198734e+000 3.200025e+000 vertex 3.660639e+001 3.202881e+000 3.200025e+000 endloop endfacet facet normal 9.784563e-002 9.952016e-001 0.000000e+000 outer loop vertex 3.664262e+001 3.198734e+000 5.200025e+000 vertex 3.660639e+001 3.202881e+000 3.200025e+000 vertex 3.660639e+001 3.202881e+000 5.200025e+000 endloop endfacet facet normal 6.518985e-002 9.978729e-001 0.000000e+000 outer loop vertex 3.660639e+001 3.202881e+000 5.200025e+000 vertex 3.660639e+001 3.202881e+000 3.200025e+000 vertex 3.656998e+001 3.204647e+000 3.200025e+000 endloop endfacet facet normal 4.841512e-002 9.988273e-001 0.000000e+000 outer loop vertex 3.660639e+001 3.202881e+000 5.200025e+000 vertex 3.656998e+001 3.204647e+000 3.200025e+000 vertex 3.656998e+001 3.204647e+000 5.200025e+000 endloop endfacet facet normal -8.029469e-002 9.967712e-001 0.000000e+000 outer loop vertex 3.656998e+001 3.204647e+000 5.200025e+000 vertex 3.656998e+001 3.204647e+000 3.200025e+000 vertex 3.649423e+001 3.198350e+000 3.200025e+000 endloop endfacet facet normal -1.236667e-001 9.923238e-001 0.000000e+000 outer loop vertex 3.656998e+001 3.204647e+000 5.200025e+000 vertex 3.649423e+001 3.198350e+000 3.200025e+000 vertex 3.649423e+001 3.198350e+000 5.200025e+000 endloop endfacet facet normal -2.181754e-001 9.759095e-001 0.000000e+000 outer loop vertex 3.649423e+001 3.198350e+000 5.200025e+000 vertex 3.649423e+001 3.198350e+000 3.200025e+000 vertex 3.643799e+001 3.184169e+000 3.200025e+000 endloop endfacet facet normal -2.691686e-001 9.630930e-001 0.000000e+000 outer loop vertex 3.649423e+001 3.198350e+000 5.200025e+000 vertex 3.643799e+001 3.184169e+000 3.200025e+000 vertex 3.643799e+001 3.184169e+000 5.200025e+000 endloop endfacet facet normal -3.672135e-001 9.301367e-001 0.000000e+000 outer loop vertex 3.643799e+001 3.184169e+000 5.200025e+000 vertex 3.643799e+001 3.184169e+000 3.200025e+000 vertex 3.637543e+001 3.157461e+000 3.200025e+000 endloop endfacet facet normal -4.143118e-001 9.101350e-001 0.000000e+000 outer loop vertex 3.643799e+001 3.184169e+000 5.200025e+000 vertex 3.637543e+001 3.157461e+000 3.200025e+000 vertex 3.637543e+001 3.157461e+000 5.200025e+000 endloop endfacet facet normal -5.055244e-001 8.628123e-001 0.000000e+000 outer loop vertex 3.637543e+001 3.157461e+000 5.200025e+000 vertex 3.637543e+001 3.157461e+000 3.200025e+000 vertex 3.631043e+001 3.116841e+000 3.200025e+000 endloop endfacet facet normal -5.496045e-001 8.354250e-001 0.000000e+000 outer loop vertex 3.637543e+001 3.157461e+000 5.200025e+000 vertex 3.631043e+001 3.116841e+000 3.200025e+000 vertex 3.631043e+001 3.116841e+000 5.200025e+000 endloop endfacet facet normal -6.318345e-001 7.751034e-001 0.000000e+000 outer loop vertex 3.631043e+001 3.116841e+000 5.200025e+000 vertex 3.631043e+001 3.116841e+000 3.200025e+000 vertex 3.624706e+001 3.062424e+000 3.200025e+000 endloop endfacet facet normal -6.700756e-001 7.422929e-001 0.000000e+000 outer loop vertex 3.631043e+001 3.116841e+000 5.200025e+000 vertex 3.624706e+001 3.062424e+000 3.200025e+000 vertex 3.624706e+001 3.062424e+000 5.200025e+000 endloop endfacet facet normal -7.332622e-001 6.799459e-001 0.000000e+000 outer loop vertex 3.624706e+001 3.062424e+000 5.200025e+000 vertex 3.624706e+001 3.062424e+000 3.200025e+000 vertex 3.617809e+001 2.982518e+000 3.200025e+000 endloop endfacet facet normal -7.589482e-001 6.511511e-001 0.000000e+000 outer loop vertex 3.624706e+001 3.062424e+000 5.200025e+000 vertex 3.617809e+001 2.982518e+000 3.200025e+000 vertex 3.617809e+001 2.982518e+000 5.200025e+000 endloop endfacet facet normal -8.475689e-001 5.306854e-001 0.000000e+000 outer loop vertex 3.617809e+001 2.982518e+000 5.200025e+000 vertex 3.617809e+001 2.982518e+000 3.200025e+000 vertex 3.605597e+001 2.775135e+000 3.200025e+000 endloop endfacet facet normal -8.722842e-001 4.889992e-001 0.000000e+000 outer loop vertex 3.617809e+001 2.982518e+000 5.200025e+000 vertex 3.605597e+001 2.775135e+000 3.200025e+000 vertex 3.605597e+001 2.775135e+000 5.200025e+000 endloop endfacet facet normal -9.028624e-001 4.299298e-001 0.000000e+000 outer loop vertex 3.605597e+001 2.775135e+000 5.200025e+000 vertex 3.605597e+001 2.775135e+000 3.200025e+000 vertex 3.595596e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal -9.105287e-001 4.134459e-001 0.000000e+000 outer loop vertex 3.605597e+001 2.775135e+000 5.200025e+000 vertex 3.595596e+001 2.555998e+000 3.200025e+000 vertex 3.595596e+001 2.555998e+000 5.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.796694e+001 2.555998e+000 5.200025e+000 vertex 3.595596e+001 2.555998e+000 5.200025e+000 vertex 3.796694e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 3.796694e+001 2.555998e+000 3.200025e+000 vertex 3.595596e+001 2.555998e+000 5.200025e+000 vertex 3.595596e+001 2.555998e+000 3.200025e+000 endloop endfacet facet normal 3.787623e-002 -9.992824e-001 0.000000e+000 outer loop vertex 3.796694e+001 2.555998e+000 5.200025e+000 vertex 3.796694e+001 2.555998e+000 3.200025e+000 vertex 3.810260e+001 2.561219e+000 3.200025e+000 endloop endfacet facet normal 5.614331e-002 -9.984227e-001 0.000000e+000 outer loop vertex 3.796694e+001 2.555998e+000 5.200025e+000 vertex 3.810260e+001 2.561219e+000 3.200025e+000 vertex 3.810260e+001 2.561219e+000 5.200025e+000 endloop endfacet facet normal 1.291741e-001 -9.916219e-001 0.000000e+000 outer loop vertex 3.810260e+001 2.561219e+000 5.200025e+000 vertex 3.810260e+001 2.561219e+000 3.200025e+000 vertex 3.833492e+001 2.598041e+000 3.200025e+000 endloop endfacet facet normal 1.837360e-001 -9.829756e-001 0.000000e+000 outer loop vertex 3.810260e+001 2.561219e+000 5.200025e+000 vertex 3.833492e+001 2.598041e+000 3.200025e+000 vertex 3.833492e+001 2.598041e+000 5.200025e+000 endloop endfacet facet normal 2.866869e-001 -9.580243e-001 0.000000e+000 outer loop vertex 3.833492e+001 2.598041e+000 5.200025e+000 vertex 3.833492e+001 2.598041e+000 3.200025e+000 vertex 3.850486e+001 2.653722e+000 3.200025e+000 endloop endfacet facet normal 3.351820e-001 -9.421534e-001 0.000000e+000 outer loop vertex 3.833492e+001 2.598041e+000 5.200025e+000 vertex 3.850486e+001 2.653722e+000 3.200025e+000 vertex 3.850486e+001 2.653722e+000 5.200025e+000 endloop endfacet facet normal 4.337839e-001 -9.010170e-001 0.000000e+000 outer loop vertex 3.850486e+001 2.653722e+000 5.200025e+000 vertex 3.850486e+001 2.653722e+000 3.200025e+000 vertex 3.866585e+001 2.737305e+000 3.200025e+000 endloop endfacet facet normal 4.836807e-001 -8.752446e-001 0.000000e+000 outer loop vertex 3.850486e+001 2.653722e+000 5.200025e+000 vertex 3.866585e+001 2.737305e+000 3.200025e+000 vertex 3.866585e+001 2.737305e+000 5.200025e+000 endloop endfacet facet normal 5.477461e-001 -8.366446e-001 0.000000e+000 outer loop vertex 3.866585e+001 2.737305e+000 5.200025e+000 vertex 3.866585e+001 2.737305e+000 3.200025e+000 vertex 3.870705e+001 2.764786e+000 3.200025e+000 endloop endfacet facet normal 5.634010e-001 -8.261836e-001 0.000000e+000 outer loop vertex 3.866585e+001 2.737305e+000 5.200025e+000 vertex 3.870705e+001 2.764786e+000 3.200025e+000 vertex 3.870705e+001 2.764786e+000 5.200025e+000 endloop endfacet facet normal 6.225181e-001 -7.826054e-001 0.000000e+000 outer loop vertex 3.870705e+001 2.764786e+000 5.200025e+000 vertex 3.870705e+001 2.764786e+000 3.200025e+000 vertex 3.884526e+001 2.880932e+000 3.200025e+000 endloop endfacet facet normal 6.644500e-001 -7.473328e-001 0.000000e+000 outer loop vertex 3.870705e+001 2.764786e+000 5.200025e+000 vertex 3.884526e+001 2.880932e+000 3.200025e+000 vertex 3.884526e+001 2.880932e+000 5.200025e+000 endloop endfacet facet normal 7.395979e-001 -6.730490e-001 0.000000e+000 outer loop vertex 3.884526e+001 2.880932e+000 5.200025e+000 vertex 3.884526e+001 2.880932e+000 3.200025e+000 vertex 3.895345e+001 3.008364e+000 3.200025e+000 endloop endfacet facet normal 7.730812e-001 -6.343071e-001 0.000000e+000 outer loop vertex 3.884526e+001 2.880932e+000 5.200025e+000 vertex 3.895345e+001 3.008364e+000 3.200025e+000 vertex 3.895345e+001 3.008364e+000 5.200025e+000 endloop endfacet facet normal 8.330182e-001 -5.532457e-001 0.000000e+000 outer loop vertex 3.895345e+001 3.008364e+000 5.200025e+000 vertex 3.895345e+001 3.008364e+000 3.200025e+000 vertex 3.905618e+001 3.170650e+000 3.200025e+000 endloop endfacet facet normal 8.595781e-001 -5.110044e-001 0.000000e+000 outer loop vertex 3.895345e+001 3.008364e+000 5.200025e+000 vertex 3.905618e+001 3.170650e+000 3.200025e+000 vertex 3.905618e+001 3.170650e+000 5.200025e+000 endloop endfacet facet normal 9.000982e-001 -4.356871e-001 0.000000e+000 outer loop vertex 3.905618e+001 3.170650e+000 5.200025e+000 vertex 3.905618e+001 3.170650e+000 3.200025e+000 vertex 3.914515e+001 3.367653e+000 3.200025e+000 endloop endfacet facet normal 9.151232e-001 -4.031743e-001 0.000000e+000 outer loop vertex 3.905618e+001 3.170650e+000 5.200025e+000 vertex 3.914515e+001 3.367653e+000 3.200025e+000 vertex 3.914515e+001 3.367653e+000 5.200025e+000 endloop endfacet facet normal 9.444622e-001 -3.286202e-001 0.000000e+000 outer loop vertex 4.001002e+001 5.853295e+000 5.200025e+000 vertex 3.914515e+001 3.367653e+000 5.200025e+000 vertex 4.001002e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 9.444622e-001 -3.286202e-001 0.000000e+000 outer loop vertex 4.001002e+001 5.853295e+000 3.200025e+000 vertex 3.914515e+001 3.367653e+000 5.200025e+000 vertex 3.914515e+001 3.367653e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 4.108012e+001 5.853295e+000 5.200025e+000 vertex 4.001002e+001 5.853295e+000 5.200025e+000 vertex 4.108012e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop vertex 4.108012e+001 5.853295e+000 3.200025e+000 vertex 4.001002e+001 5.853295e+000 5.200025e+000 vertex 4.001002e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 8.747022e-001 -4.846607e-001 0.000000e+000 outer loop vertex 4.146947e+001 6.555998e+000 5.200025e+000 vertex 4.108012e+001 5.853295e+000 5.200025e+000 vertex 4.146947e+001 6.555998e+000 3.200025e+000 endloop endfacet facet normal 8.747022e-001 -4.846607e-001 0.000000e+000 outer loop vertex 4.146947e+001 6.555998e+000 3.200025e+000 vertex 4.108012e+001 5.853295e+000 5.200025e+000 vertex 4.108012e+001 5.853295e+000 3.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.739110e+001 3.983120e+000 5.200025e+000 vertex 3.757827e+001 4.031086e+000 5.200025e+000 vertex 3.771231e+001 4.090940e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.895345e+001 3.008364e+000 5.200025e+000 vertex 3.905618e+001 3.170650e+000 5.200025e+000 vertex 3.914515e+001 3.367653e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.595596e+001 2.555998e+000 5.200025e+000 vertex 3.796694e+001 2.555998e+000 5.200025e+000 vertex 3.798890e+001 2.987586e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.715083e+001 3.961946e+000 5.200025e+000 vertex 3.682832e+001 5.142647e+000 5.200025e+000 vertex 3.711981e+001 3.961403e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.711981e+001 3.961403e+000 5.200025e+000 vertex 3.682832e+001 5.142647e+000 5.200025e+000 vertex 3.673830e+001 5.061723e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.711981e+001 3.961403e+000 5.200025e+000 vertex 3.673830e+001 5.061723e+000 5.200025e+000 vertex 3.685820e+001 3.981283e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.666818e+001 4.973625e+000 5.200025e+000 vertex 3.660741e+001 4.868336e+000 5.200025e+000 vertex 3.655056e+001 4.718160e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.850486e+001 2.653722e+000 5.200025e+000 vertex 3.798890e+001 2.987586e+000 5.200025e+000 vertex 3.833492e+001 2.598041e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.833492e+001 2.598041e+000 5.200025e+000 vertex 3.798890e+001 2.987586e+000 5.200025e+000 vertex 3.796694e+001 2.555998e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.833492e+001 2.598041e+000 5.200025e+000 vertex 3.796694e+001 2.555998e+000 5.200025e+000 vertex 3.810260e+001 2.561219e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.771231e+001 4.090940e+000 5.200025e+000 vertex 3.783687e+001 4.175931e+000 5.200025e+000 vertex 3.721776e+001 5.305002e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.721776e+001 5.305002e+000 5.200025e+000 vertex 3.783687e+001 4.175931e+000 5.200025e+000 vertex 3.789184e+001 4.225810e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.721776e+001 5.305002e+000 5.200025e+000 vertex 3.789184e+001 4.225810e+000 5.200025e+000 vertex 3.733265e+001 5.312755e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.733265e+001 5.312755e+000 5.200025e+000 vertex 3.789184e+001 4.225810e+000 5.200025e+000 vertex 3.795374e+001 4.298023e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.733265e+001 5.312755e+000 5.200025e+000 vertex 3.795374e+001 4.298023e+000 5.200025e+000 vertex 3.747779e+001 5.302271e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.747779e+001 5.302271e+000 5.200025e+000 vertex 3.795374e+001 4.298023e+000 5.200025e+000 vertex 3.800050e+001 4.373044e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.747779e+001 5.302271e+000 5.200025e+000 vertex 3.800050e+001 4.373044e+000 5.200025e+000 vertex 3.759322e+001 5.275767e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.759322e+001 5.275767e+000 5.200025e+000 vertex 3.800050e+001 4.373044e+000 5.200025e+000 vertex 3.803274e+001 4.450180e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.759322e+001 5.275767e+000 5.200025e+000 vertex 3.803274e+001 4.450180e+000 5.200025e+000 vertex 3.769533e+001 5.234879e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.769533e+001 5.234879e+000 5.200025e+000 vertex 3.803274e+001 4.450180e+000 5.200025e+000 vertex 3.805639e+001 4.545071e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.769533e+001 5.234879e+000 5.200025e+000 vertex 3.805639e+001 4.545071e+000 5.200025e+000 vertex 3.778228e+001 5.183082e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.778228e+001 5.183082e+000 5.200025e+000 vertex 3.805639e+001 4.545071e+000 5.200025e+000 vertex 3.806407e+001 4.646369e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.778228e+001 5.183082e+000 5.200025e+000 vertex 3.806407e+001 4.646369e+000 5.200025e+000 vertex 3.787234e+001 5.106674e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.787234e+001 5.106674e+000 5.200025e+000 vertex 3.806407e+001 4.646369e+000 5.200025e+000 vertex 3.805677e+001 4.747995e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.787234e+001 5.106674e+000 5.200025e+000 vertex 3.805677e+001 4.747995e+000 5.200025e+000 vertex 3.794726e+001 5.017816e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.794726e+001 5.017816e+000 5.200025e+000 vertex 3.805677e+001 4.747995e+000 5.200025e+000 vertex 3.803732e+001 4.835501e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.794726e+001 5.017816e+000 5.200025e+000 vertex 3.803732e+001 4.835501e+000 5.200025e+000 vertex 3.799866e+001 4.932467e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.715083e+001 3.961946e+000 5.200025e+000 vertex 3.739110e+001 3.983120e+000 5.200025e+000 vertex 3.682832e+001 5.142647e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.682832e+001 5.142647e+000 5.200025e+000 vertex 3.739110e+001 3.983120e+000 5.200025e+000 vertex 3.771231e+001 4.090940e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.682832e+001 5.142647e+000 5.200025e+000 vertex 3.771231e+001 4.090940e+000 5.200025e+000 vertex 3.686221e+001 5.169174e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.686221e+001 5.169174e+000 5.200025e+000 vertex 3.771231e+001 4.090940e+000 5.200025e+000 vertex 3.721776e+001 5.305002e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.686221e+001 5.169174e+000 5.200025e+000 vertex 3.721776e+001 5.305002e+000 5.200025e+000 vertex 3.699149e+001 5.242303e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.699149e+001 5.242303e+000 5.200025e+000 vertex 3.721776e+001 5.305002e+000 5.200025e+000 vertex 3.710032e+001 5.282188e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 5.200025e+000 vertex 3.664262e+001 3.198734e+000 5.200025e+000 vertex 3.595596e+001 2.555998e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.595596e+001 2.555998e+000 5.200025e+000 vertex 3.664262e+001 3.198734e+000 5.200025e+000 vertex 3.660639e+001 3.202881e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.595596e+001 2.555998e+000 5.200025e+000 vertex 3.660639e+001 3.202881e+000 5.200025e+000 vertex 3.605597e+001 2.775135e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.605597e+001 2.775135e+000 5.200025e+000 vertex 3.660639e+001 3.202881e+000 5.200025e+000 vertex 3.656998e+001 3.204647e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.605597e+001 2.775135e+000 5.200025e+000 vertex 3.656998e+001 3.204647e+000 5.200025e+000 vertex 3.617809e+001 2.982518e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.617809e+001 2.982518e+000 5.200025e+000 vertex 3.656998e+001 3.204647e+000 5.200025e+000 vertex 3.649423e+001 3.198350e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.617809e+001 2.982518e+000 5.200025e+000 vertex 3.649423e+001 3.198350e+000 5.200025e+000 vertex 3.624706e+001 3.062424e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.624706e+001 3.062424e+000 5.200025e+000 vertex 3.649423e+001 3.198350e+000 5.200025e+000 vertex 3.643799e+001 3.184169e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.624706e+001 3.062424e+000 5.200025e+000 vertex 3.643799e+001 3.184169e+000 5.200025e+000 vertex 3.631043e+001 3.116841e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.631043e+001 3.116841e+000 5.200025e+000 vertex 3.643799e+001 3.184169e+000 5.200025e+000 vertex 3.637543e+001 3.157461e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.850486e+001 2.653722e+000 5.200025e+000 vertex 3.866585e+001 2.737305e+000 5.200025e+000 vertex 3.798890e+001 2.987586e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 5.200025e+000 vertex 3.866585e+001 2.737305e+000 5.200025e+000 vertex 3.870705e+001 2.764786e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 5.200025e+000 vertex 3.870705e+001 2.764786e+000 5.200025e+000 vertex 3.884526e+001 2.880932e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.673830e+001 5.061723e+000 5.200025e+000 vertex 3.666818e+001 4.973625e+000 5.200025e+000 vertex 3.685820e+001 3.981283e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.685820e+001 3.981283e+000 5.200025e+000 vertex 3.666818e+001 4.973625e+000 5.200025e+000 vertex 3.655056e+001 4.718160e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.685820e+001 3.981283e+000 5.200025e+000 vertex 3.655056e+001 4.718160e+000 5.200025e+000 vertex 3.663758e+001 4.035502e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.663758e+001 4.035502e+000 5.200025e+000 vertex 3.655056e+001 4.718160e+000 5.200025e+000 vertex 3.651631e+001 4.729245e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.663758e+001 4.035502e+000 5.200025e+000 vertex 3.651631e+001 4.729245e+000 5.200025e+000 vertex 3.645763e+001 4.109829e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.645763e+001 4.109829e+000 5.200025e+000 vertex 3.651631e+001 4.729245e+000 5.200025e+000 vertex 3.625664e+001 4.236741e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.625664e+001 4.236741e+000 5.200025e+000 vertex 3.651631e+001 4.729245e+000 5.200025e+000 vertex 3.649402e+001 4.740480e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.625664e+001 4.236741e+000 5.200025e+000 vertex 3.649402e+001 4.740480e+000 5.200025e+000 vertex 3.612392e+001 4.354509e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.612392e+001 4.354509e+000 5.200025e+000 vertex 3.649402e+001 4.740480e+000 5.200025e+000 vertex 3.647124e+001 4.756949e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.612392e+001 4.354509e+000 5.200025e+000 vertex 3.647124e+001 4.756949e+000 5.200025e+000 vertex 3.602639e+001 4.474357e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.758270e+001 6.550544e+000 5.200025e+000 vertex 3.714959e+001 6.493544e+000 5.200025e+000 vertex 3.776762e+001 6.555998e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.776762e+001 6.555998e+000 5.200025e+000 vertex 3.714959e+001 6.493544e+000 5.200025e+000 vertex 3.735376e+001 5.853295e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.776762e+001 6.555998e+000 5.200025e+000 vertex 3.735376e+001 5.853295e+000 5.200025e+000 vertex 4.146947e+001 6.555998e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 4.146947e+001 6.555998e+000 5.200025e+000 vertex 3.735376e+001 5.853295e+000 5.200025e+000 vertex 3.898637e+001 5.853295e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.884526e+001 2.880932e+000 5.200025e+000 vertex 3.895345e+001 3.008364e+000 5.200025e+000 vertex 3.798890e+001 2.987586e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 5.200025e+000 vertex 3.895345e+001 3.008364e+000 5.200025e+000 vertex 3.914515e+001 3.367653e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.798890e+001 2.987586e+000 5.200025e+000 vertex 3.914515e+001 3.367653e+000 5.200025e+000 vertex 3.898637e+001 5.853295e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 5.200025e+000 vertex 3.914515e+001 3.367653e+000 5.200025e+000 vertex 4.001002e+001 5.853295e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.898637e+001 5.853295e+000 5.200025e+000 vertex 4.001002e+001 5.853295e+000 5.200025e+000 vertex 4.146947e+001 6.555998e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 4.146947e+001 6.555998e+000 5.200025e+000 vertex 4.001002e+001 5.853295e+000 5.200025e+000 vertex 4.108012e+001 5.853295e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.647124e+001 4.756949e+000 5.200025e+000 vertex 3.645226e+001 4.775826e+000 5.200025e+000 vertex 3.602639e+001 4.474357e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.602639e+001 4.474357e+000 5.200025e+000 vertex 3.645226e+001 4.775826e+000 5.200025e+000 vertex 3.643568e+001 4.798648e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.602639e+001 4.474357e+000 5.200025e+000 vertex 3.643568e+001 4.798648e+000 5.200025e+000 vertex 3.594708e+001 4.611193e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.594708e+001 4.611193e+000 5.200025e+000 vertex 3.643568e+001 4.798648e+000 5.200025e+000 vertex 3.641783e+001 4.832980e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.594708e+001 4.611193e+000 5.200025e+000 vertex 3.641783e+001 4.832980e+000 5.200025e+000 vertex 3.589002e+001 4.763933e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.589002e+001 4.763933e+000 5.200025e+000 vertex 3.641783e+001 4.832980e+000 5.200025e+000 vertex 3.640246e+001 4.879472e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.589002e+001 4.763933e+000 5.200025e+000 vertex 3.640246e+001 4.879472e+000 5.200025e+000 vertex 3.585817e+001 4.922856e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.585817e+001 4.922856e+000 5.200025e+000 vertex 3.640246e+001 4.879472e+000 5.200025e+000 vertex 3.639240e+001 4.936398e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.585817e+001 4.922856e+000 5.200025e+000 vertex 3.639240e+001 4.936398e+000 5.200025e+000 vertex 3.584785e+001 5.087248e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.584785e+001 5.087248e+000 5.200025e+000 vertex 3.639240e+001 4.936398e+000 5.200025e+000 vertex 3.638839e+001 5.012079e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.584785e+001 5.087248e+000 5.200025e+000 vertex 3.638839e+001 5.012079e+000 5.200025e+000 vertex 3.586516e+001 5.303418e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.586516e+001 5.303418e+000 5.200025e+000 vertex 3.638839e+001 5.012079e+000 5.200025e+000 vertex 3.639725e+001 5.133657e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.586516e+001 5.303418e+000 5.200025e+000 vertex 3.639725e+001 5.133657e+000 5.200025e+000 vertex 3.590902e+001 5.486102e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.590902e+001 5.486102e+000 5.200025e+000 vertex 3.639725e+001 5.133657e+000 5.200025e+000 vertex 3.642010e+001 5.234116e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.590902e+001 5.486102e+000 5.200025e+000 vertex 3.642010e+001 5.234116e+000 5.200025e+000 vertex 3.599011e+001 5.675723e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.599011e+001 5.675723e+000 5.200025e+000 vertex 3.642010e+001 5.234116e+000 5.200025e+000 vertex 3.646354e+001 5.343081e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.599011e+001 5.675723e+000 5.200025e+000 vertex 3.646354e+001 5.343081e+000 5.200025e+000 vertex 3.609706e+001 5.845630e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.609706e+001 5.845630e+000 5.200025e+000 vertex 3.646354e+001 5.343081e+000 5.200025e+000 vertex 3.652083e+001 5.440029e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.609706e+001 5.845630e+000 5.200025e+000 vertex 3.652083e+001 5.440029e+000 5.200025e+000 vertex 3.623904e+001 6.009370e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.623904e+001 6.009370e+000 5.200025e+000 vertex 3.652083e+001 5.440029e+000 5.200025e+000 vertex 3.659898e+001 5.534632e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.623904e+001 6.009370e+000 5.200025e+000 vertex 3.659898e+001 5.534632e+000 5.200025e+000 vertex 3.631914e+001 6.085559e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.631914e+001 6.085559e+000 5.200025e+000 vertex 3.659898e+001 5.534632e+000 5.200025e+000 vertex 3.670427e+001 5.628633e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.631914e+001 6.085559e+000 5.200025e+000 vertex 3.670427e+001 5.628633e+000 5.200025e+000 vertex 3.656573e+001 6.266929e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.656573e+001 6.266929e+000 5.200025e+000 vertex 3.670427e+001 5.628633e+000 5.200025e+000 vertex 3.687299e+001 5.737394e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.656573e+001 6.266929e+000 5.200025e+000 vertex 3.687299e+001 5.737394e+000 5.200025e+000 vertex 3.684798e+001 6.403257e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.684798e+001 6.403257e+000 5.200025e+000 vertex 3.687299e+001 5.737394e+000 5.200025e+000 vertex 3.702763e+001 5.803219e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.684798e+001 6.403257e+000 5.200025e+000 vertex 3.702763e+001 5.803219e+000 5.200025e+000 vertex 3.714959e+001 6.493544e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.714959e+001 6.493544e+000 5.200025e+000 vertex 3.702763e+001 5.803219e+000 5.200025e+000 vertex 3.717976e+001 5.839212e+000 5.200025e+000 endloop endfacet facet normal 1.913131e-013 -8.944174e-014 1.000000e+000 outer loop vertex 3.714959e+001 6.493544e+000 5.200025e+000 vertex 3.717976e+001 5.839212e+000 5.200025e+000 vertex 3.735376e+001 5.853295e+000 5.200025e+000 endloop endfacet endsolidsfact-2011.12.18/calibration/simple_print.stl000066400000000000000000002252011167321211700207320ustar00rootroot00000000000000solid "Screw_Holder_Bottom"; Produced by Art of Illusion 2.4, Fri Oct 16 16:42:04 PDT 2009 facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.804173569059 0.110046151702 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 24.730643081307 0 vertex 14.883210818105 25.830303993361 0 vertex 15.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 23 0 vertex 54.002309837942 24.730643081307 0 vertex 60 40 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 54.002309837942 15.269356918694 0 vertex 48.011309837942 15.269356918694 0 vertex 54.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 15.830303993361 11.883210818105 0 vertex 16.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 43.737436867076 27.737436867076 0 vertex 43.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 43.169696006639 15.116789181895 0 vertex 42.5 15.25 0 vertex 41.422110817733 17 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 48.011309837942 24.730643081307 0 vertex 54.002309837942 24.730643081307 0 vertex 48.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 43.169696006639 28.116789181895 0 vertex 42.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 40 0 vertex 52 30 0 vertex 52 40 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 14.169696006639 0 vertex 14.75 13.5 0 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 27.169696006639 0 vertex 14.042553191489 30 0 vertex 15.262563132924 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 16.5 11.75 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 48.011309837942 15.195826430941 0.110046151702 vertex 54.002309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 17.169696006639 28.116789181895 0 vertex 16.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 14.75 13.5 0 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 17 0 vertex 60 17 0 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 42.5 11.75 0 vertex 43.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 15.262563132924 14.737436867076 0 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 14.464705848856 10 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 15.830303993361 28.116789181895 0 vertex 15.262563132924 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 15.262563132924 12.262563132924 0 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 16.5 28.25 0 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 24.730643081307 0 vertex 60 23 0 vertex 54.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 23 0 vertex 16.5 24.75 0 vertex 17.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 15.195826430941 0.110046151702 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.75 26.5 0 vertex 12.002309837942 24.730643081307 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 60 40 0 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.422110817733 17 0 vertex 48.011309837942 17 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 13.5 0 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 6.011309837942 17 0 vertex 6.011309837942 15.269356918694 0 vertex 0 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.422110817733 17 0 vertex 41.830303993361 15.116789181895 0 vertex 41.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 11.883210818105 0 vertex 17.737436867076 12.262563132924 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 15.269356918694 0 vertex 0 10 0 vertex 0 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 25.830303993361 0 vertex 12.002309837942 24.730643081307 0 vertex 14.75 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 52 30 0 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 17 0 vertex 43.737436867076 14.737436867076 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 15.25 0 vertex 41.830303993361 15.116789181895 0 vertex 41.422110817733 17 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 14.883210818105 12.830303993361 0 vertex 6.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 23 0 vertex 0 30 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 12.002309837942 15.269356918694 0 vertex 6.011309837942 15.269356918694 0 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 60 17 0 vertex 52 10 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 23 0 vertex 0 23 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 48.011309837942 15.269356918694 0 vertex 44.25 13.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 27.169696006639 0 vertex 41.262563132924 25.262563132924 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 25.830303993361 0 vertex 18.25 26.5 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 14.737436867076 0 vertex 41.262563132924 14.737436867076 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.830303993361 24.883210818105 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 25.262563132924 0 vertex 18.116789181895 25.830303993361 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 12.262563132924 0 vertex 18.116789181895 12.830303993361 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 12.262563132924 0 vertex 41.262563132924 12.262563132924 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 17.169696006639 28.116789181895 0 vertex 41.830303993361 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 11.75 0 vertex 14.464705848856 10 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.25 26.5 0 vertex 44.116789181895 27.169696006639 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 12.830303993361 0 vertex 41.262563132924 12.262563132924 0 vertex 17.737436867076 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 17.737436867076 25.262563132924 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 12.830303993361 0 vertex 44.25 13.5 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 12.830303993361 0 vertex 40.75 13.5 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.25 13.5 0 vertex 18.116789181895 14.169696006639 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 14.737436867076 0 vertex 17.737436867076 14.737436867076 0 vertex 17.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 14.169696006639 0 vertex 17.737436867076 14.737436867076 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 44.25 26.5 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 14.75 13.5 0.77775 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.75 13.5 0.77775 vertex 14.75 13.5 0 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 41.830303993361 28.116789181895 0 vertex 42.5 28.25 0.77775 vertex 41.830303993361 28.116789181895 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.830303993361 24.883210818105 0.77775 vertex 15.830303993361 24.883210818105 0 vertex 15.262563132924 25.262563132924 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 16.5 28.25 0 vertex 17.169696006639 28.116789181895 0.77775 vertex 16.5 28.25 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 43.169696006639 24.883210818105 0 vertex 42.5 24.75 0.77775 vertex 43.169696006639 24.883210818105 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 28.25 0.77775 vertex 15.830303993361 28.116789181895 0.77775 vertex 16.5 28.25 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 15.830303993361 28.116789181895 0.77775 vertex 15.830303993361 28.116789181895 0 vertex 16.5 28.25 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 23 0 vertex 6.011309837942 23 0.77775 vertex 0 23 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 60 0 0.77775 vertex 52 10 0.77775 vertex 52 0 0.77775 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 27.169696006639 0 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.75 26.5 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.169696006639 24.883210818105 0 vertex 16.5 24.75 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 0 0 vertex 52 0 0.77775 vertex 52 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.883210818105 12.830303993361 0.77775 vertex 40.75 13.5 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 42.5 24.75 0 vertex 41.830303993361 24.883210818105 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 0 0 vertex 60 0 0.77775 vertex 52 0 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 28.116789181895 0.77775 vertex 15.262563132924 27.737436867076 0.77775 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.262563132924 27.737436867076 0.77775 vertex 15.262563132924 27.737436867076 0 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0 1 0 outer loop vertex 6.011309837942 17 0.77775 vertex 6.011309837942 17 0 vertex 0 17 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 17 0 vertex 48.011309837942 17 0.77775 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 18.25 26.5 0 vertex 18.25 26.5 0.77775 vertex 18.116789181895 27.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.455907969142 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 54.002309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 44.25 26.5 0 vertex 44.25 26.5 0.77775 vertex 44.116789181895 27.169696006639 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 10 0 vertex 15.306548743796 10 0.77775 vertex 14.464705848856 10 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 26.5 0.77775 vertex 40.883210818105 25.830303993361 0 vertex 40.75 26.5 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 48.011309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 43.737436867076 27.737436867076 0.77775 vertex 44.116789181895 27.169696006639 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 43.737436867076 27.737436867076 0 vertex 44.116789181895 27.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 10 0 vertex 52 10 0.77775 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 23 0.77775 vertex 6.011309837942 23 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.883210818105 14.169696006639 0.77775 vertex 41.262563132924 14.737436867076 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 26.5 0 vertex 14.883210818105 25.830303993361 0.77775 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 6.011309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 18.116789181895 14.169696006639 0.77775 vertex 17.737436867076 14.737436867076 0.77775 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 17.737436867076 14.737436867076 0 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 42.5 15.25 0.77775 vertex 41.830303993361 15.116789181895 0.77775 vertex 42.5 15.25 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 41.830303993361 15.116789181895 0.77775 vertex 41.830303993361 15.116789181895 0 vertex 42.5 15.25 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 14.883210818105 14.169696006639 0.77775 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 14.883210818105 14.169696006639 0 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 43.169696006639 15.116789181895 0 vertex 43.737436867076 14.737436867076 0.77775 vertex 43.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 13.5 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.75 13.5 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 40.883210818105 14.169696006639 0.77775 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 11.75 0.77775 vertex 43.169696006639 11.883210818105 0.77775 vertex 43.169696006639 11.883210818105 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 17.169696006639 15.116789181895 0 vertex 17.737436867076 14.737436867076 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.730643081307 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 6.011309837942 23 0.77775 vertex 0 23 0 vertex 6.011309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 48.011309837942 23 0 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.195826430941 0.110046151702 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 10 0 vertex 6.011309837942 15.269356918694 0 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 -0 outer loop vertex 17.169696006639 28.116789181895 0.77775 vertex 16.5 28.25 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 44.116789181895 27.169696006639 0 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.25 26.5 0.77775 vertex 44.25 26.5 0 vertex 44.116789181895 25.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 40.75 26.5 0.77775 vertex 37.474084379442 23 0.77775 vertex 40.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.75 13.5 0.77775 vertex 40.883210818105 14.169696006639 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 17.169696006639 11.883210818105 0 vertex 16.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 52 30 0.77775 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 15.063011877768 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.75 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 48.011309837942 15.063011877768 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 24.883210818105 0.77775 vertex 42.5 24.75 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 24.730643081307 0 vertex 14.883210818105 27.169696006639 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.737436867076 14.737436867076 0.77775 vertex 43.169696006639 15.116789181895 0 vertex 43.737436867076 14.737436867076 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 41.866228156844 30 0.77775 vertex 43.169696006639 28.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 41.830303993361 15.116789181895 0.77775 vertex 42.5 15.25 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 11.75 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 0 23 0.77775 vertex 0 30 0 vertex 0 23 0 endloop endfacet facet normal -1 0 0 outer loop vertex 0 30 0 vertex 0 23 0.77775 vertex 0 30 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 52 10 0 vertex 52 0 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 11.883210818105 0 vertex 17.169696006639 11.883210818105 0.77775 vertex 17.737436867076 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 43.169696006639 28.116789181895 0.77775 vertex 41.866228156844 30 0.77775 vertex 42.5 28.25 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 14.042553191489 30 0 vertex 41.866228156844 30 0.77775 vertex 52 30 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 42.5 11.75 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 12.262563132924 0.77775 vertex 15.830303993361 11.883210818105 0 vertex 15.262563132924 12.262563132924 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 40.75 26.5 0.77775 vertex 40.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 27.169696006639 0 vertex 40.883210818105 25.830303993361 0 vertex 41.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 17.169696006639 28.116789181895 0 vertex 14.042553191489 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 15.262563132924 27.737436867076 0.77775 vertex 15.830303993361 28.116789181895 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 25.830303993361 0.77775 vertex 15.262563132924 25.262563132924 0.77775 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 15.262563132924 25.262563132924 0.77775 vertex 15.262563132924 25.262563132924 0 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 24.804173569059 0.110046151702 vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 43.737436867076 27.737436867076 0 vertex 52 30 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 25.830303993361 0 vertex 18.116789181895 25.830303993361 0.77775 vertex 18.25 26.5 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.195826430941 0.110046151702 vertex 54.002309837942 15.063011877768 0.77775 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 15.116789181895 0 vertex 41.830303993361 15.116789181895 0.77775 vertex 41.262563132924 14.737436867076 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 43.169696006639 28.116789181895 0.77775 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.169696006639 28.116789181895 0.77775 vertex 43.169696006639 28.116789181895 0 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 42.5 11.75 0.77775 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 23 0.77775 vertex 15.830303993361 24.883210818105 0.77775 vertex 15.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 41.262563132924 14.737436867076 0 vertex 41.830303993361 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 17 0 vertex 60 0 0 vertex 52 0 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 25.262563132924 0 vertex 15.262563132924 25.262563132924 0.77775 vertex 15.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 23 0 vertex 17.379510917074 23 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 6.011309837942 23 0.77775 vertex 6.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 11.883210818105 0 vertex 41.830303993361 11.883210818105 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 14.042553191489 30 0 vertex 52 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 43.169696006639 15.116789181895 0.77775 vertex 43.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 17 0.77775 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 18.116789181895 27.169696006639 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.75 26.5 0 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.75 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 0 30 0.77775 vertex 14.883210818105 27.169696006639 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 11.75 0.77775 vertex 43.169696006639 11.883210818105 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 15.830303993361 28.116789181895 0.77775 vertex 16.5 28.25 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 52 30 0.77775 vertex 52 30 0 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 17 0 vertex 52 0 0 vertex 52 10 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 0 outer loop vertex 44.116789181895 14.169696006639 0.77775 vertex 43.737436867076 14.737436867076 0.77775 vertex 43.737436867076 14.737436867076 0 endloop endfacet facet normal 0 1 0 outer loop vertex 14.607403236621 30 0.77775 vertex 41.866228156844 30 0.77775 vertex 14.042553191489 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 15.306548743796 10 0.77775 vertex 17.737436867076 12.262563132924 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.269356918694 0 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 17 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 16.5 24.75 0 vertex 16.5 24.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 43.169696006639 24.883210818105 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 6.011309837942 17 0.77775 vertex 0 17 0 vertex 0 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 16.5 28.25 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 17.737436867076 25.262563132924 0 vertex 17.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 24.75 0.77775 vertex 17.379510917074 23 0.77775 vertex 17.169696006639 24.883210818105 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 44.116789181895 27.169696006639 0 vertex 44.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.75 13.5 0 vertex 18.25 13.5 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 48.011309837942 24.730643081307 0 vertex 48.011309837942 23 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 10 0.77775 vertex 0 10 0 vertex 14.464705848856 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 15.306548743796 10 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.262563132924 12.262563132924 0.77775 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 28.116789181895 0 vertex 43.169696006639 28.116789181895 0.77775 vertex 42.5 28.25 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 16.5 11.75 0 vertex 16.5 11.75 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 18.25 13.5 0.77775 vertex 18.116789181895 14.169696006639 0.77775 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.737436867076 25.262563132924 0 vertex 17.169696006639 24.883210818105 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 10 0.77775 vertex 14.464705848856 10 0 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 17.737436867076 14.737436867076 0 vertex 17.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.866228156844 30 0.77775 vertex 41.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 16.5 11.75 0.77775 vertex 15.830303993361 11.883210818105 0 vertex 15.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.75 26.5 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 44.116789181895 14.169696006639 0.77775 vertex 43.737436867076 14.737436867076 0 vertex 44.116789181895 14.169696006639 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 60 17 0.77775 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 12.002309837942 15.195826430941 0.110046151702 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 23 0.77775 vertex 17.379510917074 23 0.77775 vertex 15.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.830303993361 24.883210818105 0.77775 vertex 17.379510917074 23 0.77775 vertex 16.5 24.75 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.25 26.5 0.77775 vertex 18.25 26.5 0 vertex 18.116789181895 25.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 25.262563132924 0.77775 vertex 37.474084379442 23 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 14.883210818105 27.169696006639 0.77775 vertex 15.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 15.455907969142 17 0.77775 vertex 17.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 34.416922535211 17 0.77775 vertex 15.455907969142 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.306548743796 10 0.77775 vertex 15.262563132924 12.262563132924 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.737436867076 25.262563132924 0.77775 vertex 17.737436867076 25.262563132924 0 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 15.25 0.77775 vertex 15.455907969142 17 0.77775 vertex 15.830303993361 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 42.5 28.25 0.77775 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 18.25 13.5 0.77775 vertex 18.25 13.5 0 endloop endfacet facet normal 0 1 0 outer loop vertex 60 17 0.77775 vertex 60 17 0 vertex 54.002309837942 17 0 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 12.002309837942 17 0 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 11.883210818105 0 vertex 43.737436867076 12.262563132924 0.77775 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 11.883210818105 0 vertex 43.169696006639 11.883210818105 0.77775 vertex 43.737436867076 12.262563132924 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 18.25 13.5 0.77775 vertex 18.116789181895 14.169696006639 0 vertex 18.25 13.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 41.830303993361 28.116789181895 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 23 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 15.455907969142 17 0.77775 vertex 16.5 15.25 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 17.737436867076 12.262563132924 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 52 40 0.77775 vertex 60 23 0.77775 vertex 60 40 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.75 13.5 0 vertex 18.116789181895 12.830303993361 0 vertex 18.25 13.5 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 28.116789181895 0 vertex 42.5 28.25 0.77775 vertex 42.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 12.002309837942 23 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 23 0.77775 vertex 60 23 0.77775 vertex 54.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 23 0.77775 vertex 6.011309837942 24.730643081307 0 vertex 6.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 17.169696006639 15.116789181895 0 vertex 16.5 15.25 0.77775 vertex 16.5 15.25 0 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 17 0.77775 vertex 6.011309837942 15.063011877768 0.77775 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 1 0 0 outer loop vertex 60 17 0.77775 vertex 60 0 0 vertex 60 17 0 endloop endfacet facet normal 1 0 0 outer loop vertex 60 0 0.77775 vertex 60 0 0 vertex 60 17 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 12.262563132924 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 43.737436867076 12.262563132924 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 12.002309837942 15.063011877768 0.77775 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.379510917074 23 0.77775 vertex 17.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 43.737436867076 12.262563132924 0.77775 vertex 43.169696006639 11.883210818105 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 42.5 28.25 0.77775 vertex 41.830303993361 28.116789181895 0 vertex 42.5 28.25 0 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 17 0 vertex 6.011309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 25.830303993361 0.77775 vertex 37.474084379442 23 0.77775 vertex 41.262563132924 25.262563132924 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 18.25 13.5 0 vertex 18.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 25.262563132924 0.77775 vertex 17.379510917074 23 0.77775 vertex 18.116789181895 25.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 41.262563132924 14.737436867076 0.77775 vertex 41.830303993361 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 30 0.77775 vertex 6.011309837942 24.936988122232 0.77775 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 17.379510917074 23 0.77775 vertex 37.474084379442 23 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 43.169696006639 11.883210818105 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 40.883210818105 14.169696006639 0 vertex 41.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 43.169696006639 24.883210818105 0 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.25 26.5 0.77775 vertex 44.116789181895 25.830303993361 0 vertex 44.116789181895 25.830303993361 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 60 17 0.77775 vertex 54.002309837942 17 0 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 42.5 24.75 0 vertex 43.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 44.116789181895 27.169696006639 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 18.116789181895 25.830303993361 0 vertex 17.737436867076 25.262563132924 0 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.195826430941 0.110046151702 vertex 54.002309837942 17 0.77775 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 14.75 26.5 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 0 0.77775 vertex 52 0 0 vertex 60 0 0.77775 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 14.75 26.5 0.77775 vertex 14.75 26.5 0 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.269356918694 0 vertex 54.002309837942 17 0.77775 vertex 54.002309837942 17 0 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 11.75 0.77775 vertex 15.306548743796 10 0.77775 vertex 17.169696006639 11.883210818105 0.77775 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 17.169696006639 15.116789181895 0 vertex 17.169696006639 15.116789181895 0.77775 vertex 16.5 15.25 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.195826430941 0.110046151702 vertex 12.002309837942 15.063011877768 0.77775 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 48.011309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 16.5 11.75 0.77775 vertex 16.5 11.75 0 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 48.011309837942 15.269356918694 0 vertex 48.011309837942 17 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 52 30 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 24.75 0.77775 vertex 43.169696006639 24.883210818105 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 26.5 0 vertex 14.75 26.5 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 43.737436867076 14.737436867076 0 vertex 48.011309837942 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 48.011309837942 17 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 41.830303993361 24.883210818105 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 42.5 24.75 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 1 0 outer loop vertex 52 40 0 vertex 52 40 0.77775 vertex 60 40 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 52 40 0 vertex 60 40 0.77775 vertex 60 40 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0.77775 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 15.830303993361 24.883210818105 0 vertex 15.830303993361 24.883210818105 0.77775 vertex 16.5 24.75 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 15.830303993361 24.883210818105 0 vertex 16.5 24.75 0.77775 vertex 16.5 24.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 24.936988122232 0.77775 vertex 12.002309837942 23 0.77775 vertex 15.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 24.936988122232 0.77775 vertex 15.262563132924 25.262563132924 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 60 40 0.77775 vertex 60 23 0.77775 vertex 60 23 0 endloop endfacet facet normal 1 0 0 outer loop vertex 60 40 0.77775 vertex 60 23 0 vertex 60 40 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 27.737436867076 0 vertex 15.262563132924 27.737436867076 0.77775 vertex 14.883210818105 27.169696006639 0.77775 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 27.737436867076 0 vertex 14.883210818105 27.169696006639 0.77775 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 1 outer loop vertex 37.474084379442 23 0.77775 vertex 48.011309837942 23 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 37.474084379442 23 0.77775 vertex 42.5 24.75 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 14.737436867076 0 vertex 12.002309837942 17 0 vertex 41.422110817733 17 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 15.116789181895 0.77775 vertex 42.5 15.25 0.77775 vertex 42.5 15.25 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 -0 outer loop vertex 43.169696006639 15.116789181895 0.77775 vertex 42.5 15.25 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 52 10 0.77775 vertex 60 0 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 60 0 0.77775 vertex 60 17 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 13.5 0.77775 vertex 40.883210818105 12.830303993361 0.77775 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 13.5 0.77775 vertex 40.883210818105 12.830303993361 0 vertex 40.75 13.5 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.737436867076 27.737436867076 0 vertex 17.737436867076 27.737436867076 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.737436867076 27.737436867076 0 vertex 17.169696006639 28.116789181895 0.77775 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 0 30 0.77775 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 14.75 26.5 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 12.262563132924 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 12.262563132924 0.77775 vertex 44.116789181895 12.830303993361 0 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 48.011309837942 23 0.77775 vertex 37.474084379442 23 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 15.25 0.77775 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.830303993361 15.116789181895 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 15.25 0.77775 vertex 15.830303993361 15.116789181895 0 vertex 16.5 15.25 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 41.262563132924 12.262563132924 0.77775 vertex 41.262563132924 12.262563132924 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 41.262563132924 12.262563132924 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 16.5 15.25 0 vertex 15.830303993361 15.116789181895 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 25.262563132924 0 vertex 43.737436867076 25.262563132924 0.77775 vertex 44.116789181895 25.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 25.262563132924 0 vertex 44.116789181895 25.830303993361 0.77775 vertex 44.116789181895 25.830303993361 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 14.169696006639 0.77775 vertex 40.75 13.5 0.77775 vertex 40.75 13.5 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 14.169696006639 0.77775 vertex 40.75 13.5 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 23 0 vertex 60 23 0.77775 vertex 54.002309837942 23 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 23 0 vertex 54.002309837942 23 0.77775 vertex 54.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 30 0 vertex 14.042553191489 30 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 30 0 vertex 14.883210818105 27.169696006639 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.262563132924 25.262563132924 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.830303993361 24.883210818105 0.77775 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.262563132924 27.737436867076 0.77775 vertex 41.262563132924 27.737436867076 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.262563132924 27.737436867076 0 vertex 41.830303993361 28.116789181895 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 24.883210818105 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 24.883210818105 0.77775 vertex 43.737436867076 25.262563132924 0 vertex 43.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 43.169696006639 11.883210818105 0 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 43.737436867076 12.262563132924 0 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 60 23 0.77775 vertex 52 40 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 52 40 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 34.416922535211 17 0.77775 vertex 41.422110817733 17 0 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 41.422110817733 17 0 vertex 12.002309837942 17 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 12.002309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 12.002309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.730643081307 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 15.455907969142 17 0.77775 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 12.002309837942 17 0.77775 vertex 14.883210818105 14.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 25.830303993361 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 17 0.77775 vertex 0 10 0.77775 vertex 6.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 17 0.77775 vertex 6.011309837942 15.063011877768 0.77775 vertex 6.011309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 34.416922535211 17 0.77775 vertex 42.5 15.25 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 42.5 15.25 0.77775 vertex 43.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 12.002309837942 15.063011877768 0.77775 vertex 14.75 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 0 30 0.77775 vertex 0 23 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 0 23 0.77775 vertex 6.011309837942 23 0.77775 endloop endfacet facet normal -0 -0 -1 outer loop vertex 40.75 26.5 0 vertex 40.883210818105 25.830303993361 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 44.25 13.5 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 44.116789181895 14.169696006639 0 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 44.25 13.5 0.77775 vertex 44.116789181895 14.169696006639 0 vertex 44.25 13.5 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 17.737436867076 12.262563132924 0 vertex 17.737436867076 12.262563132924 0.77775 vertex 18.116789181895 12.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 17.737436867076 12.262563132924 0 vertex 18.116789181895 12.830303993361 0.77775 vertex 18.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 0 10 0.77775 vertex 15.306548743796 10 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 54.002309837942 24.936988122232 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.936988122232 0.77775 vertex 48.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 12.830303993361 0 vertex 14.883210818105 12.830303993361 0.77775 vertex 15.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 12.830303993361 0 vertex 15.262563132924 12.262563132924 0.77775 vertex 15.262563132924 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 43.737436867076 12.262563132924 0 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 44.116789181895 12.830303993361 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 1 0 outer loop vertex 0 30 0 vertex 0 30 0.77775 vertex 14.607403236621 30 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 0 30 0 vertex 14.607403236621 30 0.77775 vertex 14.042553191489 30 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 12.262563132924 0 vertex 41.262563132924 12.262563132924 0.77775 vertex 41.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 12.262563132924 0 vertex 41.830303993361 11.883210818105 0.77775 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal -1 0 0 outer loop vertex 0 10 0 vertex 0 10 0.77775 vertex 0 17 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 0 10 0 vertex 0 17 0.77775 vertex 0 17 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.116789181895 12.830303993361 0.77775 vertex 44.25 13.5 0.77775 vertex 44.25 13.5 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.116789181895 12.830303993361 0.77775 vertex 44.25 13.5 0 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal 0 1 0 outer loop vertex 41.422110817733 17 0 vertex 34.416922535211 17 0.77775 vertex 48.011309837942 17 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 41.422110817733 17 0 vertex 48.011309837942 17 0.77775 vertex 48.011309837942 17 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 30 0.77775 vertex 52 40 0.77775 vertex 52 40 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 30 0.77775 vertex 52 40 0 vertex 52 30 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.830303993361 24.883210818105 0 vertex 16.5 24.75 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 40.883210818105 27.169696006639 0 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 17.737436867076 27.737436867076 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 0 10 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 12.002309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 43.737436867076 14.737436867076 0.77775 vertex 44.116789181895 14.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.262563132924 25.262563132924 0 vertex 15.830303993361 24.883210818105 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.262563132924 25.262563132924 0 vertex 12.002309837942 23 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 44.25 26.5 0.77775 vertex 44.116789181895 25.830303993361 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 27.169696006639 0 vertex 40.75 26.5 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 27.169696006639 0 vertex 18.116789181895 27.169696006639 0 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 41.262563132924 14.737436867076 0 vertex 17.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 17.169696006639 15.116789181895 0 vertex 16.5 15.25 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 15.116789181895 0 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.262563132924 14.737436867076 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 15.116789181895 0 vertex 15.262563132924 14.737436867076 0.77775 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.883210818105 27.169696006639 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0 vertex 41.262563132924 27.737436867076 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 37.474084379442 23 0.77775 vertex 17.379510917074 23 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 17.379510917074 23 0.77775 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 15.830303993361 15.116789181895 0 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 15.262563132924 14.737436867076 0 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 40.883210818105 25.830303993361 0.77775 vertex 41.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 41.262563132924 25.262563132924 0.77775 vertex 41.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 12.830303993361 0 vertex 15.262563132924 12.262563132924 0 vertex 14.464705848856 10 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 12.830303993361 0 vertex 14.464705848856 10 0 vertex 0 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 41.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 17.169696006639 28.116789181895 0.77775 vertex 17.737436867076 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.936988122232 0.77775 vertex 43.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 43.169696006639 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 44.25 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 44.25 26.5 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 48.011309837942 24.936988122232 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 23 0.77775 vertex 54.002309837942 24.936988122232 0.77775 vertex 54.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 41.866228156844 30 0.77775 vertex 14.607403236621 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 14.607403236621 30 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.25 13.5 0.77775 vertex 44.116789181895 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 14.169696006639 0.77775 vertex 18.25 13.5 0.77775 vertex 41.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.25 26.5 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 18.116789181895 27.169696006639 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 24.730643081307 0 vertex 54.002309837942 23 0 vertex 54.002309837942 23 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 24.730643081307 0 vertex 54.002309837942 23 0.77775 vertex 54.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 41.262563132924 12.262563132924 0.77775 vertex 18.25 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 18.25 13.5 0.77775 vertex 18.116789181895 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 17.737436867076 12.262563132924 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 42.5 11.75 0.77775 vertex 41.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 15.306548743796 10 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 52 10 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 18.116789181895 14.169696006639 0.77775 vertex 41.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.25 26.5 0.77775 vertex 40.75 26.5 0.77775 vertex 40.883210818105 27.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 37.474084379442 23 0.77775 vertex 40.75 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 40.75 26.5 0.77775 vertex 18.25 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 34.416922535211 17 0.77775 vertex 17.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 17.737436867076 14.737436867076 0.77775 vertex 18.116789181895 14.169696006639 0.77775 endloop endfacet endsolid sfact-2011.12.18/calibration/star.STL000066400000000000000000000424241167321211700170420ustar00rootroot00000000000000STLEXP Object01`„–U?î ¿ÎBZƒÊA¨VB‘kB¨VB‘kB@„–U?î ¿ÎBZƒÊA¨VB‘kB@ÎBZƒÊA@3nˆ¾‚¾v?¨VB‘kB¸níA aúA¸níA aúA@3nˆ¾‚¾v?¨VB‘kB¸níA aúA@¨VB‘kB@K8H?7†?¸níA aúAè¸A 'Bè¸A 'B@K8H?7†?¸níA aúAè¸A 'B@¸níA aúA@P¿¿ò5=è¸A 'B‹)µAšèA‹)µAšèA@P¿¿ò5=è¸A 'B‹)µAšèA@è¸A 'B@ϰ³¾S·o?‹)µAšèA¹vLAYƒÊA¹vLAYƒÊA@ϰ³¾S·o?‹)µAšèA¹vLAYƒÊA@‹)µAšèA@ݳ¾U·o¿¹vLAYƒÊA‹)µAî¬A‹)µAî¬A@ݳ¾U·o¿€¹vLAYƒÊA‹)µAî¬A@¹vLAYƒÊA@P¿¿5ò5½‹)µAî¬Aè¸ẢBGDÄABÛˆBôÜÅABÛˆBôÜÅA@¸Àb?ð¥í>̉BGDÄABÛˆBôÜÅA@̉BGDÄA@'Yt??µ˜>BÛˆBôÜÅA‘·ˆBÕ¥ÇA‘·ˆBÕ¥ÇA@'Yt??µ˜>BÛˆBôÜÅA‘·ˆBÕ¥ÇA@BÛˆBôÜÅA@G}?æá>‘·ˆBÕ¥ÇA¸¥ˆB¢‹ÉA¸¥ˆB¢‹ÉA@G}?æá>‘·ˆBÕ¥ÇA¸¥ˆB¢‹ÉA@‘·ˆBÕ¥ÇA@€?¸¥ˆB¢‹ÉA¸¥ˆB{ËA¸¥ˆB{ËA@€?¸¥ˆB¢‹ÉA¸¥ˆB{ËA@¸¥ˆB¢‹ÉA@êG}?¼Ù¾¸¥ˆB{ËA·ˆBß`ÍA·ˆBß`ÍA@êG}?¼Ù¾¸¥ˆB{ËA·ˆBß`ÍA@¸¥ˆB{ËA@‹Xt?%¹˜¾·ˆBß`ÍABÛˆBÀ)ÏABÛˆBÀ)ÏA@‹Xt?%¹˜¾·ˆBß`ÍABÛˆBÀ)ÏA@·ˆBß`ÍA@¸Àb?ð¥í¾BÛˆBÀ)ÏẢBmÂÐẢBmÂÐA@¸Àb?ð¥í¾BÛˆBÀ)ÏẢBmÂÐA@BÛˆBÀ)ÏA@‚–U?ð ¿Ì‰BmÂÐAJB,ûAJB,ûA@‚–U?ð ¿Ì‰BmÂÐAJB,ûA@̉BmÂÐA@(‰`? ìõ¾JB,ûAä¹B4ôÿAä¹B4ôÿA@(‰`? ìõ¾JB,ûAä¹B4ôÿA@JB,ûA@av?3º‰¾ä¹B4ôÿA‘BÿB‘BÿB@av?3º‰¾ä¹B4ôÿA‘BÿB@ä¹B4ôÿA@1æ~?m¸½=‘BÿBýîBg™BýîBg™B@1æ~?m¸½=‘BÿBýîBg™B@‘BÿB@EO?¾y?ýîBg™BÀ„BؽBÀ„BؽB@EO?¾y?ýîBg™BÀ„BؽB@ýîBg™B@,¦Ê>%k?À„BؽB‚ÇBø`B‚ÇBø`B@,¦Ê>%k?À„BؽB‚ÇBø`B@À„BؽB@-+=¿Æ?‚ÇBø`Bc»ŽBfwBc»ŽBfwB@-+=¿Æ?‚ÇBø`Bc»ŽBfwB@‚ÇBø`B@¥:>¾9‹{?c»ŽBfwB†dBÁõB†dBÁõB@¥:>¾9‹{?c»ŽBfwB†dBÁõB@c»ŽBfwB@£b|?d;€BØüA½„BjüA½„BjüA@Ñx+>£b|?d;€BØüA½„BjüA@d;€BØüA@²7ž>gxs?½„BjüA$™~B+ýA$™~B+ýA@²7ž>gxs?½„BjüA$™~B+ýA@½„BjüA@_Tã>éae?$™~B+ýA)½}B.ÝýA)½}B.ÝýA@_Tã>éae?$™~B+ýA)½}B.ÝýA@$™~B+ýA@!?†ÊP?)½}B.ÝýAöù|B'òþAöù|B'òþA@!?†ÊP?)½}B.ÝýAöù|B'òþA@)½}B.ÝýA@ 7?3ï2?öù|B'òþA·X|BB·X|BB@ 7?3ï2?öù|B'òþA·X|BB@öù|B'òþA@I8H?:†?·X|BB‚lBÿB‚lBÿB@I8H?:†?·X|BB‚lBÿB@·X|BB@;T:?“Œ/?‚lBÿB‚£jBûB‚£jBûB@;T:?“Œ/?‚lBÿB‚£jBûB@‚lBÿB@¯ ?X7U?‚£jBûBähB$BähB$B@¯ ?X7U?‚£jBûBähB$B@‚£jBûB@^Ú`>„Ày?ähB$BiRgB~BiRgB~B@^Ú`>„Ày?ähB$BiRgB~B@ähB$B@¨7ž¾ixs?iRgB~B úeBÜB úeBÜB@¨7ž¾ixs?iRgB~B úeBÜB@iRgB~B@îF@¿n)? úeBÜB†êdBNÙB†êdBNÙB@îF@¿n)? úeBÜB†êdBNÙB@ úeBÜB@±óo¿bm²>†êdBNÙB|/dB=âB|/dB=âB@±óo¿bm²>†êdBNÙB|/dB=âB@†êdBNÙB@¬í}¿Í>|/dB=âBâÖcB.BâÖcB.B@¬í}¿Í>|/dB=âBâÖcB.B@|/dB=âB@P¿¿¿ñ5=âÖcB.BÚµbBP“ïAÚµbBP“ïA@P¿¿¿ñ5=âÖcB.BÚµbBP“ïA@âÖcB.B@SJ}¿˜>ÚµbBP“ïA`”bBÎÊíA`”bBÎÊíA@SJ}¿˜>ÚµbBP“ïA`”bBÎÊíA@ÚµbBP“ïA@Ør¿(´£>`”bBÎÊíAÚGbBCìAÚGbBCìA@Ør¿(´£>`”bBÎÊíAÚGbBCìA@`”bBÎÊíA@Éb¿5†í>ÚGbBCìAõÕaBHRêAõÕaBHRêA@Éb¿5†í>ÚGbBCìAõÕaBHRêA@ÚGbBCìA@ÞO¿êx?õÕaBHRêAZDaBvÁèAZDaBvÁèA@ÞO¿êx?õÕaBHRêAZDaBvÁèA@õÕaBHRêA@ 7¿ü2?ZDaBvÁèA´˜`BgbçA´˜`BgbçA@ 7¿ü2?ZDaBvÁèA´˜`BgbçA@ZDaBvÁèA@rÌ¿ fM?´˜`BgbçA­Ø_B³DæA­Ø_B³DæA@rÌ¿ fM?´˜`BgbçA­Ø_B³DæA@´˜`BgbçA@þ3ã¾îie?­Ø_B³DæAð _BôwåAð _BôwåA@þ3ã¾îie?­Ø_B³DæAð _BôwåA@­Ø_B³DæA@ʰ³¾T·o?ð _BôwåA =GB½ ÓA =GB½ ÓA@ʰ³¾T·o?ð _BôwåA =GB½ ÓA@ð _BôwåA@ÌÁÚ¾þtg? =GB½ ÓAÆDBdLÑAÆDBdLÑA@ÌÁÚ¾þtg? =GB½ ÓAÆDBdLÑA@ =GB½ ÓA@ ÿ¿££H?ÆDBdLÑAo!CB¶±ÎAo!CB¶±ÎA@ ÿ¿££H?ÆDBdLÑAo!CB¶±ÎA@ÆDBdLÑA@Ñ(\¿ß¢?o!CB¶±ÎAOBBÓìËAOBBÓìËA@Ñ(\¿ß¢?o!CB¶±ÎAOBBÓìËA@o!CB¶±ÎA@€¿OBBÓìËAOBBàÉAOBBàÉA@€¿OBBÓìËAOBBàÉA@OBBÓìËA@‹(\¿U£¿OBBàÉAp!CBýTÆAp!CBýTÆA@‹(\¿U£¿€OBBàÉAp!CBýTÆA@OBBàÉA@ÿ¿V£H¿p!CBýTÆAÆDBNºÃAÆDBNºÃA@ÿ¿V£H¿€p!CBýTÆAÆDBNºÃA@p!CBýTÆA@ÁÚ¾ug¿ÆDBNºÃA =GBöeÁA =GBöeÁA@ÁÚ¾ug¿€ÆDBNºÃA =GBöeÁA@ÆDBNºÃA@ʰ³¾T·o¿ =GBöeÁAð _B¿Ž¯Að _B¿Ž¯A@ʰ³¾T·o¿€ =GBöeÁAð _B¿Ž¯A@ =GBöeÁA@þ3ã¾îie¿ð _B¿Ž¯A­Ø_B®A­Ø_B®A@þ3ã¾îie¿€ð _B¿Ž¯A­Ø_B®A@ð _B¿Ž¯A@Ì¿LfM¿­Ø_B®A´˜`BM¤­A´˜`BM¤­A@Ì¿LfM¿€­Ø_B®A´˜`BM¤­A@­Ø_B®A@ 7¿ü2¿´˜`BM¤­AZDaB>E¬AZDaB>E¬A@ 7¿ü2¿€´˜`BM¤­AZDaB>E¬A@´˜`BM¤­A@`O¿˜y¿ZDaB>E¬AöÕaBl´ªAöÕaBl´ªA@`O¿˜y¿€ZDaB>E¬AöÕaBl´ªA@ZDaB>E¬A@Éb¿5†í¾öÕaBl´ªAÛGbBq©AÛGbBq©A@Éb¿5†í¾€öÕaBl´ªAÛGbBq©A@öÕaBl´ªA@+r¿<²£¾ÛGbBq©A`”bBæ;§A`”bBæ;§A@+r¿<²£¾€ÛGbBq©A`”bBæ;§A@ÛGbBq©A@SJ}¿˜¾`”bBæ;§AÚµbBds¥AÚµbBds¥A@SJ}¿˜¾€`”bBæ;§AÚµbBds¥A@`”bBæ;§A@P¿¿cò5½ÚµbBds¥AãÖcBZUeAãÖcBZUeA@P¿¿cò5½€ÚµbBds¥AãÖcBZUeA@ÚµbBds¥A@¹í}¿8¾ãÖcBZUeA|/dBs„ZA|/dBs„ZA@¹í}¿8¾€ãÖcBZUeA|/dBs„ZA@ãÖcBZUeA@®óo¿vm²¾|/dBs„ZA†êdB0¨RA†êdB0¨RA@®óo¿vm²¾€|/dBs„ZA†êdB0¨RA@|/dBs„ZA@îF@¿n)¿†êdB0¨RA úeBøÑMA úeBøÑMA@îF@¿n)¿€†êdB0¨RA úeBøÑMA@†êdB0¨RA@¨7ž¾ixs¿ úeBøÑMAiRgB(LAiRgB(LA@¨7ž¾ixs¿€ úeBøÑMAiRgB(LA@ úeBøÑMA@Û`>{Ày¿iRgB(LA€ähB*}MA€ähB*}MA@Û`>{Ày¿iRgB(LA€ähB*}MA@iRgB(LA@¯ ?X7U¿€ähB*}MAƒ£jBZ!RAƒ£jBZ!RA@¯ ?X7U¿€ähB*}MAƒ£jBZ!RA@€ähB*}MA@0T:?ŸŒ/¿ƒ£jBZ!RA‚lB!ZA‚lB!ZA@0T:?ŸŒ/¿ƒ£jBZ!RA‚lB!ZA@ƒ£jBZ!RA@M8H?5†¿‚lB!ZA·X|B–Ê”A·X|B–Ê”A@M8H?5†¿‚lB!ZA·X|B–Ê”A@‚lB!ZA@7?Äï2¿·X|B–Ê”A÷ù|B–A÷ù|B–A@7?Äï2¿·X|B–Ê”A÷ù|B–A@·X|B–Ê”A@˜!?*ÊP¿÷ù|B–A)½}B†)—A)½}B†)—A@˜!?*ÊP¿÷ù|B–A)½}B†)—A@÷ù|B–A@aTã>éae¿)½}B†)—A%™~BŠ˜A%™~BŠ˜A@aTã>éae¿)½}B†)—A%™~BŠ˜A@)½}B†)—A@_7ž>uxs¿%™~BŠ˜A½„B£œ˜A½„B£œ˜A@_7ž>uxs¿%™~BŠ˜A½„B£œ˜A@%™~BŠ˜A@Øz+>Œb|¿½„B£œ˜Ad;€BÝî˜Ad;€BÝî˜A@Øz+>Œb|¿½„B£œ˜Ad;€BÝî˜A@½„B£œ˜A@¥8<×û¿d;€BÝî˜A ³€BBô˜A ³€BBô˜A@¥8<×û¿d;€BÝî˜A ³€BBô˜A@d;€BÝî˜A@AÃ+¾y_|¿ ³€BBô˜AÃ$BÞ¦˜AÃ$BÞ¦˜A@AÃ+¾y_|¿€ ³€BBô˜AÃ$BÞ¦˜A@ ³€BBô˜A@)nˆ¾ƒ¾v¿Ã$BÞ¦˜A†dB4‹A†dB4‹A@)nˆ¾ƒ¾v¿€Ã$BÞ¦˜A†dB4‹A@Ã$BÞ¦˜A@[;>¾1‹{¿†dB4‹Ac»ŽBéŠAc»ŽBéŠA@[;>¾1‹{¿€†dB4‹Ac»ŽBéŠA@†dB4‹A@9)+=ÂÆ¿c»ŽBéŠA‚ÇBÄDŠA‚ÇBÄDŠA@9)+=ÂÆ¿c»ŽBéŠA‚ÇBÄDŠA@c»ŽBéŠA@Q¦Ê>k¿‚ÇBÄDŠAÁ„B‹‹AÁ„B‹‹A@Q¦Ê>k¿‚ÇBÄDŠAÁ„B‹‹A@‚ÇBÄDŠA@³O?&y¿Á„B‹‹AýîBæÓAýîBæÓA@³O?&y¿Á„B‹‹AýîBæÓA@Á„B‹‹A@3æ~?÷·½½ýîBæÓA‘B¦‘A‘B¦‘A@3æ~?÷·½½ýîBæÓA‘B¦‘A@ýîBæÓA@\v?Rº‰>‘B¦‘Aä¹B•Aä¹B•A@\v?Rº‰>‘B¦‘Aä¹B•A@‘B¦‘A@(‰`? ìõ>ä¹B•AJB´Ú™AJB´Ú™A@(‰`? ìõ>ä¹B•AJB´Ú™A@ä¹B•A@–U?ó ?JB´Ú™ẢBGDÄẢBGDÄA@–U?ó ?JB´Ú™ẢBGDÄA@JB´Ú™A@€¿ úeBøÑMA€ähB*}MAiRgB(LA€¿†êdB0¨RA€ähB*}MA úeBøÑMA€¿|/dBs„ZA€ähB*}MA†êdB0¨RA€¿|/dBs„ZAƒ£jBZ!RA€ähB*}MA€¿ãÖcBZUeAƒ£jBZ!RA|/dBs„ZA€¿ãÖcBZUeA‚lB!ZAƒ£jBZ!RA€¿ÚµbBds¥A‚lB!ZAãÖcBZUeA€¿ÚµbBds¥A·X|B–Ê”A‚lB!ZA€¿`”bBæ;§A·X|B–Ê”AÚµbBds¥A€¿`”bBæ;§A÷ù|B–A·X|B–Ê”A€¿ÛGbBq©A÷ù|B–A`”bBæ;§A€¿ÛGbBq©A)½}B†)—A÷ù|B–A€¿ÛGbBq©A%™~BŠ˜A)½}B†)—A€¿öÕaBl´ªA%™~BŠ˜AÛGbBq©A€¿ZDaB>E¬A%™~BŠ˜AöÕaBl´ªA€¿ZDaB>E¬A½„B£œ˜A%™~BŠ˜A€¿iRgB~B†êdBNÙB úeBÜB€¿ähB$B†êdBNÙBiRgB~B€¿‚£jBûB†êdBNÙBähB$B€¿‚£jBûB|/dB=âB†êdBNÙB€¿‚lBÿB|/dB=âB‚£jBûB€¿‚lBÿBâÖcB.B|/dB=âB€¿‚lBÿBÚµbBP“ïAâÖcB.B€¿·X|BBÚµbBP“ïA‚lBÿB€¿öù|B'òþAÚµbBP“ïA·X|BB€¿öù|B'òþA`”bBÎÊíAÚµbBP“ïA€¿)½}B.ÝýA`”bBÎÊíAöù|B'òþA€¿)½}B.ÝýAÚGbBCìA`”bBÎÊíA€¿)½}B.ÝýAõÕaBHRêAÚGbBCìA€¿$™~B+ýAõÕaBHRêA)½}B.ÝýA€¿½„BjüAõÕaBHRêA$™~B+ýA€¿½„BjüAZDaBvÁèAõÕaBHRêA€¿Á„B‹‹A‘B¦‘AýîBæÓA€¿‚ÇBÄDŠA‘B¦‘AÁ„B‹‹A€¿c»ŽBéŠA‘B¦‘A‚ÇBÄDŠA€¿c»ŽBéŠAä¹B•A‘B¦‘A€¿c»ŽBéŠAJB´Ú™Aä¹B•A€€¿†dB4‹AJB´Ú™Ac»ŽBéŠA€€¿Ã$BÞ¦˜AJB´Ú™A†dB4‹A€¿Ã$BÞ¦˜ẢBGDÄAJB´Ú™A€€¿ ³€BBô˜ẢBGDÄAÃ$BÞ¦˜A€¿ ³€BBô˜ABÛˆBôÜÅẢBGDÄA€¿d;€BÝî˜ABÛˆBôÜÅA ³€BBô˜A€¿d;€BÝî˜A‘·ˆBÕ¥ÇABÛˆBôÜÅA€¿d;€BÝî˜A¸¥ˆB¢‹ÉA‘·ˆBÕ¥ÇA€¿½„B£œ˜A¸¥ˆB¢‹ÉAd;€BÝî˜A€€¿ZDaB>E¬A¸¥ˆB¢‹ÉA½„B£œ˜A€¿ZDaB>E¬A¸¥ˆB{ËA¸¥ˆB¢‹ÉA€¿ZDaB>E¬A·ˆBß`ÍA¸¥ˆB{ËA€€¿´˜`BM¤­A·ˆBß`ÍAZDaB>E¬A€€¿­Ø_B®A·ˆBß`ÍA´˜`BM¤­A€¿­Ø_B®ABÛˆBÀ)ÏA·ˆBß`ÍA€€¿ð _B¿Ž¯ABÛˆBÀ)ÏA­Ø_B®A€¿ð _B¿Ž¯ẢBmÂÐABÛˆBÀ)ÏA€€¿ =GBöeÁẢBmÂÐAð _B¿Ž¯A€¿ =GBöeÁAJB,ûẢBmÂÐA€¿ =GBöeÁAä¹B4ôÿAJB,ûA€¿ =GBöeÁA‘BÿBä¹B4ôÿA€¿ =GBöeÁAýîBg™B‘BÿB€¿ =GBöeÁAÀ„BؽBýîBg™B€¿ =GBöeÁA‚ÇBø`BÀ„BؽB€¿ =GBöeÁAc»ŽBfwB‚ÇBø`B€¿ =GBöeÁA†dBÁõBc»ŽBfwB€¿ =GBöeÁAÃ$BÖ_üA†dBÁõB€¿ =GBöeÁA ³€BrüAÃ$BÖ_üA€¿ =GBöeÁAd;€BØüA ³€BrüA€¿ =GBöeÁA½„BjüAd;€BØüA€€¿ÆDBNºÃA½„BjüA =GBöeÁA€€¿p!CBýTÆA½„BjüAÆDBNºÃA€€¿OBBàÉA½„BjüAp!CBýTÆA€€¿OBBÓìËA½„BjüAOBBàÉA€€¿o!CB¶±ÎA½„BjüAOBBÓìËA€€¿ÆDBdLÑA½„BjüAo!CB¶±ÎA€€¿ =GB½ ÓA½„BjüAÆDBdLÑA€€¿ð _BôwåA½„BjüA =GB½ ÓA€€¿­Ø_B³DæA½„BjüAð _BôwåA€€¿´˜`BgbçA½„BjüA­Ø_B³DæA€¿´˜`BgbçAZDaBvÁèA½„BjüA€? úeBøÑMA@iRgB(LA@€ähB*}MA@€?†êdB0¨RA@ úeBøÑMA@€ähB*}MA@€?|/dBs„ZA@†êdB0¨RA@€ähB*}MA@€?|/dBs„ZA@€ähB*}MA@ƒ£jBZ!RA@€?ãÖcBZUeA@|/dBs„ZA@ƒ£jBZ!RA@€?ãÖcBZUeA@ƒ£jBZ!RA@‚lB!ZA@€?ÚµbBds¥A@ãÖcBZUeA@‚lB!ZA@€?ÚµbBds¥A@‚lB!ZA@·X|B–Ê”A@€?`”bBæ;§A@ÚµbBds¥A@·X|B–Ê”A@€?`”bBæ;§A@·X|B–Ê”A@÷ù|B–A@€?ÛGbBq©A@`”bBæ;§A@÷ù|B–A@€?ÛGbBq©A@÷ù|B–A@)½}B†)—A@€?ÛGbBq©A@)½}B†)—A@%™~BŠ˜A@€?öÕaBl´ªA@ÛGbBq©A@%™~BŠ˜A@€?ZDaB>E¬A@öÕaBl´ªA@%™~BŠ˜A@€?ZDaB>E¬A@%™~BŠ˜A@½„B£œ˜A@€?iRgB~B@ úeBÜB@†êdBNÙB@€€?ähB$B@iRgB~B@†êdBNÙB@€€?‚£jBûB@ähB$B@†êdBNÙB@€?‚£jBûB@†êdBNÙB@|/dB=âB@€€?‚lBÿB@‚£jBûB@|/dB=âB@€?‚lBÿB@|/dB=âB@âÖcB.B@€?‚lBÿB@âÖcB.B@ÚµbBP“ïA@€€?·X|BB@‚lBÿB@ÚµbBP“ïA@€€?öù|B'òþA@·X|BB@ÚµbBP“ïA@€?öù|B'òþA@ÚµbBP“ïA@`”bBÎÊíA@€€?)½}B.ÝýA@öù|B'òþA@`”bBÎÊíA@€?)½}B.ÝýA@`”bBÎÊíA@ÚGbBCìA@€?)½}B.ÝýA@ÚGbBCìA@õÕaBHRêA@€€?$™~B+ýA@)½}B.ÝýA@õÕaBHRêA@€€?½„BjüA@$™~B+ýA@õÕaBHRêA@€?½„BjüA@õÕaBHRêA@ZDaBvÁèA@€?Á„B‹‹A@ýîBæÓA@‘B¦‘A@€?‚ÇBÄDŠA@Á„B‹‹A@‘B¦‘A@€?c»ŽBéŠA@‚ÇBÄDŠA@‘B¦‘A@€?c»ŽBéŠA@‘B¦‘A@ä¹B•A@€?c»ŽBéŠA@ä¹B•A@JB´Ú™A@€?†dB4‹A@c»ŽBéŠA@JB´Ú™A@€?Ã$BÞ¦˜A@†dB4‹A@JB´Ú™A@€?Ã$BÞ¦˜A@JB´Ú™A@̉BGDÄA@€? ³€BBô˜A@Ã$BÞ¦˜A@̉BGDÄA@€? ³€BBô˜A@̉BGDÄA@BÛˆBôÜÅA@€?d;€BÝî˜A@ ³€BBô˜A@BÛˆBôÜÅA@€?d;€BÝî˜A@BÛˆBôÜÅA@‘·ˆBÕ¥ÇA@€?d;€BÝî˜A@‘·ˆBÕ¥ÇA@¸¥ˆB¢‹ÉA@€?½„B£œ˜A@d;€BÝî˜A@¸¥ˆB¢‹ÉA@€?ZDaB>E¬A@½„B£œ˜A@¸¥ˆB¢‹ÉA@€?ZDaB>E¬A@¸¥ˆB¢‹ÉA@¸¥ˆB{ËA@€?ZDaB>E¬A@¸¥ˆB{ËA@·ˆBß`ÍA@€?´˜`BM¤­A@ZDaB>E¬A@·ˆBß`ÍA@€?­Ø_B®A@´˜`BM¤­A@·ˆBß`ÍA@€?­Ø_B®A@·ˆBß`ÍA@BÛˆBÀ)ÏA@€?ð _B¿Ž¯A@­Ø_B®A@BÛˆBÀ)ÏA@€?ð _B¿Ž¯A@BÛˆBÀ)ÏA@̉BmÂÐA@€? =GBöeÁA@ð _B¿Ž¯A@̉BmÂÐA@€? =GBöeÁA@̉BmÂÐA@JB,ûA@€? =GBöeÁA@JB,ûA@ä¹B4ôÿA@€? =GBöeÁA@ä¹B4ôÿA@‘BÿB@€? =GBöeÁA@‘BÿB@ýîBg™B@€? =GBöeÁA@ýîBg™B@À„BؽB@€? =GBöeÁA@À„BؽB@‚ÇBø`B@€? =GBöeÁA@‚ÇBø`B@c»ŽBfwB@€? =GBöeÁA@c»ŽBfwB@†dBÁõB@€? =GBöeÁA@†dBÁõB@Ã$BÖ_üA@€? =GBöeÁA@Ã$BÖ_üA@ ³€BrüA@€? =GBöeÁA@ ³€BrüA@d;€BØüA@€? =GBöeÁA@d;€BØüA@½„BjüA@€?ÆDBNºÃA@ =GBöeÁA@½„BjüA@€?p!CBýTÆA@ÆDBNºÃA@½„BjüA@€?OBBàÉA@p!CBýTÆA@½„BjüA@€€?OBBÓìËA@OBBàÉA@½„BjüA@€€?o!CB¶±ÎA@OBBÓìËA@½„BjüA@€€?ÆDBdLÑA@o!CB¶±ÎA@½„BjüA@€€? =GB½ ÓA@ÆDBdLÑA@½„BjüA@€€?ð _BôwåA@ =GB½ ÓA@½„BjüA@€€?­Ø_B³DæA@ð _BôwåA@½„BjüA@€€?´˜`BgbçA@­Ø_B³DæA@½„BjüA@€?´˜`BgbçA@½„BjüA@ZDaBvÁèA@sfact-2011.12.18/calibration/testpiece.STL000066400000000000000000001066741167321211700200660ustar00rootroot00000000000000solid testpiece Ô€?"³|A×_ŠA AÅA:Î…A A‡A‡A A€?‡A‡A AÅA:Î…A A:Î…AÅA A€?‡A‡A A:Î…AÅA AYO‹AÉ…ƒA A€?YO‹AÉ…ƒA A:Î…AÅA A×_ŠA"³|A A€?YO‹AÉ…ƒA A×_ŠA"³|A AAö¢€A A€?Aö¢€A A×_ŠA"³|A A&bA½:wA A€?Aö¢€A A&bA½:wA Ab•A® }A A€?b•A® }A A&bA½:wA A»”A–=sA A€?b•A® }A A»”A–=sA AW~šA~wzA A€?W~šA~wzA A»”A–=sA A²NšAuÐpA A€?W~šA~wzA A²NšAuÐpA A Aš™yA A€? Aš™yA A²NšAuÐpA A ApA A€? Aš™yA A ApA Aš™ Bš™yA A€?š™ Bš™yA A ApA A BpA A€?š™ Bš™yA A BpA Aš™ Bš™ B A€?š™ Bš™ B A BpA A B B A€?š™ Bš™ B A B B Aš™yAš™ B A€?š™yAš™ B A B B ApA B A€?š™yAš™ B ApA B Aš™yA A A€?š™yA A ApA B ApA A A€?š™yA A ApA A A~wzAW~šA A€?~wzAW~šA ApA A AuÐpA²NšA A€?~wzAW~šA AuÐpA²NšA A® }Ab•A A€?® }Ab•A AuÐpA²NšA A–=sA»”A A€?® }Ab•A A–=sA»”A Aö¢€AA A€?ö¢€AA A–=sA»”A A½:wA&bA A€?ö¢€AA A½:wA&bA AÉ…ƒAYO‹A A€?É…ƒAYO‹A A½:wA&bA A"³|A×_ŠA A€?É…ƒAYO‹A A"³|A×_ŠA A‡A‡A A€¿&bA½:wA×_ŠA"³|AYO‹AÉ…ƒA€¿YO‹AÉ…ƒA×_ŠA"³|A:Î…AÅA€¿YO‹AÉ…ƒA:Î…AÅA‡A‡A€¿‡A‡A:Î…AÅAÅA:Î…A€¿‡A‡AÅA:Î…AÉ…ƒAYO‹A€¿É…ƒAYO‹AÅA:Î…A"³|A×_ŠA€¿É…ƒAYO‹A"³|A×_ŠAö¢€AA€¿ö¢€AA"³|A×_ŠA½:wA&bA€¿ö¢€AA½:wA&bA® }Ab•A€¿® }Ab•A½:wA&bA–=sA»”A€¿® }Ab•A–=sA»”A~wzAW~šA€¿~wzAW~šA–=sA»”AuÐpA²NšA€¿~wzAW~šAuÐpA²NšAš™yA A€¿š™yA AuÐpA²NšApA A€¿š™yA ApA Aš™yAš™ B€¿š™yAš™ BpA ApA B€¿š™yAš™ BpA Bš™ Bš™ B€¿š™ Bš™ BpA B B B€¿š™ Bš™ B B Bš™ Bš™yA€¿š™ Bš™yA B B BpA€¿š™ Bš™yA BpA Aš™yA€¿ Aš™yA BpA ApA€¿ Aš™yA ApAW~šA~wzA€¿W~šA~wzA ApA²NšAuÐpA€¿W~šA~wzA²NšAuÐpAb•A® }A€¿b•A® }A²NšAuÐpA»”A–=sA€¿b•A® }A»”A–=sAAö¢€A€¿Aö¢€A»”A–=sA&bA½:wA€¿Aö¢€A&bA½:wAYO‹AÉ…ƒA€¿pA A ApA B ApA A€¿pA ApA B ApA Bâµ¿Š¿B½pA A ApA AuÐpA²NšA×~¿‰¿Â½pA A AuÐpA²NšAuÐpA²NšA A!`{¿ÐÁA¾uÐpA²NšA AuÐpA²NšA–=sA»”AÈx¿÷sq¾uÐpA²NšA A–=sA»”A–=sA»”A AYìq¿þp§¾–=sA»”A A–=sA»”A½:wA&bA¥¨m¿íN¾¾–=sA»”A A½:wA&bA½:wA&bA AÍ‹c¿y˜ê¾½:wA&bA A½:wA&bA"³|A×_ŠA©²]¿ ¿½:wA&bA A"³|A×_ŠA"³|A×_ŠA Ak‰P¿°|¿"³|A×_ŠA A"³|A×_ŠAÅA:Î…AQ9I¿†A¿"³|A×_ŠA AÅA:Î…AÅA:Î…A ADH9¿O§0¿ÅA:Î…A AÅA:Î…A:Î…AÅAO§0¿DH9¿ÅA:Î…A A:Î…AÅA:Î…AÅA A†A¿Q9I¿:Î…AÅA A:Î…AÅA×_ŠA"³|A°|¿k‰P¿:Î…AÅA A×_ŠA"³|A×_ŠA"³|A A ¿©²]¿×_ŠA"³|A A×_ŠA"³|A&bA½:wAy˜ê¾Í‹c¿×_ŠA"³|A A&bA½:wA&bA½:wA AíN¾¾¥¨m¿&bA½:wA A&bA½:wA»”A–=sAþp§¾Yìq¿&bA½:wA A»”A–=sA»”A–=sA A÷sq¾Èx¿»”A–=sA A»”A–=sA²NšAuÐpAÐÁA¾!`{¿»”A–=sA A²NšAuÐpA²NšAuÐpA A‰¿Â½×~¿²NšAuÐpA A²NšAuÐpA ApAŠ¿B½âµ¿²NšAuÐpA A ApA ApA A€¿ BpA A ApA A BpA€¿ BpA ApA A ApA€? B B A BpA A B B€? B B BpA A BpA€?pA B A B B ApA B€?pA B B B A B B€?š™yAš™ B Aš™yA A Aš™yAš™ B€?š™yAš™ Bš™yA A Aš™yA A,V=Y¦? Aš™yA A Aš™yAW~šA~wzA,Ö=¨˜~? Aš™yA AW~šA~wzAW~šA~wzA A‚ÚT>‰hz?W~šA~wzA AW~šA~wzAb•A® }AŠ„>Fw?W~šA~wzA Ab•A® }Ab•A® }A A#v·>Ao?b•A® }A Ab•A® }AAö¢€A‡EÐ>ÖÜi?b•A® }A AAö¢€AAö¢€A AŽúÿ>iµ]?Aö¢€A AAö¢€AYO‹AÉ…ƒAp ?g±V?Aö¢€A AYO‹AÉ…ƒAYO‹AÉ…ƒA A²!?õF?YO‹AÉ…ƒA AYO‹AÉ…ƒA‡A‡A{N+?¢<>?YO‹AÉ…ƒA A‡A‡A‡A‡A A¢<>?{N+?‡A‡A A‡A‡AÉ…ƒAYO‹AõF?²!?‡A‡A AÉ…ƒAYO‹AÉ…ƒAYO‹A Ag±V?p ?É…ƒAYO‹A AÉ…ƒAYO‹Aö¢€AAiµ]?Žúÿ>É…ƒAYO‹A Aö¢€AAö¢€AA AÖÜi?‡EÐ>ö¢€AA Aö¢€AA® }Ab•AAo?#v·>ö¢€AA A® }Ab•A® }Ab•A AFw?Š„>® }Ab•A A® }Ab•A~wzAW~šA‰hz?‚ÚT>® }Ab•A A~wzAW~šA~wzAW~šA A¨˜~?,Ö=~wzAW~šA A~wzAW~šAš™yA AY¦?,V=~wzAW~šA Aš™yA Aš™yA A A€? Aš™yA Aš™ Bš™yA A Aš™yA€? Aš™yAš™ Bš™yA Aš™ Bš™yA€¿š™ Bš™yA Aš™ Bš™ B Aš™ Bš™yA€¿š™ Bš™yAš™ Bš™ B Aš™ Bš™ B€¿š™ Bš™ B Aš™yAš™ B Aš™ Bš™ B€¿š™ Bš™ Bš™yAš™ B Aš™yAš™ B€?Ù BÈ(B A^³ BB AË’B)B A€?Ë’B)B A^³ BB A BÂûB A€?Ë’B)B A BÂûB AĵBi–B A€?ĵBi–B A BÂûB Aï÷BC#B A€?ĵBi–B Aï÷BC#B AÙQBb$B A€?ÙQBb$B Aï÷BC#B A/QB;ä'B A€?ÙQBb$B A/QB;ä'B A_xBò~(B A€?_xBò~(B A/QB;ä'B AE;B Ó+B A€?_xBò~(B AE;B Ó+B Aí;Büá+B A€?í;Büá+B AE;B Ó+B AŸ‘ÿA*/B A€?í;Büá+B AŸ‘ÿA*/B AL`óAô.B A€?L`óAô.B AŸ‘ÿA*/B AºðA8r1B A€?L`óAô.B AºðA8r1B A ÓãA½W0B A€? ÓãA½W0B AºðA8r1B A{:àAÕ3B A€? ÓãA½W0B A{:àAÕ3B AFúÓAY^1B A€?FúÓAY^1B A{:àAÕ3B A—ÐA·å3B A€?FúÓAY^1B A—ÐA·å3B AÄA“1B A€?ÄA“1B A—ÐA·å3B Aiå¿A·å3B A€?ÄA“1B Aiå¿A·å3B A”´A+õ0B A€?”´A+õ0B Aiå¿A·å3B A…ůAÕ3B A€?”´A+õ0B A…ůAÕ3B A;Z¤A{†/B A€?;Z¤A{†/B A…ůAÕ3B AFåŸA8r1B A€?;Z¤A{†/B AFåŸA8r1B Až•AÙJ-B A€?ž•AÙJ-B AFåŸA8r1B A`nA*/B A€?ž•AÙJ-B A`nA*/B A`5†ARH*B A€?`5†ARH*B A`nA*/B Au‰A Ó+B A€?`5†ARH*B Au‰A Ó+B AU5pA‡&B A€?U5pA‡&B Au‰A Ó+B AE»fA;ä'B A€?U5pA‡&B AE»fA;ä'B A‰±UAJ"B A€?‰±UAJ"B AE»fA;ä'B AG LAC#B A€?‰±UAJ"B AG LAC#B AP'=AóB A€?P'=AóB AG LAC#B AÕ‡3AÂûB A€?P'=AóB AÕ‡3AÂûB ABÙ&AQ:B A€?BÙ&AQ:B AÕ‡3AÂûB A‰2AB A€?BÙ&AQ:B A‰2AB AåAöB A€?åAöB A‰2AB A[ A“³B A€?åAöB A[ A“³B A ÝAÄ8 B A€? ÝAÄ8 B A[ A“³B Akð@üÒ B A€? ÝAÄ8 B Akð@üÒ B A„&ç@BB A€?„&ç@BB Akð@üÒ B AöÝÓ@hŒB A€?„&ç@BB AöÝÓ@hŒB AžšÐ@Ù2÷A A€?žšÐ@Ù2÷A AöÝÓ@hŒB AÕY½@êå÷A A€?žšÐ@Ù2÷A AÕY½@êå÷A A‘SÀ@¿çA A€?‘SÀ@¿çA AÕY½@êå÷A AЭ@15èA A€?‘SÀ@¿çA AЭ@15èA Aˆ}¶@4õ×A A€?ˆ}¶@4õ×A AЭ@15èA AH£@Û/ØA A€?ˆ}¶@4õ×A AH£@Û/ØA A33³@ÈA A€?33³@ÈA AH£@Û/ØA A @ÈA A€?33³@ÈA A @ÈA Aˆ}¶@Í ¸A A€?ˆ}¶@Í ¸A A @ÈA AH£@%зA A€?ˆ}¶@Í ¸A AH£@%зA A‘SÀ@ç@¨A A€?‘SÀ@ç@¨A AH£@%зA AЭ@ÐʧA A€?‘SÀ@ç@¨A AЭ@ÐʧA AžšÐ@'͘A A€?žšÐ@'͘A AЭ@ÐʧA AÕY½@˜A A€?žšÐ@'͘A AÕY½@˜A A„&ç@|Ù‰A A€?„&ç@|Ù‰A AÕY½@˜A AöÝÓ@/çˆA A€?„&ç@|Ù‰A AöÝÓ@/çˆA A ÝAówA A€? ÝAówA AöÝÓ@/çˆA Akð@´tA A€? ÝAówA Akð@´tA AåAÐ%\A A€?åAÐ%\A Akð@´tA A[ Aµ1YA A€?åAÐ%\A A[ Aµ1YA ABÙ&A»CA A€?BÙ&A»CA A[ Aµ1YA A‰2A‘?A A€?BÙ&A»CA A‰2A‘?A AP'=A¶3,A A€?P'=A¶3,A A‰2A‘?A AÕ‡3Aú(A A€?P'=A¶3,A AÕ‡3Aú(A A‰±UAÛºA A€?‰±UAÛºA AÕ‡3Aú(A AG LA§óA A€?‰±UAÛºA AG LA§óA AU5pAºãA A€?U5pAºãA AG LA§óA AE»fAoA A€?U5pAºãA AE»fAoA A`5†As½í@ A€?`5†As½í@ AE»fAoA Au‰A´gá@ A€?`5†As½í@ Au‰A´gá@ Až•A<©Õ@ A€?ž•A<©Õ@ Au‰A´gá@ A`nA±ÖÇ@ A€?ž•A<©Õ@ A`nA±ÖÇ@ A;Z¤A)ÌÃ@ A€?;Z¤A)ÌÃ@ A`nA±ÖÇ@ AFåŸA?n´@ A€?;Z¤A)ÌÃ@ AFåŸA?n´@ A”´A¬V¸@ A€?”´A¬V¸@ AFåŸA?n´@ A…ůAZa§@ A€?”´A¬V¸@ A…ůAZa§@ AÄAãg³@ A€?ÄAãg³@ A…ůAZa§@ Aiå¿AJÒ @ A€?ÄAãg³@ Aiå¿AJÒ @ AFúÓA3 µ@ A€?FúÓA3 µ@ Aiå¿AJÒ @ A—ÐAJÒ @ A€?FúÓA3 µ@ A—ÐAJÒ @ A ÓãAB½@ A€? ÓãAB½@ A—ÐAJÒ @ A{:àAZa§@ A€? ÓãAB½@ A{:àAZa§@ AL`óA`ðË@ A€?L`óA`ðË@ A{:àAZa§@ AºðA?n´@ A€?L`óA`ðË@ AºðA?n´@ Aí;B'ðà@ A€?í;B'ðà@ AºðA?n´@ AŸ‘ÿA±ÖÇ@ A€?í;B'ðà@ AŸ‘ÿA±ÖÇ@ A_xBrü@ A€?_xBrü@ AŸ‘ÿA±ÖÇ@ AE;B´gá@ A€?_xBrü@ AE;B´gá@ AÙQBáwA A€?ÙQBáwA AE;B´gá@ A/QBoA A€?ÙQBáwA A/QBoA AĵBa¦!A A€?ĵBa¦!A A/QBoA Aï÷B§óA A€?ĵBa¦!A Aï÷B§óA AË’B°[7A A€?Ë’B°[7A Aï÷B§óA A Bú(A A€?Ë’B°[7A A Bú(A AÙ Bá\OA A€?Ù Bá\OA A Bú(A A^³ B‘?A A€?Ù Bá\OA A^³ B‘?A Az%BÖhiA A€?z%BÖhiA A^³ B‘?A A<©%Bµ1YA A€?z%BÖhiA A<©%Bµ1YA A†i)Bnœ‚A A€?†i)Bnœ‚A A<©%Bµ1YA Ažò)B´tA A€?†i)Bnœ‚A Ažò)B´tA A“œ,B½@‘A A€?“œ,B½@‘A Ažò)B´tA AB„-B/çˆA A€?“œ,B½@‘A AB„-B/çˆA A– /By A A€?– /By A AB„-B/çˆA AÅT0B˜A A€?– /By A AÅT0B˜A Aõ¬0B¾°A A€?õ¬0B¾°A AÅT0B˜A AÆ\2BÐʧA A€?õ¬0B¾°A AÆ\2BÐʧA AC1B±ÀA A€?C1B±ÀA AÆ\2BÐʧA Aì–3B%зA A€?C1B±ÀA Aì–3B%зA A™™1BÈA A€?™™1BÈA Aì–3B%зA A4BÈA A€?™™1BÈA A4BÈA AC1BPýÏA A€?C1BPýÏA A4BÈA Aì–3BÛ/ØA A€?C1BPýÏA Aì–3BÛ/ØA Aõ¬0BBâßA A€?õ¬0BBâßA Aì–3BÛ/ØA AÆ\2B15èA A€?õ¬0BBâßA AÆ\2B15èA A– /Bd†ïA A€?– /Bd†ïA AÆ\2B15èA AÅT0Bêå÷A A€?– /Bd†ïA AÅT0Bêå÷A A“œ,BC¿þA A€?“œ,BC¿þA AÅT0Bêå÷A AB„-BhŒB A€?“œ,BC¿þA AB„-BhŒB A†i)BʱB A€?†i)BʱB AB„-BhŒB Ažò)BüÒ B A€?†i)BʱB Ažò)BüÒ B Az%BË¥ B A€?z%BË¥ B Ažò)BüÒ B A<©%B“³B A€?z%BË¥ B A<©%B“³B AÙ BÈ(B A€?Ù BÈ(B A<©%B“³B A^³ BB A€¿žšÐ@Ù2÷AÕY½@êå÷A„&ç@BB€¿„&ç@BBÕY½@êå÷AöÝÓ@hŒB€¿„&ç@BBöÝÓ@hŒB ÝAÄ8 B€¿ ÝAÄ8 BöÝÓ@hŒBkð@üÒ B€¿ ÝAÄ8 Bkð@üÒ BåAöB€¿åAöBkð@üÒ B[ A“³B€¿åAöB[ A“³BBÙ&AQ:B€¿BÙ&AQ:B[ A“³B‰2AB€¿BÙ&AQ:B‰2ABP'=AóB€¿P'=AóB‰2ABÕ‡3AÂûB€¿P'=AóBÕ‡3AÂûB‰±UAJ"B€¿‰±UAJ"BÕ‡3AÂûBG LAC#B€¿‰±UAJ"BG LAC#BU5pA‡&B€¿U5pA‡&BG LAC#BE»fA;ä'B€¿U5pA‡&BE»fA;ä'B`5†ARH*B€¿`5†ARH*BE»fA;ä'Bu‰A Ó+B€¿`5†ARH*Bu‰A Ó+Bž•AÙJ-B€¿ž•AÙJ-Bu‰A Ó+B`nA*/B€¿ž•AÙJ-B`nA*/B;Z¤A{†/B€¿;Z¤A{†/B`nA*/BFåŸA8r1B€¿;Z¤A{†/BFåŸA8r1B”´A+õ0B€¿”´A+õ0BFåŸA8r1B…ůAÕ3B€¿”´A+õ0B…ůAÕ3BÄA“1B€¿ÄA“1B…ůAÕ3Biå¿A·å3B€¿ÄA“1Biå¿A·å3BFúÓAY^1B€¿FúÓAY^1Biå¿A·å3B—ÐA·å3B€¿FúÓAY^1B—ÐA·å3B ÓãA½W0B€¿ ÓãA½W0B—ÐA·å3B{:àAÕ3B€¿ ÓãA½W0B{:àAÕ3BL`óAô.B€¿L`óAô.B{:àAÕ3BºðA8r1B€¿L`óAô.BºðA8r1Bí;Büá+B€¿í;Büá+BºðA8r1BŸ‘ÿA*/B€¿í;Büá+BŸ‘ÿA*/B_xBò~(B€¿_xBò~(BŸ‘ÿA*/BE;B Ó+B€¿_xBò~(BE;B Ó+BÙQBb$B€¿ÙQBb$BE;B Ó+B/QB;ä'B€¿ÙQBb$B/QB;ä'BĵBi–B€¿ÄµBi–B/QB;ä'Bï÷BC#B€¿ÄµBi–Bï÷BC#BË’B)B€¿Ë’B)Bï÷BC#B BÂûB€¿Ë’B)B BÂûBÙ BÈ(B€¿Ù BÈ(B BÂûB^³ BB€¿Ù BÈ(B^³ BBz%BË¥ B€¿z%BË¥ B^³ BB<©%B“³B€¿z%BË¥ B<©%B“³B†i)BʱB€¿†i)BʱB<©%B“³Bžò)BüÒ B€¿†i)BʱBžò)BüÒ B“œ,BC¿þA€¿“œ,BC¿þAžò)BüÒ BB„-BhŒB€¿“œ,BC¿þAB„-BhŒB– /Bd†ïA€¿– /Bd†ïAB„-BhŒBÅT0Bêå÷A€¿– /Bd†ïAÅT0Bêå÷Aõ¬0BBâßA€¿õ¬0BBâßAÅT0Bêå÷AÆ\2B15èA€¿õ¬0BBâßAÆ\2B15èAC1BPýÏA€¿C1BPýÏAÆ\2B15èAì–3BÛ/ØA€¿C1BPýÏAì–3BÛ/ØA™™1BÈA€¿™™1BÈAì–3BÛ/ØA4BÈA€¿™™1BÈA4BÈAC1B±ÀA€¿C1B±ÀA4BÈAì–3B%зA€¿C1B±ÀAì–3B%зAõ¬0B¾°A€¿õ¬0B¾°Aì–3B%зAÆ\2BÐʧA€¿õ¬0B¾°AÆ\2BÐʧA– /By A€¿– /By AÆ\2BÐʧAÅT0B˜A€¿– /By AÅT0B˜A“œ,B½@‘A€¿“œ,B½@‘AÅT0B˜AB„-B/çˆA€¿“œ,B½@‘AB„-B/çˆA†i)Bnœ‚A€¿†i)Bnœ‚AB„-B/çˆAžò)B´tA€¿†i)Bnœ‚Ažò)B´tAz%BÖhiA€¿z%BÖhiAžò)B´tA<©%Bµ1YA€¿z%BÖhiA<©%Bµ1YAÙ Bá\OA€¿Ù Bá\OA<©%Bµ1YA^³ B‘?A€¿Ù Bá\OA^³ B‘?AË’B°[7A€¿Ë’B°[7A^³ B‘?A Bú(A€¿Ë’B°[7A Bú(AĵBa¦!A€¿ÄµBa¦!A Bú(Aï÷B§óA€¿ÄµBa¦!Aï÷B§óAÙQBáwA€¿ÙQBáwAï÷B§óA/QBoA€¿ÙQBáwA/QBoA_xBrü@€¿_xBrü@/QBoAE;B´gá@€¿_xBrü@E;B´gá@í;B'ðà@€¿í;B'ðà@E;B´gá@Ÿ‘ÿA±ÖÇ@€¿í;B'ðà@Ÿ‘ÿA±ÖÇ@L`óA`ðË@€¿L`óA`ðË@Ÿ‘ÿA±ÖÇ@ºðA?n´@€¿L`óA`ðË@ºðA?n´@ ÓãAB½@€¿ ÓãAB½@ºðA?n´@{:àAZa§@€¿ ÓãAB½@{:àAZa§@FúÓA3 µ@€¿FúÓA3 µ@{:àAZa§@—ÐAJÒ @€¿FúÓA3 µ@—ÐAJÒ @ÄAãg³@€¿ÄAãg³@—ÐAJÒ @iå¿AJÒ @€¿ÄAãg³@iå¿AJÒ @”´A¬V¸@€¿”´A¬V¸@iå¿AJÒ @…ůAZa§@€¿”´A¬V¸@…ůAZa§@;Z¤A)ÌÃ@€¿;Z¤A)ÌÃ@…ůAZa§@FåŸA?n´@€¿;Z¤A)ÌÃ@FåŸA?n´@ž•A<©Õ@€¿ž•A<©Õ@FåŸA?n´@`nA±ÖÇ@€¿ž•A<©Õ@`nA±ÖÇ@`5†As½í@€¿`5†As½í@`nA±ÖÇ@u‰A´gá@€¿`5†As½í@u‰A´gá@U5pAºãA€¿U5pAºãAu‰A´gá@E»fAoA€¿U5pAºãAE»fAoA‰±UAÛºA€¿‰±UAÛºAE»fAoAG LA§óA€¿‰±UAÛºAG LA§óAP'=A¶3,A€¿P'=A¶3,AG LA§óAÕ‡3Aú(A€¿P'=A¶3,AÕ‡3Aú(ABÙ&A»CA€¿BÙ&A»CAÕ‡3Aú(A‰2A‘?A€¿BÙ&A»CA‰2A‘?AåAÐ%\A€¿åAÐ%\A‰2A‘?A[ Aµ1YA€¿åAÐ%\A[ Aµ1YA ÝAówA€¿ ÝAówA[ Aµ1YAkð@´tA€¿ ÝAówAkð@´tA„&ç@|Ù‰A€¿„&ç@|Ù‰Akð@´tAöÝÓ@/çˆA€¿„&ç@|Ù‰AöÝÓ@/çˆAžšÐ@'͘A€¿žšÐ@'͘AöÝÓ@/çˆAÕY½@˜A€¿žšÐ@'͘AÕY½@˜A‘SÀ@ç@¨A€¿‘SÀ@ç@¨AÕY½@˜AЭ@ÐʧA€¿‘SÀ@ç@¨AЭ@ÐʧAˆ}¶@Í ¸A€¿ˆ}¶@Í ¸AЭ@ÐʧAH£@%зA€¿ˆ}¶@Í ¸AH£@%зA33³@ÈA€¿33³@ÈAH£@%зA @ÈA€¿33³@ÈA @ÈAˆ}¶@4õ×A€¿ˆ}¶@4õ×A @ÈAH£@Û/ØA€¿ˆ}¶@4õ×AH£@Û/ØA‘SÀ@¿çA€¿‘SÀ@¿çAH£@Û/ØAЭ@15èA€¿‘SÀ@¿çAЭ@15èAžšÐ@Ù2÷A€¿žšÐ@Ù2÷AЭ@15èAÕY½@êå÷A£Ú¿GI =H£@Û/ØA A @ÈA @ÈA A£Ú¿GI ½ @ÈA A @ÈAH£@%зAnj¿GIн @ÈA AH£@%зAH£@%зA A¿ª}¿vî ¾H£@%зA AH£@%зAЭ@ÐʧAE[|¿÷%,¾H£@%зA AЭ@ÐʧAЭ@ÐʧA A}àx¿Eào¾Ð­@ÐʧA AЭ@ÐʧAÕY½@˜A0µv¿Š±ˆ¾Ð­@ÐʧA AÕY½@˜AÕY½@˜A Auˆq¿ú­©¾ÕY½@˜A AÕY½@˜AöÝÓ@/çˆA‡n¿é¹¾ÕY½@˜A AöÝÓ@/çˆAöÝÓ@/çˆA Añµg¿®Ù¾öÝÓ@/çˆA AöÝÓ@/çˆAkð@´tAHæc¿8é¾öÝÓ@/çˆA Akð@´tAkð@´tA A¾‚[¿.¹¿kð@´tA Akð@´tA[ Aµ1YAÞîV¿I ¿kð@´tA A[ Aµ1YA[ Aµ1YA AêM¿LA¿[ Aµ1YA A[ Aµ1YA‰2A‘?AÖÂG¿2 ¿[ Aµ1YA A‰2A‘?A‰2A‘?A Ai€<¿Ó6-¿‰2A‘?A A‰2A‘?AÕ‡3Aú(AŠ6¿Œ|3¿‰2A‘?A AÕ‡3Aú(AÕ‡3Aú(A A¼*¿Ve?¿Õ‡3Aú(A AÕ‡3Aú(AG LA§óAÃq#¿gE¿Õ‡3Aú(A AG LA§óAG LA§óA AtÆ¿O¿G LA§óA AG LA§óAE»fAoA¬¿«ŽT¿G LA§óA AE»fAoAE»fAoA A»¿l³]¿E»fAoA AE»fAoAu‰A´gá@]ßð¾’æa¿E»fAoA Au‰A´gá@u‰A´gá@ A‚ÕѾbƒi¿u‰A´gá@ Au‰A´gá@`nA±ÖÇ@¾íÁ¾ íl¿u‰A´gá@ A`nA±ÖÇ@`nA±ÖÇ@ AW‚¡¾îír¿`nA±ÖÇ@ A`nA±ÖÇ@FåŸA?n´@²þ¾%…u¿`nA±ÖÇ@ AFåŸA?n´@FåŸA?n´@ AÎ _¾RÚy¿FåŸA?n´@ AFåŸA?n´@…ůAZa§@ƒ%=¾I˜{¿FåŸA?n´@ A…ůAZa§@…ůAZa§@ Aý™ñ½`6~¿…ůAZa§@ A…ůAZa§@iå¿AJÒ @ˆ¹¬½‚¿…ůAZa§@ Aiå¿AJÒ @iå¿AJÒ @ AÆvм£ö¿iå¿AJÒ @ Aiå¿AJÒ @—ÐAJÒ @ÆvŠ<£ö¿iå¿AJÒ @ A—ÐAJÒ @—ÐAJÒ @ Aˆ¹¬=‚¿—ÐAJÒ @ A—ÐAJÒ @{:àAZa§@ý™ñ=`6~¿—ÐAJÒ @ A{:àAZa§@{:àAZa§@ Aƒ%=>I˜{¿{:àAZa§@ A{:àAZa§@ºðA?n´@Î _>RÚy¿{:àAZa§@ AºðA?n´@ºðA?n´@ A²þ>%…u¿ºðA?n´@ AºðA?n´@Ÿ‘ÿA±ÖÇ@W‚¡>îír¿ºðA?n´@ AŸ‘ÿA±ÖÇ@Ÿ‘ÿA±ÖÇ@ A¾íÁ> íl¿Ÿ‘ÿA±ÖÇ@ AŸ‘ÿA±ÖÇ@E;B´gá@‚ÕÑ>bƒi¿Ÿ‘ÿA±ÖÇ@ AE;B´gá@E;B´gá@ A]ßð>’æa¿E;B´gá@ AE;B´gá@/QBoA»?l³]¿E;B´gá@ A/QBoA/QBoA A¬?«ŽT¿/QBoA A/QBoAï÷B§óAtÆ?O¿/QBoA Aï÷B§óAï÷B§óA AÃq#?gE¿ï÷B§óA Aï÷B§óA Bú(A¼*?Ve?¿ï÷B§óA A Bú(A Bú(A AŠ6?Œ|3¿ Bú(A A Bú(A^³ B‘?Ai€ì–3BÛ/ØA Aì–3BÛ/ØAÆ\2B15èAE[|?÷%,>ì–3BÛ/ØA AÆ\2B15èAÆ\2B15èA A}àx?Eào>Æ\2B15èA AÆ\2B15èAÅT0Bêå÷A0µv?бˆ>Æ\2B15èA AÅT0Bêå÷AÅT0Bêå÷A Auˆq?ú­©>ÅT0Bêå÷A AÅT0Bêå÷AB„-BhŒB‡n?é¹>ÅT0Bêå÷A AB„-BhŒBB„-BhŒB Añµg?®Ù>B„-BhŒB AB„-BhŒBžò)BüÒ BHæc?8é>B„-BhŒB Ažò)BüÒ Bžò)BüÒ B A¾‚[?.¹?žò)BüÒ B Ažò)BüÒ B<©%B“³BÞîV?I ?žò)BüÒ B A<©%B“³B<©%B“³B AêM?LA?<©%B“³B A<©%B“³B^³ BBÖÂG?2 ?<©%B“³B A^³ BB^³ BB Ai€’æa?/QB;ä'B AE;B Ó+BE;B Ó+B A‚ÕÑ>bƒi?E;B Ó+B AE;B Ó+BŸ‘ÿA*/B¾íÁ> íl?E;B Ó+B AŸ‘ÿA*/BŸ‘ÿA*/B AW‚¡>îír?Ÿ‘ÿA*/B AŸ‘ÿA*/BºðA8r1B²þ>%…u?Ÿ‘ÿA*/B AºðA8r1BºðA8r1B AÎ _>RÚy?ºðA8r1B AºðA8r1B{:àAÕ3Bƒ%=>I˜{?ºðA8r1B A{:àAÕ3B{:àAÕ3B Aý™ñ=`6~?{:àAÕ3B A{:àAÕ3B—ÐA·å3Bˆ¹¬=‚?{:àAÕ3B A—ÐA·å3B—ÐA·å3B AÆvŠ<£ö?—ÐA·å3B A—ÐA·å3Biå¿A·å3BÆvм£ö?—ÐA·å3B Aiå¿A·å3Biå¿A·å3B Aˆ¹¬½‚?iå¿A·å3B Aiå¿A·å3B…ůAÕ3Bý™ñ½`6~?iå¿A·å3B A…ůAÕ3B…ůAÕ3B Aƒ%=¾I˜{?…ůAÕ3B A…ůAÕ3BFåŸA8r1BÎ _¾RÚy?…ůAÕ3B AFåŸA8r1BFåŸA8r1B A²þ¾%…u?FåŸA8r1B AFåŸA8r1B`nA*/BW‚¡¾îír?FåŸA8r1B A`nA*/B`nA*/B A¾íÁ¾ íl?`nA*/B A`nA*/Bu‰A Ó+B‚ÕѾbƒi?`nA*/B Au‰A Ó+Bu‰A Ó+B A]ßð¾’æa?u‰A Ó+B Au‰A Ó+BE»fA;ä'B»¿l³]?u‰A Ó+B AE»fA;ä'BE»fA;ä'B A¬¿«ŽT?E»fA;ä'B AE»fA;ä'BG LAC#BtÆ¿O?E»fA;ä'B AG LAC#BG LAC#B AÃq#¿gE?G LAC#B AG LAC#BÕ‡3AÂûB¼*¿Ve??G LAC#B AÕ‡3AÂûBÕ‡3AÂûB AŠ6¿Œ|3?Õ‡3AÂûB AÕ‡3AÂûB‰2ABi€<¿Ó6-?Õ‡3AÂûB A‰2AB‰2AB AÖÂG¿2 ?‰2AB A‰2AB[ A“³BêM¿LA?‰2AB A[ A“³B[ A“³B AÞîV¿I ?[ A“³B A[ A“³Bkð@üÒ B¾‚[¿.¹?[ A“³B Akð@üÒ Bkð@üÒ B AHæc¿8é>kð@üÒ B Akð@üÒ BöÝÓ@hŒBñµg¿®Ù>kð@üÒ B AöÝÓ@hŒBöÝÓ@hŒB A‡n¿é¹>öÝÓ@hŒB AöÝÓ@hŒBÕY½@êå÷Auˆq¿ú­©>öÝÓ@hŒB AÕY½@êå÷AÕY½@êå÷A A0µv¿Š±ˆ>ÕY½@êå÷A AÕY½@êå÷AЭ@15èA}àx¿Eào>ÕY½@êå÷A AЭ@15èAЭ@15èA AE[|¿÷%,>Э@15èA AЭ@15èAH£@Û/ØA¿ª}¿vî >Э@15èA AH£@Û/ØAH£@Û/ØA Anj¿GIŠ=H£@Û/ØA AH£@Û/ØA @ÈAXö¿ÞœŒ<C1B±ÀA A™™1BÈA A™™1BÈAXö¿ÞœŒ¼™™1BÈA™™1BÈA AC1BPýÏA_Ù¿Þœ =™™1BÈAC1B±ÀAC1B±ÀA AÌ¿kŒ¯=C1B±ÀA AC1B±ÀAõ¬0B¾°AC'~¿L‹õ=C1B±ÀA Aõ¬0B¾°Aõ¬0B¾°A A s{¿Ò5@>õ¬0B¾°A Aõ¬0B¾°A– /By A„¦y¿Œ¦b>õ¬0B¾°A A– /By A– /By A A-u¿ëM“>– /By A A– /By A“œ,B½@‘AK€r¿2¤>– /By A A“œ,B½@‘A“œ,B½@‘A AÁMl¿1ñÄ>“œ,B½@‘A A“œ,B½@‘A†i)Bnœ‚AÈh¿èÕ>“œ,B½@‘A A†i)Bnœ‚A†i)Bnœ‚A A(í`¿~ô>†i)Bnœ‚A A†i)Bnœ‚Az%BÖhiA ˜\¿¸æ?†i)Bnœ‚A Az%BÖhiAz%BÖhiA A/*S¿³¹?z%BÖhiA Az%BÖhiAÙ Bá\OArN¿úä?z%BÖhiA AÙ Bá\OAÙ Bá\OA A.*C¿¥«%?Ù Bá\OA AÙ Bá\OAË’B°[7A§[=¿ G,?Ù Bá\OA AË’B°[7AË’B°[7A A‘1¿Ü8?Ë’B°[7A AË’B°[7AĵBa¦!A¤*¿›Õ>?Ë’B°[7A AĵBa¦!AĵBa¦!A A`&¿¿J?ĵBa¦!A AĵBa¦!AÙQBáwAM¿O^O?ĵBa¦!A AÙQBáwAÙQBáwA A»‰¿-Y?ÙQBáwA AÙQBáwA_xBrü@yþÿ¾H´]?ÙQBáwA A_xBrü@_xBrü@ Aúà¾öe?_xBrü@ A_xBrü@í;B'ðà@¦ Ѿ¡°i?_xBrü@ Aí;B'ðà@í;B'ðà@ A&°¾Op?í;B'ðà@ Aí;B'ðà@L`óA`ðË@ŽáŸ¾Ñ2s?í;B'ðà@ AL`óA`ðË@L`óA`ðË@ AI|¾Öx?L`óA`ðË@ AL`óA`ðË@ ÓãAB½@1 Z¾ !z?L`óA`ðË@ A ÓãAB½@ ÓãAB½@ A4è¾bG}? ÓãAB½@ A ÓãAB½@FúÓA3 µ@)佂h~? ÓãAB½@ AFúÓA3 µ@FúÓA3 µ@ A Ë/½žÃ?FúÓA3 µ@ AFúÓA3 µ@ÄAãg³@i ¼˜ý?FúÓA3 µ@ AÄAãg³@ÄAãg³@ AÃçu=ʉ?ÄAãg³@ AÄAãg³@”´A¬V¸@„Á=Ü~?ÄAãg³@ A”´A¬V¸@”´A¬V¸@ AÑ?&>…š|?”´A¬V¸@ A”´A¬V¸@;Z¤A)ÌÃ@ÝH>Ñ{?”´A¬V¸@ A;Z¤A)ÌÃ@;Z¤A)ÌÃ@ AF¡†>Äýv?;Z¤A)ÌÃ@ A;Z¤A)ÌÃ@ž•A<©Õ@e…—>lˆt?;Z¤A)ÌÃ@ Až•A<©Õ@ž•A<©Õ@ AMµ¸>ÄÂn?ž•A<©Õ@ Až•A<©Õ@`5†As½í@É>trk?ž•A<©Õ@ A`5†As½í@`5†As½í@ AÔè>Øÿc?`5†As½í@ A`5†As½í@U5pAºãAP[ø>ŽÝ_?`5†As½í@ AU5pAºãAU5pAºãA Aˆ= ?7ÒV?U5pAºãA AU5pAºãA‰±UAÛºAˉ?*éQ?U5pAºãA A‰±UAÛºA‰±UAÛºA A*— ?¡]G?‰±UAÛºA A‰±UAÛºAP'=A¶3,AGX'?%»A?‰±UAÛºA AP'=A¶3,AP'=A¶3,A A=4?Ì5?P'=A¶3,A AP'=A¶3,ABÙ&A»CA£`:?g/?P'=A¶3,A ABÙ&A»CABÙ&A»CA AÀùE?M"?BÙ&A»CA ABÙ&A»CAåAÐ%\A ÝAówA A ÝAówA„&ç@|Ù‰AÖëf?¡Ý> ÝAówA A„&ç@|Ù‰A„&ç@|Ù‰A Aíôm?#м>„&ç@|Ù‰A A„&ç@|Ù‰AžšÐ@'͘A@q? Z¬>„&ç@|Ù‰A AžšÐ@'͘AžšÐ@'͘A A gv?ààŠ>žšÐ@'͘A AžšÐ@'͘A‘SÀ@ç@¨Aƒ¤x?»s>žšÐ@'͘A A‘SÀ@ç@¨A‘SÀ@ç@¨A A<|?|ñ.>‘SÀ@ç@¨A A‘SÀ@ç@¨Aˆ}¶@Í ¸A —}?™- >‘SÀ@ç@¨A Aˆ}¶@Í ¸Aˆ}¶@Í ¸A A|e?òŒŒ=ˆ}¶@Í ¸A Aˆ}¶@Í ¸A33³@ÈAhÙ?òŒ =ˆ}¶@Í ¸A A33³@ÈA33³@ÈA AhÙ?òŒ ½33³@ÈA A33³@ÈAˆ}¶@4õ×A|e?òŒŒ½33³@ÈA Aˆ}¶@4õ×Aˆ}¶@4õ×A A —}?™- ¾ˆ}¶@4õ×A Aˆ}¶@4õ×A‘SÀ@¿çA<|?|ñ.¾ˆ}¶@4õ×A A‘SÀ@¿çA‘SÀ@¿çA Aƒ¤x?»s¾‘SÀ@¿çA A‘SÀ@¿çAžšÐ@Ù2÷A gv?ààŠ¾‘SÀ@¿çA AžšÐ@Ù2÷AžšÐ@Ù2÷A A@q? Z¬¾žšÐ@Ù2÷A AžšÐ@Ù2÷A„&ç@BBíôm?#м¾žšÐ@Ù2÷A A„&ç@BB„&ç@BB AÖëf?¡ݾ„&ç@BB A„&ç@BB ÝAÄ8 Býb?¿ì¾„&ç@BB A ÝAÄ8 B ÝAÄ8 B AÇUZ?º©¿ ÝAÄ8 B A ÝAÄ8 BåAöB?U?½ ¿ ÝAÄ8 B AåAöBåAöB AŽÝ_¿U5pA‡&B AU5pA‡&B`5†ARH*BÔè>Øÿc¿U5pA‡&B A`5†ARH*B`5†ARH*B AÉ>trk¿`5†ARH*B A`5†ARH*Bž•AÙJ-BMµ¸>ÄÂn¿`5†ARH*B Až•AÙJ-Bž•AÙJ-B Ae…—>lˆt¿ž•AÙJ-B Až•AÙJ-B;Z¤A{†/BF¡†>Äýv¿ž•AÙJ-B A;Z¤A{†/B;Z¤A{†/B AÝH>Ñ{¿;Z¤A{†/B A;Z¤A{†/B”´A+õ0BÑ?&>…š|¿;Z¤A{†/B A”´A+õ0B”´A+õ0B A„Á=Ü~¿”´A+õ0B A”´A+õ0BÄA“1BÃçu=ʉ¿”´A+õ0B AÄA“1BÄA“1B Ai ¼˜ý¿ÄA“1B AÄA“1BFúÓAY^1B Ë/½žÃ¿ÄA“1B AFúÓAY^1BFúÓAY^1B A)佂h~¿FúÓAY^1B AFúÓAY^1B ÓãA½W0B4è¾bG}¿FúÓAY^1B A ÓãA½W0B ÓãA½W0B A1 Z¾ !z¿ ÓãA½W0B A ÓãA½W0BL`óAô.BI|¾Öx¿ ÓãA½W0B AL`óAô.BL`óAô.B AŽáŸ¾Ñ2s¿L`óAô.B AL`óAô.Bí;Büá+B&°¾Op¿L`óAô.B Aí;Büá+Bí;Büá+B A¦ Ѿ¡°i¿í;Büá+B Aí;Büá+B_xBò~(Búà¾öe¿í;Büá+B A_xBò~(B_xBò~(B Ayþÿ¾H´]¿_xBò~(B A_xBò~(BÙQBb$B»‰¿-Y¿_xBò~(B AÙQBb$BÙQBb$B AM¿O^O¿ÙQBb$B AÙQBb$BĵBi–B`&¿¿J¿ÙQBb$B AĵBi–BĵBi–B A¤*¿›Õ>¿ÄµBi–B AĵBi–BË’B)B‘1¿Ü8¿ÄµBi–B AË’B)BË’B)B A§[=¿ G,¿Ë’B)B AË’B)BÙ BÈ(B.*C¿¥«%¿Ë’B)B AÙ BÈ(BÙ BÈ(B ArN¿úä¿Ù BÈ(B AÙ BÈ(Bz%BË¥ B/*S¿³¹¿Ù BÈ(B Az%BË¥ Bz%BË¥ B A ˜\¿¸æ¿z%BË¥ B Az%BË¥ B†i)BʱB(í`¿~ô¾z%BË¥ B A†i)BʱB†i)BʱB AÈh¿èÕ¾†i)BʱB A†i)BʱB“œ,BC¿þAÁMl¿1ñľ†i)BʱB A“œ,BC¿þA“œ,BC¿þA AK€r¿2¤¾“œ,BC¿þA A“œ,BC¿þA– /Bd†ïA-u¿ëM“¾“œ,BC¿þA A– /Bd†ïA– /Bd†ïA A„¦y¿Œ¦b¾– /Bd†ïA A– /Bd†ïAõ¬0BBâßA s{¿Ò5@¾– /Bd†ïA Aõ¬0BBâßAõ¬0BBâßA AC'~¿L‹õ½õ¬0BBâßA Aõ¬0BBâßAC1BPýÏAÌ¿kŒ¯½õ¬0BBâßA AC1BPýÏAC1BPýÏA A_Ù¿Þœ ½C1BPýÏA AC1BPýÏA™™1BÈA A€?€ý;B…®CB Ao=BôÑEB ANp9B½DB A€?Np9B½DB Ao=BôÑEB A+.:BiGB A€?Np9B½DB A+.:BiGB AÕÀ6B!bEB A€?ÕÀ6B!bEB A+.:BiGB Añ 7BöÀGB A€?ÕÀ6B!bEB Añ 7BöÀGB A4Bš™EB A€?4Bš™EB Añ 7BöÀGB A4BHB A€?4Bš™EB A4BHB A¨™?š™EB A€?¨™?š™EB A4BHB AHB A€?¨™?š™EB AHB A¨™?¨™? A€?¨™?¨™? AHB A A€?¨™?¨™? A Aš™EB¨™? A€?š™EB¨™? A AHB A€?š™EB¨™? AHB Aš™EB4B A€?š™EB4B AHB AHB4B A€?š™EB4B AHB4B A!bEBÕÀ6B A€?!bEBÕÀ6B AHB4B AöÀGBñ 7B A€?!bEBÕÀ6B AöÀGBñ 7B A½DBNp9B A€?½DBNp9B AöÀGBñ 7B AiGB+.:B A€?½DBNp9B AiGB+.:B A…®CB€ý;B A€?…®CB€ý;B AiGB+.:B AôÑEBo=B A€?…®CB€ý;B AôÑEBo=B A=BBSX>B A€?=BBSX>B AôÑEBo=B A+.DBvÁ?B A€?=BBSX>B A+.DBvÁ?B Añq@Bñq@B A€?ñq@Bñq@B A+.DBvÁ?B Ac$BBc$BB A€?ñq@Bñq@B Ac$BBc$BB ASX>B=BB A€?SX>B=BB Ac$BBc$BB AvÁ?B+.DB A€?SX>B=BB AvÁ?B+.DB A€ý;B…®CB A€?€ý;B…®CB AvÁ?B+.DB Ao=BôÑEB A€¿€ý;B…®CBo=BôÑEBSX>B=BB€¿SX>B=BBo=BôÑEBvÁ?B+.DB€¿SX>B=BBvÁ?B+.DBñq@Bñq@B€¿ñq@Bñq@BvÁ?B+.DBc$BBc$BB€¿ñq@Bñq@Bc$BBc$BB=BBSX>B€¿=BBSX>Bc$BBc$BB+.DBvÁ?B€¿=BBSX>B+.DBvÁ?B…®CB€ý;B€¿…®CB€ý;B+.DBvÁ?BôÑEBo=B€¿…®CB€ý;BôÑEBo=B½DBNp9B€¿½DBNp9BôÑEBo=BiGB+.:B€¿½DBNp9BiGB+.:B!bEBÕÀ6B€¿!bEBÕÀ6BiGB+.:BöÀGBñ 7B€¿!bEBÕÀ6BöÀGBñ 7Bš™EB4B€¿š™EB4BöÀGBñ 7BHB4B€¿š™EB4BHB4Bš™EB¨™?€¿š™EB¨™?HB4BHB€¿š™EB¨™?HB¨™?¨™?€¿¨™?¨™?HB€¿¨™?¨™?¨™?š™EB€¿¨™?š™EBHB€¿¨™?š™EBHB4Bš™EB€¿4Bš™EBHB4BHB€¿4Bš™EB4BHBÕÀ6B!bEB€¿ÕÀ6B!bEB4BHBñ 7BöÀGB€¿ÕÀ6B!bEBñ 7BöÀGBNp9B½DB€¿Np9B½DBñ 7BöÀGB+.:BiGB€¿Np9B½DB+.:BiGB€ý;B…®CB€¿€ý;B…®CB+.:BiGBo=BôÑEB€¿ ¤ AHB A€¿ ¤HB AHB€¿HB A AHB€¿HB A€?Ç1%HB4B AHB AHB4B€?Ç1%HB4BHB AHBY¦?,V=HB4B AHB4BöÀGBñ 7B¨˜~?,Ö=HB4B AöÀGBñ 7BöÀGBñ 7B A‰hz?‚ÚT>öÀGBñ 7B AöÀGBñ 7BiGB+.:BFw?Š„>öÀGBñ 7B AiGB+.:BiGB+.:B AAo?#v·>iGB+.:B AiGB+.:BôÑEBo=BÖÜi?‡EÐ>iGB+.:B AôÑEBo=BôÑEBo=B Aiµ]?Žúÿ>ôÑEBo=B AôÑEBo=B+.DBvÁ?Bg±V?p ?ôÑEBo=B A+.DBvÁ?B+.DBvÁ?B AõF?²!?+.DBvÁ?B A+.DBvÁ?Bc$BBc$BB¢<>?{N+?+.DBvÁ?B Ac$BBc$BBc$BBc$BB A{N+?¢<>?c$BBc$BB Ac$BBc$BBvÁ?B+.DB²!?õF?c$BBc$BB AvÁ?B+.DBvÁ?B+.DB Ap ?g±V?vÁ?B+.DB AvÁ?B+.DBo=BôÑEBŽúÿ>iµ]?vÁ?B+.DB Ao=BôÑEBo=BôÑEB A‡EÐ>ÖÜi?o=BôÑEB Ao=BôÑEB+.:BiGB#v·>Ao?o=BôÑEB A+.:BiGB+.:BiGB AŠ„>Fw?+.:BiGB A+.:BiGBñ 7BöÀGB‚ÚT>‰hz?+.:BiGB Añ 7BöÀGBñ 7BöÀGB A,Ö=¨˜~?ñ 7BöÀGB Añ 7BöÀGB4BHB,V=Y¦?ñ 7BöÀGB A4BHB4BHB A€?HB A4BHB AHB€?HB4BHB A4BHB€? $¨™?š™EB A¨™?¨™? A¨™?š™EB€? $¨™?š™EB¨™?¨™? A¨™?¨™?€?¨™?¨™? Aš™EB¨™? A¨™?¨™?€?¨™?¨™?š™EB¨™? Aš™EB¨™?€¿Ç1¥š™EB¨™? Aš™EB4B Aš™EB¨™?€¿Ç1¥š™EB¨™?š™EB4B Aš™EB4B,V½Y¦¿4Bš™EB A4Bš™EBÕÀ6B!bEB,Ö½¨˜~¿4Bš™EB AÕÀ6B!bEBÕÀ6B!bEB A‚ÚT¾‰hz¿ÕÀ6B!bEB AÕÀ6B!bEBNp9B½DBŠ„¾Fw¿ÕÀ6B!bEB ANp9B½DBNp9B½DB A#v·¾Ao¿Np9B½DB ANp9B½DB€ý;B…®CB‡EоÖÜi¿Np9B½DB A€ý;B…®CB€ý;B…®CB AŽúÿ¾iµ]¿€ý;B…®CB A€ý;B…®CBSX>B=BBp ¿g±V¿€ý;B…®CB ASX>B=BBSX>B=BB A²!¿õF¿SX>B=BB ASX>B=BBñq@Bñq@B{N+¿¢<>¿SX>B=BB Añq@Bñq@Bñq@Bñq@B A¢<>¿{N+¿ñq@Bñq@B Añq@Bñq@B=BBSX>BõF¿²!¿ñq@Bñq@B A=BBSX>B=BBSX>B Ag±V¿p ¿=BBSX>B A=BBSX>B…®CB€ý;Biµ]¿Žúÿ¾=BBSX>B A…®CB€ý;B…®CB€ý;B AÖÜi¿‡Eо…®CB€ý;B A…®CB€ý;B½DBNp9BAo¿#v·¾…®CB€ý;B A½DBNp9B½DBNp9B AFw¿Š„¾½DBNp9B A½DBNp9B!bEBÕÀ6B‰hz¿‚ÚT¾½DBNp9B A!bEBÕÀ6B!bEBÕÀ6B A¨˜~¿,Ö½!bEBÕÀ6B A!bEBÕÀ6Bš™EB4BY¦¿,V½!bEBÕÀ6B Aš™EB4Bš™EB4B A€¿4Bš™EB A¨™?š™EB A4Bš™EB€¿4Bš™EB¨™?š™EB A¨™?š™EBsfact-2011.12.18/calibration/vertex_blobs.STL000066400000000000000000012350701167321211700205710ustar00rootroot00000000000000solid balltest ²ÃJ=¡®?¿Ä¶;Þ€AªïA,+>Jñ€AªïAûŽ«=pAðABÏ(?E=¡®?×>S<·‘€AªïA+©>&¾€AªïAïk>pAðABÏ(Ô˜@=¡®?Ɇ<·‘€AªïA+©>pAðABÏ(Y€AªïAÛ­Ñ>®;=¡®?¤1£<\€AªïA„ù>Y€AªïAÛ­Ñ>pAðABÏ(Èf4=¡®? °¾pAðABÏ(œÅ,=¡®?Ù<›Ñ~AªïAÿ¦!?HˆAªïAV{?pAðABÏ(-$=¡®?ÂUò<·~AªïA:ë2?›Ñ~AªïAÿ¦!?pAðABÏ(†©=¡®?ü=¿%}AªïAO/C?·~AªïA:ë2?pAðABÏ(‰H=¡®?‰H=õ2|AªïAó[R?¿%}AªïAO/C?pAðABÏ(ü=¡®?†©=´.{AªïAn[`?õ2|AªïAó[R?pAðABÏ(ÂUò<¡®?-$=pzAªïAµm?´.{AªïAn[`?pAðABÏ(Ù<¡®?œÅ,=µ÷xAªïAŠ„x?pzAªïAµm?pAðABÏ( °¾<¡®?Èf4=$ÈwAªïAÊE?µ÷xAªïAŠ„x?pAðABÏ(¤1£<¡®?®;=nvAªïA=…?$ÈwAªïAÊE?pAðABÏ(Ɇ<¡®?Ô˜@=XIuAªïAw‰?nvAªïA=…?pAðABÏ(×>S<¡®??E=¯ýsAªïAhâ‹?XIuAªïAw‰?pAðABÏ(:½<¡®?}}H=P¬rAªïAá?¯ýsAªïAhâ‹?pAðABÏ(¿Ä¶;¡®?²ÃJ=WqAªïA¡?P¬rAªïAá?pAðABÏ(%ô:¡®?žçK=pAªïAV{?WqAªïA¡?pAðABÏ(%ôº¡®?žçK=â¨nAªïA¡?pAªïAV{?pAðABÏ(¿Ä¶»¡®?²ÃJ=¯SmAªïAá?â¨nAªïA¡?pAðABÏ(:½¼¡®?}}H=PlAªïAhâ‹?¯SmAªïAá?pAðABÏ(×>S¼¡®??E=¨¶jAªïAw‰?PlAªïAhâ‹?pAðABÏ(Ɇ¼¡®?Ô˜@=‘riAªïA=…?¨¶jAªïAw‰?pAðABÏ(¤1£¼¡®?®;=Û7hAªïAÊE?‘riAªïA=…?pAðABÏ( °¾¼¡®?Èf4=JgAªïAŠ„x?Û7hAªïAÊE?pAðABÏ(Ù¼¡®?œÅ,=åeAªïAµm?JgAªïAŠ„x?pAðABÏ(ÂUò¼¡®?-$=LÑdAªïAn[`?åeAªïAµm?pAðABÏ(ü½¡®?†©= ÍcAªïAó[R?LÑdAªïAn[`?pAðABÏ(‰H½¡®?‰H=AÚbAªïAO/C? ÍcAªïAó[R?pAðABÏ(†©½¡®?ü=IúaAªïA:ë2?AÚbAªïAO/C?pAðABÏ(-$½¡®?ÂUò·w`AªïAV{?pAðABÏ(®;½¡®?¤1£<øM_AªïAÛ­Ñ>G×_AªïA„ù>pAðABÏ(Ô˜@½¡®?Ɇ<‘Ü^AªïA+©>øM_AªïAÛ­Ñ>pAðABÏ(?E½¡®?×>S<³ƒ^AªïAïk>‘Ü^AªïA+©>pAðABÏ(N}®=—?Çô:VÁ„A÷QïAqU(Åõ€AÀ…ïA^ˆ(Jñ€AªïAûŽ«=ðK=š®?…%ô:Jñ€AªïAûŽ«=Åõ€AÀ…ïA^ˆ(pAðABÏ(}}H=¡®?:½<&¾€AªïAïk>Þ€AªïA,+>pAðABÏ(ëÔ->XH|?Âls;¬]‘AÕIíAlgr&èÛ‰AuîAÓ0(ÆÕ‰Aâ¨îA,+>„š>¬t?nžð;o°AíéAß2¨ÑW›AJ‘êAm» ¨E›A2«êA+©>Z Ã>%«l?Á)<á•©A´FåA€×¶¨nÇ£Aê‹çAÞ0‰¨ä·£Aq´çAÛ­Ñ>ºŽ?R[]?ÂL<~ë´AñbßA*ú©Þù³AàßARD© Õ³AMìßAV{?ô?ë–Q?ˆþe>© œÂAÝÑÕA:ë2?G<=?DY,?M§•<ùNÒAxÇAj{©ŒÞÏA¿†ÉA¾êq©b¸ÏAèžÉAó[R?”а<¸øàAf%²AÏ’š©Ë×ßA+ó³AëZ˜©é¡ßAÿÿ³AŠ„x?ÔYh? Ö>ÿ·<´ŽæA­¨¦Az¥©ÎöãA÷ý«A“t ©_ÐãAé¬AÊE?Γr? (£>Y:Ã<YêAá^›Aw‰?¢êA’[›A)­©¸–çAÌ£Ak”§©š?÷YL½É¾ËE~ @3=¹½¶º~¿Ôñ)=øM_AxÌ+=Û­Ñ>G×_AxÌ+=„ù>°ÅOAòŽ+>CRx?:½<¡®¿}}H=¯ýsAxÌ+=hâ‹?P¬rAxÌ+=á?pABÏ(:½¼¡®¿}}H=pABÏ(¯SmAxÌ+=á?PlAxÌ+=hâ‹?®;½¡®¿¤1£øM_AxÌ+=Û­Ñ>pABÏ(ÑrÎ>‘ó¦>¯ãZ?üõ¦AQiApÌOAO¨©A^œA¹:NA‡w¨AG×£AIIAb?øô†;25L?7¿AþörA£IAAl¿ApA‚IAA›ÑÂApAº£;A–Ìc>…"³¾Èõh?³–AAñA5XYAý‘AAñA-Á[ANÛArQAðÎYA’¯>#³¾îƒl?QŽAAñAZ]A"̈AAñAùå^A¦ˆArQAê\AÒm±=m$³¾|Ên?‡g†AAñAJ°_Al€AAñA{Ì`AY€ArQAöÈ^A’ArQAðÎYA¡ž®¾0 ³¾3a_?%{AAñAÔIRA1šAÆùAòQAaArQAZ÷OAªy;ê.±¾§Y?ð'AßA|tMAðà A°Au¿KAðArQAIIAOÍ-¿S½;?bbš@QËdA6ú/A(¸™@ê hAÁÒ/Anš@•^AÅp/AÆ’¿Ñï’>q®K?ƒžÝ@á^›AÎ|=ARÜ@4™Aý—>AAæ@)КA¢¸@AGÏz>$,³>„xg?³–A`¡A5XYAóì˜AG×£Aö{UAý‘A`¡A-Á[A6ßk>[2·>(ªg?ý‘A`¡A-Á[Aóì˜AG×£Aö{UANÛAG×£AðÎYA”M>ç³>Õ@j?ý‘A`¡A-Á[ANÛAG×£AðÎYAQŽA`¡AZ]A 5>%·>ºµj?QŽA`¡AZ]ANÛAG×£AðÎYA¦ˆAG×£Aê\A’¯>#³>îƒl?QŽA`¡AZ]A¦ˆAG×£Aê\A"̈A`¡Aùå^Ax%>‹³>úem?"̈A`¡Aùå^A¦ˆAG×£Aê\A‡g†A`¡AJ°_A[Bà=Š%·>€im?‡g†A`¡AJ°_A¦ˆAG×£Aê\AY€AG×£AöÈ^AÒm±=m$³>|Ên?‡g†A`¡AJ°_AY€AG×£AöÈ^Al€A`¡A{Ì`AZôƒ=!³>RBo?l€A`¡A{Ì`AY€AG×£AöÈ^A³Ö|A`¡A¡+aA/(="&·>vÔn?³Ö|A`¡A¡+aAY€AG×£AöÈ^ApAG×£Aâh_A’LÆo?³Ö|A`¡A¡+aApAG×£Aâh_A€ÿoA`¡AôqaAû’‘»©³>IÓo?€ÿoA`¡AôqaApAG×£Aâh_A·ÍlA`¡AtƒaAÆqâ¼Ù&·>£ôn?·ÍlA`¡AtƒaApAG×£Aâh_AøM_AG×£AöÈ^A&$Q½&³>vo?·ÍlA`¡AtƒaAøM_AG×£AöÈ^A4&_A`¡AtÕ`AO–½"³>o?4&_A`¡AtÕ`AøM_AG×£AöÈ^AàÈ\A`¡AR·`Ag÷Ľ¯'·>ÛÉm?àÈ\A`¡AR·`AøM_AG×£AöÈ^A׳NAG×£Aê\A õ½Û&³>Úm?àÈ\A`¡AR·`A׳NAG×£Aê\A¹m?¿Uk?èÜLA`¡ABÈ^A׳NAG×£Aê\AcI>AG×£AðÎYA'@¾'³>²ôj?èÜLA`¡ABÈ^AcI>AG×£AðÎYAoÑ=A`¡A“Û[AœuV¾é³>Ãi?oÑ=A`¡A“Û[AcI>AG×£AðÎYAn=A`¡AǸ[A·Ül¾¼)·>²›g?n=A`¡AǸ[AcI>AG×£AðÎYA&.AG×£Aö{UAJG‚¾F(³>¿Ìf?n=A`¡AǸ[A&.AG×£Aö{UAÓ¡-A`¡AÕŒWA ˜¾ó'³>3qc?Ó¡-A`¡AÕŒWA&.AG×£Aö{UA%{A`¡AÔIRAÌk)·>Æ¿`?%{A`¡AÔIRA&.AG×£Aö{UAaAG×£AZ÷OA>ž®¾³>¶`_?%{A`¡AÔIRAaAG×£AZ÷OAšAk¡A\òQA¸¹Í¾ï#±>º Y?ðà AL' Aa¿KA«ÍAB‰ A§PMAðAG×£AIIAQȾX ²>æ Z?ðAG×£AIIA«ÍAB‰ A§PMAµ|AÈ AÂÅNA%n¿¾ôʶ>=#[?ðAG×£AIIAµ|AÈ AÂÅNAaAG×£AZ÷OAmp¶¾.´²>á]?aAG×£AZ÷OAµ|AÈ AÂÅNAó A¡A.QAÞ¥°¾U³>9ü^?aAG×£AZ÷OAó A¡A.QAšAk¡A\òQA†ê¾[C¬>ú›R?KAG×£A~zAA ACžAÂ#FA¨ØAà"ŸAê‚HAžüß¾Èx´>ÌÇS?KAG×£A~zAA¨ØAà"ŸAê‚HAðAG×£AIIAîÀ×¾:à®>ÉW?ðAG×£AIIA¨ØAà"ŸAê‚HAôÄ A¦òŸA¸çJAÒ¾kM°>ÿ0X?ðAG×£AIIAôÄ A¦òŸA¸çJAðà AL' Aa¿KA‡ ¿-r¤>êK?·ê@Õ^›Aö‰AAƒ¬ð@šSœAñBA3Lä@G×£Aú–8Av5¿°Š¦>K¶L?3Lä@G×£Aú–8Aƒ¬ð@šSœAñBA&Äô@xØœA¥ËCA¸Éü¾¦B±>ø7L?3Lä@G×£Aú–8A&Äô@xØœA¥ËCAKAG×£A~zAA'2ô¾1e¨>ߨP?KAG×£A~zAA&Äô@xØœA¥ËCA(%ü@ªAREAî$ð¾+ª>_yQ?KAG×£A~zAA(%ü@ªAREA ACžAÂ#FA¡ï¿>«C?ÎkÀ@ij’AŒ“8AõjÇ@í¡”A«:AVÂ@á^›A¢M3AÐI¿h“„>éZD?õjÇ@í¡”A«:AHÉ@G,•AÒ•:AVÂ@á^›A¢M3AP¿ïGˆ>œ8E?VÂ@á^›A¢M3AHÉ@G,•AÒ•:A“‹Ò@ø;—A|‰cGF?VÂ@á^›A¢M3A“‹Ò@ø;—A|‰-4J?ƒžÝ@á^›AÎ|=A“‹Ò@ø;—A|‰AzZ ¿€ƒ>zéJ?ƒžÝ@á^›AÎ|=AÕÜ@B™A‹•>ARÜ@4™Aý—>A¼Ÿ&¿ÉI6>ÒîY‡=?&®«@l‹AXð3A¾‘±@×§A–D5A䳡@س’A~…+AV #¿D;N>w„>?䳡@س’A~…+A¾‘±@×§A–D5AH(¸@ØAH¾6A“%!¿š\>6??䳡@س’A~…+AH(¸@ØAH¾6At:¼@س’A_ï6A@¿öX>tCC?t:¼@س’A_ï6AH(¸@ØAH¾6Ab»@®"‘Aªu7Aå2¿P¥^>ŸÕC?t:¼@س’A_ï6Ab»@®"‘Aªu7Añp¿@n’AY\8A+`+¿Cmé=Bì;?îü@a0‚AcÏ0Aß9¡@Bñ„AŽ1Aã)@”â‰Aª÷-AÃ*¿z->µzÇ =?ã)@”â‰Aª÷-A¯9¥@Ë¡‡Ax2AvP©@yâ‰A×f3A{Ê-¿evT=€;?(¸™@òüwAÁÒ/Azqš@äj{Aµý/Anš@µ÷€AÅp/Aàs-¿ØÝz=Ó ;?nš@µ÷€AÅp/Azqš@äj{Aµý/A_„›@ù½~AS=0A -¿é÷= Ô;?nš@µ÷€AÅp/A_„›@ù½~AS=0A¢êœ@÷€A 0A¦ú2¿Œ `9l 7?•"€@pAÐ=#ArÛ˜@pA’Ÿ/AÞØ˜@^'pAùž/Ali2¿,¶y=Þì6?nš@µ÷€AÅp/Au@µ÷€AõÈ"A(¸™@òüwAÁÒ/A*$7¿u£=R¢2?(¸™@òüwAÁÒ/Au@µ÷€AõÈ"A•"€@pAÐ=#A%Ç2¿k÷œ<ì*7?(¸™@òüwAÁÒ/A•"€@pAÐ=#AÊA™@&ÌuAQ·/AŽë2¿oƒ< 7?ÊA™@&ÌuAQ·/A•"€@pAÐ=#AÞØ˜@^'pAùž/A÷V-¿Ä‚½¯;?bbš@QËdA6ú/Anš@•^AÅp/AY9œ@_p_A)g0AQ )¿¤¡¾e«?¦g¸@Éž?AjÌ6AÞ±@sDAÂU5A䳡@P˜:A~…+A>%¿ @¾Š=?䳡@P˜:A~…+AÞ±@sDAÂU5A;«@íJA·å3Aò(¿¥ý4¾;ð:?䳡@P˜:A~…+A;«@íJA·å3Aã)@×:LAª÷-Aù}'¿Yξ¥=?ã)@×:LAª÷-A;«@íJA·å3Al^©@E;LAäi3Aù^(¿²h¾ª<=?ã)@×:LAª÷-Al^©@E;LAäi3A$†¦@Y4OA]Ä2A®*¿—Í^¾EÙC?'Ÿ¿@~;Af8A'b»@¸¹=A±u7At:¼@P˜:A_ï6AE¿wHŒ¾ 8F?_àØ@Ë÷.Ažæ=AÐ@—™2A4Avä¿v——¾åAM?úé@SB)A­ˆAAƒžÝ@=B)AÎ|=AÑí@%W(A8,BA û¿z¼£¾ê1J?Ñí@%W(A8,BAƒžÝ@=B)AÎ|=A3Lä@rQAú–8A T¿a[¦¾;¬L?Ñí@%W(A8,BA3Lä@rQAú–8A^Ê÷@N–%AlDA¯Ëá¾. ¯¾ÈoT?%! AT A½ KA¤4A‡!AL¨HAKArQA~zAAlNé¾e¿¬¾™ßR?KArQA~zAA¤4A‡!AL¨HAÐ…AÓ8#Aï¾FA“ï¾l“ª¾Ú°Q?KArQA~zAAÐ…AÓ8#Aï¾FA"%ü@ ¬$A‡REAOƾ,F²¾þ•Z?ð'AßA|tMAðArQAIIA†FAh-AoÞOAlM£¾„)³¾ |a?%{AAñAÔIRAaArQAZ÷OAÓ¡-AAñAÕŒWA¹“>A²¾u_d?»UœA÷ãA´ÞUA‰—šA¢nAtÙVAóì˜ArQAö{UA‡U>Ë„²¾Oûd?óì˜ArQAö{UA‰—šA¢nAtÙVA{@™A=A ™WAš‹>Õ²¾7–e?óì˜ArQAö{UA{@™A=A ™WAƒŒ—AþA†ŒXA6Ï>¡¦¾&ÅZ?ï5©Aâ^'A}NA>ó§A”&Aj9OA‡w¨ArQAIIAWf¶>‚r¬¾™_?#¥A±£#ApÚPA„B¢Až!A—RAtÏ ArQAZ÷OA°±>Ø0®¾oÛ_?tÏ ArQAZ÷OA„B¢Až!A—RAÂg¡A(!AGþRA©ä¬>:Q¯¾Ús`?tÏ ArQAZ÷OAÂg¡A(!AGþRAõRŸA Aù-TAïø>`}†¾j›U?Áò²A¥ž5A£ºHAN²Aþ 4AM=IA™U±A=B)A±œFAÏßô>„g‰¾qV?™U±A=B)A±œFAN²Aþ 4AM=IAÕ´°A‚1AìJAƒï>·ß¾ÅÚV?Õ´°A‚1AìJA\U®AþÂ-AÎzKA™U±A=B)A±œFA0™è>^ô’¾­åW?™U±A=B)A±œFA\U®AþÂ-AÎzKAeÕ«Axa*APôLA®ã>-–¾§X?™U±A=B)A±œFAeÕ«Axa*APôLA2ÛªAVB)AÒ†MAå"?#£€¾ØQ?Ð<µA˜:A†YGAÓ³Ahg7Aß3HA_˜¸A=B)AÎ|=AÆ ?š¶K¾ë+Q?>¹AɘEAdêDAœ·A^›@AgéEAQç¹AP˜:AYSAAc?£‰Y¾«èQ?Qç¹AP˜:AYSAAœ·A^›@AgéEAŸÍµA³ß;A"GAIô?“ܽÈ+L?%¾A¼ý]A·äAATe½ALXA§[BA­ûÁA×:LA5‹9Aõ·?ÅŒü½íL?­ûÁA×:LA5‹9ATe½ALXA§[BA€r¼A·¼RAðñBA;9?–å ¾”öL?€r¼A·¼RAðñBA»L»AQMA#§CA­ûÁA×:LA5‹9A©8?¥(¾¿FM?­ûÁA×:LA5‹9A»L»AQMA#§CA »Aò:LAËÐCA@ß?o¾„dM?­ûÁA×:LA5‹9A »Aò:LAËÐCA3ͺABEKA–õCAßÌ?„ç\½ò.L?Ûé¾AŠLgAAjAA­°¾ASÑcAÜAA œÂA•^Ai;A­"?Ô÷'½¦ L?Ûé¾AŠLgAAjAA œÂA•^Ai;A¡¿A( mAaIAAÐ>?¿ †<}EL?7¿AþörA£IAA›ÑÂApAº£;ATè¾AüÏxA6kAAà?ªû>eM?VͺAÖTŠApõCA| »A‹â‰AÐCA­ûÁA”â‰A5‹9AL?dj>×RM?­ûÁA”â‰A5‹9A| »A‹â‰AÐCAB»A`ȉA ÈCAMó?øs>Þ M?­ûÁA”â‰A5‹9AB»A`ȉA ÈCAE¼Aƒ‡Aþ CAM'?øG¯=.µL?Ã?½AÔS„AïrBAY¾A9A#÷AA œÂAµ÷€Ai;A Å?m$œ=4}L? œÂAµ÷€Ai;AY¾A9A#÷AA1$¾A¥÷€A4åAA¡?ÍÅ=gcL? œÂAµ÷€Ai;A1$¾A¥÷€A4åAA |¾As©~Aš®AA´?H]e>æ¤R?'Ó´A„5“A†™GA >µA¶³’AÓXGAQç¹Aس’AYSAAo ?íÖ^>º:R?Qç¹Aس’AYSAA >µA¶³’AÓXGAçµ¶AFëAVuFA÷L ?eàR>&‰Q?Qç¹Aس’AYSAAçµ¶AFëAVuFAæl¸AãŽA*jEA… à>ý—>í!Y?o«©AÓœAç8NA…ÚªAÓ^›A4‡MA™U±Aá^›A±œFA“Hä>ÕÉ•>‡X?™U±Aá^›A±œFA…ÚªAÓ^›A4‡MA+C¬AÕ‰šAÀ³LAkÆé>"$’>§·W?™U±Aá^›A±œFA+C¬AÕ‰šAÀ³LA_¼®A5Ò˜AÉ=KA%?ÉІ>(‚R?ÿIJA™]•AÖHA_˜¸Aá^›AÎ|=AA²A9ú•A\=IAÙ?,]>í·Q?A²A9ú•A\=IA_˜¸Aá^›AÎ|=A™U±Aá^›A±œFA´¤ô>ùš‰>V?A²A9ú•A\=IA™U±Aá^›A±œFAv‹°Ab—A”*JA?Ùï>'¤>‰ÌV?v‹°Ab—A”*JA™U±Aá^›A±œFA_¼®A5Ò˜AÉ=KAD9Û>ú2°>KêU?‡w¨AG×£AIIAO¨©A^œA¹:NA8Ú¯AG×£A~zAAd¹¬>ý[¯>z`?„4ŸAf AA?TA¿g¡AOlŸARþRAtÏ AG×£AZ÷OA‘æ°>Ÿ>®>Fá_?tÏ AG×£AZ÷OA¿g¡AOlŸARþRAb$¢A :ŸAÔ’RA" »>§´>€ˆ\?tÏ AG×£AZ÷OAb$¢A :ŸAÔ’RA‡w¨AG×£AIIA¥À¿>g­>à]?‡w¨AG×£AIIAb$¢A :ŸAÔ’RAq#¤A掞A¬mQAƒ—Æ>!{ª> \?‡w¨AG×£AIIAq#¤A掞A¬mQAüõ¦AQiApÌOA€áˆ>Më²>ãe?³–A`¡A5XYA&0™Aãé A—¢WAóì˜AG×£Aö{UA³T>X»²>Q@e?óì˜AG×£Aö{UA&0™Aãé A—¢WAx@™A è Aq™WA4A˜>—þ¶>¥¥b?óì˜AG×£Aö{UAx@™A è Aq™WAtÏ AG×£AZ÷OA|ìœ>£R²>#Èb?tÏ AG×£AZ÷OAx@™A è Aq™WA8œA†’ AjïUA…[¥>“±>À‰a?tÏ AG×£AZ÷OA8œA†’ AjïUA„4ŸAf AA?TA‰( =˜Ú¿†ô:Jñ€AxÌ+=ûŽ«=pABÏ(cvAð)®;Âãµ(Sá½?r~¿è½¶;sTLAòŽ+>,+>T}VA¼®=ù…)k^AxÌ+=ûŽ«=N}®½—¿Çô:k^AxÌ+=ûŽ«=T}VA¼®=ù…)u^AÆ€t=·W )ðK½š®¿…%ô:k^AxÌ+=ûŽ«=u^AÆ€t=·W )pABÏ(žˆ|¿ «=ù¿AA´À>¿žÕ?°ÅOAòŽ+>CRx?«QAòŽ+>¡?+äá½~¿Étj=«QAòŽ+>¡?°ÅOAòŽ+>CRx?G×_AxÌ+=„ù>_²½¶º~¿Â'E=«QAòŽ+>¡?G×_AxÌ+=„ù>·w`AxÌ+=V{?Èf4½¡®¿ °¾<·w`AxÌ+=V{?G×_AxÌ+=„ù>pABÏ(øïB=ˆ|¿-æ*>νA´À>+!L@¨õwAòŽ+>E~ @‹zAòŽ+>R¹@û =~¿R¹@¨õwAòŽ+>E~ @¯ýsAxÌ+=hâ‹?Á¨á<¶º~¿¦ÕÃ=‹zAòŽ+>R¹@¯ýsAxÌ+=hâ‹?XIuAxÌ+=w‰?×>S<¡®¿?E=XIuAxÌ+=w‰?¯ýsAxÌ+=hâ‹?pABÏ(0p=¿Îô:cvAð)®;Âãµ(‚÷€ApJ3=´ˆ(Jñ€AxÌ+=ûŽ«=å[œ=œ@¿ôþó:Jñ€AxÌ+=ûŽ«=‚÷€ApJ3=´ˆ(“A”ÞC=ûºƒ(zìÎ=›¯~¿ö;Jñ€AxÌ+=ûŽ«=“A”ÞC=ûºƒ(ÆÕ‰AòŽ+>,+>”.|¾îx¿²@S<át)Aµ™*?+©>¡:AD’Ä>y>R)‹¾:A´À>ïk>~Ù_¾èÍy¿&¤µ;‹¾:A´À>ïk>¡:AD’Ä>y>R)§D=AŠ­>T÷L)“¼F¾{¿ýº<‹¾:A´À>ïk>§D=AŠ­>T÷L)sTLAòŽ+>,+>ëÔ-¾XH|¿Âls;sTLAòŽ+>,+>§D=AŠ­>T÷L)0HLApE@>@ð.).é ¾xª}¿|]s;sTLAòŽ+>,+>0HLApE@>@ð.)T}VA¼®=ù…)ÍS¾Îx¿u‡ >5Aµ™*?\f@ù¿AA´À>¿žÕ?ìßCA´À>H¬ð?þ³,¾,îz¿‰Ô=ìßCA´À>H¬ð?ù¿AA´À>¿žÕ?«QAòŽ+>¡?ñ¾ˆ|¿žâÁ=ìßCA´À>H¬ð?«QAòŽ+>¡?rRAòŽ+>H3¡?Êؽ~¿úÇ…=rRAòŽ+>H3¡?«QAòŽ+>¡?·w`AxÌ+=V{?pª½¶º~¿mC_=rRAòŽ+>H3¡?·w`AxÌ+=V{?e.aAxÌ+=ÿ¦!?œÅ,½¡®¿Ùì„Aµ™*?̳ƒ@νA´À>+!L@jÁA´À>uÚF@&Y‚=,îz¿"@>jÁA´À>uÚF@νA´À>+!L@‹zAòŽ+>R¹@?zu=ˆ|¿‚Ç&>jÁA´À>uÚF@‹zAòŽ+>R¹@|}AòŽ+> 0@¸€$=~¿×ð=|}AòŽ+> 0@‹zAòŽ+>R¹@XIuAxÌ+=w‰?˜È =¶º~¿2¿=|}AòŽ+> 0@XIuAxÌ+=w‰?nvAxÌ+==…?Ɇ<¡®¿Ô˜@=nvAxÌ+==…?XIuAxÌ+=w‰?pABÏ(oê>ö}¿;rs;“A”ÞC=ûºƒ([݉AT?> (ÆÕ‰AòŽ+>,+>3â$>b¨|¿5Zs;ÆÕ‰AòŽ+>,+>[݉AT?> (<ŽAPü„>,Æ€'_Ï=>n{¿ô·<ÆÕ‰AòŽ+>,+><ŽAPü„>,Æ€'º ’A´À>ïk> »¾<¯r¿SJE>”r+A?ɬZ@5Aµ™*?\f@8±8Aµ™*?ÿl0@¢±`¾qqv¿®L">8±8Aµ™*?ÿl0@5Aµ™*?\f@ìßCA´À>H¬ð?YîH¾Îx¿òø>8±8Aµ™*?ÿl0@ìßCA´À>H¬ð? ?FA´À> 0@[G$¾,îz¿JÁí= ?FA´À> 0@ìßCA´À>H¬ð?rRAòŽ+>H3¡?åG ¾ˆ|¿žš×= ?FA´À> 0@rRAòŽ+>H3¡?¥TAòŽ+>'k²?uåͽ~¿ –•=¥TAòŽ+>'k²?rRAòŽ+>H3¡?e.aAxÌ+=ÿ¦!?ů¡½¶º~¿vx=¥TAòŽ+>'k²?e.aAxÌ+=ÿ¦!?IúaAxÌ+=:ë2?-$½¡®¿ÂUò<¯r¿½m”>™‹A?Jÿ@ì„Aµ™*?̳ƒ@ÄX‡Aµ™*?Pñ~@hvØ=qqv¿å,>ÄX‡Aµ™*?Pñ~@ì„Aµ™*?̳ƒ@jÁA´À>uÚF@ýÙÐ=Îx¿Ðîe>ÄX‡Aµ™*?Pñ~@jÁA´À>uÚF@õ•ƒA´À>w@@ஞ=,îz¿Öœ:>õ•ƒA´À>w@@jÁA´À>uÚF@|}AòŽ+> 0@‹R“=ˆ|¿º!>õ•ƒA´À>w@@|}AòŽ+> 0@$…AòŽ+>@é@ò H=~¿&ê=$…AòŽ+>@é@|}AòŽ+> 0@nvAxÌ+==…?Ôñ)=¶º~¿3=¹=$…AòŽ+>@é@nvAxÌ+==…?$ÈwAxÌ+=ÊE?¤1£<¡®¿®;=$ÈwAxÌ+=ÊE?nvAxÌ+==…?pABÏ(vùV>‚Jz¿Ýªµ;<ŽAPü„>,Æ€'Zª’AŠCÊ>(©¥º ’A´À>ïk>;^z>æ9x¿ö»µ;º ’A´À>ïk>Zª’AŠCÊ>(©¥ž¤šAÖ#?±¹¨ãc‰>Öv¿§>S<º ’A´À>ïk>ž¤šAÖ#?±¹¨E›Aµ™*?+©> ¦¾ß r¿ðƆ<7A?Û­Ñ>!Ÿ$A$PB?aB~)át)Aµ™*?+©>„š¾¬t¿nžð;át)Aµ™*?+©>!Ÿ$A$PB?aB~)^P)A°Ö-?äßt)*ŠŠ¾iqv¿tÁð;át)Aµ™*?+©>^P)A°Ö-?äßt)¡:AD’Ä>y>R)í×”¾|ëk¿ã¾ƒ>pª#AÈ#¾?×§@”r+A?ɬZ@ƒ¹/A?"Žn@åà…¾3”p¿ùta>ƒ¹/A?"Žn@”r+A?ɬZ@8±8Aµ™*?ÿl0@þs¾<¯r¿Ó X>ƒ¹/A?"Žn@8±8Aµ™*?ÿl0@œ$œ$ 0@ð<¾Îx¿q'>œ$ 0@òÙHA´À>oL@‡ï¾,îz¿ZÒ>òÙHA´À>oL@ ?FA´À> 0@¥TAòŽ+>'k²?jÔ¾ˆ|¿ñì=òÙHA´À>oL@¥TAòŽ+>'k²?TÇUAòŽ+>–£Â?[$½~¿ó¤=TÇUAòŽ+>–£Â?¥TAòŽ+>'k²?IúaAxÌ+=:ë2? ö—½¶º~¿#̇=TÇUAòŽ+>–£Â?IúaAxÌ+=:ë2?AÚbAxÌ+=O/C?†©½¡®¿ü=AÚbAxÌ+=O/C?IúaAxÌ+=:ë2?pABÏ(º¤>>|ëk¿„m®>t’AÈ#¾?²\´@™‹A?Jÿ@£ëA?’Þ—@9 >3”p¿8››>£ëA?’Þ—@™‹A?Jÿ@ÄX‡Aµ™*?Pñ~@‚j><¯r¿æûŽ>£ëA?’Þ—@ÄX‡Aµ™*?Pñ~@q¯‰Aµ™*? u@íþý=qqv¿¬_v>q¯‰Aµ™*? u@ÄX‡Aµ™*?Pñ~@õ•ƒA´À>w@@!¢ò=Îx¿u|]>q¯‰Aµ™*? u@õ•ƒA´À>w@@ìY…A´À>9@l!º=,îz¿b)4>ìY…A´À>9@õ•ƒA´À>w@@$…AòŽ+>@é@ «=ˆ|¿Å>ìY…A´À>9@$…AòŽ+>@é@Jñ€AòŽ+>¤Ò÷?Étj=~¿+äá=Jñ€AòŽ+>¤Ò÷?$…AòŽ+>@é@$ÈwAxÌ+=ÊE?Â'E=¶º~¿_²=Jñ€AòŽ+>¤Ò÷?$ÈwAxÌ+=ÊE?µ÷xAxÌ+=Š„x? °¾<¡®¿Èf4=µ÷xAxÌ+=Š„x?$ÈwAxÌ+=ÊE?pABÏ((é¾pÖc¿µ¶¾<Ì«ð@™@V{?8ùA Ä¿?Ç›)¸(AÈ#¾?„ù>SrÚ¾…ƒg¿1<¸(AÈ#¾?„ù>8ùA Ä¿?Ç›)>Ô AÆ”«?ì–)â©Î¾Ù)j¿Z0£<¸(AÈ#¾?„ù>>Ô AÆ”«?ì–)7A?Û­Ñ>Z þ%«l¿Á)<7A?Û­Ñ>>Ô AÆ”«?ì–)$qA^A‡?,O‹);4²¾iûo¿y*<7A?Û­Ñ>$qA^A‡?,O‹)!Ÿ$A$PB?aB~)ËÏ¢¾%Öc¿ÒS§>aA™@µî¯@pª#AÈ#¾?×§@,)AÈ#¾? «˜@w–¾À^i¿m*“>,)AÈ#¾? «˜@pª#AÈ#¾?×§@ƒ¹/A?"Žn@÷”о|ëk¿€Ž>,)AÈ#¾? «˜@ƒ¹/A?"Žn@w\4A?ùŒ€@í(z¾3”p¿Öt>w\4A?ùŒ€@ƒ¹/A?"Žn@œ$w\4A?ùŒ€@œ$<â?Aµ™*?‘mO@œ$oL@0ã/¾Îx¿ 65><â?Aµ™*?‘mO@òÙHA´À>oL@ä¬KA´À>8˜@â¹¾,îz¿Ã>ä¬KA´À>8˜@òÙHA´À>oL@TÇUAòŽ+>–£Â?ˆE÷½ˆ|¿:Oÿ=ä¬KA´À>8˜@TÇUAòŽ+>–£Â?«WAòŽ+>^ÅÑ?NMµ½~¿Dš²=«WAòŽ+>^ÅÑ?TÇUAòŽ+>–£Â?AÚbAxÌ+=O/C?êc½¶º~¿ Æ’=«WAòŽ+>^ÅÑ?AÚbAxÌ+=O/C? ÍcAxÌ+=ó[R?‰H½¡®¿‰H= ÍcAxÌ+=ó[R?AÚbAxÌ+=O/C?pABÏ(kÎ}>%Öc¿¨öÃ>™Ì™A™@LÆ@t’AÈ#¾?²\´@pT•AÈ#¾?r¬@ý[>À^i¿°p³>pT•AÈ#¾?r¬@t’AÈ#¾?²\´@£ëA?’Þ—@/.X>|ëk¿Ѧ>pT•AÈ#¾?r¬@£ëA?’Þ—@L²A?lä@7>3”p¿;/•>L²A?lä@£ëA?’Þ—@q¯‰Aµ™*? u@]Y1><¯r¿[½ˆ>L²A?lä@q¯‰Aµ™*? u@Ëì‹Aµ™*?ðËi@è >qqv¿º1l>Ëì‹Aµ™*?ðËi@q¯‰Aµ™*? u@ìY…A´À>9@u‡ >Îx¿ÍS>Ëì‹Aµ™*?ðËi@ìY…A´À>9@Ä ‡A´À>O€0@‰Ô=,îz¿þ³,>Ä ‡A´À>O€0@ìY…A´À>9@Jñ€AòŽ+>¤Ò÷?žâÁ=ˆ|¿ñ>Ä ‡A´À>O€0@Jñ€AòŽ+>¤Ò÷?5‚AòŽ+>üoì?úÇ…=~¿ÊØ=5‚AòŽ+>üoì?Jñ€AòŽ+>¤Ò÷?µ÷xAxÌ+=Š„x?mC_=¶º~¿pª=5‚AòŽ+>üoì?µ÷xAxÌ+=Š„x?pzAxÌ+=µm?Ù<¡®¿œÅ,=pzAxÌ+=µm?µ÷xAxÌ+=Š„x?pABÏ(Ö¾•>ŠÌt¿Á›ð;ž¤šAÖ#?±¹¨’[›A¿+?†ö ¨E›Aµ™*?+©>ï¢>#¯r¿BÂð;E›Aµ™*?+©>’[›A¿+?†ö ¨Ì£Al”†?1Y‰¨¿Ñ®>ý“p¿Ë†Ì£Al”†?1Y‰¨ä·£A?Û­Ñ>.ì¾>.†m¿é <ä·£A?Û­Ñ>Ì£Al”†?1Y‰¨­¨¦Aº—?4ÕŸ¨Ê>kk¿Ê/£<ä·£A?Û­Ñ>­¨¦Aº—?4ÕŸ¨£ë«AÈ#¾?„ù>®R«¾³zZ¿¦˜Ì>Ç´AÏ&@úfÓ@aA™@µî¯@d.%A™@º£»@€¼¡¾TÛ`¿j±·>d.%A™@º£»@aA™@µî¯@,)AÈ#¾? «˜@Ú•¾%Öc¿Ç³>d.%A™@º£»@,)AÈ#¾? «˜@/AÈ#¾?×Ó¢@ú ‹¾À^i¿ÿ>/AÈ#¾?×Ó¢@,)AÈ#¾? «˜@w\4A?ùŒ€@4¾|ëk¿Hu˜>/AÈ#¾?×Ó¢@w\4A?ùŒ€@ÍT9A?؉@ì)g¾3”p¿Elƒ>ÍT9A?؉@w\4A?ùŒ€@<â?Aµ™*?‘mO@ Q¾<¯r¿Tz>ÍT9A?؉@<â?Aµ™*?‘mO@ÀäCAµ™*?;]@ýñ6¾qqv¿½:P>ÀäCAµ™*?;]@<â?Aµ™*?‘mO@ä¬KA´À>8˜@ŒÚ!¾Îx¿6ÙA>ÀäCAµ™*?;]@ä¬KA´À>8˜@׳NA´À>Ñ'@ µ¾,îz¿Õs>׳NA´À>Ñ'@ä¬KA´À>8˜@«WAòŽ+>^ÅÑ?:€ã½ˆ|¿€‰>׳NA´À>Ñ'@«WAòŽ+>^ÅÑ?›²YAòŽ+>Ôºß?²r§½~¿ã¦¿=›²YAòŽ+>Ôºß?«WAòŽ+>^ÅÑ? ÍcAxÌ+=ó[R?Ê‚½¶º~¿üíœ=›²YAòŽ+>Ôºß? ÍcAxÌ+=ó[R?LÑdAxÌ+=n[`?ü½¡®¿†©=LÑdAxÌ+=n[`? ÍcAxÌ+=ó[R?pABÏ(üW¡>³zZ¿ôÔ>œ%¢AÏ&@úfÓ@™Ì™A™@LÆ@ÍhA™@º£»@>TÛ`¿ŠŽÆ>ÍhA™@º£»@™Ì™A™@LÆ@pT•AÈ#¾?r¬@S1>%Öc¿œî¹>ÍhA™@º£»@pT•AÈ#¾?r¬@pv˜AÈ#¾?×Ó¢@Q1v>À^i¿ó·ª>pv˜AÈ#¾?×Ó¢@pT•AÈ#¾?r¬@L²A?lä@$‚p>|ëk¿ËEž>pv˜AÈ#¾?×Ó¢@L²A?lä@™U“A?؉@'ÑL>3”p¿©í>™U“A?؉@L²A?lä@Ëì‹Aµ™*?ðËi@SJE><¯r¿ »>™U“A?؉@Ëì‹Aµ™*?ðËi@  ŽAµ™*?;]@®L">qqv¿¢±`>  ŽAµ™*?;]@Ëì‹Aµ™*?ðËi@Ä ‡A´À>O€0@òø>Îx¿YîH>  ŽAµ™*?;]@Ä ‡A´À>O€0@¦ˆA´À>Ñ'@JÁí=,îz¿[G$>¦ˆA´À>Ñ'@Ä ‡A´À>O€0@5‚AòŽ+>üoì?žš×=ˆ|¿åG >¦ˆA´À>Ñ'@5‚AòŽ+>üoì?²&ƒAòŽ+>Ôºß? –•=~¿uåÍ=²&ƒAòŽ+>Ôºß?5‚AòŽ+>üoì?pzAxÌ+=µm?vx=¶º~¿Å¯¡=²&ƒAòŽ+>Ôºß?pzAxÌ+=µm?´.{AxÌ+=n[`?ÂUò<¡®¿-$=´.{AxÌ+=n[`?pzAxÌ+=µm?pABÏ(UÖ>yh¿¡%1<­¨¦Aº—?4ÕŸ¨÷ý«A“À?@Ãɨ£ë«AÈ#¾?„ù>%³æ>à…d¿M*1<£ë«AÈ#¾?„ù>÷ý«A“À?@Ãɨf%²Amtð?…%ú¨{Êñ>˜“a¿ë±¾<£ë«AÈ#¾?„ù>f%²Amtð?…%ú¨ Õ³A™@V{?—æ¿tZ¿<$Ù<È\Ò@Ï&@ÿ¦!?Rì@vè@M—­)Ì«ð@™@V{?ºŽ¿R[]¿ÂL<Ì«ð@™@V{?Rì@vè@M—­)ˆð@ü@ ´«)æ©ô¾nÛ`¿=8L<Ì«ð@™@V{?ˆð@ü@ ´«)8ùA Ä¿?Ç›)Å/®¾pæO¿e¸ò>Ç´AqQ@ÐE÷@Ç´AÏ&@úfÓ@G×#AÏ&@âhß@‡p§¾W¿¹~Ý>G×#AÏ&@âhß@Ç´AÏ&@úfÓ@d.%A™@º£»@³zZ¿ÂÓØ>G×#AÏ&@âhß@d.%A™@º£»@Îf,A™@LÆ@ƒŽ“¾TÛ`¿DÃ>Îf,A™@LÆ@d.%A™@º£»@/AÈ#¾?×Ó¢@ê ˆ¾%Öc¿m¹½>Îf,A™@LÆ@/AÈ#¾?×Ó¢@W5AÈ#¾?r¬@”³}¾À^i¿›ò§>W5AÈ#¾?r¬@/AÈ#¾?×Ó¢@ÍT9A?؉@G—g¾|ëk¿4¡>W5AÈ#¾?r¬@ÍT9A?؉@h›>A?lä@øßR¾3”p¿b±‹>h›>A?lä@ÍT9A?؉@ÀäCAµ™*?;]@'È=¾<¯r¿]€„>h›>A?lä@ÀäCAµ™*?;]@i&HAµ™*?ðËi@kß&¾qqv¿—Q]>i&HAµ™*?ðËi@ÀäCAµ™*?;]@׳NA´À>Ñ'@1ê¾Îx¿ÛfM>i&HAµ™*?ðËi@׳NA´À>Ñ'@wêQA´À>O€0@Œáó½,îz¿¤">wêQA´À>O€0@׳NA´À>Ñ'@›²YAòŽ+>Ôºß?8uνˆ|¿é§>wêQA´À>O€0@›²YAòŽ+>Ôºß?—Ù[AòŽ+>üoì?[¨˜½~¿!¡Ë=—Ù[AòŽ+>üoì?›²YAòŽ+>Ôºß?LÑdAxÌ+=n[`?ßk½¶º~¿-5¦=—Ù[AòŽ+>üoì?LÑdAxÌ+=n[`?åeAxÌ+=µm?ÂUò¼¡®¿-$=åeAxÌ+=µm?LÑdAxÌ+=n[`?pABÏ(èßÅ>pæO¿iÔß>ÃãªAqQ@ZbÛ@œ%¢AÏ&@úfÓ@…ú¥AÏ&@j6Æ@Ñ®²>W¿_‡Ô>…ú¥AÏ&@j6Æ@œ%¢AÏ&@úfÓ@ÍhA™@º£»@ÙÆ°>³zZ¿&çÇ>…ú¥AÏ&@j6Æ@ÍhA™@º£»@tÏ A™@µî¯@(‰>TÛ`¿ÒN»>tÏ A™@µî¯@ÍhA™@º£»@pv˜AÈ#¾?×Ó¢@N±š>%Öc¿_Ü®>tÏ A™@µî¯@pv˜AÈ#¾?×Ó¢@õi›AÈ#¾? «˜@‹‚‡>À^i¿Î ¡>õi›AÈ#¾? «˜@pv˜AÈ#¾?×Ó¢@™U“A?؉@㾃>|ëk¿í×”>õi›AÈ#¾? «˜@™U“A?؉@ÄÑ•A?ùŒ€@ùta>3”p¿åà…>ÄÑ•A?ùŒ€@™U“A?؉@  ŽAµ™*?;]@Ó X><¯r¿þs>ÄÑ•A?ùŒ€@  ŽAµ™*?;]@áAµ™*?‘mO@£2>qqv¿ÙïS>áAµ™*?‘mO@  ŽAµ™*?;]@¦ˆA´À>Ñ'@q'>Îx¿ð<>áAµ™*?‘mO@¦ˆA´À>Ñ'@)ŠA´À>8˜@ZÒ>,îz¿‡ï>)ŠA´À>8˜@¦ˆA´À>Ñ'@²&ƒAòŽ+>Ôºß?ñì=ˆ|¿jÔ>)ŠA´À>8˜@²&ƒAòŽ+>Ôºß?:*„AòŽ+>^ÅÑ?ó¤=~¿[$Â=:*„AòŽ+>^ÅÑ?²&ƒAòŽ+>Ôºß?´.{AxÌ+=n[`?#̇=¶º~¿ ö—=:*„AòŽ+>^ÅÑ?´.{AxÌ+=n[`?õ2|AxÌ+=ó[R?ü=¡®¿†©=õ2|AxÌ+=ó[R?´.{AxÌ+=n[`?pABÏ(Yü¿ÜM¿»Yò<̵@qQ@:ë2?`¾Á@•e=@ áÂ)È\Ò@Ï&@ÿ¦!?ô¿ë–Q¿ˆþe<È\Ò@Ï&@ÿ¦!?`¾Á@•e=@ áÂ) öÑ@[á'@Jź)Êk ¿€¬V¿Of<È\Ò@Ï&@ÿ¦!? öÑ@[á'@Jź)Rì@vè@M—­)ƒV«¾g(D¿’l ?aA•"€@ _ AÇ´AqQ@ÐE÷@d.%AqQ@—Air§¾´L¿(Ý?d.%AqQ@—AÇ´AqQ@ÐE÷@G×#AÏ&@âhß@ ›¾pæO¿ÿ>d.%AqQ@—AG×#AÏ&@âhß@Îf,AÏ&@ò*ê@Ek–¾W¿qcé>Îf,AÏ&@ò*ê@G×#AÏ&@âhß@Îf,A™@LÆ@{ꊾ³zZ¿qØã>Îf,AÏ&@ò*ê@Îf,A™@LÆ@ÿÿ3A™@™ØÏ@F„¾TÛ`¿2¿Í>ÿÿ3A™@™ØÏ@Îf,A™@LÆ@W5AÈ#¾?r¬@Úýr¾%Öc¿u\Ç>ÿÿ3A™@™ØÏ@W5AÈ#¾?r¬@ï;AÈ#¾?²\´@ýãc¾À^i¿'õ°>ï;AÈ#¾?²\´@W5AÈ#¾?r¬@h›>A?lä@ÌËN¾|ëk¿Óé>ï;AÈ#¾?²\´@h›>A?lä@¸(DA?’Þ—@h=¾3”p¿€.“>¸(DA?’Þ—@h›>A?lä@i&HAµ™*?ðËi@r)¾<¯r¿Ý8‹>¸(DA?’Þ—@i&HAµ™*?ðËi@¡LAµ™*? u@ðݾqqv¿—+i>¡LAµ™*? u@i&HAµ™*?ðËi@wêQA´À>O€0@€'¾Îx¿pÎW>¡LAµ™*? u@wêQA´À>O€0@(LUA´À>9@ÝûÚ½,îz¿~­*>(LUA´À>9@wêQA´À>O€0@—Ù[AòŽ+>üoì?¢B¸½ˆ|¿:÷>(LUA´À>9@—Ù[AòŽ+>üoì?k^AòŽ+>¤Ò÷?w‰½~¿ØwÖ=k^AòŽ+>¤Ò÷?—Ù[AòŽ+>üoì?åeAxÌ+=µm?Ã^R½¶º~¿jŽ®=k^AòŽ+>¤Ò÷?åeAxÌ+=µm?JgAxÌ+=Š„x?Ù¼¡®¿œÅ,=JgAxÌ+=Š„x?åeAxÌ+=µm?pABÏ(5®ë>h(D¿i‰å> Õ³A•"€@•Þ@ÃãªAqQ@ZbÛ@–Ø®AqQ@ Ë@–ô×>´L¿& Ý>–Ø®AqQ@ Ë@ÃãªAqQ@ZbÛ@…ú¥AÏ&@j6Æ@T Ö>pæO¿«jÐ>–Ø®AqQ@ Ë@…ú¥AÏ&@j6Æ@š©AÏ&@ê·@ÇÂ>W¿ß”Æ>š©AÏ&@ê·@…ú¥AÏ&@j6Æ@tÏ A™@µî¯@¡8¿>³zZ¿("º>š©AÏ&@ê·@tÏ A™@µî¯@­û£A™@Ð=£@Á«>TÛ`¿ð¯>­û£A™@Ð=£@tÏ A™@µî¯@õi›AÈ#¾? «˜@ÒS§>%Öc¿ËÏ¢>­û£A™@Ð=£@õi›AÈ#¾? «˜@È*žAÈ#¾?×§@m*“>À^i¿w–>È*žAÈ#¾?×§@õi›AÈ#¾? «˜@ÄÑ•A?ùŒ€@€Ž>|ëk¿÷”Š>È*žAÈ#¾?×§@ÄÑ•A?ùŒ€@>#˜A?"Žn@Öt>3”p¿í(z>>#˜A?"Žn@ÄÑ•A?ùŒ€@áAµ™*?‘mO@éÁi><¯r¿¥(c>>#˜A?"Žn@áAµ™*?‘mO@²í‘Aµ™*?w@@ÆùA>qqv¿§þE>²í‘Aµ™*?w@@áAµ™*?‘mO@)ŠA´À>8˜@ 65>Îx¿0ã/>²í‘Aµ™*?w@@)ŠA´À>8˜@“‹A´À>oL@Ã>,îz¿â¹>“‹A´À>oL@)ŠA´À>8˜@:*„AòŽ+>^ÅÑ?:Oÿ=ˆ|¿ˆE÷=“‹A´À>oL@:*„AòŽ+>^ÅÑ?V…AòŽ+>–£Â?Dš²=~¿NMµ=V…AòŽ+>–£Â?:*„AòŽ+>^ÅÑ?õ2|AxÌ+=ó[R? Æ’=¶º~¿êc=V…AòŽ+>–£Â?õ2|AxÌ+=ó[R?¿%}AxÌ+=O/C?‰H=¡®¿‰H=¿%}AxÌ+=O/C?õ2|AxÌ+=ó[R?pABÏ(+ý>º}^¿ñLŽ~<̵@qQ@:ë2?Œµ@[R@ 3É)`¾Á@•e=@ áÂ)bõ?RQ7¿ Œå>WƼA_„™@ZbÛ@ Õ³A•"€@•Þ@LзA•"€@ Ë@Kþ>ÿþ?¿éß>LзA•"€@ Ë@ Õ³A•"€@•Þ@–Ø®AqQ@ Ë@¾,ü>g(D¿QHÓ>LзA•"€@ Ë@–Ø®AqQ@ Ë@å~²AqQ@P˜º@ÂÞç>³L¿IÌ>å~²AqQ@P˜º@–Ø®AqQ@ Ë@š©AÏ&@ê·@Nå>pæO¿ŠÖ¿>å~²AqQ@P˜º@š©AÏ&@ê·@¿Ù¬AÏ&@r–¨@ç\Ð>W¿†·>¿Ù¬AÏ&@r–¨@š©AÏ&@ê·@­û£A™@Ð=£@¦˜Ì>³zZ¿®R«>¿Ù¬AÏ&@r–¨@­û£A™@Ð=£@îè¦A™@6£•@j±·>TÛ`¿€¼¡>îè¦A™@6£•@­û£A™@Ð=£@È*žAÈ#¾?×§@dz>%Öc¿Ú•>îè¦A™@6£•@È*žAÈ#¾?×§@ö´ AÈ#¾?ÁÙ@ÿ>À^i¿ú ‹>ö´ AÈ#¾?ÁÙ@È*žAÈ#¾?×§@>#˜A?"Žn@Hu˜>|ëk¿4>ö´ AÈ#¾?ÁÙ@>#˜A?"Žn@¶FšA?ɬZ@Elƒ>3”p¿ì)g>¶FšA?ɬZ@>#˜A?"Žn@²í‘Aµ™*?w@@Tz><¯r¿ Q>¶FšA?ɬZ@²í‘Aµ™*?w@@d§“Aµ™*?ÿl0@½:P>qqv¿ýñ6>d§“Aµ™*?ÿl0@²í‘Aµ™*?w@@“‹A´À>oL@6ÙA>Îx¿ŒÚ!>d§“Aµ™*?ÿl0@“‹A´À>oL@zàŒA´À> 0@Õs>,îz¿ µ>zàŒA´À> 0@“‹A´À>oL@V…AòŽ+>–£Â?€‰>ˆ|¿:€ã=zàŒA´À> 0@V…AòŽ+>–£Â?­û…AòŽ+>'k²?㦿=~¿²r§=­û…AòŽ+>'k²?V…AòŽ+>–£Â?¿%}AxÌ+=O/C?üíœ=¶º~¿Ê‚=­û…AòŽ+>'k²?¿%}AxÌ+=O/C?·~AxÌ+=:ë2?†©=¡®¿ü=·~AxÌ+=:ë2?¿%}AxÌ+=O/C?pABÏ(Ðh?6dK¿S ~© œÂAqQ@:ë2?%ˆ"? ¿E¿¡•~< œÂAqQ@:ë2?D·ÂAx}R@É5>©xÇA2ˆm@›"O©l@'?¢A¿ü= œÂAqQ@:ë2?xÇA2ˆm@›"O©{dÉA•"€@O/C?yÝ?}s)¿KÜß>~„ÅA’¹´@úfÓ@WƼA_„™@ZbÛ@]®ÀA_„™@j6Æ@y?)Î2¿[Ý>]®ÀA_„™@j6Æ@WƼA_„™@ZbÛ@LзA•"€@ Ë@'?RQ7¿ˆoÐ>]®ÀA_„™@j6Æ@LзA•"€@ Ë@.p»A•"€@ê·@‚ ?ÿþ?¿ãKÌ>.p»A•"€@ê·@LзA•"€@ Ë@å~²AqQ@P˜º@!¡?h(D¿¿Ø¿>.p»A•"€@ê·@å~²AqQ@P˜º@tѵAqQ@r–¨@ú|ö>³L¿`cº>tѵAqQ@r–¨@å~²AqQ@P˜º@¿Ù¬AÏ&@r–¨@e¸ò>pæO¿Å/®>tѵAqQ@r–¨@¿Ù¬AÏ&@r–¨@8Ú¯AÏ&@rQ˜@¹~Ý>W¿‡p§>8Ú¯AÏ&@rQ˜@¿Ù¬AÏ&@r–¨@îè¦A™@6£•@ÂÓØ>³zZ¿î›>8Ú¯AÏ&@rQ˜@îè¦A™@6£•@“©A™@c2‡@DÃ>TÛ`¿ƒŽ“>“©A™@c2‡@îè¦A™@6£•@ö´ AÈ#¾?ÁÙ@m¹½>%Öc¿ê ˆ>“©A™@c2‡@ö´ AÈ#¾?ÁÙ@Ü£AÈ#¾?ˆ£j@›ò§>À^i¿”³}>Ü£AÈ#¾?ˆ£j@ö´ AÈ#¾?ÁÙ@¶FšA?ɬZ@4¡>|ëk¿G—g>Ü£AÈ#¾?ˆ£j@¶FšA?ɬZ@9œA?_’E@b±‹>3”p¿øßR>9œA?_’E@¶FšA?ɬZ@d§“Aµ™*?ÿl0@]€„><¯r¿'È=>9œA?_’E@d§“Aµ™*?ÿl0@~9•Aµ™*?\f@—Q]>qqv¿kß&>~9•Aµ™*?\f@d§“Aµ™*?ÿl0@zàŒA´À> 0@ÛfM>Îx¿1ê>~9•Aµ™*?\f@zàŒA´À> 0@ ŽA´À>H¬ð?¤">,îz¿Œáó= ŽA´À>H¬ð?zàŒA´À> 0@­û…AòŽ+>'k²?é§>ˆ|¿8uÎ= ŽA´À>H¬ð?­û…AòŽ+>'k²?džAòŽ+>H3¡?!¡Ë=~¿[¨˜=džAòŽ+>H3¡?­û…AòŽ+>'k²?·~AxÌ+=:ë2?-5¦=¶º~¿ßk=džAòŽ+>H3¡?·~AxÌ+=:ë2?›Ñ~AxÌ+=ÿ¦!?-$=¡®¿ÂUò<›Ñ~AxÌ+=ÿ¦!?·~AxÌ+=:ë2?pABÏ(¼IA¿à“'¿¤±=\ŠS@’¹´@n[`?2ˆm@ê£@C^è)u@_„™@ó[R?G<=¿DY,¿M§•ÝÍA:›Ñ@LÆ@~„ÅA’¹´@úfÓ@@ÉA’¹´@º£»@¾¿$?$¿H‘Ô>@ÉA’¹´@º£»@~„ÅA’¹´@úfÓ@]®ÀA_„™@j6Æ@:Ë#?|s)¿^ðÇ>@ÉA’¹´@º£»@]®ÀA_„™@j6Æ@U.ÄA_„™@µî¯@võ?)Î2¿É›Æ>U.ÄA_„™@µî¯@]®ÀA_„™@j6Æ@.p»A•"€@ê·@òˆ?RQ7¿†(º>U.ÄA_„™@µî¯@.p»A•"€@ê·@…¯¾A•"€@Ð=£@O?ÿþ?¿HŠ·>…¯¾A•"€@Ð=£@.p»A•"€@ê·@tѵAqQ@r–¨@’l ?g(D¿ƒV«>…¯¾A•"€@Ð=£@tѵAqQ@r–¨@ƒË¸AqQ@6£•@(Ý?´L¿ir§>ƒË¸AqQ@6£•@tѵAqQ@r–¨@8Ú¯AÏ&@rQ˜@ÿ>pæO¿ ›>ƒË¸AqQ@6£•@8Ú¯AÏ&@rQ˜@¼Š²AÏ&@c2‡@qcé>W¿Ek–>¼Š²AÏ&@c2‡@8Ú¯AÏ&@rQ˜@“©A™@c2‡@qØã>³zZ¿{êŠ>¼Š²AÏ&@c2‡@“©A™@c2‡@&ö«A™@p@2¿Í>TÛ`¿F„>&ö«A™@p@“©A™@c2‡@Ü£AÈ#¾?ˆ£j@u\Ç>%Öc¿Úýr>&ö«A™@p@Ü£AÈ#¾?ˆ£j@,¥AÈ#¾?£CP@'õ°>À^i¿ýãc>,¥AÈ#¾?£CP@Ü£AÈ#¾?ˆ£j@9œA?_’E@Óé>|ëk¿ÌËN>,¥AÈ#¾?£CP@9œA?_’E@¥÷A?]/@€.“>3”p¿h=>¥÷A?]/@9œA?_’E@~9•Aµ™*?\f@Ý8‹><¯r¿r)>¥÷A?]/@~9•Aµ™*?\f@¡–Aµ™*?„{ @—+i>qqv¿ðÝ>¡–Aµ™*?„{ @~9•Aµ™*?\f@ ŽA´À>H¬ð?pÎW>Îx¿€'>¡–Aµ™*?„{ @ ŽA´À>H¬ð? A´À>¿žÕ?~­*>,îz¿ÝûÚ= A´À>¿žÕ? ŽA´À>H¬ð?džAòŽ+>H3¡?:÷>ˆ|¿¢B¸= A´À>¿žÕ?džAòŽ+>H3¡?*}‡AòŽ+>¡?ØwÖ=~¿w‰=*}‡AòŽ+>¡?džAòŽ+>H3¡?›Ñ~AxÌ+=ÿ¦!?jŽ®=¶º~¿Ã^R=*}‡AòŽ+>¡?›Ñ~AxÌ+=ÿ¦!?HˆAxÌ+=V{?œÅ,=¡®¿Ù¥¡ÕAð@²\´@ÝÍA:›Ñ@LÆ@qTÑA:›Ñ@r¬@ÑŒ6?Æ¿-œÆ>qTÑA:›Ñ@r¬@ÝÍA:›Ñ@LÆ@@ÉA’¹´@º£»@9˜5?®¢¿<û¹>qTÑA:›Ñ@r¬@@ÉA’¹´@º£»@X‡ÌA’¹´@×Ó¢@;,?$¿ˆY»>X‡ÌA’¹´@×Ó¢@@ÉA’¹´@º£»@U.ÄA_„™@µî¯@|Î*?|s)¿2æ®>X‡ÌA’¹´@×Ó¢@U.ÄA_„™@µî¯@©‰ÁA•"€@×§@…¯¾A•"€@Ð=£@ƒË¸AqQ@6£•@ún?h(D¿üÞ•>©‰ÁA•"€@×§@ƒË¸AqQ@6£•@Îh»AqQ@ÁÙ@æÁ?´L¿¹‘“>Îh»AqQ@ÁÙ@ƒË¸AqQ@6£•@¼Š²AÏ&@c2‡@9ü?pæO¿Äˆ>Îh»AqQ@ÁÙ@¼Š²AÏ&@c2‡@qç´AÏ&@ˆ£j@úó>W¿«Ž„>qç´AÏ&@ˆ£j@¼Š²AÏ&@c2‡@&ö«A™@p@ï–í>³zZ¿Ms>qç´AÏ&@ˆ£j@&ö«A™@p@á®A™@£CP@Á×>TÛ`¿‡œi>á®A™@£CP@&ö«A™@p@,¥AÈ#¾?£CP@âÏ>%Öc¿þƒT>á®A™@£CP@,¥AÈ#¾?£CP@îè¦AÈ#¾?’¹4@[ú¸>À^i¿$ÎH>îè¦AÈ#¾?’¹4@,¥AÈ#¾?£CP@¥÷A?]/@g±>|ëk¿@Ø4>îè¦AÈ#¾?’¹4@¥÷A?]/@ÒŸA?Ç,@çØ™>3”p¿á&>ÒŸA?Ç,@¥÷A?]/@¡–Aµ™*?„{ @ *‘><¯r¿_*>ÒŸA?Ç,@¡–Aµ™*?„{ @*Þ—Aµ™*?=Œõ?Å·s>qqv¿æ>*Þ—Aµ™*?=Œõ?¡–Aµ™*?„{ @ A´À>¿žÕ?a>Îx¿Rå=*Þ—Aµ™*?=Œõ? A´À>¿žÕ?áA´À>a_¹?b2>,îz¿¬ÜÀ=áA´À>a_¹? A´À>¿žÕ?*}‡AòŽ+>¡?ûl>ˆ|¿@¡=áA´À>a_¹?*}‡AòŽ+>¡?'ˆAòŽ+>CRx?„à=~¿Õ4q='ˆAòŽ+>CRx?*}‡AòŽ+>¡?HˆAxÌ+=V{?¿íµ=¶º~¿U±7='ˆAòŽ+>CRx?HˆAxÌ+=V{?\€AxÌ+=„ù>Èf4=¡®¿ °¾<\€AxÌ+=„ù>HˆAxÌ+=V{?pABÏ(W"D?/r$¿Å±Ÿ¤ÜA.ÞAJÿ@¥¡ÕAð@²\´@?½ØAð@’Þ—@×G?Œ¿°€³>?½ØAð@’Þ—@¥¡ÕAð@²\´@qTÑA:›Ñ@r¬@3(F?ô ¿Åߦ>?½ØAð@’Þ—@qTÑA:›Ñ@r¬@}KÔA:›Ñ@lä@ðu=?Å¿OŪ>}KÔA:›Ñ@lä@qTÑA:›Ñ@r¬@X‡ÌA’¹´@×Ó¢@: }KÔA:›Ñ@lä@X‡ÌA’¹´@×Ó¢@™UÏA’¹´@؉@ê¿2?$¿Ž¡>™UÏA’¹´@؉@X‡ÌA’¹´@×Ó¢@™UÏA’¹´@؉@­âÉA_„™@ùŒ€@­âÉA_„™@ùŒ€@©‰ÁA•"€@×§@„úÃA•"€@"Žn@–e?ÿþ?¿õ‹>„úÃA•"€@"Žn@©‰ÁA•"€@×§@Îh»AqQ@ÁÙ@¾Ÿ?h(D¿É!>„úÃA•"€@"Žn@Îh»AqQ@ÁÙ@—¥½AqQ@ɬZ@Jä ?³L¿†»}>—¥½AqQ@ɬZ@Îh»AqQ@ÁÙ@qç´AÏ&@ˆ£j@޲ ?pæO¿;žg>—¥½AqQ@ɬZ@qç´AÏ&@ˆ£j@óì¶AÏ&@_’E@S3ý>W¿’èc>óì¶AÏ&@_’E@qç´AÏ&@ˆ£j@á®A™@£CP@Gö>³zZ¿¿ÏN>óì¶AÏ&@_’E@á®A™@£CP@8Ú¯A™@]/@e4ß>TÛ`¿ÐH>8Ú¯A™@]/@á®A™@£CP@îè¦AÈ#¾?’¹4@>×>%Öc¿âÙ4>8Ú¯A™@]/@îè¦AÈ#¾?’¹4@‡w¨AÈ#¾?Ç,@½ö¿>À^i¿Î˜,>‡w¨AÈ#¾?Ç,@îè¦AÈ#¾?’¹4@ÒŸA?Ç,@ŒG·>|ëk¿Íá>‡w¨AÈ#¾?Ç,@ÒŸA?Ç,@tÏ A?–"@ §Ÿ>3”p¿+k>tÏ A?–"@ÒŸA?Ç,@*Þ—Aµ™*?=Œõ?gK–><¯r¿!ü=tÏ A?–"@*Þ—Aµ™*?=Œõ?óì˜Aµ™*?çÁÎ?ç|>qqv¿´áâ=óì˜Aµ™*?çÁÎ?*Þ—Aµ™*?=Œõ?áA´À>a_¹?ñh>Îx¿á Ã=óì˜Aµ™*?çÁÎ?áA´À>a_¹?NÛA´À>Ÿœ?9>,îz¿^©¥=NÛA´À>Ÿœ?áA´À>a_¹?'ˆAòŽ+>CRx?ëÿ#>ˆ|¿Tçˆ=NÛA´À>Ÿœ?'ˆAòŽ+>CRx?¦ˆAòŽ+>ÂQ?W~è=~¿k O=¦ˆAòŽ+>ÂQ?'ˆAòŽ+>CRx?\€AxÌ+=„ù>ŸH¼=¶º~¿ëü=¦ˆAòŽ+>ÂQ?\€AxÌ+=„ù>Y€AxÌ+=Û­Ñ>®;=¡®¿¤1£<Y€AxÌ+=Û­Ñ>\€AxÌ+=„ù>pABÏ(úoQ?Ÿ¿Ç´¨û½âArQA̳ƒ@¤ÜA.ÞAJÿ@PßA.ÞAPñ~@V?z±é¾ù«›>PßA.ÞAPñ~@¤ÜA.ÞAJÿ@?½ØAð@’Þ—@`U?*üô¾ >PßA.ÞAPñ~@?½ØAð@’Þ—@XNÛAð@ u@UCM?Œ¿Ê=•>XNÛAð@ u@?½ØAð@’Þ—@}KÔA:›Ñ@lä@”ÖK?ô ¿yʈ>XNÛAð@ u@}KÔA:›Ñ@lä@g¾ÖA:›Ñ@ðËi@ÑOC?Å¿õù>g¾ÖA:›Ñ@ðËi@}KÔA:›Ñ@lä@™UÏA’¹´@؉@mA?¯¢¿ Æ>g¾ÖA:›Ñ@ðËi@™UÏA’¹´@؉@ѦÑA’¹´@;]@ÎD8?$¿õê…>ѦÑA’¹´@;]@™UÏA’¹´@؉@­âÉA_„™@ùŒ€@¸î5?|s)¿Öt>ѦÑA’¹´@;]@­âÉA_„™@ùŒ€@âÌA_„™@‘mO@02,?)Î2¿Å8z>âÌA_„™@‘mO@­âÉA_„™@ùŒ€@„úÃA•"€@"Žn@1l)?RQ7¿…6c>âÌA_„™@‘mO@„úÃA•"€@"Žn@›þÅA•"€@w@@U)?ÿþ?¿Ð5g>›þÅA•"€@w@@„úÃA•"€@"Žn@—¥½AqQ@ɬZ@n÷?g(D¿WQ>›þÅA•"€@w@@—¥½AqQ@ɬZ@«~¿AqQ@ÿl0@ø<?´L¿ZèR>«~¿AqQ@ÿl0@—¥½AqQ@ɬZ@óì¶AÏ&@_’E@Á£ ?pæO¿QÏ=>«~¿AqQ@ÿl0@óì¶AÏ&@_’E@_˜¸AÏ&@\f@?W¿…m=>_˜¸AÏ&@\f@óì¶AÏ&@_’E@8Ú¯A™@]/@l ý>³zZ¿w)>_˜¸AÏ&@\f@8Ú¯A™@]/@™U±A™@„{ @|æ>TÛ`¿ä&>™U±A™@„{ @8Ú¯A™@]/@‡w¨AÈ#¾?Ç,@ìeÝ>%Öc¿Û,>™U±A™@„{ @‡w¨AÈ#¾?Ç,@¾À©AÈ#¾?=Œõ?KàÅ>À^i¿`l>¾À©AÈ#¾?=Œõ?‡w¨AÈ#¾?Ç,@tÏ A?–"@N„¼>|ëk¿ü=¾À©AÈ#¾?=Œõ?tÏ A?–"@¨ä¡A?çÁÎ?¡¤>3”p¿ÒOî=¨ä¡A?çÁÎ?tÏ A?–"@óì˜Aµ™*?çÁÎ?—•š><¯r¿”zÎ=¨ä¡A?çÁÎ?óì˜Aµ™*?çÁÎ?™Ì™Aµ™*?Ϧ?V‚>qqv¿Êr¼=™Ì™Aµ™*?Ϧ?óì˜Aµ™*?çÁÎ?NÛA´À>Ÿœ?Œ”o>Îx¿j°Ÿ=™Ì™Aµ™*?Ϧ?NÛA´À>Ÿœ?%„‘A´À>ÎÜ{?BÃ>>,îz¿äˆ‰=%„‘A´À>ÎÜ{?NÛA´À>Ÿœ?¦ˆAòŽ+>ÂQ?¨(>ˆ|¿Î`=%„‘A´À>ÎÜ{?¦ˆAòŽ+>ÂQ?*‰AòŽ+>é±(?Q”ï=~¿—µ+=*‰AòŽ+>é±(?¦ˆAòŽ+>ÂQ?Y€AxÌ+=Û­Ñ>ð•Á=¶º~¿_Òþ<*‰AòŽ+>é±(?Y€AxÌ+=Û­Ñ>·‘€AxÌ+=+©>Ô˜@=¡®¿Ɇ<·‘€AxÌ+=+©>Y€AxÌ+=Û­Ñ>pABÏ(«=p¿—7¯¾¶³@=[Ü4?=B)Aw‰?l”†?áfAáv *Q¸‰?rQA=…?­hm¿Ü.¿¾¾bì@.ÞAâ¨2AKArQA~zAA3Lä@rQAú–8A’+ú¾Dn²¾ÜÄL?3Lä@rQAú–8AKArQA~zAA"%ü@ ¬$A‡REAKý¾.û¨¾{ÏM?3Lä@rQAú–8A"%ü@ ¬$A‡REA^Ê÷@N–%AlDA ÂѾ=]°¾È=X?ðà A°Au¿KA%! AT A½ KAðArQAIIA&…Û¾‡°µ¾ý¯T?ðArQAIIA%! AT A½ KAKArQA~zAAúá¾Uûƾq.O?ðArQAIIAKArQA~zAA=âA.ÞAKC;A\6󾊰ҾÆG?=âA.ÞAKC;AKArQA~zAA>bì@.ÞAâ¨2A‹ ÷¾z±é¾a??=âA.ÞAKC;A>bì@.ÞAâ¨2A Õõ@ð@»+AU ³¾Wä²¾›ˆ^?1šAÆùAòQA†FAh-AoÞOAaArQAZ÷OA£r½¾‰ú¶¾}‡[?aArQAZ÷OA†FAh-AoÞOAðArQAIIAjéÁ¾Tûƾ7W?aArQAZ÷OAðArQAIIA".A.ÞAœÑBAjÅÔ¾Š°Ò¾¬§O?".A.ÞAœÑBAðArQAIIA=âA.ÞAKC;A1¾Ù¾y±é¾H?".A.ÞAœÑBA=âA.ÞAKC;A³Að@4AßLê¾*üô¾FÚ??³Að@4A=âA.ÞAKC;A Õõ@ð@»+A¦Ù쾌¿ƒ7?³Að@4A Õõ@ð@»+AKA:›Ñ@G×#AJG‚¾F(³¾¿Ìf?n=AAñAǸ[AÓ¡-AAñAÕŒWA&.ArQAö{UAH(˜¾ð*·¾ß b?&.ArQAö{UAÓ¡-AAñAÕŒWAaArQAZ÷OA>;¡¾Uûƾ&¬]?&.ArQAö{UAaArQAZ÷OA[!A.ÞAIIAÚ#µ¾‰°Ò¾GW?[!A.ÞAIIAaArQAZ÷OA".A.ÞAœÑBA;»¾z±é¾´¦O?[!A.ÞAIIA".A.ÞAœÑBA§ÑAð@KC;A†øÌ¾)üô¾!H?§ÑAð@KC;A".A.ÞAœÑBA³Að@4A›ÂоŒ¿IÙ??§ÑAð@KC;A³Að@4AòÙ A:›Ñ@»+Aêà¾ô ¿‚7?òÙ A:›Ñ@»+A³Að@4AKA:›Ñ@G×#A³Vá¾Å¿Yž.?òÙ A:›Ñ@»+AKA:›Ñ@G×#A‚LA’¹´@ûAœuV¾é³¾Ãi?oÑ=AAñA“Û[An=AAñAǸ[AcI>ArQAðÎYA·Ül¾¼)·¾²›g?cI>ArQAðÎYAn=AAñAǸ[A&.ArQAö{UAyL¾Tûƾ¸c?cI>ArQAðÎYA&.ArQAö{UA¬C0A.ÞA= NAö~”¾Š°Ò¾ 1]?¬C0A.ÞA= NA&.ArQAö{UA[!A.ÞAIIAù«›¾z±é¾V?¬C0A.ÞA= NA[!A.ÞAIIA·$Að@~zAA»~®¾*üô¾+O?·$Að@~zAA[!A.ÞAIIA§ÑAð@KC;A°€³¾Œ¿×G?·$Að@~zAA§ÑAð@KC;AGöA:›Ñ@â¨2A*ľô ¿ ^??GöA:›Ñ@â¨2A§ÑAð@KC;AòÙ A:›Ñ@»+A-œÆ¾Æ¿ÑŒ6?GöA:›Ñ@â¨2AòÙ A:›Ñ@»+A".A’¹´@)€"A=šÔ¾®¢¿<#.?".A’¹´@)€"AòÙ A:›Ñ@»+A‚LA’¹´@ûAH‘Ô¾$¿¾¿$?".A’¹´@)€"A‚LA’¹´@ûAËä A_„™@º\AÛ%¾Œ³¾¹m?ArQAðÎYAø´:¾Uûƾ26g?׳NArQAê\AcI>ArQAðÎYA<â?A.ÞA¦ÏRAò f¾‰°Ò¾#b?<â?A.ÞA¦ÏRAcI>ArQAðÎYA¬C0A.ÞA= NAñ{v¾z±é¾ØH[?<â?A.ÞA¦ÏRA¬C0A.ÞA= NA}¼2Að@±œFA ¾*üô¾`U?}¼2Að@±œFA¬C0A.ÞA= NA·$Að@~zAAÊ=•¾Œ¿UCM?}¼2Að@±œFA·$Að@~zAAÊ'A:›Ñ@ú–8AÅߦ¾ô ¿3(F?Ê'A:›Ñ@ú–8A·$Að@~zAAGöA:›Ñ@â¨2AOŪ¾Å¿ðu=?Ê'A:›Ñ@ú–8AGöA:›Ñ@â¨2A–A’¹´@²)A<û¹¾®¢¿9˜5?–A’¹´@²)AGöA:›Ñ@â¨2A".A’¹´@)€"AˆY»¾$¿;,?–A’¹´@²)A".A’¹´@)€"A¦A_„™@ª\A^ðǾ|s)¿:Ë#?¦A_„™@ª\A".A’¹´@)€"AËä A_„™@º\Aɛƾ)Î2¿võ?¦A_„™@ª\AËä A_„™@º\Aõ A•"€@]àAû’‘»©³¾IÓo?€ÿoAAñAôqaA·ÍlAAñAtƒaApArQAâh_AÆqâ¼Ù&·¾£ôn?pArQAâh_A·ÍlAAñAtƒaAøM_ArQAöÈ^A;½Uûƾ–k?pArQAâh_AøM_ArQAöÈ^AG×_A.ÞA¾ WAQU¹½Š°Ò¾æ*h?G×_A.ÞA¾ WAøM_ArQAöÈ^A°ÅOA.ÞA@ÑUA:â½y±é¾ûb?G×_A.ÞA¾ WA°ÅOA.ÞA@ÑUA«QAð@N†MAg×¾*üô¾íc]?«QAð@N†MA°ÅOA.ÞA@ÑUAù¿AAð@¢JAÇ,¾Œ¿V?«QAð@N†MAù¿AAð@¢JAìßCA:›Ñ@YSAA¬âS¾ô ¿"aP?ìßCA:›Ñ@YSAAù¿AAð@¢JA5A:›Ñ@Î|=A±Æ`¾Å¿H?ìßCA:›Ñ@YSAA5A:›Ñ@Î|=A8±8A’¹´@¢M3A ƾ¯¢¿mA?8±8A’¹´@¢M3A5A:›Ñ@Î|=A”r+A’¹´@2«.Aõê…¾$¿ÎD8?8±8A’¹´@¢M3A”r+A’¹´@2«.Aƒ¹/A_„™@ZÅ#A¢á”¾|s)¿5Ý0?ƒ¹/A_„™@ZÅ#A”r+A’¹´@2«.Apª#A_„™@y‚A[–¾)Î2¿. '?ƒ¹/A_„™@ZÅ#Apª#A_„™@y‚A,)A•"€@RAZôƒ=!³¾RBo?l€AAñA{Ì`A³Ö|AAñA¡+aAY€ArQAöÈ^A/(="&·¾vÔn?Y€ArQAöÈ^A³Ö|AAñA¡+aApArQAâh_A -¾‹³¾úem?"̈AAñAùå^A‡g†AAñAJ°_A¦ˆArQAê\A[Bà=Š%·¾€im?¦ˆArQAê\A‡g†AAñAJ°_AY€ArQAöÈ^Aõa¼=Tûƾ¤²j?¦ˆArQAê\AY€ArQAöÈ^A\€A.ÞA¾ WA3;=Š°Ò¾úi?\€A.ÞA¾ WAY€ArQAöÈ^ApA.ÞA‡;XAV¸ç³¾Õ@j?ý‘AAñA-Á[AQŽAAñAZ]ANÛArQAðÎYA 5>%·¾ºµj?NÛArQAðÎYAQŽAAñAZ]A¦ˆArQAê\A{$>Uûƾ&Hh?NÛArQAðÎYA¦ˆArQAê\A'ˆA.ÞA@ÑUANœè=Š°Ò¾p€g?'ˆA.ÞA@ÑUA¦ˆArQAê\A\€A.ÞA¾ WA–¶=z±é¾£b?'ˆA.ÞA@ÑUA\€A.ÞA¾ WAHˆAð@ÑCOA´|4=*üô¾U‚`?HˆAð@ÑCOA\€A.ÞA¾ WApAð@™ØOAê°<Œ¿VZ?HˆAð@ÑCOApAð@™ØOApA:›Ñ@LFAuȨ¼ô ¿1ñV?pA:›Ñ@LFApAð@™ØOAe.aA:›Ñ@)¾EAg>$½Æ¿ O?pA:›Ñ@LFAe.aA:›Ñ@)¾EAIúaA’¹´@i;AÁ¿¡½®¢¿ÕK?IúaA’¹´@i;Ae.aA:›Ñ@)¾EA¥TA’¹´@5‹9A)6½$¿lŒB?IúaA’¹´@i;A¥TA’¹´@5‹9ATÇUA_„™@ª÷-A”ß¾|s)¿þAÏ&@̳û@;žg¾pæO¿Ž² ?h›>AÏ&@̳û@ÍT9AqQ@.K AW5AÏ&@Âó@’èc¾W¿S3ý>h›>AÏ&@̳û@W5AÏ&@Âó@ï;A™@‡;Ø@Þ‹†>) ³¾5f?ƒŒ—AþA†ŒXA³–AAñA5XYAóì˜ArQAö{UAp$z>¸$·¾ß¼f?óì˜ArQAö{UA³–AAñA5XYANÛArQAðÎYAi>Uûƾ‘d?óì˜ArQAö{UANÛArQAðÎYAáA.ÞA¦ÏRA?.9>Š°Ò¾w®d?áA.ÞA¦ÏRANÛArQAðÎYA'ˆA.ÞA@ÑUA`€>y±é¾N`?áA.ÞA¦ÏRA'ˆA.ÞA@ÑUA*}‡Að@N†MAA6à=*üô¾Ñ _?*}‡Að@N†MA'ˆA.ÞA@ÑUAHˆAð@ÑCOA’¢®=Œ¿òOY?*}‡Að@N†MAHˆAð@ÑCOA›Ñ~A:›Ñ@)¾EAÉØ,=ô ¿<¼V?›Ñ~A:›Ñ@)¾EAHˆAð@ÑCOApA:›Ñ@LFA†Ç¨<ƿھO?›Ñ~A:›Ñ@)¾EApA:›Ñ@LFApA’¹´@º£;A_´Ÿ¼¯¢¿PõK?pA’¹´@º£;ApA:›Ñ@LFAIúaA’¹´@i;A ¸½$¿–ÑC?pA’¹´@º£;AIúaA’¹´@i;AAÚbA_„™@Åp/AÞ˜½|s)¿Ãò>?AÚbA_„™@Åp/AIúaA’¹´@i;ATÇUA_„™@ª÷-AÉ[µ½)Î2¿rÌ5?AÚbA_„™@Åp/ATÇUA_„™@ª÷-A«WA•"€@k!A_W÷½RQ7¿ÿ/?«WA•"€@k!ATÇUA_„™@ª÷-Aä¬KA•"€@&A›½¾ÿþ?¿±ÿ%?«WA•"€@k!Aä¬KA•"€@&A׳NAqQ@ÅâA‹ã!¾h(D¿Ôo?׳NAqQ@ÅâAä¬KA•"€@&AÀäCAqQ@UýA;ç&¾´L¿·Å?׳NAqQ@ÅâAÀäCAqQ@UýAi&HAÏ&@¾0AQÏ=¾pæO¿Á£ ?i&HAÏ&@¾0AÀäCAqQ@UýAh›>AÏ&@̳û@…m=¾W¿?i&HAÏ&@¾0Ah›>AÏ&@̳û@¸(DA™@âhß@¿ÏN¾³zZ¿Gö>¸(DA™@âhß@h›>AÏ&@̳û@ï;A™@‡;Ø@ÐH¾TÛ`¿e4ß>¸(DA™@âhß@ï;A™@‡;Ø@›ÑBAÈ#¾?º£»@а¥>ñ°¾Z}a?õRŸA Aù-TA»UœA÷ãA´ÞUAtÏ ArQAZ÷OAöŸœ>Hy¶¾²b?tÏ ArQAZ÷OA»UœA÷ãA´ÞUAóì˜ArQAö{UA]–>TûƾՒ_?tÏ ArQAZ÷OAóì˜ArQAö{UA*Þ—A.ÞA= NA8}>‰°Ò¾•`?*Þ—A.ÞA= NAóì˜ArQAö{UAáA.ÞA¦ÏRAŠa>z±é¾m·\?*Þ—A.ÞA= NAáA.ÞA¦ÏRA Að@¢JA”v2>*üô¾ýQ\? Að@¢JAáA.ÞA¦ÏRA*}‡Að@N†MAN>Œ¿ÆW? Að@¢JA*}‡Að@N†MAdžA:›Ñ@DA+Ö=ô ¿ÚSU?džA:›Ñ@DA*}‡Að@N†MA›Ñ~A:›Ñ@)¾EAŽF¦=Æ¿=ÅN?džA:›Ñ@DA›Ñ~A:›Ñ@)¾EA·~A’¹´@i;Aw=$=®¢¿ÊÂK?·~A’¹´@i;A›Ñ~A:›Ñ@)¾EApA’¹´@º£;Ap³Ÿ<ÿœ$¿iþC?·~A’¹´@i;ApA’¹´@º£;ApA_„™@µî/AÈ»•¼|s)¿™Õ??pA_„™@µî/ApA’¹´@º£;AAÚbA_„™@Åp/AaT½)Î2¿ü6?pA_„™@µî/AAÚbA_„™@Åp/A ÍcA•"€@õÈ"An½RQ7¿•Ð1? ÍcA•"€@õÈ"AAÚbA_„™@Åp/A«WA•"€@k!A~§½ÿþ?¿‚(? ÍcA•"€@õÈ"A«WA•"€@k!A›²YAqQ@Z÷Aóã½h(D¿ø"?›²YAqQ@Z÷A«WA•"€@k!A׳NAqQ@ÅâAQîó½´L¿yy?›²YAqQ@Z÷A׳NAqQ@ÅâAwêQAÏ&@¡ÎA¬ð¾pæO¿,Ê?wêQAÏ&@¡ÎA׳NAqQ@ÅâAi&HAÏ&@¾0AEã¾W¿Ÿ­?wêQAÏ&@¡ÎAi&HAÏ&@¾0A¡LA™@dVå@w)¾³zZ¿l ý>¡LA™@dVå@i&HAÏ&@¾0A¸(DA™@âhß@ä&¾TÛ`¿|æ>¡LA™@dVå@¸(DA™@âhß@ÎôIAÈ#¾? ÞÁ@âÙ4¾%Öc¿>×>ÎôIAÈ#¾? ÞÁ@¸(DA™@âhß@›ÑBAÈ#¾?º£»@Θ,¾À^i¿½ö¿>ÎôIAÈ#¾? ÞÁ@›ÑBAÈ#¾?º£»@ÎôIA?Jÿ@òjÉ>ÝH©¾§œ[?>ó§A”&Aj9OA#¥A±£#ApÚPA‡w¨ArQAIIAgL¿>Š ³¾úë[?‡w¨ArQAIIA#¥A±£#ApÚPAtÏ ArQAZ÷OA1\·>Tûƾ{TY?‡w¨ArQAIIAtÏ ArQAZ÷OAÒŸA.ÞAIIAü¸Ÿ>Š°Ò¾6:[?ÒŸA.ÞAIIAtÏ ArQAZ÷OA*Þ—A.ÞA= NA6:‘>y±é¾ÍäW?ÒŸA.ÞAIIA*Þ—A.ÞA= NA¡–Að@±œFAˆÒs>*üô¾½^X?¡–Að@±œFA*Þ—A.ÞA= NA Að@¢JAªåW>Œ¿°¡S?¡–Að@±œFA Að@¢JA ŽA:›Ñ@YSAAc¿*>ô ¿ºR? ŽA:›Ñ@YSAA Að@¢JAdžA:›Ñ@DA–¶>Å¿™£L? ŽA:›Ñ@YSAAdžA:›Ñ@DA­û…A’¹´@5‹9Aþ´Ë=¯¢¿ŽlJ?­û…A’¹´@5‹9AdžA:›Ñ@DA·~A’¹´@i;A–üœ=$¿£C?­û…A’¹´@5‹9A·~A’¹´@i;A¿%}A_„™@Åp/A#·=|s)¿Ë¥??¿%}A_„™@Åp/A·~A’¹´@i;ApA_„™@µî/A井<)Î2¿—%7?¿%}A_„™@Åp/ApA_„™@µî/ApA•"€@Ð=#A 튼RQ7¿‚£2?pA•"€@Ð=#ApA_„™@µî/A ÍcA•"€@õÈ"AT"½ÿþ?¿Ã )?pA•"€@Ð=#A ÍcA•"€@õÈ"ALÑdAqQ@8A ‚½h(D¿)°#?LÑdAqQ@8A ÍcA•"€@õÈ"A›²YAqQ@Z÷A󰘽³L¿_T?LÑdAqQ@8A›²YAqQ@Z÷A—Ù[AÏ&@ѯALνpæO¿M!?—Ù[AÏ&@ѯA›²YAqQ@Z÷AwêQAÏ&@¡ÎAÞÛ½W¿Ï?—Ù[AÏ&@ѯAwêQAÏ&@¡ÎA(LUA™@’ûé@Û+¾³zZ¿¦U?(LUA™@’ûé@wêQAÏ&@¡ÎA¡LA™@dVå@5 ¾TÛ`¿,­ë>(LUA™@’ûé@¡LA™@dVå@xNQAÈ#¾?øÇ@Û,¾%Öc¿ìeÝ>xNQAÈ#¾?øÇ@¡LA™@dVå@ÎôIAÈ#¾? ÞÁ@`l¾À^i¿KàÅ>xNQAÈ#¾?øÇ@ÎôIAÈ#¾? ÞÁ@Z÷OA?Ð=£@Íá¾|ëk¿ŒG·>Z÷OA?Ð=£@ÎôIAÈ#¾? ÞÁ@ÎôIA?Jÿ@+k¾3”p¿ §Ÿ>Z÷OA?Ð=£@ÎôIA?Jÿ@xNQAµ™*?Pñ~@`T×>TûƾýÞQ?8Ú¯ArQA~zAA‡w¨ArQAIIAîè¦A.ÞAœÑBA¯ À>Š°Ò¾w¥T?îè¦A.ÞAœÑBA‡w¨ArQAIIAÒŸA.ÞAIIA¾±>y±é¾ÝQ?îè¦A.ÞAœÑBAÒŸA.ÞAIIA¥÷Að@~zAAµè™>*üô¾¸5S?¥÷Að@~zAAÒŸA.ÞAIIA¡–Að@±œFA÷F‹>Œ¿žO?¥÷Að@~zAA¡–Að@±œFA~9•A:›Ñ@Î|=A¾Bi>ô ¿“òN?~9•A:›Ñ@Î|=A¡–Að@±œFA ŽA:›Ñ@YSAA·zM>Å¿ý\I?~9•A:›Ñ@Î|=A ŽA:›Ñ@YSAAzàŒA’¹´@_ï6AÎ">¯¢¿„ôG?zàŒA’¹´@_ï6A ŽA:›Ñ@YSAA­û…A’¹´@5‹9AÈ•>$¿–A?zàŒA’¹´@_ï6A­û…A’¹´@5‹9AV…A_„™@ª÷-AV·¿=|s)¿žc>?V…A_„™@ª÷-A­û…A’¹´@5‹9A¿%}A_„™@Åp/A Ò’=)Î2¿ùH6?V…A_„™@ª÷-A¿%}A_„™@Åp/Aõ2|A•"€@õÈ"A…S=RQ7¿±v2?õ2|A•"€@õÈ"A¿%}A_„™@Åp/ApA•"€@Ð=#A8ìŠ<ÿþ?¿áF)?õ2|A•"€@õÈ"ApA•"€@Ð=#ApAqQ@6£A^¯~¼h(D¿r$?pAqQ@6£ApA•"€@Ð=#ALÑdAqQ@8Aïcò¼³L¿ÀS?pAqQ@6£ALÑdAqQ@8AåeAÏ&@›ÑABëk½pæO¿Ë¥?åeAÏ&@›ÑALÑdAqQ@8A—Ù[AÏ&@ѯA¤ ‰½W¿"Å ?åeAÏ&@›ÑA—Ù[AÏ&@ѯAk^A™@ÄQí@ I¸½³zZ¿ml?k^A™@ÄQí@—Ù[AÏ&@ѯA(LUA™@’ûé@’âÀ½TÛ`¿tóï>k^A™@ÄQí@(LUA™@’ûé@ÔXAÈ#¾?ç Ë@fWå½%Öc¿ÍPâ>ÔXAÈ#¾?ç Ë@(LUA™@’ûé@xNQAÈ#¾?øÇ@8åâ½À^i¿Ž®Ê>ÔXAÈ#¾?ç Ë@xNQAÈ#¾?øÇ@Ã'VA?¢’§@ü½|ëk¿N„¼>Ã'VA?¢’§@xNQAÈ#¾?øÇ@Z÷OA?Ð=£@ÒOî½3”p¿¡¤>Ã'VA?¢’§@Z÷OA?Ð=£@Ã'VAµ™*?̳ƒ@!ü½<¯r¿gK–>Ã'VAµ™*?̳ƒ@Z÷OA?Ð=£@xNQAµ™*?Pñ~@´áâ½qqv¿ç|>Ã'VAµ™*?̳ƒ@xNQAµ™*?Pñ~@ÔXA´À>w@@Si?i6¯¾û6m>3ËçA=B)A+!L@û½âArQA̳ƒ@xçäArQAuÚF@¸c?TûƾyL>xçäArQAuÚF@û½âArQA̳ƒ@PßA.ÞAPñ~@#b?‰°Ò¾ò f>xçäArQAuÚF@PßA.ÞAPñ~@ÓgáA.ÞAw@@ØH[?z±é¾ñ{v>ÓgáA.ÞAw@@PßA.ÞAPñ~@XNÛAð@ u@ÜY?*üô¾p•]>ÓgáA.ÞAw@@XNÛAð@ u@FQÝAð@9@öCR?Œ¿qJl>FQÝAð@9@XNÛAð@ u@g¾ÖA:›Ñ@ðËi@"aP?ô ¿¬âS>FQÝAð@9@g¾ÖA:›Ñ@ðËi@­©ØA:›Ñ@O€0@H?Å¿±Æ`>­©ØA:›Ñ@O€0@g¾ÖA:›Ñ@ðËi@ѦÑA’¹´@;]@ê»E?¯¢¿¢I>­©ØA:›Ñ@O€0@ѦÑA’¹´@;]@¯wÓA’¹´@Ñ'@âÁ¯wÓA’¹´@Ñ'@ѦÑA’¹´@;]@âÌA_„™@‘mO@Åû9?|s)¿þþ<>¯wÓA’¹´@Ñ'@âÌA_„™@‘mO@¾ÂÍA_„™@8˜@«c0?)Î2¿— F>¾ÂÍA_„™@8˜@âÌA_„™@‘mO@›þÅA•"€@w@@1-?RQ7¿ ï/>¾ÂÍA_„™@8˜@›þÅA•"€@w@@“ÇA•"€@oL@7 #?ÿþ?¿±ü6>“ÇA•"€@oL@›þÅA•"€@w@@«~¿AqQ@ÿl0@Ôo?h(D¿‹ã!>“ÇA•"€@oL@«~¿AqQ@ÿl0@cñÀAqQ@ 0@·Å?´L¿;ç&>cñÀAqQ@ 0@«~¿AqQ@ÿl0@_˜¸AÏ&@\f@,Ê?pæO¿¬ð>cñÀAqQ@ 0@_˜¸AÏ&@\f@Qç¹AÏ&@H¬ð?Ÿ­?W¿Eã>Qç¹AÏ&@H¬ð?_˜¸AÏ&@\f@™U±A™@„{ @¦U?³zZ¿Û+>Qç¹AÏ&@H¬ð?™U±A™@„{ @å~²A™@¿žÕ?,­ë>TÛ`¿5 >å~²A™@¿žÕ?™U±A™@„{ @¾À©AÈ#¾?=Œõ?ÍPâ>%Öc¿fWå=å~²A™@¿žÕ?¾À©AÈ#¾?=Œõ?ºÂªAÈ#¾?a_¹?Ž®Ê>À^i¿8åâ=ºÂªAÈ#¾?a_¹?¾À©AÈ#¾?=Œõ?¨ä¡A?çÁÎ?+³À>|ëk¿ Ã=ºÂªAÈ#¾?a_¹?¨ä¡A?çÁÎ?â½¢A?Ÿœ?œŽ¨>3”p¿t¼=â½¢A?Ÿœ?¨ä¡A?çÁÎ?™Ì™Aµ™*?Ϧ?xž><¯r¿l±Ÿ=â½¢A?Ÿœ?™Ì™Aµ™*?Ϧ?Ú{šAµ™*?ÎÜ{?~…>rqv¿ö”=Ú{šAµ™*?ÎÜ{?™Ì™Aµ™*?Ϧ?%„‘A´À>ÎÜ{?Œàt>Îx¿ªÞv=Ú{šAµ™*?ÎÜ{?%„‘A´À>ÎÜ{?t’A´À>È#>?I^C>,îz¿GY=t’A´À>È#>?%„‘A´À>ÎÜ{?*‰AòŽ+>é±(?Ã^,>ˆ|¿=ú,=t’A´À>È#>?*‰AòŽ+>é±(?Éo‰AòŽ+>µþ>LSõ=~¿ïk=Éo‰AòŽ+>µþ>*‰AòŽ+>é±(?·‘€AxÌ+=+©>ÎÅ=¶º~¿>Ä<Éo‰AòŽ+>µþ>·‘€AxÌ+=+©>&¾€AxÌ+=ïk>?E=¡®¿×>S<&¾€AxÌ+=ïk>·‘€AxÌ+=+©>pABÏ(á7]?o·¿¶Î°<ñbßARì@Ô AÇ£©ÍÒi?§!Ͼ$;=_ÐãA.ÞAÊE?´FåA>Ô AÇ£©{dçArQA=…?ãK̾ÿþ?¿‚ ?׳AqQ@’ûé@õ A•"€@]àAz8 A•"€@/Aÿ@ˆoоRQ7¿'?z8 A•"€@/Aÿ@õ A•"€@]àAËä A_„™@º\A[ݾ)Î2¿y?z8 A•"€@/Aÿ@Ëä A_„™@º\AÓNA_„™@®Œ AKÜß¾}s)¿yÝ?ÓNA_„™@®Œ AËä A_„™@º\A‚LA’¹´@ûA·˜ì¾$¿‚X?ÓNA_„™@®Œ A‚LA’¹´@ûAmö@’¹´@سAàî¾®¢¿ò´%?mö@’¹´@سA‚LA’¹´@ûAKA:›Ñ@G×#AžÎú¾Å¿ãµ%?mö@’¹´@سAKA:›Ñ@G×#A0ºè@:›Ñ@ûAÞàú¾ô ¿QŸ.?0ºè@:›Ñ@ûAKA:›Ñ@G×#A Õõ@ð@»+AÎοŒ¿ &.?0ºè@:›Ñ@ûA Õõ@ð@»+AöÑÜ@ð@)€"Aä(¿*üô¾À6?öÑÜ@ð@)€"A Õõ@ð@»+A>bì@.ÞAâ¨2Aœy ¿y±é¾5?öÑÜ@ð@)€"A>bì@.ÞAâ¨2AÈ\Ò@.ÞA²)AŽ%¿‰°Ò¾Ìz=?È\Ò@.ÞA²)A>bì@.ÞAâ¨2A3Lä@rQAú–8A_¿TûƾñA{è¿5³¾†(G?VÂ@=B)A¢M3AbÜ@"Ñ-A&—>A_àØ@Ë÷.Ažæ=A~?›+„¾ÇR?Ó³Ahg7Aß3HAÁò²A¥ž5A£ºHA_˜¸A=B)AÎ|=Al»?m>޾s‰Q?_˜¸A=B)AÎ|=AÁò²A¥ž5A£ºHA™U±A=B)A±œFA%ý>x'£¾.O?_˜¸A=B)AÎ|=A™U±A=B)A±œFA8Ú¯ArQA~zAApé>)"£¾$¶T?8Ú¯ArQA~zAA™U±A=B)A±œFA2ÛªAVB)AÒ†MAYñÜ>J4¯¾]­U?8Ú¯ArQA~zAA2ÛªAVB)AÒ†MA‡w¨ArQAIIA¢Ô> ¤¾iZ?‡w¨ArQAIIA2ÛªAVB)AÒ†MA}¨©AYâ'Aj:NA™§Ñ>M^¥¾nmZ?‡w¨ArQAIIA}¨©AYâ'Aj:NAï5©Aâ^'A}NA¯r?¤ÀоŒþ*>E¯ëAP˜:AE~ @3ËçA=B)A+!L@RcéA=B)AR¹@wÚm?x'£¾t@>RcéA=B)AR¹@3ËçA=B)A+!L@xçäArQAuÚF@üål?i6¯¾Þ&>RcéA=B)AR¹@xçäArQAuÚF@ uæArQA 0@26g?Uûƾø´:> uæArQA 0@xçäArQAuÚF@ÓgáA.ÞAw@@‚Ée?Š°Ò¾¡Î!> uæArQA 0@ÓgáA.ÞAw@@ èâA.ÞA@é@½F_?z±é¾ ?4> èâA.ÞA@é@ÓgáA.ÞAw@@FQÝAð@9@íc]?*üô¾g×> èâA.ÞA@é@FQÝAð@9@'ÃÞAð@¤Ò÷?V?Œ¿Ç,>'ÃÞAð@¤Ò÷?FQÝAð@9@­©ØA:›Ñ@O€0@\ÁS?ô ¿>'ÃÞAð@¤Ò÷?­©ØA:›Ñ@O€0@ ÚA:›Ñ@üoì?æµK?Å¿ªW$> ÚA:›Ñ@üoì?­©ØA:›Ñ@O€0@¯wÓA’¹´@Ñ'@µïH?®¢¿lU > ÚA:›Ñ@üoì?¯wÓA’¹´@Ñ'@›ÅÔA’¹´@Ôºß?º0@?$¿ ý>›ÅÔA’¹´@Ôºß?¯wÓA’¹´@Ñ'@¾ÂÍA_„™@8˜@þ›ÅÔA’¹´@Ôºß?¾ÂÍA_„™@8˜@ÕûÎA_„™@^ÅÑ?ž˜3?)Î2¿ßÄ>ÕûÎA_„™@^ÅÑ?¾ÂÍA_„™@8˜@“ÇA•"€@oL@ÿ/?RQ7¿_W÷=ÕûÎA_„™@^ÅÑ?“ÇA•"€@oL@‡µÈA•"€@–£Â?±ÿ%?ÿþ?¿›½>‡µÈA•"€@–£Â?“ÇA•"€@oL@cñÀAqQ@ 0@ø"?h(D¿óã=‡µÈA•"€@–£Â?cñÀAqQ@ 0@­ûÁAqQ@'k²?yy?´L¿Qîó=­ûÁAqQ@'k²?cñÀAqQ@ 0@Qç¹AÏ&@H¬ð?M!?pæO¿LÎ=­ûÁAqQ@'k²?Qç¹AÏ&@H¬ð?é׺AÏ&@H3¡?Ï?W¿ÞÛ=é׺AÏ&@H3¡?Qç¹AÏ&@H¬ð?å~²A™@¿žÕ?ml?³zZ¿ I¸=é׺AÏ&@H3¡?å~²A™@¿žÕ?qT³A™@¡?tóï>TÛ`¿’âÀ=qT³A™@¡?å~²A™@¿žÕ?ºÂªAÈ#¾?a_¹?­÷å>%Öc¿¼ ¡=qT³A™@¡?ºÂªAÈ#¾?a_¹? |«AÈ#¾?CRx?§ZÎ>À^i¿Ù¬¥= |«AÈ#¾?CRx?ºÂªAÈ#¾?a_¹?â½¢A?Ÿœ?'ÎÃ>|ëk¿èéˆ= |«AÈ#¾?CRx?â½¢A?Ÿœ?ìY£A?ÂQ?G›«>3”p¿¡Š‰=ìY£A?ÂQ?â½¢A?Ÿœ?Ú{šAµ™*?ÎÜ{?! ><¯r¿I`=ìY£A?ÂQ?Ú{šAµ™*?ÎÜ{?¿ùšAµ™*?é±(?þæ‡>qqv¿;HY=¿ùšAµ™*?é±(?Ú{šAµ™*?ÎÜ{?t’A´À>È#>?øÍx>Îx¿û,=¿ùšAµ™*?é±(?t’A´À>È#>?~g’A´À>µþ>áF>,îz¿4E=~g’A´À>µþ>t’A´À>È#>?Éo‰AòŽ+>µþ>­/>ˆ|¿ðñ<~g’A´À>µþ>Éo‰AòŽ+>µþ>q¯‰AòŽ+>¶™ª>³ù=~¿ÏÀĶ™ª>Éo‰AòŽ+>µþ>&¾€AxÌ+=ïk>ëÈ=¶º~¿Ùˆ¶™ª>&¾€AxÌ+=ïk>Þ€AxÌ+=,+>}}H=¡®¿:½<Þ€AxÌ+=,+>&¾€AxÌ+=ïk>pABÏ(¿Ä¶;¡®¿²ÃJ=WqAxÌ+=¡?pABÏ(P¬rAxÌ+=á?0l??cþ¾<´FåA>Ô AÇ£©ê‹çA$qA,§©{dçArQA=…?7ßo?9v²¾‚¾<{dçArQA=…?ê‹çA$qA,§©íéA!Ÿ$AR-¬©Ìq?>o¦¾+®@={dçArQA=…?íéA!Ÿ$AR-¬©YêA=B)Aw‰?Bv¿Âµ‰¾Â2E=q}Õ>P˜:Ahâ‹?Ö#?Ķ*A*Ä *[Ü4?=B)Aw‰?i²t¿šö•¾ÖÃ<[Ü4?=B)Aw‰?Ö#?Ķ*A*Ä *¿+?ÚH)A/‚ *Γr¿ (£¾Y:Ã<[Ü4?=B)Aw‰?¿+?ÚH)A/‚ *l”†?áfAáv *I̾³L¿ÂÞç>õ AÏ&@j6Æ@׳AqQ@’ûé@z8 AqQ@ZbÛ@QHÓ¾g(D¿¾,ü>z8 AqQ@ZbÛ@׳AqQ@’ûé@z8 A•"€@/Aÿ@éß¾ÿþ?¿Kþ>z8 AqQ@ZbÛ@z8 A•"€@/Aÿ@µ÷A•"€@3Tï@ Œå¾RQ7¿bõ?µ÷A•"€@3Tï@z8 A•"€@/Aÿ@ÓNA_„™@®Œ ArHò¾)Î2¿Op ?µ÷A•"€@3Tï@ÓNA_„™@®Œ AÌ«ð@_„™@µ÷A»‡ö¾|s)¿“?Ì«ð@_„™@µ÷AÓNA_„™@®Œ Amö@’¹´@سA·¦¿$¿p?Ì«ð@_„™@µ÷Amö@’¹´@سAоà@’¹´@®Œ A]¿®¢¿kY?оà@’¹´@®Œ Amö@’¹´@سA0ºè@:›Ñ@ûA¼o ¿Æ¿.à?оà@’¹´@®Œ A0ºè@:›Ñ@ûAF?Ò@:›Ñ@º\AS# ¿ô ¿Â$?F?Ò@:›Ñ@º\A0ºè@:›Ñ@ûAöÑÜ@ð@)€"At¿Œ¿ÜÏ#?F?Ò@:›Ñ@º\AöÑÜ@ð@)€"AëAÅ@ð@ª\A’o¿*üô¾Þ?,?ëAÅ@ð@ª\AöÑÜ@ð@)€"AÈ\Ò@.ÞA²)A¢©¿z±é¾ Õ*?ëAÅ@ð@ª\AÈ\Ò@.ÞA²)A[Ù¹@.ÞAy‚Aí¿Š°Ò¾ŽÆ2?[Ù¹@.ÞAy‚AÈ\Ò@.ÞA²)A£iÉ@rQA2«.Ar¿Tûƾ—å0?[Ù¹@.ÞAy‚A£iÉ@rQA2«.Aë°@rQAZÅ#A¼“¿i6¯¾3M8?ë°@rQAZÅ#A£iÉ@rQA2«.AVÂ@=B)A¢M3AÃ… ¿x'£¾Âø5?ë°@rQAZÅ#AVÂ@=B)A¢M3A•¨@=B)AÄ(A]¿¥ÀоÒË?|s)¿Þ˜=´ŽÕA’¹´@n[`?ÕûÎA_„™@^ÅÑ?b¸ÏA_„™@ó[R?rÌ5?)Î2¿É[µ=b¸ÏA_„™@ó[R?ÕûÎA_„™@^ÅÑ?‡µÈA•"€@–£Â?•Ð1?RQ7¿n=b¸ÏA_„™@ó[R?‡µÈA•"€@–£Â?{dÉA•"€@O/C?‚(?ÿþ?¿~§={dÉA•"€@O/C?‡µÈA•"€@–£Â?­ûÁAqQ@'k²?)°#?h(D¿ ‚={dÉA•"€@O/C?­ûÁAqQ@'k²? œÂAqQ@:ë2?_T?³L¿ó°˜= œÂAqQ@:ë2?­ûÁAqQ@'k²?é׺AÏ&@H3¡?Ë¥?pæO¿Bëk= œÂAqQ@:ë2?é׺AÏ&@H3¡?Îh»AÏ&@ÿ¦!?"Å ?W¿¤ ‰=Îh»AÏ&@ÿ¦!?é׺AÏ&@H3¡?qT³A™@¡? Ç?³zZ¿egR=Îh»AÏ&@ÿ¦!?qT³A™@¡? Õ³A™@V{?4âò>TÛ`¿*=q= Õ³A™@V{?qT³A™@¡? |«AÈ#¾?CRx?QUè>%Öc¿·7= Õ³A™@V{? |«AÈ#¾?CRx?£ë«AÈ#¾?„ù>PßÐ>À^i¿•O=£ë«AÈ#¾?„ù> |«AÈ#¾?CRx?ìY£A?ÂQ?ÏÐÅ>|ëk¿W=£ë«AÈ#¾?„ù>ìY£A?ÂQ?ä·£A?Û­Ñ>B²­>3”p¿o¸+=ä·£A?Û­Ñ>ìY£A?ÂQ?¿ùšAµ™*?é±(?ï1¢><¯r¿ûÕþ<ä·£A?Û­Ñ>¿ùšAµ™*?é±(?E›Aµ™*?+©>O‰>qqv¿8m=E›Aµ™*?+©>¿ùšAµ™*?é±(?~g’A´À>µþ>/W{>Îx¿ ?Ä~g’A´À>µþ>º ’A´À>ïk>6HI>,îz¿–ÁÄ<º ’A´À>ïk>~g’A´À>µþ>q¯‰AòŽ+>¶™ª>áã0>ˆ|¿F‘ˆ<º ’A´À>ïk>q¯‰AòŽ+>¶™ª>ÆÕ‰AòŽ+>,+>T­ü=~¿$ s<ÆÕ‰AòŽ+>,+>q¯‰AòŽ+>¶™ª>Þ€AxÌ+=,+>kèÊ=¶º~¿2@<ÆÕ‰AòŽ+>,+>Þ€AxÌ+=,+>Jñ€AxÌ+=ûŽ«=²ÃJ=¡®¿¿Ä¶;Jñ€AxÌ+=ûŽ«=Þ€AxÌ+=,+>pABÏ(§:{¿gF>¾?”H=BV>×:LAá?Pü„>܇CA7Ì*q}Õ>P˜:Ahâ‹?$3z¿þNW¾ÈÇP˜:Ahâ‹?Pü„>܇CA7Ì*ŠCÊ>K«:A·*K!x¿û·z¾È*ÇP˜:Ahâ‹?ŠCÊ>K«:A·*Ö#?Ķ*A*Ä *ñ\¿ZUL½æL=xÌ+=pAV{?|•;=^A^‚*òŽ«=•^A¡?Ï+¿¾šœ½ižË<òŽ«=•^A¡?|•;=^A^‚*”ÞC=ñÙ\A9~*ù]~¿QzϽáJ=òŽ«=•^A¡?”ÞC=ñÙ\A9~*BV>×:LAá?²à}¿·"¾(Ê×:LAá?”ÞC=ñÙ\A9~*T?>KELAb*(’|¿–%¾ºïÉ×:LAá?T?>KELAb*Pü„>܇CA7Ì*ߔƾW¿ÇÂ>¦A™@Ð=£@õ AÏ&@j6Æ@Ëä AÏ&@ê·@«jоpæO¿T Ö>Ëä AÏ&@ê·@õ AÏ&@j6Æ@z8 AqQ@ZbÛ@& ݾ´L¿–ô×>Ëä AÏ&@ê·@z8 AqQ@ZbÛ@ÓNAqQ@ Ë@i‰å¾h(D¿5®ë>ÓNAqQ@ Ë@z8 AqQ@ZbÛ@µ÷A•"€@3Tï@‘Eò¾ÿþ?¿Ï£ì>ÓNAqQ@ Ë@µ÷A•"€@3Tï@Ì«ð@•"€@•Þ@`ù¾RQ7¿=ÿÿ>Ì«ð@•"€@•Þ@µ÷A•"€@3Tï@Ì«ð@_„™@µ÷AÕ¿)Î2¿a?Ì«ð@•"€@•Þ@Ì«ð@_„™@µ÷A”Þ@_„™@3Tï@é¿|s)¿ q ?”Þ@_„™@3Tï@Ì«ð@_„™@µ÷Aоà@’¹´@®Œ AsG ¿$¿Ñ÷?”Þ@_„™@3Tï@оà@’¹´@®Œ A£æÌ@’¹´@/Aÿ@¥b¿®¢¿ ?£æÌ@’¹´@/Aÿ@оà@’¹´@®Œ AF?Ò@:›Ñ@º\Ae³¿Å¿Q+?£æÌ@’¹´@/Aÿ@F?Ò@:›Ñ@º\A‹F½@:›Ñ@]àAr¿ô ¿èù?‹F½@:›Ñ@]àAF?Ò@:›Ñ@º\AëAÅ@ð@ª\A‹J¿Œ¿?‹F½@:›Ñ@]àAëAÅ@ð@ª\A«F¯@ð@ _ Axç¿*üô¾aù ?«F¯@ð@ _ AëAÅ@ð@ª\A[Ù¹@.ÞAy‚Aõ#¿y±é¾q?«F¯@ð@ _ A[Ù¹@.ÞAy‚Aû¢@.ÞARAÖÝ"¿Š°Ò¾]'?û¢@.ÞARA[Ù¹@.ÞAy‚Aë°@rQAZÅ#AóÏ(¿Uûƾý½$?û¢@.ÞARAë°@rQAZÅ#ALu˜@rQA õAðê'¿h6¯¾<,?Lu˜@rQA õAë°@rQAZÅ#A•¨@=B)AÄ(A$¬-¿x'£¾Žw)?Lu˜@rQA õA•¨@=B)AÄ(AwÄ@=B)A5ýA~,¿¤Àо o0?wÄ@=B)A5ýA•¨@=B)AÄ(A䳡@P˜:A~…+A1¿Ò|¾S>-?wÄ@=B)A5ýA䳡@P˜:A~…+Aõˆ@P˜:A&A‹-/¿K¾2¥3?õˆ@P˜:A&A䳡@P˜:A~…+Aã)@×:LAª÷-Akt4¿ë1¾Ö 0?õˆ@P˜:A&Aã)@×:LAª÷-A¬„@×:LAk!A‹X1¿wÒþ½åÙ5?¬„@×:LAk!Aã)@×:LAª÷-Anš@•^AÅp/A³V6¿·̽ß1?¬„@×:LAk!Anš@•^AÅp/Au@•^AõÈ"A†i2¿7y½ùì6?u@•^AõÈ"Anš@•^AÅp/A(¸™@ê hAÁÒ/A9$7¿m|½c¢2?u@•^AõÈ"A(¸™@ê hAÁÒ/A•"€@pAÐ=#AÚÈ2¿»n™¼*7?•"€@pAÐ=#A(¸™@ê hAÁÒ/AÁ7™@q|jAý´/AÃì2¿tû»P7?•"€@pAÐ=#AÁ7™@q|jAý´/ArÛ˜@pA’Ÿ/A«??žîˆ½ïXL?­°¾ASÑcAÜAA%¾A¼ý]A·äAA œÂA•^Ai;A3®?­)̽@I? œÂA•^Ai;A%¾A¼ý]A·äAA­ûÁA×:LA5‹9Af¿#?·̽C? œÂA•^Ai;A­ûÁA×:LA5‹9A{dÉA•^AÅp/A)t?­Oš¾ÇÃ<íéA!Ÿ$AR-¬©J‘êA^P)ADo­©YêA=B)Aw‰?5Xv?çÀо;Ã<YêA=B)Aw‰?J‘êA^P)ADo­©·íìA¡:AG²©ÏÄw?£Ð|¾¼5E=YêA=B)Aw‰?·íìA¡:AG²© ªìAP˜:Ahâ‹?@¶y?0`¾=Ç< ªìAP˜:Ahâ‹?·íìA¡:AG²©ÕIíA§D=AVȲ©ÈËz?ž4G¾ð—H= ªìAP˜:Ahâ‹?ÕIíA§D=AVȲ©ñSîA×:LAá?â1|?.¾þþÉ<ñSîA×:LAá?ÕIíA§D=AVȲ©uîA0HLAê(µ©Þ”}?¾" ¾ÓòÉ<ñSîA×:LAá?uîA0HLAê(µ©÷QïAT}VA¬Æ¶©ÊÆT<¶º~¿0Ê=WqAxÌ+=¡?P¬rAxÌ+=á?ÍTuAòŽ+>„{ @Ú¿µ<~¿¾hú=ÍTuAòŽ+>„{ @P¬rAxÌ+=á?¨õwAòŽ+>E~ @N=ˆ|¿,.>ÍTuAòŽ+>„{ @¨õwAòŽ+>E~ @=â{A´À>£CP@‘J=,îz¿…ZD>=â{A´À>£CP@¨õwAòŽ+>E~ @νA´À>+!L@¹ú‰=Îx¿µír>=â{A´À>£CP@νA´À>+!L@ùl‚Aµ™*?c2‡@ý·±=rqv¿fFƒ>ùl‚Aµ™*?c2‡@νA´À>+!L@ì„Aµ™*?̳ƒ@kà=<¯r¿ ™>ùl‚Aµ™*?c2‡@ì„Aµ™*?̳ƒ@SˆA?Ð=£@‹„>3”p¿p(¡>SˆA?Ð=£@ì„Aµ™*?̳ƒ@™‹A?Jÿ@V $>|ëk¿@µ>SˆA?Ð=£@™‹A?Jÿ@2—ŽAÈ#¾?º£»@ç@>À^i¿ˆ(»>2—ŽAÈ#¾?º£»@™‹A?Jÿ@t’AÈ#¾?²\´@ÑÎ_>%Öc¿'æÌ>2—ŽAÈ#¾?º£»@t’AÈ#¾?²\´@ÿÿ•A™@™ØÏ@¸>TÛ`¿ÿ±Ð>ÿÿ•A™@™ØÏ@t’AÈ#¾?²\´@™Ì™A™@LÆ@!‘>³zZ¿sà>ÿÿ•A™@™ØÏ@™Ì™A™@LÆ@\žAÏ&@âhß@ M¢>W¿šIá>\žAÏ&@âhß@™Ì™A™@LÆ@œ%¢AÏ&@úfÓ@2˜´>pæO¿µýí>\žAÏ&@âhß@œ%¢AÏ&@úfÓ@¦¦AqQ@’ûé@<ÕÆ>´L¿Wì>¦¦AqQ@’ûé@œ%¢AÏ&@úfÓ@ÃãªAqQ@ZbÛ@@ÞÙ>h(D¿âö>¦¦AqQ@’ûé@ÃãªAqQ@ZbÛ@%„¯A•"€@3Tï@Ï£ì>ÿþ?¿‘Eò>%„¯A•"€@3Tï@ÃãªAqQ@ZbÛ@ Õ³A•"€@•Þ@=ÿÿ>RQ7¿`ù>%„¯A•"€@3Tï@ Õ³A•"€@•Þ@Ú{¸A_„™@3Tï@Op ?)Î2¿rHò>Ú{¸A_„™@3Tï@ Õ³A•"€@•Þ@WƼA_„™@ZbÛ@“?|s)¿»‡ö>Ú{¸A_„™@3Tï@WƼA_„™@ZbÛ@ìYÁA’¹´@’ûé@‚X?$¿·˜ì>ìYÁA’¹´@’ûé@WƼA_„™@ZbÛ@~„ÅA’¹´@úfÓ@ò´%?®¢¿àî>ìYÁA’¹´@’ûé@~„ÅA’¹´@úfÓ@£ëÉA:›Ñ@âhß@Yž.?Å¿³Vá>£ëÉA:›Ñ@âhß@~„ÅA’¹´@úfÓ@ÝÍA:›Ñ@LÆ@‚7?ô ¿êà>£ëÉA:›Ñ@âhß@ÝÍA:›Ñ@LÆ@ÒAð@™ØÏ@IÙ??Œ¿›ÂÐ>ÒAð@™ØÏ@ÝÍA:›Ñ@LÆ@¥¡ÕAð@²\´@!H?)üô¾†øÌ>ÒAð@™ØÏ@¥¡ÕAð@²\´@ÎhÙA.ÞAº£»@´¦O?z±é¾;»>ÎhÙA.ÞAº£»@¥¡ÕAð@²\´@¤ÜA.ÞAJÿ@GW?‰°Ò¾Ú#µ>ÎhÙA.ÞAº£»@¤ÜA.ÞAJÿ@­ûßArQAÐ=£@&¬]?Uûƾ>;¡>­ûßArQAÐ=£@¤ÜA.ÞAJÿ@û½âArQA̳ƒ@ëd?i6¯¾™>­ûßArQAÐ=£@û½âArQA̳ƒ@“åA=B)Ac2‡@U™i?x'£¾©Wƒ>“åA=B)Ac2‡@û½âArQA̳ƒ@3ËçA=B)A+!L@Ïn?¥Àо2s>“åA=B)Ac2‡@3ËçA=B)A+!L@áêAP˜:A£CP@õ)s?Ò|¾®vD>áêAP˜:A£CP@3ËçA=B)A+!L@E¯ëAP˜:AE~ @sw?K¾ö).>áêAP˜:A£CP@E¯ëAP˜:AE~ @™UíA×:LA„{ @;'z?ë1¾ÕŽú=™UíA×:LA„{ @E¯ëAP˜:AE~ @ñSîA×:LAá?À|?wÒþ½Œ-Ê=™UíA×:LA„{ @ñSîA×:LAá?qTïA•^A¡?\ ~?ƑὡÛJ=qTïA•^A¡?ñSîA×:LAá?÷QïAT}VA¬Æ¶©²ü~?A½®½ ¤Ë5®@ÇT<~¿Àý=P¬rAòŽ+>5®@WqAxÌ+=¡?ÍTuAòŽ+>„{ @+Àµ<ˆ|¿ø@0>P¬rAòŽ+>5®@ÍTuAòŽ+>„{ @¨õwA´À>ð;S@ìN=,îz¿Ë–G>¨õwA´À>ð;S@ÍTuAòŽ+>„{ @=â{A´À>£CP@#’J=Îx¿¦gw>¨õwA´À>ð;S@=â{A´À>£CP@νAµ™*?kï‰@#û‰=rqv¿h:†>νAµ™*?kï‰@=â{A´À>£CP@ùl‚Aµ™*?c2‡@•¸±=<¯r¿OÍœ>νAµ™*?kï‰@ùl‚Aµ™*?c2‡@ì„A?¢’§@@à=3”p¿íÎ¥>ì„A?¢’§@ùl‚Aµ™*?c2‡@SˆA?Ð=£@…>|ëk¿Â¯º>ì„A?¢’§@SˆA?Ð=£@™‹AÈ#¾? ÞÁ@ $>À^i¿nÔÁ>™‹AÈ#¾? ÞÁ@SˆA?Ð=£@2—ŽAÈ#¾?º£»@ÍŽ@>%Öc¿N°Ô>™‹AÈ#¾? ÞÁ@2—ŽAÈ#¾?º£»@t’A™@‡;Ø@ëÏ_>TÛ`¿­ªÙ>t’A™@‡;Ø@2—ŽAÈ#¾?º£»@ÿÿ•A™@™ØÏ@Y¹>³zZ¿;:ê>t’A™@‡;Ø@ÿÿ•A™@™ØÏ@™Ì™AÏ&@ò*ê@è‘>W¿LÉì>™Ì™AÏ&@ò*ê@ÿÿ•A™@™ØÏ@\žAÏ&@âhß@ðM¢>pæO¿IÒú>™Ì™AÏ&@ò*ê@\žAÏ&@âhß@œ%¢AqQ@ÐE÷@:™´>³L¿ÛÂú>œ%¢AqQ@ÐE÷@\žAÏ&@âhß@¦¦AqQ@’ûé@bÖÆ>g(D¿¸ ?œ%¢AqQ@ÐE÷@¦¦AqQ@’ûé@ÃãªA•"€@/Aÿ@‰ßÙ>ÿþ?¿££?ÃãªA•"€@/Aÿ@¦¦AqQ@’ûé@%„¯A•"€@3Tï@6¥ì>RQ7¿…ç?ÃãªA•"€@/Aÿ@%„¯A•"€@3Tï@ Õ³A_„™@µ÷Aa?)Î2¿Õ? Õ³A_„™@µ÷A%„¯A•"€@3Tï@Ú{¸A_„™@3Tï@ q ?|s)¿é? Õ³A_„™@µ÷AÚ{¸A_„™@3Tï@WƼA’¹´@/Aÿ@p?$¿·¦?WƼA’¹´@/Aÿ@Ú{¸A_„™@3Tï@ìYÁA’¹´@’ûé@kY?®¢¿]?WƼA’¹´@/Aÿ@ìYÁA’¹´@’ûé@~„ÅA:›Ñ@ÐE÷@ãµ%?Å¿žÎú>~„ÅA:›Ñ@ÐE÷@ìYÁA’¹´@’ûé@£ëÉA:›Ñ@âhß@QŸ.?ô ¿Þàú>~„ÅA:›Ñ@ÐE÷@£ëÉA:›Ñ@âhß@ÝÍAð@ò*ê@ƒ7?Œ¿¦Ùì>ÝÍAð@ò*ê@£ëÉA:›Ñ@âhß@ÒAð@™ØÏ@FÚ??*üô¾ßLê>ÝÍAð@ò*ê@ÒAð@™ØÏ@¥¡ÕA.ÞA‡;Ø@H?y±é¾1¾Ù>¥¡ÕA.ÞA‡;Ø@ÒAð@™ØÏ@ÎhÙA.ÞAº£»@¬§O?Š°Ò¾jÅÔ>¥¡ÕA.ÞA‡;Ø@ÎhÙA.ÞAº£»@¤ÜArQA ÞÁ@7W?TûƾjéÁ>¤ÜArQA ÞÁ@ÎhÙA.ÞAº£»@­ûßArQAÐ=£@ ­]?i6¯¾‹Åº>¤ÜArQA ÞÁ@­ûßArQAÐ=£@û½âA=B)A¢’§@Ä d?x'£¾ã¥>û½âA=B)A¢’§@­ûßArQAÐ=£@“åA=B)Ac2‡@ši?¥Àоïáœ>û½âA=B)A¢’§@“åA=B)Ac2‡@3ËçAP˜:Akï‰@CÐn?Ò|¾éL†>3ËçAP˜:Akï‰@“åA=B)Ac2‡@áêAP˜:A£CP@•*s?K¾"‹w>3ËçAP˜:Akï‰@áêAP˜:A£CP@E¯ëA×:LAð;S@ýw?ë1¾^´G>E¯ëA×:LAð;S@áêAP˜:A£CP@™UíA×:LA„{ @¬'z?wÒþ½Ç[0>E¯ëA×:LAð;S@™UíA×:LA„{ @ñSîA•^A5®@jÀ|?·̽Bý=ñSîA•^A5®@™UíA×:LA„{ @qTïA•^A¡?Xi~?QL½išË=ñSîA•^A5®@qTïA•^A¡?ªïApAV{?;š?Q̼ýL=ªïApAV{?qTïA•^A¡?ðApA¾¸©7×?½UÌ< QÌ<ªïApAV{?ðApA¾¸©H¤ïAz÷€Axh·©%ôº¡®¿žçK=â¨nAxÌ+=¡?pABÏ(pAxÌ+=V{?!‰¿‡ =†L=òŽ«=µ÷€A¡?ð)®;cvAEÕ*xÌ+=pAV{? é¿å£<¹4ÌS<pABÏ(‘Ü^AxÌ+=+©>³ƒ^AxÌ+=ïk>¦Õý¶º~¿Á¨á<³ƒ^AxÌ+=ïk>‘Ü^AxÌ+=+©>«ÑMAòŽ+>é±(?«ÑMAòŽ+>é±(?o MAòŽ+>µþ>-æ*¾ˆ|¿øïB=o MAòŽ+>µþ>«ÑMAòŽ+>é±(?µ÷ÎÜ{?…ZD¾,îz¿‘J=o MAòŽ+>µþ>µ÷ÎÜ{?ï;A´À>È#>?µír¾Îx¿¹ú‰=ï;A´À>È#>?µ÷ÎÜ{?Îf,Aµ™*?Ϧ?h:†¾rqv¿#û‰=ï;A´À>È#>?Îf,Aµ™*?Ϧ?J+Aµ™*?ÎÜ{?OÍœ¾<¯r¿•¸±=J+Aµ™*?ÎÜ{?Îf,Aµ™*?Ϧ?¯6A?çÁÎ? ˆ©¾3”p¿–è­=J+Aµ™*?ÎÜ{?¯6A?çÁÎ?;„A?Ÿœ?ÿC¿¾|ëk¿ÐxØ=;„A?Ÿœ?¯6A?çÁÎ?„~ AÈ#¾?=Œõ?ºã˾À^i¿×ÝÐ=;„A?Ÿœ?„~ AÈ#¾?=Œõ?Œz AÈ#¾?a_¹?«©à¾%Öc¿ þ=Œz AÈ#¾?a_¹?„~ AÈ#¾?=Œõ?š©ú@™@„{ @\í¾TÛ`¿î¨ò=Œz AÈ#¾?a_¹?š©ú@™@„{ @mö@™@¿žÕ?Hg¿³zZ¿J>mö@™@¿žÕ?š©ú@™@„{ @ƒžÝ@Ï&@\f@4¿W¿ÂŒ >mö@™@¿žÕ?ƒžÝ@Ï&@\f@½bØ@Ï&@H¬ð?U¿pæO¿[S">½bØ@Ï&@H¬ð?ƒžÝ@Ï&@\f@VÂ@qQ@ÿl0@´¿³L¿>½bØ@Ï&@H¬ð?VÂ@qQ@ÿl0@t:¼@qQ@ 0@ýO¿h(D¿¬2>t:¼@qQ@ 0@VÂ@qQ@ÿl0@•¨@•"€@w@@$¿ÿþ?¿¾™'>t:¼@qQ@ 0@•¨@•"€@w@@䳡@•"€@oL@aû+¿RQ7¿FB>䳡@•"€@oL@•¨@•"€@w@@wÄ@_„™@‘mO@‡ƒ1¿)Î2¿VC5>䳡@•"€@oL@wÄ@_„™@‘mO@õˆ@_„™@8˜@à°8¿|s)¿¢JP>õˆ@_„™@8˜@wÄ@_„™@‘mO@uÉr@’¹´@;]@$ø=¿$¿ºéA>õˆ@_„™@8˜@uÉr@’¹´@;]@‚Bd@’¹´@Ñ'@6^D¿¯¢¿e]>‚Bd@’¹´@Ñ'@uÉr@’¹´@;]@Ç J@:›Ñ@ðËi@ý\I¿Å¿·zM>‚Bd@’¹´@Ñ'@Ç J@:›Ñ@ðËi@š²:@:›Ñ@O€0@“òN¿ô ¿¾Bi>š²:@:›Ñ@O€0@Ç J@:›Ñ@ðËi@:%@ð@ u@°¡S¿Œ¿ªåW>š²:@:›Ñ@O€0@:%@ð@ u@Ìu@ð@9@½^X¿*üô¾ˆÒs>Ìu@ð@9@:%@ð@ u@ @.ÞAPñ~@m·\¿z±é¾Ša>Ìu@ð@9@ @.ÞAPñ~@Ï‚é?.ÞAw@@•`¿‰°Ò¾8}>Ï‚é?.ÞAw@@ @.ÞAPñ~@J Ô?rQA̳ƒ@‘d¿Uûƾi>Ï‚é?.ÞAw@@J Ô?rQA̳ƒ@|ˆ±?rQAuÚF@щg¿i6¯¾Åf‚>|ˆ±?rQAuÚF@J Ô?rQA̳ƒ@Ϧ?=B)Ac2‡@d#k¿y'£¾Æ´o>|ˆ±?rQAuÚF@Ϧ?=B)Ac2‡@ËLƒ?=B)A+!L@Ö2m¿¥Àо…>ËLƒ?=B)A+!L@Ϧ?=B)Ac2‡@ËLƒ?P˜:Akï‰@Édp¿Ò|¾ u>ËLƒ?=B)A+!L@ËLƒ?P˜:Akï‰@È#>?P˜:A£CP@ú‡q¿K¾ú‡>È#>?P˜:A£CP@ËLƒ?P˜:Akï‰@¦•S?×:LAùæ‹@±Mt¿ë1¾2òx>È#>?P˜:A£CP@¦•S?×:LAùæ‹@R ?×:LAð;S@ù‚t¿xÒþ½,¡‰>R ?×:LAð;S@¦•S?×:LAùæ‹@[Ü4?•^A>@uØv¿·̽Ž|{>R ?×:LAð;S@[Ü4?•^A>@q}Õ>•^AÔU@v¿QL½þ‚Š>q}Õ>•^AÔU@[Ü4?•^A>@µ™*?pA„{@fx¿Q̼rž|>q}Õ>•^AÔU@µ™*?pA„{@´À>pA¿žU@=[v¿QÌ´À>pA¿žU@µ™*?pA„{@[Ü4?µ÷€A>@ØÆw¿QL=9V|>´À>pA¿žU@[Ü4?µ÷€A>@q}Õ>µ÷€AÔU@×ð½~¿¸€$=‘Ü^AxÌ+=+©>׳NAòŽ+>ÂQ?«ÑMAòŽ+>é±(?‚Ç&¾ˆ|¿?zu=«ÑMAòŽ+>é±(?׳NAòŽ+>ÂQ?cI>A´À>Ÿœ?"@¾,îz¿&Y‚=«ÑMAòŽ+>é±(?cI>A´À>Ÿœ?µ÷ÎÜ{?ùm¾Îx¿×æ­=µ÷ÎÜ{?cI>A´À>Ÿœ?&.Aµ™*?çÁÎ?fFƒ¾rqv¿ý·±=µ÷ÎÜ{?&.Aµ™*?çÁÎ?Îf,Aµ™*?Ϧ? ™¾<¯r¿kà=Îf,Aµ™*?Ϧ?&.Aµ™*?çÁÎ?aA?–"@íÎ¥¾3”p¿@à=Îf,Aµ™*?Ϧ?aA?–"@¯6A?çÁÎ?¯º¾|ëk¿…>¯6A?çÁÎ?aA?–"@ðAÈ#¾?Ç,@ÓjǾÀ^i¿Y>¯6A?çÁÎ?ðAÈ#¾?Ç,@„~ AÈ#¾?=Œõ?õIÛ¾%Öc¿; >„~ AÈ#¾?=Œõ?ðAÈ#¾?Ç,@KA™@]/@êç¾TÛ`¿çm>„~ AÈ#¾?=Œõ?KA™@]/@š©ú@™@„{ @«ú¾³zZ¿W 7>š©ú@™@„{ @KA™@]/@3Lä@Ï&@_’E@¿W¿_1>š©ú@™@„{ @3Lä@Ï&@_’E@ƒžÝ@Ï&@\f@S ¿pæO¿ØL>ƒžÝ@Ï&@\f@3Lä@Ï&@_’E@£iÉ@qQ@ɬZ@+m¿³L¿åRE>ƒžÝ@Ï&@\f@£iÉ@qQ@ɬZ@VÂ@qQ@ÿl0@ˆ¿h(D¿=a>VÂ@qQ@ÿl0@£iÉ@qQ@ɬZ@ë°@•"€@"Žn@ z ¿ÿþ?¿¾,X>VÂ@qQ@ÿl0@ë°@•"€@"Žn@•¨@•"€@w@@Nà'¿RQ7¿ät>•¨@•"€@w@@ë°@•"€@"Žn@Lu˜@_„™@ùŒ€@‡¡-¿)Î2¿”Ñi>•¨@•"€@w@@Lu˜@_„™@ùŒ€@wÄ@_„™@‘mO@wH4¿|s)¿`uƒ>wÄ@_„™@‘mO@Lu˜@_„™@ùŒ€@œ©‚@’¹´@؉@¸Ð9¿$¿(z>wÄ@_„™@‘mO@œ©‚@’¹´@؉@uÉr@’¹´@;]@Æ®?¿¯¢¿²¼‹>uÉr@’¹´@;]@œ©‚@’¹´@؉@¤]@:›Ñ@lä@öD¿Å¿VŒ„>uÉr@’¹´@;]@¤]@:›Ñ@lä@Ç J@:›Ñ@ðËi@ÐJ¿ô ¿<“>Ç J@:›Ñ@ðËi@¤]@:›Ñ@lä@:@ð@’Þ—@žO¿Œ¿÷F‹>Ç J@:›Ñ@ðËi@:@ð@’Þ—@:%@ð@ u@¸5S¿*üô¾µè™>:%@ð@ u@:@ð@’Þ—@÷Û@.ÞAJÿ@ÍäW¿y±é¾6:‘>:%@ð@ u@÷Û@.ÞAJÿ@ @.ÞAPñ~@6:[¿Š°Ò¾ü¸Ÿ> @.ÞAPñ~@÷Û@.ÞAJÿ@•"@rQAÐ=£@Õ’_¿Tûƾ]–> @.ÞAPñ~@•"@rQAÐ=£@J Ô?rQA̳ƒ@ºb¿h6¯¾¤¤>J Ô?rQA̳ƒ@•"@rQAÐ=£@J Ô?=B)A¢’§@Ÿf¿x'£¾g©š>J Ô?rQA̳ƒ@J Ô?=B)A¢’§@Ϧ?=B)Ac2‡@t‹g¿¥Àо(¤¨>Ϧ?=B)Ac2‡@J Ô?=B)A¢’§@|ˆ±?P˜:AŠ÷ª@à$k¿Ò|¾¹ž>Ϧ?=B)Ac2‡@|ˆ±?P˜:AŠ÷ª@ËLƒ?P˜:Akï‰@gÆk¿K¾*²«>ËLƒ?P˜:Akï‰@|ˆ±?P˜:AŠ÷ª@P¯˜?×:LA¯g­@,øn¿ë1¾}£ >ËLƒ?P˜:Akï‰@P¯˜?×:LA¯g­@¦•S?×:LAùæ‹@u¯n¿xÒþ½Ê­>¦•S?×:LAùæ‹@P¯˜?×:LA¯g­@Q¸‰?•^A“ß®@÷tq¿·̽I¢>¦•S?×:LAùæ‹@Q¸‰?•^A“ß®@[Ü4?•^A>@eBp¿QL½õè®>[Ü4?•^A>@Q¸‰?•^A“ß®@?pA]¯@ª—r¿Q̼ò£>[Ü4?•^A>@?pA]¯@µ™*?pA„{@ò|p¿QÌ< ¯>µ™*?pA„{@?pA]¯@Q¸‰?µ÷€A“ß®@ ^r¿QL=/Ù¢>µ™*?pA„{@Q¸‰?µ÷€A“ß®@[Ü4?µ÷€A>@Öœ:¾,îz¿à®ž=׳NAòŽ+>ÂQ?<â?A´À>a_¹?cI>A´À>Ÿœ?Ðîe¾Îx¿ýÙÐ=cI>A´À>Ÿœ?<â?A´À>a_¹?¬C0Aµ™*?=Œõ?å,¾qqv¿hvØ=cI>A´À>Ÿœ?¬C0Aµ™*?=Œõ?&.Aµ™*?çÁÎ?½m”¾<¯r¿·›>&.Aµ™*?çÁÎ?¬C0Aµ™*?=Œõ?[!A?Ç,@p(¡¾3”p¿‹„>&.Aµ™*?çÁÎ?[!A?Ç,@aA?–"@@µ¾|ëk¿V $>aA?–"@[!A?Ç,@".AÈ#¾?’¹4@nÔÁ¾À^i¿ $>aA?–"@".AÈ#¾?’¹4@ðAÈ#¾?Ç,@N°Ô¾%Öc¿ÍŽ@>ðAÈ#¾?Ç,@".AÈ#¾?’¹4@=âA™@£CP@ºká¾TÛ`¿b§>>ðAÈ#¾?Ç,@=âA™@£CP@KA™@]/@® ó¾³zZ¿T\>KA™@]/@=âA™@£CP@>bì@Ï&@ˆ£j@#Áÿ¾W¿y3X>KA™@]/@>bì@Ï&@ˆ£j@3Lä@Ï&@_’E@ç¿pæO¿ 7v>3Lä@Ï&@_’E@>bì@Ï&@ˆ£j@È\Ò@qQ@ÁÙ@œT¿³L¿¹Šp>3Lä@Ï&@_’E@È\Ò@qQ@ÁÙ@£iÉ@qQ@ɬZ@ã¿g(D¿“‡‡>£iÉ@qQ@ɬZ@È\Ò@qQ@ÁÙ@[Ù¹@•"€@×§@Eý¿ÿþ?¿"Ń>£iÉ@qQ@ɬZ@[Ù¹@•"€@×§@ë°@•"€@"Žn@äÔ"¿RQ7¿¡1“>ë°@•"€@"Žn@[Ù¹@•"€@×§@û¢@_„™@ «˜@òÆ(¿)Î2¿‰ˆŽ>ë°@•"€@"Žn@û¢@_„™@ «˜@Lu˜@_„™@ùŒ€@ôÝ.¿|s)¿; ž>Lu˜@_„™@ùŒ€@û¢@_„™@ «˜@œâ@’¹´@×Ó¢@GŸ4¿$¿ €˜>Lu˜@_„™@ùŒ€@œâ@’¹´@×Ó¢@œ©‚@’¹´@؉@êì9¿¯¢¿Ëþ§>œ©‚@’¹´@؉@œâ@’¹´@×Ó¢@x\u@:›Ñ@r¬@9u?¿Æ¿Ž¡>œ©‚@’¹´@؉@x\u@:›Ñ@r¬@¤]@:›Ñ@lä@ØñC¿ô ¿ú±>¤]@:›Ñ@lä@x\u@:›Ñ@r¬@ÓòR@ð@²\´@09I¿Œ¿´Ó©>¤]@:›Ñ@lä@ÓòR@ð@²\´@:@ð@’Þ—@RÞL¿*üô¾Î ¹>:@ð@’Þ—@ÓòR@ð@²\´@¹4@.ÞAº£»@ÝQ¿y±é¾¾±>:@ð@’Þ—@¹4@.ÞAº£»@÷Û@.ÞAJÿ@w¥T¿Š°Ò¾¯ À>÷Û@.ÞAJÿ@¹4@.ÞAº£»@÷Û@rQA ÞÁ@{TY¿Tûƾ1\·>÷Û@.ÞAJÿ@÷Û@rQA ÞÁ@•"@rQAÐ=£@<[¿i6¯¾…öÅ>•"@rQAÐ=£@÷Û@rQA ÞÁ@ @=B)AøÇ@‘”_¿w'£¾›¼>•"@rQAÐ=£@ @=B)AøÇ@J Ô?=B)A¢’§@”˜`¿¤ÀоÁÆÊ>J Ô?=B)A¢’§@ @=B)AøÇ@Ï‚é?P˜:Aç Ë@T”d¿Ò|¾˜ËÀ>J Ô?=B)A¢’§@Ï‚é?P˜:Aç Ë@|ˆ±?P˜:AŠ÷ª@H³d¿K¾qtÎ>|ˆ±?P˜:AŠ÷ª@Ï‚é?P˜:Aç Ë@ûuÑ?×:LA$ðÍ@ˆLh¿ë1¾èçÃ>|ˆ±?P˜:AŠ÷ª@ûuÑ?×:LA$ðÍ@P¯˜?×:LA¯g­@8†g¿wÒþ½=úÐ>P¯˜?×:LA¯g­@ûuÑ?×:LA$ðÍ@úÂ?•^AŽ®Ï@Ë·j¿·̽oëÅ>P¯˜?×:LA¯g­@úÂ?•^AŽ®Ï@Q¸‰?•^A“ß®@Q i¿QL½‚TÒ>Q¸‰?•^A“ß®@úÂ?•^AŽ®Ï@È#¾?pA£CÐ@žÒk¿Q̼FÓÆ>Q¸‰?•^A“ß®@È#¾?pA£CÐ@?pA]¯@ZFi¿QÌ?pA]¯@È#¾?pA£CÐ@úÂ?µ÷€AŽ®Ï@i›k¿QL=žÆ>?pA]¯@úÂ?µ÷€AŽ®Ï@Q¸‰?µ÷€A“ß®@¬_v¾qqv¿íþý=<â?A´À>a_¹?}¼2Aµ™*?„{ @¬C0Aµ™*?=Œõ?æû޾<¯r¿‚j>¬C0Aµ™*?=Œõ?}¼2Aµ™*?„{ @·$A?]/@8››¾3”p¿9 >¬C0Aµ™*?=Œõ?·$A?]/@[!A?Ç,@„m®¾|ëk¿º¤>>[!A?Ç,@·$A?]/@§ÑAÈ#¾?£CP@ˆ(»¾À^i¿ç@>[!A?Ç,@§ÑAÈ#¾?£CP@".AÈ#¾?’¹4@'æÌ¾%Öc¿ÑÎ_>".AÈ#¾?’¹4@§ÑAÈ#¾?£CP@³A™@p@­ªÙ¾TÛ`¿ëÏ_>".AÈ#¾?’¹4@³A™@p@=âA™@£CP@;:ê¾³zZ¿Y¹>=âA™@£CP@³A™@p@ Õõ@Ï&@c2‡@ÿõö¾W¿VÒ}>=âA™@£CP@ Õõ@Ï&@c2‡@>bì@Ï&@ˆ£j@â¿pæO¿Q>>bì@Ï&@ˆ£j@ Õõ@Ï&@c2‡@öÑÜ@qQ@6£•@Gp ¿´L¿5>>bì@Ï&@ˆ£j@öÑÜ@qQ@6£•@È\Ò@qQ@ÁÙ@Pg¿h(D¿>È\Ò@qQ@ÁÙ@öÑÜ@qQ@6£•@ëAÅ@•"€@Ð=£@+¡¿ÿþ?¿=·š>È\Ò@qQ@ÁÙ@ëAÅ@•"€@Ð=£@[Ù¹@•"€@×§@Zà¿RQ7¿«>[Ù¹@•"€@×§@ëAÅ@•"€@Ð=£@«F¯@_„™@µî¯@¼ú"¿)Î2¿:\§>[Ù¹@•"€@×§@«F¯@_„™@µî¯@û¢@_„™@ «˜@y(¿|s)¿Õº·>û¢@_„™@ «˜@«F¯@_„™@µî¯@®ÿš@’¹´@º£»@?k.¿ÿœ$¿ä³>û¢@_„™@ «˜@®ÿš@’¹´@º£»@œâ@’¹´@×Ó¢@ß 3¿®¢¿aPÃ>œâ@’¹´@×Ó¢@®ÿš@’¹´@º£»@û‰ˆ@:›Ñ@LÆ@?â8¿Æ¿cǽ>œâ@’¹´@×Ó¢@û‰ˆ@:›Ñ@LÆ@x\u@:›Ñ@r¬@YÈ<¿ô ¿wÎÍ>x\u@:›Ñ@r¬@û‰ˆ@:›Ñ@LÆ@ýÿo@ð@™ØÏ@­PB¿Œ¿NmÇ>x\u@:›Ñ@r¬@ýÿo@ð@™ØÏ@ÓòR@ð@²\´@žaE¿*üô¾û%×>ÓòR@ð@²\´@ýÿo@ð@™ØÏ@ÓòR@.ÞA‡;Ø@ï¨J¿y±é¾½õÏ>ÓòR@ð@²\´@ÓòR@.ÞA‡;Ø@¹4@.ÞAº£»@GàL¿‰°Ò¾rIß>¹4@.ÞAº£»@ÓòR@.ÞA‡;Ø@:@rQAâhß@ýÞQ¿Tûƾ`T×>¹4@.ÞAº£»@:@rQAâhß@÷Û@rQA ÞÁ@…9S¿i6¯¾ -æ>÷Û@rQA ÞÁ@:@rQAâhß@:%@=B)AdVå@nèW¿x'£¾•~Ý>÷Û@rQA ÞÁ@:%@=B)AdVå@ @=B)AøÇ@)dX¿¤Àо Çë> @=B)AøÇ@:%@=B)AdVå@Ìu@P˜:A’ûé@ˆ¼\¿Ò|¾qkâ> @=B)AøÇ@Ìu@P˜:A’ûé@Ï‚é?P˜:Aç Ë@½X\¿K¾$ð>Ï‚é?P˜:Aç Ë@Ìu@P˜:A’ûé@Èæ @×:LAÄQí@QT`¿ë1¾×æ>Ï‚é?P˜:Aç Ë@Èæ @×:LAÄQí@ûuÑ?×:LA$ðÍ@‡_¿wÒþ½/ÿò>ûuÑ?×:LA$ðÍ@Èæ @×:LAÄQí@¹ð@•^A3Tï@•ªb¿·̽}rè>ûuÑ?×:LA$ðÍ@¹ð@•^A3Tï@úÂ?•^AŽ®Ï@—Š`¿QL½ñ’ô>úÂ?•^AŽ®Ï@¹ð@•^A3Tï@™@pAð@õ»c¿Q̼ôƒé>úÂ?•^AŽ®Ï@™@pAð@È#¾?pA£CÐ@ËÁ`¿QÌ<Èô>È#¾?pA£CÐ@™@pAð@¹ð@µ÷€A3Tï@ã†c¿QL=°Fé>È#¾?pA£CÐ@¹ð@µ÷€A3Tï@úÂ?µ÷€AŽ®Ï@;/•¾3”p¿7>}¼2Aµ™*?„{ @Ê'A?_’E@·$A?]/@Ѧ¾|ëk¿/.X>·$A?]/@Ê'A?_’E@GöAÈ#¾?ˆ£j@°p³¾À^i¿ý[>·$A?]/@GöAÈ#¾?ˆ£j@§ÑAÈ#¾?£CP@¨öþ%Öc¿kÎ}>§ÑAÈ#¾?£CP@GöAÈ#¾?ˆ£j@òÙ A™@c2‡@ÿ±Ð¾TÛ`¿¸>§ÑAÈ#¾?£CP@òÙ A™@c2‡@³A™@p@sླzZ¿!‘>³A™@p@òÙ A™@c2‡@KAÏ&@rQ˜@LÉì¾W¿è‘>³A™@p@KAÏ&@rQ˜@ Õõ@Ï&@c2‡@IÒú¾pæO¿ðM¢> Õõ@Ï&@c2‡@KAÏ&@rQ˜@0ºè@qQ@r–¨@/Ç¿³L¿©Z¡> Õõ@Ï&@c2‡@0ºè@qQ@r–¨@öÑÜ@qQ@6£•@á ¿h(D¿Ü±²>öÑÜ@qQ@6£•@0ºè@qQ@r–¨@F?Ò@•"€@ê·@jm¿ÿþ?¿Ù˰>öÑÜ@qQ@6£•@F?Ò@•"€@ê·@ëAÅ@•"€@Ð=£@9 ¿RQ7¿aÂ>ëAÅ@•"€@Ð=£@F?Ò@•"€@ê·@‹F½@_„™@j6Æ@1E¿)Î2¿P@¿>ëAÅ@•"€@Ð=£@‹F½@_„™@j6Æ@«F¯@_„™@µî¯@ #!¿|s)¿eeÐ>«F¯@_„™@µî¯@‹F½@_„™@j6Æ@ î©@’¹´@úfÓ@‚='¿$¿J£Ì>«F¯@_„™@µî¯@ î©@’¹´@úfÓ@®ÿš@’¹´@º£»@aT+¿¯¢¿XŠÝ>®ÿš@’¹´@º£»@ î©@’¹´@úfÓ@rQ˜@:›Ñ@âhß@•F1¿Å¿†áØ>®ÿš@’¹´@º£»@rQ˜@:›Ñ@âhß@û‰ˆ@:›Ñ@LÆ@”4¿ô ¿Nré>û‰ˆ@:›Ñ@LÆ@rQ˜@:›Ñ@âhß@û‰ˆ@ð@ò*ê@øQ:¿Œ¿géã>û‰ˆ@:›Ñ@LÆ@û‰ˆ@ð@ò*ê@ýÿo@ð@™ØÏ@UÊ<¿*üô¾# ô>ýÿo@ð@™ØÏ@û‰ˆ@ð@ò*ê@x\u@.ÞAÂó@¢RB¿y±é¾«í>ýÿo@ð@™ØÏ@x\u@.ÞAÂó@ÓòR@.ÞA‡;Ø@ÉõC¿Š°Ò¾‹Hý>ÓòR@.ÞA‡;Ø@x\u@.ÞAÂó@¤]@rQA̳û@=I¿UûƾIö>ÓòR@.ÞA‡;Ø@¤]@rQA̳û@:@rQAâhß@“J¿i6¯¾?:@rQAâhß@¤]@rQA̳û@Ç J@=B)A¾0A.O¿x'£¾%ý>:@rQAâhß@Ç J@=B)A¾0A:%@=B)AdVå@ñùN¿¥Àоåº?:%@=B)AdVå@Ç J@=B)A¾0Aš²:@P˜:A¡ÎA·¨S¿Ò|¾’c?:%@=B)AdVå@š²:@P˜:A¡ÎAÌu@P˜:A’ûé@»ÂR¿K¾)?Ìu@P˜:A’ûé@š²:@P˜:A¡ÎA‡«/@×:LAѯAñW¿ë1¾3{?Ìu@P˜:A’ûé@‡«/@×:LAѯAÈæ @×:LAÄQí@y]U¿wÒþ½Ô ?Èæ @×:LAÄQí@‡«/@×:LAѯAY)@•^A›ÑAÝXY¿·̽bÖ?Èæ @×:LAÄQí@Y)@•^A›ÑA¹ð@•^A3Tï@eÆV¿QL½¹ ?¹ð@•^A3Tï@Y)@•^A›ÑAÏ&@pAc2AB_Z¿Q̼)s?¹ð@•^A3Tï@Ï&@pAc2A™@pAð@uûV¿QÌÊ'A?_’E@–AÈ#¾?ÁÙ@GöAÈ#¾?ˆ£j@œî¹¾%Öc¿S1>GöAÈ#¾?ˆ£j@–AÈ#¾?ÁÙ@".A™@6£•@ŠŽÆ¾TÛ`¿>GöAÈ#¾?ˆ£j@".A™@6£•@òÙ A™@c2‡@ôÔ¾³zZ¿üW¡>òÙ A™@c2‡@".A™@6£•@‚LAÏ&@r–¨@šIá¾W¿ M¢>òÙ A™@c2‡@‚LAÏ&@r–¨@KAÏ&@rQ˜@µýí¾pæO¿2˜´>KAÏ&@rQ˜@‚LAÏ&@r–¨@mö@qQ@P˜º@ÛÂú¾³L¿:™´>KAÏ&@rQ˜@mö@qQ@P˜º@0ºè@qQ@r–¨@¸ ¿g(D¿bÖÆ>0ºè@qQ@r–¨@mö@qQ@P˜º@оà@•"€@ Ë@åj ¿ÿþ?¿YãÅ>0ºè@qQ@r–¨@оà@•"€@ Ë@F?Ò@•"€@ê·@I_¿RQ7¿dø×>F?Ò@•"€@ê·@оà@•"€@ Ë@£æÌ@_„™@ZbÛ@í¯¿)Î2¿˜Ö>F?Ò@•"€@ê·@£æÌ@_„™@ZbÛ@‹F½@_„™@j6Æ@Jæ¿|s)¿›åç>‹F½@_„™@j6Æ@£æÌ@_„™@ZbÛ@P˜º@’¹´@’ûé@W ¿$¿¸å>‹F½@_„™@j6Æ@P˜º@’¹´@’ûé@ î©@’¹´@úfÓ@š’"¿¯¢¿$‡ö> î©@’¹´@úfÓ@P˜º@’¹´@’ûé@ î©@:›Ñ@ÐE÷@­(¿Æ¿+Åò> î©@’¹´@úfÓ@ î©@:›Ñ@ÐE÷@rQ˜@:›Ñ@âhß@NV+¿ô ¿÷ã?rQ˜@:›Ñ@âhß@ î©@:›Ñ@ÐE÷@®ÿš@ð@—A„H1¿Œ¿3ÿ>rQ˜@:›Ñ@âhß@®ÿš@ð@—Aû‰ˆ@ð@ò*ê@Å$3¿*üô¾sÊ?û‰ˆ@ð@ò*ê@®ÿš@ð@—Aœâ@.ÞA›ÑA!æ8¿z±é¾?û‰ˆ@ð@ò*ê@œâ@.ÞA›ÑAx\u@.ÞAÂó@½ò9¿Š°Ò¾ƒî ?x\u@.ÞAÂó@œâ@.ÞA›ÑAœ©‚@rQA.K Aùz?¿UûÆ¾ï½ ?x\u@.ÞAÂó@œ©‚@rQA.K A¤]@rQA̳û@d¶?¿i6¯¾»H?¤]@rQA̳û@œ©‚@rQA.K AuÉr@=B)AUýAŠýD¿x'£¾° ?¤]@rQA̳û@uÉr@=B)AUýAÇ J@=B)A¾0AhgD¿¥ÀоÑÒ?Ç J@=B)A¾0AuÉr@=B)AUýA‚Bd@P˜:AÅâAàeI¿Ò|¾-Ø?Ç J@=B)A¾0A‚Bd@P˜:AÅâAš²:@P˜:A¡ÎAýþG¿K¾§‡?š²:@P˜:A¡ÎA‚Bd@P˜:AÅâA+ÓY@×:LAZ÷Aš­L¿ë1¾<0?š²:@P˜:A¡ÎA+ÓY@×:LAZ÷A‡«/@×:LAѯAôwJ¿wÒþ½Tc?‡«/@×:LAѯA+ÓY@×:LAZ÷A\ŠS@•^A8AûÏN¿·̽Wµ?‡«/@×:LAѯA\ŠS@•^A8AY)@•^A›ÑA·ÎK¿QL½&c?Y)@•^A›ÑA\ŠS@•^A8AqQ@pA6£AíÉO¿Q̼Je?Y)@•^A›ÑAqQ@pA6£AÏ&@pAc2AWL¿QÌ<¬…?Ï&@pAc2AqQ@pA6£A\ŠS@µ÷€A8AšO¿QL=??Ï&@pAc2A\ŠS@µ÷€A8AY)@µ÷€A›ÑAÒN»¾TÛ`¿(‰>–AÈ#¾?ÁÙ@¦A™@Ð=£@".A™@6£•@&çǾ³zZ¿Ùư>".A™@6£•@¦A™@Ð=£@Ëä AÏ&@ê·@_‡Ô¾W¿Ñ®²>".A™@6£•@Ëä AÏ&@ê·@‚LAÏ&@r–¨@iÔß¾pæO¿èßÅ>‚LAÏ&@r–¨@Ëä AÏ&@ê·@ÓNAqQ@ Ë@Wì¾´L¿<ÕÆ>‚LAÏ&@r–¨@ÓNAqQ@ Ë@mö@qQ@P˜º@âö¾h(D¿@ÞÙ>mö@qQ@P˜º@ÓNAqQ@ Ë@Ì«ð@•"€@•Þ@££¿ÿþ?¿‰ßÙ>mö@qQ@P˜º@Ì«ð@•"€@•Þ@оà@•"€@ Ë@…ç¿RQ7¿6¥ì>оà@•"€@ Ë@Ì«ð@•"€@•Þ@”Þ@_„™@3Tï@ÊE ¿)Î2¿e²ë>оà@•"€@ Ë@”Þ@_„™@3Tï@£æÌ@_„™@ZbÛ@¤Î¿|s)¿Óþ>£æÌ@_„™@ZbÛ@”Þ@_„™@3Tï@£æÌ@’¹´@/Aÿ@\¿$¿74ü>£æÌ@_„™@ZbÛ@£æÌ@’¹´@/Aÿ@P˜º@’¹´@’ûé@è¿®¢¿?P˜º@’¹´@’ûé@£æÌ@’¹´@/Aÿ@‹F½@:›Ñ@]àA+"¿Æ¿Ÿ¦?P˜º@’¹´@’ûé@‹F½@:›Ñ@]àA î©@:›Ñ@ÐE÷@¼&!¿ô ¿ÓT? î©@:›Ñ@ÐE÷@‹F½@:›Ñ@]àA«F¯@ð@ _ AAA'¿Œ¿ás ? î©@:›Ñ@ÐE÷@«F¯@ð@ _ A®ÿš@ð@—A»~(¿*üô¾nÌ?®ÿš@ð@—A«F¯@ð@ _ Aû¢@.ÞARAêp.¿y±é¾x?®ÿš@ð@—Aû¢@.ÞARAœâ@.ÞA›ÑA{å.¿Š°Ò¾ün?œâ@.ÞA›ÑAû¢@.ÞARALu˜@rQA õAǦ4¿Uûƾ‡ª?œâ@.ÞA›ÑALu˜@rQA õAœ©‚@rQA.K A¿Q4¿i6¯¾]4?œ©‚@rQA.K ALu˜@rQA õAwÄ@=B)A5ýAàÙ9¿x'£¾½?œ©‚@rQA.K AwÄ@=B)A5ýAuÉr@=B)AUýA°»8¿¥Àо«#?uÉr@=B)AUýAwÄ@=B)A5ýAõˆ@P˜:A&Aµ>¿Ò|¾l}?uÉr@=B)AUýAõˆ@P˜:A&A‚Bd@P˜:AÅâAí<¿K¾J &?‚Bd@P˜:AÅâAõˆ@P˜:A&A¬„@×:LAk!A?A¿ë1¾"?‚Bd@P˜:AÅâA¬„@×:LAk!A+ÓY@×:LAZ÷A‘p>¿wÒþ½ð(?+ÓY@×:LAZ÷A¬„@×:LAk!Au@•^AõÈ"AC¿·̽f¿#?+ÓY@×:LAZ÷Au@•^AõÈ"A\ŠS@•^A8AB³?¿QL½¨/)?\ŠS@•^A8Au@•^AõÈ"A•"€@pAÐ=#A D¿Q̼ˆ$?\ŠS@•^A8A•"€@pAÐ=#AqQ@pA6£A)ã?¿QÌ<ÝU)?qQ@pA6£A•"€@pAÐ=#Au@µ÷€AõÈ"A0ÞC¿QL=ÜW$?qQ@pA6£Au@µ÷€AõÈ"A\ŠS@µ÷€A8Aš¦?ަk=F;L? |¾As©~Aš®AATè¾AüÏxA6kAA œÂAµ÷€Ai;AóÈ?aC=ó%J? œÂAµ÷€Ai;ATè¾AüÏxA6kAA›ÑÂApAº£;AÜW$?QL=0ÞC? œÂAµ÷€Ai;A›ÑÂApAº£;A{dÉAµ÷€AÅp/AÝU)?QÌ<)ã??{dÉAµ÷€AÅp/A›ÑÂApAº£;AèžÉApAµî/AY…2?QL=ò 7?{dÉAµ÷€AÅp/AèžÉApAµî/Ab¸ÏAµ÷€AõÈ"A 37?QÌqœH=q}Õ>س’Ahâ‹?.À6>[Þ‰A¨r*BV>”â‰Aá?ÖC}¿t">¦éÉ”â‰Aá?.À6>[Þ‰A¨r*Tä>Tí‡A_Ð*“Ý}¿Ï¤ó=ßÝJ=BV>”â‰Aá?Tä>Tí‡A_Ð*òŽ«=µ÷€A¡?…È~¿_ÓÀ=æ±Ë<òŽ«=µ÷€A¡?Tä>Tí‡A_Ð*è€=Dô€A@_*‰z¿2œp=Ä«Ë<òŽ«=µ÷€A¡?è€=Dô€A@_*ð)®;cvAEÕ*ù‘,¿ÄÿŸ=Ù¹ð@µ÷€A3Tï@Èæ @”â‰AÄQí@úÂ?µ÷€AŽ®Ï@¯ b¿wÒþ= »ç>úÂ?µ÷€AŽ®Ï@Èæ @”â‰AÄQí@ûuÑ?”â‰A$ðÍ@1h¿·Ì=T€Ñ>úÂ?µ÷€AŽ®Ï@ûuÑ?”â‰A$ðÍ@Q¸‰?µ÷€A“ß®@{j¿wÒþ=@LÅ>Q¸‰?µ÷€A“ß®@ûuÑ?”â‰A$ðÍ@P¯˜?”â‰A¯g­@Å^o¿·Ì=L6®>Q¸‰?µ÷€A“ß®@P¯˜?”â‰A¯g­@[Ü4?µ÷€A>@+Êp¿wÒþ=ÿ¡>[Ü4?µ÷€A>@P¯˜?”â‰A¯g­@¦•S?”â‰Aùæ‹@×5u¿·Ì=Ûò‰>[Ü4?µ÷€A>@¦•S?”â‰Aùæ‹@q}Õ>µ÷€AÔU@ )v¿wÒþ=M¤z>q}Õ>µ÷€AÔU@¦•S?”â‰Aùæ‹@R ?”â‰Að;S@P|??í>_“L?E¼Aƒ‡Aþ CAÃ?½AÔS„AïrBA­ûÁA”â‰A5‹9Aœ?Üß=±ÌI?­ûÁA”â‰A5‹9AÃ?½AÔS„AïrBA œÂAµ÷€Ai;AžB#?wÒþ=‚˜B?­ûÁA”â‰A5‹9A œÂAµ÷€Ai;A‡µÈA”â‰Aª÷-AX‰(?·Ì=??‡µÈA”â‰Aª÷-A œÂAµ÷€Ai;A{dÉAµ÷€AÅp/A‹X1?wÒþ=åÙ5?‡µÈA”â‰Aª÷-A{dÉAµ÷€AÅp/AÕûÎA”â‰Ak!A³V6?·Ì=ß1?ÕûÎA”â‰Ak!A{dÉAµ÷€AÅp/Ab¸ÏAµ÷€AõÈ"A‘p>?wÒþ=ð(?ÕûÎA”â‰Ak!Ab¸ÏAµ÷€AõÈ"A›ÅÔA”â‰AZ÷AC?·Ì=f¿#?›ÅÔA”â‰AZ÷Ab¸ÏAµ÷€AõÈ"A´ŽÕAµ÷€A8AôwJ?wÒþ=Tc?›ÅÔA”â‰AZ÷A´ŽÕAµ÷€A8A ÚA”â‰AѯAy]U?wÒþ=Ô ?'ÃÞA”â‰AÄQí@ ÚA”â‰AѯAßÚAµ÷€A›ÑAûÏN?·Ì=Wµ?ßÚAµ÷€A›ÑA ÚA”â‰AѯA´ŽÕAµ÷€A8A·ÎK?QL=&c?ßÚAµ÷€A›ÑA´ŽÕAµ÷€A8AÝÑÕApA6£A D?QÌ<ˆ$?ÝÑÕApA6£A´ŽÕAµ÷€A8AZ÷ÏApAÐ=#A)ã??Q̼ÝU)?ÝÑÕApA6£AZ÷ÏApAÐ=#Ab¸ÏA•^AõÈ"Aò 7?QL½Y…2?b¸ÏA•^AõÈ"AZ÷ÏApAÐ=#A{dÉA•^AÅp/Aß1?·̽³V6?b¸ÏA•^AõÈ"A{dÉA•^AÅp/A‡µÈA×:LAª÷-Að(?wÒþ½‘p>?‡µÈA×:LAª÷-A{dÉA•^AÅp/A­ûÁA×:LA5‹9A"?ë1¾?A?‡µÈA×:LAª÷-A­ûÁA×:LA5‹9AcñÀAP˜:A_ï6A„*?]G3¾÷íH?cñÀAP˜:A_ï6A­ûÁA×:LA5‹9A3ͺABEKA–õCAZh?aL¾ð°K?cñÀAP˜:A_ï6A3ͺABEKA–õCAQç¹AP˜:AYSAAîß ?Ù"5¾&9P?Qç¹AP˜:AYSAA3ͺABEKA–õCA…²ºA³×JAÿDAÅ¿ ?(0=¾ŠP?Qç¹AP˜:AYSAA…²ºA³×JAÿDA>¹AɘEAdêDAÙˆ¼¶º~¿ëÈ=PlAxÌ+=hâ‹?¯SmAxÌ+=á?2«jAòŽ+>„{ @$ s¼~¿T­ü=2«jAòŽ+>„{ @¯SmAxÌ+=á?¯SmAòŽ+>5®@F‘ˆ¼ˆ|¿áã0>2«jAòŽ+>„{ @¯SmAòŽ+>5®@PlA´À>ÔU@)¾¼,îz¿¥ŽJ>PlA´À>ÔU@¯SmAòŽ+>5®@pA´À>¿žU@«Àµ»Îx¿’x|>PlA´À>ÔU@pA´À>¿žU@pAµ™*?„{@jÁð;qqv¿è‰Š>pAµ™*?„{@pA´À>¿žU@XIuAµ™*?>@ ˆ<<¯r¿ÞÁ¢>pAµ™*?„{@XIuAµ™*?>@nvA?“ß®@!Ë =3”p¿(®>nvA?“ß®@XIuAµ™*?>@|}A?¯g­@H=|ëk¿ù1Å>nvA?“ß®@|}A?¯g­@$…AÈ#¾?$ðÍ@öU“=À^i¿»8Ï>$…AÈ#¾?$ðÍ@|}A?¯g­@õ•ƒAÈ#¾?ç Ë@4&º=%Öc¿¼Çä>$…AÈ#¾?$ðÍ@õ•ƒAÈ#¾?ç Ë@ìY…A™@’ûé@î¨ò=TÛ`¿\í>ìY…A™@’ûé@õ•ƒAÈ#¾?ç Ë@q¯‰A™@dVå@J>³zZ¿Hg?ìY…A™@’ûé@q¯‰A™@dVå@Ëì‹AÏ&@¾0A_1>W¿?Ëì‹AÏ&@¾0Aq¯‰A™@dVå@L²AÏ&@̳û@ØL>pæO¿S ?Ëì‹AÏ&@¾0AL²AÏ&@̳û@™U“AqQ@.K A¹Šp>³L¿œT?™U“AqQ@.K AL²AÏ&@̳û@pv˜AqQ@›ÑA“‡‡>g(D¿ã?™U“AqQ@.K Apv˜AqQ@›ÑAõi›A•"€@RA=·š>ÿþ?¿+¡?õi›A•"€@RApv˜AqQ@›ÑAtÏ A•"€@ _ A«>RQ7¿Zà?õi›A•"€@RAtÏ A•"€@ _ A­û£A_„™@ª\AP@¿>)Î2¿1E?­û£A_„™@ª\AtÏ A•"€@ _ Aš©A_„™@º\AeeÐ>|s)¿ #!?­û£A_„™@ª\Aš©A_„™@º\A¿Ù¬A’¹´@ûA¸å>$¿W ?¿Ù¬A’¹´@ûAš©A_„™@º\Aå~²A’¹´@سA$‡ö>¯¢¿š’"?¿Ù¬A’¹´@ûAå~²A’¹´@سAtѵA:›Ñ@ûAŸ¦?Æ¿+"?tѵA:›Ñ@ûAå~²A’¹´@سA.p»A:›Ñ@º\AÓT?ô ¿¼&!?tѵA:›Ñ@ûA.p»A:›Ñ@º\A…¯¾Að@ª\A?Œ¿‹J?…¯¾Að@ª\A.p»A:›Ñ@º\AU.ÄAð@ _ Aaù ?*üô¾xç?…¯¾Að@ª\AU.ÄAð@ _ AFQÝAP˜:A’ûé@XNÛA=B)AdVå@ÓgáAP˜:Aç Ë@{L_?K¾Cãä>FQÝAP˜:A’ûé@ÓgáAP˜:Aç Ë@ èâA×:LA$ðÍ@ØÎe?ë1¾SÏ> èâA×:LA$ðÍ@ÓgáAP˜:Aç Ë@ uæA×:LA¯g­@{j?wÒþ½@LÅ> èâA×:LA$ðÍ@ uæA×:LA¯g­@{dçA•^A“ß®@Å^o?·̽L6®>{dçA•^A“ß®@ uæA×:LA¯g­@YêA•^A>@ ^r?QL½/Ù¢>{dçA•^A“ß®@YêA•^A>@2«êApA„{@=[v?Q̼GžŠ>2«êApA„{@YêA•^A>@ÉýìApA¿žU@fx?QÌ2«êApA„{@ÉýìApA¿žU@ ªìAµ÷€AÔU@@œz?QL=w­J> ªìAµ÷€AÔU@ÉýìApA¿žU@ñSîAµ÷€A5®@Úz?·Ì=ÿ0> ªìAµ÷€AÔU@ñSîAµ÷€A5®@™UíA”â‰A„{ @t |?wÒþ=5Ôü=™UíA”â‰A„{ @ñSîAµ÷€A5®@ñSîA”â‰Aá?ÆÙz?ë1>ê É=™UíA”â‰A„{ @ñSîA”â‰Aá? ªìAس’Ahâ‹?×>S¼¡®¿?E=¨¶jAxÌ+=w‰?pABÏ(PlAxÌ+=hâ‹?¸%ôº¶º~¿BÃË=â¨nAxÌ+=¡?pAxÌ+=V{?pAòŽ+>¡@Hws;~¿fbþ=pAòŽ+>¡@pAxÌ+=V{?P¬rAòŽ+>5®@Õ½<ˆ|¿pu1>pAòŽ+>¡@P¬rAòŽ+>5®@¯ýsA´À>ÔU@!~¦<,îz¿TµI>¯ýsA´À>ÔU@P¬rAòŽ+>5®@¨õwA´À>ð;S@Ñ =Îx¿dz>¯ýsA´À>ÔU@¨õwA´À>ð;S@‹zAµ™*?ùæ‹@yñB=qqv¿?nˆ>‹zAµ™*?ùæ‹@¨õwA´À>ð;S@νAµ™*?kï‰@OZ‚=<¯r¿¯Ÿ>‹zAµ™*?ùæ‹@νAµ™*?kï‰@jÁA?Š÷ª@–è­=3”p¿ ˆ©>jÁA?Š÷ª@νAµ™*?kï‰@ì„A?¢’§@ÐxØ=|ëk¿ÿC¿>jÁA?Š÷ª@ì„A?¢’§@ÄX‡AÈ#¾?øÇ@Y>À^i¿ÓjÇ>ÄX‡AÈ#¾?øÇ@ì„A?¢’§@™‹AÈ#¾? ÞÁ@; >%Öc¿õIÛ>ÄX‡AÈ#¾?øÇ@™‹AÈ#¾? ÞÁ@£ëA™@âhß@b§>>TÛ`¿ºká>£ëA™@âhß@™‹AÈ#¾? ÞÁ@t’A™@‡;Ø@T\>³zZ¿® ó>£ëA™@âhß@t’A™@‡;Ø@pT•AÏ&@Âó@VÒ}>W¿ÿõö>pT•AÏ&@Âó@t’A™@‡;Ø@™Ì™AÏ&@ò*ê@Q>pæO¿â?pT•AÏ&@Âó@™Ì™AÏ&@ò*ê@ÍhAqQ@—A©Z¡>³L¿/Ç?ÍhAqQ@—A™Ì™AÏ&@ò*ê@œ%¢AqQ@ÐE÷@ܱ²>h(D¿á ?ÍhAqQ@—Aœ%¢AqQ@ÐE÷@…ú¥A•"€@]àAYãÅ>ÿþ?¿åj ?…ú¥A•"€@]àAœ%¢AqQ@ÐE÷@ÃãªA•"€@/Aÿ@dø×>RQ7¿I_?…ú¥A•"€@]àAÃãªA•"€@/Aÿ@–Ø®A_„™@®Œ Ae²ë>)Î2¿ÊE ?–Ø®A_„™@®Œ AÃãªA•"€@/Aÿ@ Õ³A_„™@µ÷AÓþ>|s)¿¤Î?–Ø®A_„™@®Œ A Õ³A_„™@µ÷ALзA’¹´@®Œ AÑ÷?$¿sG ?LзA’¹´@®Œ A Õ³A_„™@µ÷AWƼA’¹´@/Aÿ@ ?®¢¿¥b?LзA’¹´@®Œ AWƼA’¹´@/Aÿ@]®ÀA:›Ñ@]àA.à?Æ¿¼o ?]®ÀA:›Ñ@]àAWƼA’¹´@/Aÿ@~„ÅA:›Ñ@ÐE÷@Â$?ô ¿S# ?]®ÀA:›Ñ@]àA~„ÅA:›Ñ@ÐE÷@@ÉAð@—A &.?Œ¿ÎÎ?@ÉAð@—A~„ÅA:›Ñ@ÐE÷@ÝÍAð@ò*ê@À6?*üô¾ä(?@ÉAð@—AÝÍAð@ò*ê@qTÑA.ÞAÂó@a??z±é¾‹ ÷>qTÑA.ÞAÂó@ÝÍAð@ò*ê@¥¡ÕA.ÞA‡;Ø@ÆG?Š°Ò¾\6ó>qTÑA.ÞAÂó@¥¡ÕA.ÞA‡;Ø@?½ØArQAâhß@q.O?Uûƾúá>?½ØArQAâhß@¥¡ÕA.ÞA‡;Ø@¤ÜArQA ÞÁ@ÏV?i6¯¾’aÛ>?½ØArQAâhß@¤ÜArQA ÞÁ@PßA=B)AøÇ@º3]?x'£¾÷Ç>PßA=B)AøÇ@¤ÜArQA ÞÁ@û½âA=B)A¢’§@>c?¤Àо«[¿>PßA=B)AøÇ@û½âA=B)A¢’§@xçäAP˜:AŠ÷ª@« i?Ò|¾7ž©>xçäAP˜:AŠ÷ª@û½âA=B)A¢’§@3ËçAP˜:Akï‰@–Üm?K¾óÄŸ>xçäAP˜:AŠ÷ª@3ËçAP˜:Akï‰@RcéA×:LAùæ‹@ø°r?ë1¾µˆ>RcéA×:LAùæ‹@3ËçAP˜:Akï‰@E¯ëA×:LAð;S@ )v?wÒþ½M¤z>RcéA×:LAùæ‹@E¯ëA×:LAð;S@ ªìA•^AÔU@Ú­y?·̽×ÓI> ªìA•^AÔU@E¯ëA×:LAð;S@ñSîA•^A5®@VÌ{?QL½Ò1> ªìA•^AÔU@ñSîA•^A5®@â¨îApA¡@Oï}?Q̼7Šþ=â¨îApA¡@ñSîA•^A5®@ªïApAV{?ï¥~?QÌâ¨îApA¡@ñSîAµ÷€A5®@ÉýìApA¿žU@ÖØz?Q̼ÒJ>â¨îApA¡@ÉýìApA¿žU@ ªìA•^AÔU@ØÆw?QL½9V|> ªìA•^AÔU@ÉýìApA¿žU@YêA•^A>@×5u?·̽Ûò‰> ªìA•^AÔU@YêA•^A>@RcéA×:LAùæ‹@+Êp?wÒþ½ÿ¡>RcéA×:LAùæ‹@YêA•^A>@ uæA×:LA¯g­@~él?ë1¾Íe¬>RcéA×:LAùæ‹@ uæA×:LA¯g­@xçäAP˜:AŠ÷ª@ :g?K¾šßÂ>xçäAP˜:AŠ÷ª@ uæA×:LA¯g­@ÓgáAP˜:Aç Ë@Q#b?Ò|¾®üË>xçäAP˜:AŠ÷ª@ÓgáAP˜:Aç Ë@PßA=B)AøÇ@CM[?¥ÀоrÃà>PßA=B)AøÇ@ÓgáAP˜:Aç Ë@XNÛA=B)AdVå@!U?x'£¾¾è>PßA=B)AøÇ@XNÛA=B)AdVå@?½ØArQAâhß@HM?i6¯¾„Ãú>?½ØArQAâhß@XNÛA=B)AdVå@}KÔArQA̳û@ -F?Uûƾ°×ÿ>?½ØArQAâhß@}KÔArQA̳û@qTÑA.ÞAÂó@Ìz=?‰°Ò¾Ž%?qTÑA.ÞAÂó@}KÔArQA̳û@X‡ÌA.ÞA›ÑA5?y±é¾œy ?qTÑA.ÞAÂó@X‡ÌA.ÞA›ÑA@ÉAð@—AÞ?,?*üô¾’o?@ÉAð@—AX‡ÌA.ÞA›ÑAU.ÄAð@ _ AÜÏ#?Œ¿t?@ÉAð@—AU.ÄAð@ _ A]®ÀA:›Ñ@]àAèù?ô ¿r?]®ÀA:›Ñ@]àAU.ÄAð@ _ A.p»A:›Ñ@º\AQ+?Å¿e³?]®ÀA:›Ñ@]àA.p»A:›Ñ@º\ALзA’¹´@®Œ A?®¢¿è?LзA’¹´@®Œ A.p»A:›Ñ@º\Aå~²A’¹´@سA74ü>$¿\?LзA’¹´@®Œ Aå~²A’¹´@سA–Ø®A_„™@®Œ A›åç>|s)¿Jæ?–Ø®A_„™@®Œ Aå~²A’¹´@سAš©A_„™@º\A˜Ö>)Î2¿í¯?–Ø®A_„™@®Œ Aš©A_„™@º\A…ú¥A•"€@]àAaÂ>RQ7¿9 ?…ú¥A•"€@]àAš©A_„™@º\AtÏ A•"€@ _ AÙ˰>ÿþ?¿jm?…ú¥A•"€@]àAtÏ A•"€@ _ AÍhAqQ@—A>h(D¿Pg?ÍhAqQ@—AtÏ A•"€@ _ Apv˜AqQ@›ÑA5>´L¿Gp ?ÍhAqQ@—Apv˜AqQ@›ÑApT•AÏ&@Âó@ 7v>pæO¿ç?pT•AÏ&@Âó@pv˜AqQ@›ÑAL²AÏ&@̳û@y3X>W¿#Áÿ>pT•AÏ&@Âó@L²AÏ&@̳û@£ëA™@âhß@W 7>³zZ¿«ú>£ëA™@âhß@L²AÏ&@̳û@q¯‰A™@dVå@çm>TÛ`¿êç>£ëA™@âhß@q¯‰A™@dVå@ÄX‡AÈ#¾?øÇ@ þ=%Öc¿«©à>ÄX‡AÈ#¾?øÇ@q¯‰A™@dVå@õ•ƒAÈ#¾?ç Ë@×ÝÐ=À^i¿ºãË>ÄX‡AÈ#¾?øÇ@õ•ƒAÈ#¾?ç Ë@jÁA?Š÷ª@„±ž=|ëk¿iÆÂ>jÁA?Š÷ª@õ•ƒAÈ#¾?ç Ë@|}A?¯g­@à}u=3”p¿rN¬>jÁA?Š÷ª@|}A?¯g­@‹zAµ™*?ùæ‹@Õ‚$=<¯r¿2¬¡>‹zAµ™*?ùæ‹@|}A?¯g­@XIuAµ™*?>@1«á‹zAµ™*?ùæ‹@XIuAµ™*?>@¯ýsA´À>ÔU@¯@S<Îx¿0|>¯ýsA´À>ÔU@XIuAµ™*?>@pA´À>¿žU@3Àµ;,îz¿³J>¯ýsA´À>ÔU@pA´À>¿žU@pAòŽ+>¡@µws»ˆ|¿×«1>pAòŽ+>¡@pA´À>¿žU@¯SmAòŽ+>5®@&Ŷ»~¿Û=þ=pAòŽ+>¡@¯SmAòŽ+>5®@â¨nAxÌ+=¡?2@¼¶º~¿kèÊ=â¨nAxÌ+=¡?¯SmAòŽ+>5®@¯SmAxÌ+=á?¿Ä¶»¡®¿²ÃJ=â¨nAxÌ+=¡?¯SmAxÌ+=á?pABÏ(ŽÃ'¿Z²>ƒ=?vP©@yâ‰A×f3A)ý©@žAŠA)Ž3Aã)@”â‰Aª÷-A‚7)¿3ã2>ÛÑ:?ã)@”â‰Aª÷-A)ý©@žAŠA)Ž3A䳡@س’A~…+AÖ 0¿ë1>kt4?ã)@”â‰Aª÷-A䳡@س’A~…+A¬„@”â‰Ak!A2¥3¿K>‹-/?¬„@”â‰Ak!A䳡@س’A~…+Aõˆ@س’A&A =¿ë1>?Ë&?¬„@”â‰Ak!Aõˆ@س’A&A+ÓY@”â‰AZ÷Aé;@¿K>^C!?+ÓY@”â‰AZ÷Aõˆ@س’A&A‚Bd@س’AÅâA¬úH¿ë1>H3?+ÓY@”â‰AZ÷A‚Bd@س’AÅâA‡«/@”â‰AѯAk¿K¿K>Sr?‡«/@”â‰AѯA‚Bd@س’AÅâAš²:@س’A¡ÎA‰ÊS¿ë1>kÁ?‡«/@”â‰AѯAš²:@س’A¡ÎAÈæ @”â‰AÄQí@9V¿K>Ï?Èæ @”â‰AÄQí@š²:@س’A¡ÎAÌu@س’A’ûé@1k]¿ë1>Šñ>Èæ @”â‰AÄQí@Ìu@س’A’ûé@ûuÑ?”â‰A$ðÍ@{L_¿K>Cãä>ûuÑ?”â‰A$ðÍ@Ìu@س’A’ûé@Ï‚é?س’Aç Ë@ØÎe¿ë1>SÏ>ûuÑ?”â‰A$ðÍ@Ï‚é?س’Aç Ë@P¯˜?”â‰A¯g­@ :g¿K>šßÂ>P¯˜?”â‰A¯g­@Ï‚é?س’Aç Ë@|ˆ±?س’AŠ÷ª@~él¿ë1>Íe¬>P¯˜?”â‰A¯g­@|ˆ±?س’AŠ÷ª@¦•S?”â‰Aùæ‹@–Üm¿K>óÄŸ>¦•S?”â‰Aùæ‹@|ˆ±?س’AŠ÷ª@ËLƒ?س’Akï‰@ø°r¿ë1>µˆ>¦•S?”â‰Aùæ‹@ËLƒ?س’Akï‰@R ?”â‰Að;S@•*s¿K>"‹w>R ?”â‰Að;S@ËLƒ?س’Akï‰@È#>?س’A£CP@Èq ?ä F>¬æP?æl¸AãŽA*jEAºµ¹A)hŒA¡DAQç¹Aس’AYSAAå) ?h;:>ìlP?Qç¹Aس’AYSAAºµ¹A)hŒA¡DAVͺAÖTŠApõCAi?ýIL>Û±K?Qç¹Aس’AYSAAVͺAÖTŠApõCAcñÀAس’A_ï6A4+?¶/3>ÂîH?cñÀAس’A_ï6AVͺAÖTŠApõCA­ûÁA”â‰A5‹9A^C!?K>é;@?cñÀAس’A_ï6A­ûÁA”â‰A5‹9A“ÇAس’A~…+A?Ë&?ë1> =?“ÇAس’A~…+A­ûÁA”â‰A5‹9A‡µÈA”â‰Aª÷-A‹-/?K>2¥3?“ÇAس’A~…+A‡µÈA”â‰Aª÷-A¾ÂÍAس’A&Akt4?ë1>Ö 0?¾ÂÍAس’A&A‡µÈA”â‰Aª÷-AÕûÎA”â‰Ak!AíJ &?¾ÂÍAس’A&AÕûÎA”â‰Ak!A¯wÓAس’AÅâA?A?ë1>"?¯wÓAس’AÅâAÕûÎA”â‰Ak!A›ÅÔA”â‰AZ÷AýþG?K>§‡?¯wÓAس’AÅâA›ÅÔA”â‰AZ÷A­©ØAس’A¡ÎAš­L?ë1><0?­©ØAس’A¡ÎA›ÅÔA”â‰AZ÷A ÚA”â‰AѯA»ÂR?K>)?­©ØAس’A¡ÎA ÚA”â‰AѯAFQÝAس’A’ûé@ñW?ë1>3{?FQÝAس’A’ûé@ ÚA”â‰AѯA'ÃÞA”â‰AÄQí@½X\?K>$ð>FQÝAس’A’ûé@'ÃÞA”â‰AÄQí@ÓgáAس’Aç Ë@§qw¿‰í€>‡0E=[Ü4?á^›Aw‰?kÛ>¬z”A|r*q}Õ>س’Ahâ‹? 4y¿>i>¸Çس’Ahâ‹?kÛ>¬z”A|r*ÄÊÅ>䯒AýÈ*/×z¿ K>q0ÇØ³’Ahâ‹?ÄÊÅ>䯒AýÈ*.À6>[Þ‰A¨r*wL¿¦c>×9D?ñp¿@n’AY\8AÎkÀ@ij’AŒ“8At:¼@س’A_ï6Aï¿®|>„ŒB?t:¼@س’A_ï6AÎkÀ@ij’AŒ“8AVÂ@á^›A¢M3Al}¿Ò|>µ>?t:¼@س’A_ï6AVÂ@á^›A¢M3A䳡@س’A~…+A«#¿¥ÀŠ>°»8?䳡@س’A~…+AVÂ@á^›A¢M3A•¨@á^›AÄ(AS>-¿Ò|>1?䳡@س’A~…+A•¨@á^›AÄ(Aõˆ@س’A&A o0¿¤ÀŠ>~,?õˆ@س’A&A•¨@á^›AÄ(AwÄ@á^›A5ýA6:¿Ò|>$?õˆ@س’A&AwÄ@á^›A5ýA‚Bd@س’AÅâAÒË<¿¥ÀŠ>]?‚Bd@س’AÅâAwÄ@á^›A5ýAuÉr@á^›AUýAÃÅE¿Ò|>»Á?‚Bd@س’AÅâAuÉr@á^›AUýAš²:@س’A¡ÎANH¿¥ÀŠ>ÏÏ?š²:@س’A¡ÎAuÉr@á^›AUýAÇ J@á^›A¾0A,iP¿Ò|>öŽ?š²:@س’A¡ÎAÇ J@á^›A¾0AÌu@س’A’ûé@QJR¿¤ÀŠ>¸t?Ìu@س’A’ûé@Ç J@á^›A¾0A:%@á^›AdVå@6âY¿Ò|>7í>Ìu@س’A’ûé@:%@á^›AdVå@Ï‚é?س’Aç Ë@CM[¿¥ÀŠ>rÃà>Ï‚é?س’Aç Ë@:%@á^›AdVå@ @á^›AøÇ@Q#b¿Ò|>®üË>Ï‚é?س’Aç Ë@ @á^›AøÇ@|ˆ±?س’AŠ÷ª@>c¿¤ÀŠ>«[¿>|ˆ±?س’AŠ÷ª@ @á^›AøÇ@J Ô?á^›A¢’§@« i¿Ò|>7ž©>|ˆ±?س’AŠ÷ª@J Ô?á^›A¢’§@ËLƒ?س’Akï‰@ši¿¥ÀŠ>ïáœ>ËLƒ?س’Akï‰@J Ô?á^›A¢’§@Ϧ?á^›Ac2‡@CÐn¿Ò|>éL†>ËLƒ?س’Akï‰@Ϧ?á^›Ac2‡@È#>?س’A£CP@Ïn¿¥ÀŠ>2s>È#>?س’A£CP@Ϧ?á^›Ac2‡@ËLƒ?á^›A+!L@å?nà‚>UíQ?ÿIJA™]•AÖHA'Ó´A„5“A†™GA_˜¸Aá^›AÎ|=A`+?B-~>#BO?_˜¸Aá^›AÎ|=A'Ó´A„5“A†™GAQç¹Aس’AYSAAÏÏ?¥ÀŠ>NH?_˜¸Aá^›AÎ|=AQç¹Aس’AYSAA«~¿Aá^›A¢M3A»Á?Ò|>ÃÅE?«~¿Aá^›A¢M3AQç¹Aس’AYSAAcñÀAس’A_ï6A]?¥ÀŠ>ÒË6:?›þÅAá^›AÄ(AcñÀAس’A_ï6A“ÇAس’A~…+A~,?¤ÀŠ> o0?›þÅAá^›AÄ(A“ÇAس’A~…+AâÌAá^›A5ýA1?Ò|>S>-?âÌAá^›A5ýA“ÇAس’A~…+A¾ÂÍAس’A&A°»8?¥ÀŠ>«#?âÌAá^›A5ýA¾ÂÍAس’A&AѦÑAá^›AUýAµ>?Ò|>l}?ѦÑAá^›AUýA¾ÂÍAس’A&A¯wÓAس’AÅâAhgD?¥ÀŠ>ÑÒ?ѦÑAá^›AUýA¯wÓAس’AÅâAg¾ÖAá^›A¾0AàeI?Ò|>-Ø?g¾ÖAá^›A¾0A¯wÓAس’AÅâA­©ØAس’A¡ÎAñùN?¥ÀŠ>åº?g¾ÖAá^›A¾0A­©ØAس’A¡ÎAXNÛAá^›AdVå@·¨S?Ò|>’c?XNÛAá^›AdVå@­©ØAس’A¡ÎAFQÝAس’A’ûé@)dX?¤ÀŠ> Çë>XNÛAá^›AdVå@FQÝAس’A’ûé@PßAá^›AøÇ@ˆ¼\?Ò|>qkâ>PßAá^›AøÇ@FQÝAس’A’ûé@ÓgáAس’Aç Ë@”˜`?¤ÀŠ>ÁÆÊ>PßAá^›AøÇ@ÓgáAس’Aç Ë@û½âAá^›A¢’§@²à}?·">(Ê<žïA“A@\·©ÜîA[݉A¥-µ©ñSîA”â‰Aá?(’|?–%>ºïÉ<ñSîA”â‰Aá?ÜîA[݉A¥-µ©ìíA<ŽA1´©§:{?gF>>?”H=ñSîA”â‰Aá?ìíA<ŽA1´© ªìAس’Ahâ‹?$3z?þNW>ÈÇ< ªìAس’Ahâ‹?ìíA<ŽA1´©ñÖìAZª’A…汩K!x?û·z>È*Ç< ªìAس’Ahâ‹?ñÖìAZª’A…汩äêAž¤šAØ®©>ļ¶º~¿ÎÅ=¨¶jAxÌ+=w‰?PlAxÌ+=hâ‹?W hAòŽ+>E~ @ÏÀļ~¿³ù=W hAòŽ+>E~ @PlAxÌ+=hâ‹?2«jAòŽ+>„{ @ðñ¼ˆ|¿­/>W hAòŽ+>E~ @2«jAòŽ+>„{ @W hA´À>ð;S@–Áļ,îz¿6HI>W hA´À>ð;S@2«jAòŽ+>„{ @PlA´À>ÔU@ ?ļÎx¿/W{>W hA´À>ð;S@PlA´À>ÔU@¨¶jAµ™*?>@PAS¼rqv¿³nŠ>¨¶jAµ™*?>@PlA´À>ÔU@pAµ™*?„{@9Âð»<¯r¿ˆî¢>¨¶jAµ™*?>@pAµ™*?„{@pA?]¯@†5<3”p¿™ô®>pA?]¯@pAµ™*?„{@nvA?“ß®@]5£<|ëk¿7ƒÆ>pA?]¯@nvA?“ß®@$ÈwAÈ#¾?Ž®Ï@Lö)=À^i¿eÑ>$ÈwAÈ#¾?Ž®Ï@nvA?“ß®@$…AÈ#¾?$ðÍ@»{j=%Öc¿Džç>$ÈwAÈ#¾?Ž®Ï@$…AÈ#¾?$ðÍ@Jñ€A™@ÄQí@§«=TÛ`¿4ûð>Jñ€A™@ÄQí@$…AÈ#¾?$ðÍ@ìY…A™@’ûé@‘Ô=³zZ¿3Á?Jñ€A™@ÄQí@ìY…A™@’ûé@Ä ‡AÏ&@¡ÎAÂŒ >W¿4?Ä ‡AÏ&@¡ÎAìY…A™@’ûé@Ëì‹AÏ&@¾0A[S">pæO¿UÂ?Ä ‡AÏ&@¡ÎAËì‹AÏ&@¾0A  ŽAqQ@UýAåRE>³L¿+m?  ŽAqQ@UýAËì‹AÏ&@¾0A™U“AqQ@.K A=a>h(D¿ˆ?  ŽAqQ@UýA™U“AqQ@.K AÄÑ•A•"€@ õA"Ń>ÿþ?¿Eý?ÄÑ•A•"€@ õA™U“AqQ@.K Aõi›A•"€@RA¡1“>RQ7¿äÔ"?ÄÑ•A•"€@ õAõi›A•"€@RAÈ*žA_„™@y‚A:\§>)Î2¿¼ú"?È*žA_„™@y‚Aõi›A•"€@RA­û£A_„™@ª\AÕº·>|s)¿y(?È*žA_„™@y‚A­û£A_„™@ª\Aîè¦A’¹´@)€"AJ£Ì>$¿‚='?îè¦A’¹´@)€"A­û£A_„™@ª\A¿Ù¬A’¹´@ûAXŠÝ>¯¢¿aT+?îè¦A’¹´@)€"A¿Ù¬A’¹´@ûA8Ú¯A:›Ñ@G×#A+Åò>Æ¿­(?8Ú¯A:›Ñ@G×#A¿Ù¬A’¹´@ûAtѵA:›Ñ@ûA÷ã?ô ¿NV+?8Ú¯A:›Ñ@G×#AtѵA:›Ñ@ûAƒË¸Að@)€"Aás ?Œ¿AA'?ƒË¸Að@)€"AtѵA:›Ñ@ûA…¯¾Að@ª\AnÌ?*üô¾»~(?ƒË¸Að@)€"A…¯¾Að@ª\A©‰ÁA.ÞAy‚Aq?y±é¾õ#?©‰ÁA.ÞAy‚A…¯¾Að@ª\A'ÃÞA×:LAÄQí@FQÝAP˜:A’ûé@ èâA×:LA$ðÍ@¯ b?wÒþ½ »ç>'ÃÞA×:LAÄQí@ èâA×:LA$ðÍ@_ÐãA•^AŽ®Ï@1h?·̽T€Ñ>_ÐãA•^AŽ®Ï@ èâA×:LA$ðÍ@{dçA•^A“ß®@i›k?QL½žÆ>_ÐãA•^AŽ®Ï@{dçA•^A“ß®@q´çApA]¯@ò|p?Q̼ ¯>q´çApA]¯@{dçA•^A“ß®@2«êApA„{@ª—r?QÌ<ò£>q´çApA]¯@2«êApA„{@YêAµ÷€A>@v?QL=þ‚Š>YêAµ÷€A>@2«êApA„{@ ªìAµ÷€AÔU@uØv?·Ì=Ž|{>YêAµ÷€A>@ ªìAµ÷€AÔU@E¯ëA”â‰Að;S@nøx?wÒþ=dfI>E¯ëA”â‰Að;S@ ªìAµ÷€AÔU@™UíA”â‰A„{ @tEx?ë1>9/>E¯ëA”â‰Að;S@™UíA”â‰A„{ @E¯ëAس’AE~ @t÷x?K>Øù=E¯ëAس’AE~ @™UíA”â‰A„{ @ ªìAس’Ahâ‹?…Öv?Ò|>…ëÅ=E¯ëAس’AE~ @ ªìAس’Ahâ‹?YêAá^›Aw‰?Bv?µ‰>Â2E=YêAá^›Aw‰? ªìAس’Ahâ‹?äêAž¤šAØ®©i²t?šö•>ÖÃ<YêAá^›Aw‰?äêAž¤šAØ®©¢êA’[›A)­©E–k¿6úÆ>;=úÂ?é¬AÊE?-©†?0Ê£A•u *Q¸‰?G×£A=…?0o¿Ëµ¶>‚¾Î¬@=Q¸‰?G×£A=…?¶c?kµ Ax *[Ü4?á^›Aw‰?hSs¿Ø¢ž>–'Ã<[Ü4?á^›Aw‰?¶c?kµ Ax *µ¼/?|R›ABb *Kýu¿f@>/Ã<[Ü4?á^›Aw‰?µ¼/?|R›ABb *kÛ>¬z”A|r*Q¿‹#–>â»L?Aæ@)КA¢¸@A·ê@Õ^›Aö‰AAƒžÝ@á^›AÎ|=Aþƒ¿k£>³øI?ƒžÝ@á^›AÎ|=A·ê@Õ^›Aö‰AA3Lä@G×£Aú–8A° ¿x'£>ŠýD?ƒžÝ@á^›AÎ|=A3Lä@G×£Aú–8AVÂ@á^›A¢M3A»H¿i6¯>d¶??VÂ@á^›A¢M3A3Lä@G×£Aú–8A£iÉ@G×£A2«.A½¿x'£>àÙ9?VÂ@á^›A¢M3A£iÉ@G×£A2«.A•¨@á^›AÄ(A]4¿i6¯>¿Q4?•¨@á^›AÄ(A£iÉ@G×£A2«.Aë°@G×£AZÅ#AŽw)¿x'£>$¬-?•¨@á^›AÄ(Aë°@G×£AZÅ#AwÄ@á^›A5ýA<,¿h6¯>ðê'?wÄ@á^›A5ýAë°@G×£AZÅ#ALu˜@G×£A õAÂø5¿x'£>Ã… ?wÄ@á^›A5ýALu˜@G×£A õAuÉr@á^›AUýA3M8¿i6¯>¼“?uÉr@á^›AUýALu˜@G×£A õAœ©‚@G×£A.K ApuA¿x'£>“y?uÉr@á^›AUýAœ©‚@G×£A.K AÇ J@á^›A¾0AxVC¿h6¯>:_ ?Ç J@á^›A¾0Aœ©‚@G×£A.K A¤]@G×£A̳û@'ÝK¿x'£>®›?Ç J@á^›A¾0A¤]@G×£A̳û@:%@á^›AdVå@HM¿i6¯>„Ãú>:%@á^›AdVå@¤]@G×£A̳û@:@G×£Aâhß@!U¿x'£>¾è>:%@á^›AdVå@:@G×£Aâhß@ @á^›AøÇ@ÏV¿i6¯>’aÛ> @á^›AøÇ@:@G×£Aâhß@÷Û@G×£A ÞÁ@º3]¿x'£>÷Ç> @á^›AøÇ@÷Û@G×£A ÞÁ@J Ô?á^›A¢’§@ ­]¿i6¯>‹Åº>J Ô?á^›A¢’§@÷Û@G×£A ÞÁ@•"@G×£AÐ=£@Ä d¿x'£>ã¥>J Ô?á^›A¢’§@•"@G×£AÐ=£@Ϧ?á^›Ac2‡@ëd¿i6¯>™>Ϧ?á^›Ac2‡@•"@G×£AÐ=£@J Ô?G×£A̳ƒ@U™i¿x'£>©Wƒ>Ϧ?á^›Ac2‡@J Ô?G×£A̳ƒ@ËLƒ?á^›A+!L@Si¿i6¯>û6m>ËLƒ?á^›A+!L@J Ô?G×£A̳ƒ@|ˆ±?G×£AuÚF@üïÜ>Ä"¥>€¬W?O¨©A^œA¹:NAo«©AÓœAç8NA8Ú¯AG×£A~zAAxáç>1$¤>ˆùT?8Ú¯AG×£A~zAAo«©AÓœAç8NA™U±Aá^›A±œFA„Ãú>i6¯>HM?8Ú¯AG×£A~zAA™U±Aá^›A±œFAóì¶AG×£Aú–8A®›?x'£>'ÝK?óì¶AG×£Aú–8A™U±Aá^›A±œFA_˜¸Aá^›AÎ|=A:_ ?h6¯>xVC?óì¶AG×£Aú–8A_˜¸Aá^›AÎ|=A—¥½AG×£A2«.A“y?x'£>puA?—¥½AG×£A2«.A_˜¸Aá^›AÎ|=A«~¿Aá^›A¢M3A¼“?i6¯>3M8?—¥½AG×£A2«.A«~¿Aá^›A¢M3A„úÃAG×£AZÅ#AÃ… ?x'£>Âø5?„úÃAG×£AZÅ#A«~¿Aá^›A¢M3A›þÅAá^›AÄ(Aðê'?h6¯><,?„úÃAG×£AZÅ#A›þÅAá^›AÄ(A­âÉAG×£A õA$¬-?x'£>Žw)?­âÉAG×£A õA›þÅAá^›AÄ(AâÌAá^›A5ýA¿Q4?i6¯>]4?­âÉAG×£A õAâÌAá^›A5ýA™UÏAG×£A.K AàÙ9?x'£>½?™UÏAG×£A.K AâÌAá^›A5ýAѦÑAá^›AUýAd¶??i6¯>»H?™UÏAG×£A.K AѦÑAá^›AUýA}KÔAG×£A̳û@ŠýD?x'£>° ?}KÔAG×£A̳û@ѦÑAá^›AUýAg¾ÖAá^›A¾0A“J?i6¯>?}KÔAG×£A̳û@g¾ÖAá^›A¾0A?½ØAG×£Aâhß@.O?x'£>%ý>?½ØAG×£Aâhß@g¾ÖAá^›A¾0AXNÛAá^›AdVå@…9S?i6¯> -æ>?½ØAG×£Aâhß@XNÛAá^›AdVå@¤ÜAG×£A ÞÁ@nèW?x'£>•~Ý>¤ÜAG×£A ÞÁ@XNÛAá^›AdVå@PßAá^›AøÇ@<[?i6¯>…öÅ>¤ÜAG×£A ÞÁ@PßAá^›AøÇ@­ûßAG×£AÐ=£@‘”_?w'£>›¼>­ûßAG×£AÐ=£@PßAá^›AøÇ@û½âAá^›A¢’§@ºb?h6¯>¤¤>­ûßAG×£AÐ=£@û½âAá^›A¢’§@û½âAG×£A̳ƒ@щg?i6¯>Åf‚>xçäAG×£AuÚF@û½âAG×£A̳ƒ@“åAá^›Ac2‡@Ÿf?x'£>g©š>“åAá^›Ac2‡@û½âAG×£A̳ƒ@û½âAá^›A¢’§@t‹g?¥ÀŠ>(¤¨>“åAá^›Ac2‡@û½âAá^›A¢’§@xçäAس’AŠ÷ª@T”d?Ò|>˜ËÀ>xçäAس’AŠ÷ª@û½âAá^›A¢’§@ÓgáAس’Aç Ë@H³d?K>qtÎ>xçäAس’AŠ÷ª@ÓgáAس’Aç Ë@ èâA”â‰A$ðÍ@QT`?ë1>׿> èâA”â‰A$ðÍ@ÓgáAس’Aç Ë@'ÃÞA”â‰AÄQí@‡_?wÒþ=/ÿò> èâA”â‰A$ðÍ@'ÃÞA”â‰AÄQí@é¡ßAµ÷€A3Tï@ÝXY?·Ì=bÖ?é¡ßAµ÷€A3Tï@'ÃÞA”â‰AÄQí@ßÚAµ÷€A›ÑAeÆV?QL=¹ ?é¡ßAµ÷€A3Tï@ßÚAµ÷€A›ÑA&ÛApAc2AíÉO?QÌ?“ÇAP˜:A~…+AcñÀAP˜:A_ï6A«~¿A=B)A¢M3AÑÒ?¥ÀоhgD?«~¿A=B)A¢M3AcñÀAP˜:A_ï6A_˜¸A=B)AÎ|=A° ?x'£¾ŠýD?«~¿A=B)A¢M3A_˜¸A=B)AÎ|=Aóì¶ArQAú–8A?i6¯¾“J?óì¶ArQAú–8A_˜¸A=B)AÎ|=A8Ú¯ArQA~zAAIö>Uûƾ=I?óì¶ArQAú–8A8Ú¯ArQA~zAAá®A.ÞAKC;ArIß>‰°Ò¾GàL?á®A.ÞAKC;A8Ú¯ArQA~zAAîè¦A.ÞAœÑBA½õÏ>y±é¾ï¨J?á®A.ÞAKC;Aîè¦A.ÞAœÑBA,¥Að@KC;AÎ ¹>*üô¾RÞL?,¥Að@KC;Aîè¦A.ÞAœÑBA¥÷Að@~zAA´Ó©>Œ¿09I?,¥Að@KC;A¥÷Að@~zAA9œA:›Ñ@ú–8A<“>ô ¿ÐJ?9œA:›Ñ@ú–8A¥÷Að@~zAA~9•A:›Ñ@Î|=AVŒ„>Å¿öD?9œA:›Ñ@ú–8A~9•A:›Ñ@Î|=Ad§“A’¹´@¢M3Ae]>¯¢¿6^D?d§“A’¹´@¢M3A~9•A:›Ñ@Î|=AzàŒA’¹´@_ï6AºéA>$¿$ø=?d§“A’¹´@¢M3AzàŒA’¹´@_ï6A“‹A_„™@~…+AQ€>|s)¿ÞJgA™@3Tï@k^A™@ÄQí@Üz`AÈ#¾?$ðÍ@¼ ¡½%Öc¿­÷å>Üz`AÈ#¾?$ðÍ@k^A™@ÄQí@ÔXAÈ#¾?ç Ë@Ù¬¥½À^i¿§ZÎ>Üz`AÈ#¾?$ðÍ@ÔXAÈ#¾?ç Ë@,}\A?Š÷ª@ ý|ëk¿+³À>,}\A?Š÷ª@ÔXAÈ#¾?ç Ë@Ã'VA?¢’§@t¼½3”p¿œŽ¨>,}\A?Š÷ª@Ã'VA?¢’§@&[Aµ™*?c2‡@”zν<¯r¿—•š>&[Aµ™*?c2‡@Ã'VA?¢’§@Ã'VAµ™*?̳ƒ@Êr¼½qqv¿V‚>&[Aµ™*?c2‡@Ã'VAµ™*?̳ƒ@,}\A´À>uÚF@á ýÎx¿ñh>,}\A´À>uÚF@Ã'VAµ™*?̳ƒ@ÔXA´À>w@@^©¥½,îz¿9>,}\A´À>uÚF@ÔXA´À>w@@Üz`AòŽ+>@é@lÃk?i6¯>²Ü>> uæAG×£A 0@xçäAG×£AuÚF@3ËçAá^›A+!L@d#k?y'£>Æ´o>3ËçAá^›A+!L@xçäAG×£AuÚF@“åAá^›Ac2‡@Ö2m?¥ÀŠ>…>3ËçAá^›A+!L@“åAá^›Ac2‡@3ËçAس’Akï‰@à$k?Ò|>¹ž>3ËçAس’Akï‰@“åAá^›Ac2‡@xçäAس’AŠ÷ª@gÆk?K>*²«>3ËçAس’Akï‰@xçäAس’AŠ÷ª@ uæA”â‰A¯g­@ˆLh?ë1>èçÃ> uæA”â‰A¯g­@xçäAس’AŠ÷ª@ èâA”â‰A$ðÍ@8†g?wÒþ==úÐ> uæA”â‰A¯g­@ èâA”â‰A$ðÍ@_ÐãAµ÷€AŽ®Ï@•ªb?·Ì=}rè>_ÐãAµ÷€AŽ®Ï@ èâA”â‰A$ðÍ@é¡ßAµ÷€A3Tï@—Š`?QL=ñ’ô>_ÐãAµ÷€AŽ®Ï@é¡ßAµ÷€A3Tï@MìßApAð@B_Z?QÌ<)s?MìßApAð@é¡ßAµ÷€A3Tï@&ÛApAc2AuûV?Q̼AØ ?MìßApAð@&ÛApAc2AßÚA•^A›ÑAšO?QL½??ßÚA•^A›ÑA&ÛApAc2A´ŽÕA•^A8AŠK?·̽²Ê?ßÚA•^A›ÑA´ŽÕA•^A8A›ÅÔA×:LAZ÷A‚˜B?wÒþ½žB#?›ÅÔA×:LAZ÷A´ŽÕA•^A8AÕûÎA×:LAk!A =?ë1¾?Ë&?›ÅÔA×:LAZ÷AÕûÎA×:LAk!A¾ÂÍAP˜:A&A2¥3?K¾‹-/?¾ÂÍAP˜:A&AÕûÎA×:LAk!A“ÇAP˜:A~…+AS>-?Ò|¾1?¾ÂÍAP˜:A&A“ÇAP˜:A~…+A›þÅA=B)AÄ(A«#?¥Àо°»8?›þÅA=B)AÄ(A“ÇAP˜:A~…+A«~¿A=B)A¢M3A½?x'£¾àÙ9?›þÅA=B)AÄ(A«~¿A=B)A¢M3A—¥½ArQA2«.A»H?i6¯¾d¶??—¥½ArQA2«.A«~¿A=B)A¢M3Aóì¶ArQAú–8Aï½ ?Uûƾùz??—¥½ArQA2«.Aóì¶ArQAú–8Aqç´A.ÞAâ¨2A‹Hý>Š°Ò¾ÉõC?qç´A.ÞAâ¨2Aóì¶ArQAú–8Aá®A.ÞAKC;A«í>y±é¾¢RB?qç´A.ÞAâ¨2Aá®A.ÞAKC;A&ö«Að@4Aû%×>*üô¾žaE?&ö«Að@4Aá®A.ÞAKC;A,¥Að@KC;ANmÇ>Œ¿­PB?&ö«Að@4A,¥Að@KC;AÜ£A:›Ñ@â¨2Aú±>ô ¿ØñC?Ü£A:›Ñ@â¨2A,¥Að@KC;A9œA:›Ñ@ú–8AŽ¡>Æ¿9u??Ü£A:›Ñ@â¨2A9œA:›Ñ@ú–8A¶FšA’¹´@2«.A²¼‹>¯¢¿Æ®??¶FšA’¹´@2«.A9œA:›Ñ@ú–8Ad§“A’¹´@¢M3A(z>$¿¸Ð9?¶FšA’¹´@2«.Ad§“A’¹´@¢M3A²í‘A_„™@Ä(A¢JP>|s)¿à°8?²í‘A_„™@Ä(Ad§“A’¹´@¢M3A“‹A_„™@~…+AVC5>)Î2¿‡ƒ1?²í‘A_„™@Ä(A“‹A_„™@~…+A)ŠA•"€@&A´>RQ7¿< /?)ŠA•"€@&A“‹A_„™@~…+A:*„A•"€@k!A’-ì=ÿþ?¿8½&?)ŠA•"€@&A:*„A•"€@k!A²&ƒAqQ@Z÷A*˜¤=h(D¿¤3#?²&ƒAqQ@Z÷A:*„A•"€@k!A´.{AqQ@8AÂ-x=³L¿~»?²&ƒAqQ@Z÷A´.{AqQ@8ApzAÏ&@›ÑAbòpA™@ð@JgA™@3Tï@Û7hAÈ#¾?Ž®Ï@·7½%Öc¿QUè>Û7hAÈ#¾?Ž®Ï@JgA™@3Tï@Üz`AÈ#¾?$ðÍ@•O½À^i¿PßÐ>Û7hAÈ#¾?Ž®Ï@Üz`AÈ#¾?$ðÍ@ƒîbA?¯g­@è鈽|ëk¿'ÎÃ>ƒîbA?¯g­@Üz`AÈ#¾?$ðÍ@,}\A?Š÷ª@¡Š‰½3”p¿G›«>ƒîbA?¯g­@,}\A?Š÷ª@3B`Aµ™*?kï‰@l±Ÿ½<¯r¿xž>3B`Aµ™*?kï‰@,}\A?Š÷ª@&[Aµ™*?c2‡@ö”½rqv¿~…>3B`Aµ™*?kï‰@&[Aµ™*?c2‡@3B`A´À>+!L@j°Ÿ½Îx¿Œ”o>3B`A´À>+!L@&[Aµ™*?c2‡@,}\A´À>uÚF@䈉½,îz¿BÃ>>3B`A´À>+!L@,}\A´À>uÚF@ƒîbAòŽ+> 0@T爽ˆ|¿ëÿ#>ƒîbAòŽ+> 0@,}\A´À>uÚF@Üz`AòŽ+>@é@k O½~¿W~è=ƒîbAòŽ+> 0@Üz`AòŽ+>@é@Û7hAxÌ+=ÊE?ëü½¶º~¿ŸH¼=Û7hAxÌ+=ÊE?‘riAxÌ+==…?ƒîbAòŽ+> 0@—µ+½~¿Q”ï=ƒîbAòŽ+> 0@‘riAxÌ+==…?áteAòŽ+>R¹@Î`½ˆ|¿¨(>ƒîbAòŽ+> 0@áteAòŽ+>R¹@3B`A´À>+!L@GY½,îz¿I^C>3B`A´À>+!L@áteAòŽ+>R¹@ÃdA´À>£CP@ªÞv½Îx¿Œàt>3B`A´À>+!L@ÃdA´À>£CP@3B`Aµ™*?kï‰@;HY½qqv¿þæ‡>3B`Aµ™*?kï‰@ÃdA´À>£CP@áteAµ™*?ùæ‹@I`½<¯r¿! >3B`Aµ™*?kï‰@áteAµ™*?ùæ‹@ƒîbA?¯g­@o¸+½3”p¿B²­>ƒîbA?¯g­@áteAµ™*?ùæ‹@‘riA?“ß®@W½|ëk¿ÏÐÅ>ƒîbA?¯g­@‘riA?“ß®@Û7hAÈ#¾?Ž®Ï@6£¼À^i¿ò8Ò>Û7hAÈ#¾?Ž®Ï@‘riA?“ß®@pAÈ#¾?£CÐ@261¼%Öc¿Ufé>Û7hAÈ#¾?Ž®Ï@pAÈ#¾?£CÐ@pA™@ð@58LpA™@ð@pAÈ#¾?£CÐ@µ÷xA™@3Tï@·'Ù<³zZ¿$A?pA™@ð@µ÷xA™@3Tï@pzAÏ&@›ÑAÉM_=W¿ª ?pzAÏ&@›ÑAµ÷xA™@3Tï@5‚AÏ&@ѯAœ•=pæO¿¨3?pzAÏ&@›ÑA5‚AÏ&@ѯA²&ƒAqQ@Z÷A_¦×=³L¿µ$?²&ƒAqQ@Z÷A5‚AÏ&@ѯA¦ˆAqQ@ÅâAõÙ>h(D¿65!?²&ƒAqQ@Z÷A¦ˆAqQ@ÅâA)ŠA•"€@&A¾™'>ÿþ?¿$?)ŠA•"€@&A¦ˆAqQ@ÅâAáA•"€@5ýAFB>RQ7¿aû+?)ŠA•"€@&AáA•"€@5ýA²í‘A_„™@Ä(A”Ñi>)Î2¿‡¡-?²í‘A_„™@Ä(AáA•"€@5ýA>#˜A_„™@ZÅ#A`uƒ>|s)¿wH4?²í‘A_„™@Ä(A>#˜A_„™@ZÅ#A¶FšA’¹´@2«.A €˜>$¿GŸ4?¶FšA’¹´@2«.A>#˜A_„™@ZÅ#Aö´ A’¹´@²)AËþ§>¯¢¿êì9?¶FšA’¹´@2«.Aö´ A’¹´@²)AÜ£A:›Ñ@â¨2Acǽ>Æ¿?â8?Ü£A:›Ñ@â¨2Aö´ A’¹´@²)A“©A:›Ñ@»+AwÎÍ>ô ¿YÈŒ¿øQ:?&ö«Að@4A“©A:›Ñ@»+A¼Š²Að@»+A# ô>*üô¾UÊMìßApAð@é¡ßA•^A3Tï@ÃäApA£CÐ@õ»c?QÌ<ôƒé>MìßApAð@ÃäApA£CÐ@_ÐãAµ÷€AŽ®Ï@Q i?QL=‚TÒ>_ÐãAµ÷€AŽ®Ï@ÃäApA£CÐ@{dçAµ÷€A“ß®@Ë·j?·Ì=oëÅ>_ÐãAµ÷€AŽ®Ï@{dçAµ÷€A“ß®@ uæA”â‰A¯g­@u¯n?xÒþ=Ê­> uæA”â‰A¯g­@{dçAµ÷€A“ß®@RcéA”â‰Aùæ‹@,øn?ë1>}£ > uæA”â‰A¯g­@RcéA”â‰Aùæ‹@3ËçAس’Akï‰@ú‡q?K>ú‡>3ËçAس’Akï‰@RcéA”â‰Aùæ‹@áêAس’A£CP@Édp?Ò|> u>3ËçAس’Akï‰@áêAس’A£CP@3ËçAá^›A+!L@¢†q?¤ÀŠ>¸yC>3ËçAá^›A+!L@áêAس’A£CP@RcéAá^›AR¹@…õn?x'£>¿(>3ËçAá^›A+!L@RcéAá^›AR¹@ uæAG×£A 0@€«n?i6¯>6µï= uæAG×£A 0@RcéAá^›AR¹@{dçAG×£A=…?«=p?—7¯>¶³@=¸–çAÌ£Ak”§©{dçAG×£A=…?YêAá^›Aw‰?Šqq?x'£>±Á=YêAá^›Aw‰?{dçAG×£A=…?RcéAá^›AR¹@¦€t?¥ÀŠ>¸võ=YêAá^›Aw‰?RcéAá^›AR¹@E¯ëAس’AE~ @‡Lt?Ò|>Úw,>E¯ëAس’AE~ @RcéAá^›AR¹@áêAس’A£CP@Ãïu?K>¦þF>E¯ëAس’AE~ @áêAس’A£CP@E¯ëA”â‰Að;S@±Mt?ë1>2òx>E¯ëA”â‰Að;S@áêAس’A£CP@RcéA”â‰Aùæ‹@ù‚t?xÒþ=,¡‰>E¯ëA”â‰Að;S@RcéA”â‰Aùæ‹@YêAµ÷€A>@÷tq?·Ì=I¢>YêAµ÷€A>@RcéA”â‰Aùæ‹@{dçAµ÷€A“ß®@eBp?QL=õè®>YêAµ÷€A>@{dçAµ÷€A“ß®@q´çApA]¯@žÒk?QÌq´çApA]¯@{dçAµ÷€A“ß®@ÃäApA£CÐ@ZFi?Q̼JÒ>q´çApA]¯@ÃäApA£CÐ@_ÐãA•^AŽ®Ï@ã†c?QL½°Fé>_ÐãA•^AŽ®Ï@ÃäApA£CÐ@é¡ßA•^A3Tï@Ó¶_?·̽mžó>_ÐãA•^AŽ®Ï@é¡ßA•^A3Tï@'ÃÞA×:LAÄQí@DÁX?wÒþ½ o?'ÃÞA×:LAÄQí@é¡ßA•^A3Tï@ ÚA×:LAѯA‰ÊS?ë1¾kÁ?'ÃÞA×:LAÄQí@ ÚA×:LAѯA­©ØAP˜:A¡ÎAk¿K?K¾Sr?­©ØAP˜:A¡ÎA ÚA×:LAѯA¯wÓAP˜:AÅâAÃÅE?Ò|¾»Á?­©ØAP˜:A¡ÎA¯wÓAP˜:AÅâAѦÑA=B)AUýAÒËŒ¿„H1?ƒË¸Að@)€"A¼Š²Að@»+A8Ú¯A:›Ñ@G×#ANré>ô ¿”4?8Ú¯A:›Ñ@G×#A¼Š²Að@»+A“©A:›Ñ@»+A†áØ>Å¿•F1?8Ú¯A:›Ñ@G×#A“©A:›Ñ@»+Aîè¦A’¹´@)€"AaPÃ>®¢¿ß 3?îè¦A’¹´@)€"A“©A:›Ñ@»+Aö´ A’¹´@²)Aä³>ÿœ$¿?k.?îè¦A’¹´@)€"Aö´ A’¹´@²)AÈ*žA_„™@y‚A; ž>|s)¿ôÝ.?È*žA_„™@y‚Aö´ A’¹´@²)A>#˜A_„™@ZÅ#A‰ˆŽ>)Î2¿òÆ(?È*žA_„™@y‚A>#˜A_„™@ZÅ#AÄÑ•A•"€@ õAät>RQ7¿Nà'?ÄÑ•A•"€@ õA>#˜A_„™@ZÅ#AáA•"€@5ýA¾,X>ÿþ?¿ z ?ÄÑ•A•"€@ õAáA•"€@5ýA  ŽAqQ@UýA¬2>h(D¿ýO?  ŽAqQ@UýAáA•"€@5ýA¦ˆAqQ@ÅâA>³L¿´?  ŽAqQ@UýA¦ˆAqQ@ÅâAÄ ‡AÏ&@¡ÎAbÌí=pæO¿Èc?Ä ‡AÏ&@¡ÎA¦ˆAqQ@ÅâA5‚AÏ&@ѯAëÁ=W¿É²?Ä ‡AÏ&@¡ÎA5‚AÏ&@ѯAJñ€A™@ÄQí@JÍ…=³zZ¿î_?Jñ€A™@ÄQí@5‚AÏ&@ѯAµ÷xA™@3Tï@Ô.E=TÛ`¿ ó>Jñ€A™@ÄQí@µ÷xA™@3Tï@$ÈwAÈ#¾?Ž®Ï@²¶¾<%Öc¿4)é>$ÈwAÈ#¾?Ž®Ï@µ÷xA™@3Tï@pAÈ#¾?£CÐ@_51<À^i¿œeÒ>$ÈwAÈ#¾?Ž®Ï@pAÈ#¾?£CÐ@pA?]¯@!6¼|ëk¿C¸Æ>pA?]¯@pAÈ#¾?£CÐ@‘riA?“ß®@ŠË†¼3”p¿‘Ю>pA?]¯@‘riA?“ß®@¨¶jAµ™*?>@ûÕþ¼<¯r¿ï1¢>¨¶jAµ™*?>@‘riA?“ß®@áteAµ™*?ùæ‹@8m½qqv¿O‰>¨¶jAµ™*?>@áteAµ™*?ùæ‹@W hA´À>ð;S@û,½Îx¿øÍx>W hA´À>ð;S@áteAµ™*?ùæ‹@ÃdA´À>£CP@4E½,îz¿áF>W hA´À>ð;S@ÃdA´À>£CP@W hAòŽ+>E~ @=ú,½ˆ|¿Ã^,>W hAòŽ+>E~ @ÃdA´À>£CP@áteAòŽ+>R¹@ïk½~¿LSõ=W hAòŽ+>E~ @áteAòŽ+>R¹@¨¶jAxÌ+=w‰?_Òþ¼¶º~¿ð•Á=¨¶jAxÌ+=w‰?áteAòŽ+>R¹@‘riAxÌ+==…?Ɇ¼¡®¿Ô˜@=¨¶jAxÌ+=w‰?‘riAxÌ+==…?pABÏ(¤1£¼¡®¿®;=Û7hAxÌ+=ÊE?pABÏ(‘riAxÌ+==…?×¢¾RQ7¿r?pª#A_„™@y‚AaA•"€@ _ A,)A•"€@RAéÁ¡¾ÿþ?¿ÌÄ?,)A•"€@RAaA•"€@ _ Ad.%AqQ@—AüÞ•¾h(D¿ún?,)A•"€@RAd.%AqQ@—A/AqQ@›ÑA¹‘“¾´L¿æÁ?/AqQ@›ÑAd.%AqQ@—AÎf,AÏ&@ò*ê@Ĉ¾pæO¿9ü?/AqQ@›ÑAÎf,AÏ&@ò*ê@W5AÏ&@Âó@«Ž„¾W¿úó>W5AÏ&@Âó@Îf,AÏ&@ò*ê@ÿÿ3A™@™ØÏ@Ms¾³zZ¿ï–í>W5AÏ&@Âó@ÿÿ3A™@™ØÏ@ï;A™@‡;Ø@‡œi¾TÛ`¿Á×>ï;A™@‡;Ø@ÿÿ3A™@™ØÏ@ï;AÈ#¾?²\´@þƒT¾%Öc¿âÏ>ï;A™@‡;Ø@ï;AÈ#¾?²\´@›ÑBAÈ#¾?º£»@$ÎH¾À^i¿[ú¸>›ÑBAÈ#¾?º£»@ï;AÈ#¾?²\´@¸(DA?’Þ—@@Ø4¾|ëk¿g±>›ÑBAÈ#¾?º£»@¸(DA?’Þ—@ÎôIA?Jÿ@á&¾3”p¿çØ™>ÎôIA?Jÿ@¸(DA?’Þ—@¡LAµ™*? u@_*¾<¯r¿ *‘>ÎôIA?Jÿ@¡LAµ™*? u@xNQAµ™*?Pñ~@æ¾qqv¿Å·s>xNQAµ™*?Pñ~@¡LAµ™*? u@(LUA´À>9@Rå½Îx¿a>xNQAµ™*?Pñ~@(LUA´À>9@ÔXA´À>w@@¬ÜÀ½,îz¿b2>ÔXA´À>w@@(LUA´À>9@k^AòŽ+>¤Ò÷?@¡½ˆ|¿ûl>ÔXA´À>w@@k^AòŽ+>¤Ò÷?Üz`AòŽ+>@é@Õ4q½~¿„à=Üz`AòŽ+>@é@k^AòŽ+>¤Ò÷?JgAxÌ+=Š„x?U±7½¶º~¿¿íµ=Üz`AòŽ+>@é@JgAxÌ+=Š„x?Û7hAxÌ+=ÊE? °¾¼¡®¿Èf4=Û7hAxÌ+=ÊE?JgAxÌ+=Š„x?pABÏ(­hm?Ü.¿>¾<¸–çAÌ£Ak”§©´ŽæA­¨¦Az¥©{dçAG×£A=…?4¼j?úöÊ>;={dçAG×£A=…?´ŽæA­¨¦Az¥©_ÐãAé¬AÊE?¤²j?TûÆ>õa¼={dçAG×£A=…?_ÐãAé¬AÊE? uæAG×£A 0@p€g?аÒ>Nœè= uæAG×£A 0@_ÐãAé¬AÊE? èâAé¬A@é@&Hh?UûÆ>{$> uæAG×£A 0@ èâAé¬A@é@xçäAG×£AuÚF@w®d?аÒ>?.9>xçäAG×£AuÚF@ èâAé¬A@é@ÓgáAé¬Aw@@‘d?UûÆ>i>xçäAG×£AuÚF@ÓgáAé¬Aw@@û½âAG×£A̳ƒ@•`?‰°Ò>8}>û½âAG×£A̳ƒ@ÓgáAé¬Aw@@PßAé¬APñ~@Õ’_?TûÆ>]–>û½âAG×£A̳ƒ@PßAé¬APñ~@­ûßAG×£AÐ=£@6:[?аÒ>ü¸Ÿ>­ûßAG×£AÐ=£@PßAé¬APñ~@¤ÜAé¬AJÿ@{TY?TûÆ>1\·>­ûßAG×£AÐ=£@¤ÜAé¬AJÿ@¤ÜAG×£A ÞÁ@w¥T?аÒ>¯ À>¤ÜAG×£A ÞÁ@¤ÜAé¬AJÿ@ÎhÙAé¬Aº£»@ýÞQ?TûÆ>`T×>¤ÜAG×£A ÞÁ@ÎhÙAé¬Aº£»@?½ØAG×£Aâhß@GàL?‰°Ò>rIß>?½ØAG×£Aâhß@ÎhÙAé¬Aº£»@¥¡ÕAé¬A‡;Ø@=I?UûÆ>Iö>?½ØAG×£Aâhß@¥¡ÕAé¬A‡;Ø@}KÔAG×£A̳û@ÉõC?аÒ>‹Hý>}KÔAG×£A̳û@¥¡ÕAé¬A‡;Ø@qTÑAé¬AÂó@ùz??UûÆ>ï½ ?}KÔAG×£A̳û@qTÑAé¬AÂó@™UÏAG×£A.K A½ò9?аÒ>ƒî ?™UÏAG×£A.K AqTÑAé¬AÂó@X‡ÌAé¬A›ÑAǦ4?UûÆ>‡ª?™UÏAG×£A.K AX‡ÌAé¬A›ÑA­âÉAG×£A õA{å.?аÒ>ün?­âÉAG×£A õAX‡ÌAé¬A›ÑAý½$?­âÉAG×£A õA]'?„úÃAG×£AZÅ#A—å0?„úÃAG×£AZÅ#A©‰ÁAé¬Ay‚A—¥½AG×£A2«.Aí?аÒ>ŽÆ2?—¥½AG×£A2«.A©‰ÁAé¬Ay‚AÎh»Aé¬A²)A_?TûÆ>ñÌz=?óì¶AG×£Aú–8AÎh»Aé¬A²)Aqç´Aé¬Aâ¨2A°×ÿ>UûÆ> -F?óì¶AG×£Aú–8Aqç´Aé¬Aâ¨2A8Ú¯AG×£A~zAA\6ó>аÒ>ÆG?8Ú¯AG×£A~zAAqç´Aé¬Aâ¨2Aá®Aé¬AKC;Aúá>UûÆ>q.O?8Ú¯AG×£A~zAAá®Aé¬AKC;A‡w¨AG×£AIIAjÅÔ>аÒ>¬§O?‡w¨AG×£AIIAá®Aé¬AKC;Aîè¦Aé¬AœÑBAjéÁ>TûÆ>7W?‡w¨AG×£AIIAîè¦Aé¬AœÑBAtÏ AG×£AZ÷OAÚ#µ>‰°Ò>GW?tÏ AG×£AZ÷OAîè¦Aé¬AœÑBAÒŸAé¬AIIA>;¡>UûÆ>&¬]?tÏ AG×£AZ÷OAÒŸAé¬AIIAóì˜AG×£Aö{UAö~”>аÒ> 1]?óì˜AG×£Aö{UAÒŸAé¬AIIA*Þ—Aé¬A= NAyL>TûÆ>¸c?óì˜AG×£Aö{UA*Þ—Aé¬A= NANÛAG×£AðÎYAò f>‰°Ò>#b?NÛAG×£AðÎYA*Þ—Aé¬A= NAáAé¬A¦ÏRAø´:>UûÆ>26g?NÛAG×£AðÎYAáAé¬A¦ÏRA¦ˆAG×£Aê\A¡Î!>аÒ>‚Ée?¦ˆAG×£Aê\AáAé¬A¦ÏRA'ˆAé¬A@ÑUAS$ê=TûÆ>§ j?¦ˆAG×£Aê\A'ˆAé¬A@ÑUAY€AG×£AöÈ^AQU¹=аÒ>æ*h?Y€AG×£AöÈ^A'ˆAé¬A@ÑUA\€Aé¬A¾ WA;=UûÆ>–k?Y€AG×£AöÈ^A\€Aé¬A¾ WApAG×£Aâh_A1¸<‰°Ò>ç?i?pAG×£Aâh_A\€Aé¬A¾ WApAé¬A‡;XA -¾¼UûÆ>!Ík?pAG×£Aâh_ApAé¬A‡;XAøM_AG×£AöÈ^A3;½Š°Ò>úi?øM_AG×£AöÈ^ApAé¬A‡;XAG×_Aé¬A¾ WAõa¼½TûÆ>¤²j?øM_AG×£AöÈ^AG×_Aé¬A¾ WA׳NAG×£Aê\ANœè½Š°Ò>p€g?׳NAG×£Aê\AG×_Aé¬A¾ WA°ÅOAé¬A@ÑUA{$¾UûÆ>&Hh?׳NAG×£Aê\A°ÅOAé¬A@ÑUAcI>AG×£AðÎYA?.9¾Š°Ò>w®d?cI>AG×£AðÎYA°ÅOAé¬A@ÑUA<â?Aé¬A¦ÏRAi¾UûÆ>‘d?cI>AG×£AðÎYA<â?Aé¬A¦ÏRA&.AG×£Aö{UA8}¾‰°Ò>•`?&.AG×£Aö{UA<â?Aé¬A¦ÏRA¬C0Aé¬A= NA]–¾TûÆ>Õ’_?&.AG×£Aö{UA¬C0Aé¬A= NAaAG×£AZ÷OAü¸Ÿ¾Š°Ò>6:[?aAG×£AZ÷OA¬C0Aé¬A= NA[!Aé¬AIIA1\·¾TûÆ>{TY?aAG×£AZ÷OA[!Aé¬AIIAðAG×£AIIA¯ À¾Š°Ò>w¥T?ðAG×£AIIA[!Aé¬AIIA".Aé¬AœÑBA`T×¾TûÆ>ýÞQ?ðAG×£AIIA".Aé¬AœÑBAKAG×£A~zAArIß¾‰°Ò>GàL?KAG×£A~zAA".Aé¬AœÑBA=âAé¬AKC;AIö¾UûÆ>=I?KAG×£A~zAA=âAé¬AKC;A3Lä@G×£Aú–8A‹Hý¾Š°Ò>ÉõC?3Lä@G×£Aú–8A=âAé¬AKC;A>bì@é¬Aâ¨2Aï½ ¿UûÆ>ùz??3Lä@G×£Aú–8A>bì@é¬Aâ¨2A£iÉ@G×£A2«.Aƒî ¿Š°Ò>½ò9?£iÉ@G×£A2«.A>bì@é¬Aâ¨2AÈ\Ò@é¬A²)A‡ª¿UûÆ>Ǧ4?£iÉ@G×£A2«.AÈ\Ò@é¬A²)Aë°@G×£AZÅ#Aün¿Š°Ò>{å.?ë°@G×£AZÅ#AÈ\Ò@é¬A²)A[Ù¹@é¬Ay‚Aý½$¿UûÆ>óÏ(?ë°@G×£AZÅ#A[Ù¹@é¬Ay‚ALu˜@G×£A õA]'¿Š°Ò>ÖÝ"?Lu˜@G×£A õA[Ù¹@é¬Ay‚Aû¢@é¬ARA—å0¿TûÆ>r?Lu˜@G×£A õAû¢@é¬ARAœ©‚@G×£A.K AŽÆ2¿Š°Ò>í?œ©‚@G×£A.K Aû¢@é¬ARAœâ@é¬A›ÑAñ<¿TûÆ>_?œ©‚@G×£A.K Aœâ@é¬A›ÑA¤]@G×£A̳û@Ìz=¿‰°Ò>Ž%?¤]@G×£A̳û@œâ@é¬A›ÑAx\u@é¬AÂó@ -F¿UûÆ>°×ÿ>¤]@G×£A̳û@x\u@é¬AÂó@:@G×£Aâhß@ÆG¿Š°Ò>\6ó>:@G×£Aâhß@x\u@é¬AÂó@ÓòR@é¬A‡;Ø@q.O¿UûÆ>úá>:@G×£Aâhß@ÓòR@é¬A‡;Ø@÷Û@G×£A ÞÁ@¬§O¿Š°Ò>jÅÔ>÷Û@G×£A ÞÁ@ÓòR@é¬A‡;Ø@¹4@é¬Aº£»@7W¿TûÆ>jéÁ>÷Û@G×£A ÞÁ@¹4@é¬Aº£»@•"@G×£AÐ=£@GW¿‰°Ò>Ú#µ>•"@G×£AÐ=£@¹4@é¬Aº£»@÷Û@é¬AJÿ@&¬]¿UûÆ>>;¡>•"@G×£AÐ=£@÷Û@é¬AJÿ@J Ô?G×£A̳ƒ@ 1]¿Š°Ò>ö~”>J Ô?G×£A̳ƒ@÷Û@é¬AJÿ@ @é¬APñ~@¸c¿TûÆ>yL>J Ô?G×£A̳ƒ@ @é¬APñ~@|ˆ±?G×£AuÚF@#b¿‰°Ò>ò f>|ˆ±?G×£AuÚF@ @é¬APñ~@Ï‚é?é¬Aw@@›Yc¿]Eê>)|4=¹ð@ÿÿ³AŠ„x?RÁ?z¬AË*úÂ?é¬AÊE?hhf¿ÑØÞ>‰ò·<úÂ?é¬AÊE?RÁ?z¬AË*)|¾?”¬Afø*@i¿Ñ¯Ò>8¸<úÂ?é¬AÊE?)|¾?”¬Afø*-©†?0Ê£A•u *ªdd?Fþæ>0¸<ÎöãA÷ý«A“t ©¸øàAf%²AÏ’š©_ÐãAé¬AÊE?3;a?¿Qò>¸w4=_ÐãAé¬AÊE?¸øàAf%²AÏ’š©é¡ßAÿÿ³AŠ„x?£b?z±é>–¶=_ÐãAé¬AÊE?é¡ßAÿÿ³AŠ„x? èâAé¬A@é@Ñ _?*üô>A6à= èâAé¬A@é@é¡ßAÿÿ³AŠ„x?'ÃÞAÿÿ³A¤Ò÷?N`?y±é>`€> èâAé¬A@é@'ÃÞAÿÿ³A¤Ò÷?ÓgáAé¬Aw@@ýQ\?*üô>”v2>ÓgáAé¬Aw@@'ÃÞAÿÿ³A¤Ò÷?FQÝAÿÿ³A9@m·\?z±é>Ša>ÓgáAé¬Aw@@FQÝAÿÿ³A9@PßAé¬APñ~@½^X?*üô>ˆÒs>PßAé¬APñ~@FQÝAÿÿ³A9@XNÛAÿÿ³A u@ÍäW?y±é>6:‘>PßAé¬APñ~@XNÛAÿÿ³A u@¤ÜAé¬AJÿ@¸5S?*üô>µè™>¤ÜAé¬AJÿ@XNÛAÿÿ³A u@?½ØAÿÿ³A’Þ—@ÝQ?y±é>¾±>¤ÜAé¬AJÿ@?½ØAÿÿ³A’Þ—@ÎhÙAé¬Aº£»@RÞL?*üô>Î ¹>ÎhÙAé¬Aº£»@?½ØAÿÿ³A’Þ—@¥¡ÕAÿÿ³A²\´@ï¨J?y±é>½õÏ>ÎhÙAé¬Aº£»@¥¡ÕAÿÿ³A²\´@¥¡ÕAé¬A‡;Ø@žaE?*üô>û%×>¥¡ÕAé¬A‡;Ø@¥¡ÕAÿÿ³A²\´@ÒAÿÿ³A™ØÏ@¢RB?y±é>«í>¥¡ÕAé¬A‡;Ø@ÒAÿÿ³A™ØÏ@qTÑAé¬AÂó@UÊ# ô>qTÑAé¬AÂó@ÒAÿÿ³A™ØÏ@ÝÍAÿÿ³Aò*ê@!æ8?z±é>?qTÑAé¬AÂó@ÝÍAÿÿ³Aò*ê@X‡ÌAé¬A›ÑAÅ$3?*üô>sÊ?X‡ÌAé¬A›ÑAÝÍAÿÿ³Aò*ê@@ÉAÿÿ³A—Aêp.?y±é>x?X‡ÌAé¬A›ÑA@ÉAÿÿ³A—AnÌ?q?aù ?©‰ÁAé¬Ay‚AU.ÄAÿÿ³A _ A…¯¾Aÿÿ³Aª\A¢©?z±é> Õ*?©‰ÁAé¬Ay‚A…¯¾Aÿÿ³Aª\AÎh»Aé¬A²)A’o?*üô>Þ?,?Îh»Aé¬A²)A…¯¾Aÿÿ³Aª\AƒË¸Aÿÿ³A)€"Aœy ?y±é>5?Îh»Aé¬A²)AƒË¸Aÿÿ³A)€"Aqç´Aé¬Aâ¨2Aä(?*üô>À6?qç´Aé¬Aâ¨2AƒË¸Aÿÿ³A)€"A¼Š²Aÿÿ³A»+A‹ ÷>z±é>a??qç´Aé¬Aâ¨2A¼Š²Aÿÿ³A»+Aá®Aé¬AKC;AßLê>*üô>FÚ??á®Aé¬AKC;A¼Š²Aÿÿ³A»+A&ö«Aÿÿ³A4A1¾Ù>y±é>H?á®Aé¬AKC;A&ö«Aÿÿ³A4Aîè¦Aé¬AœÑBA†øÌ>)üô>!H?îè¦Aé¬AœÑBA&ö«Aÿÿ³A4A,¥Aÿÿ³AKC;A;»>z±é>´¦O?îè¦Aé¬AœÑBA,¥Aÿÿ³AKC;AÒŸAé¬AIIA»~®>*üô>+O?ÒŸAé¬AIIA,¥Aÿÿ³AKC;A¥÷Aÿÿ³A~zAAù«›>z±é>V?ÒŸAé¬AIIA¥÷Aÿÿ³A~zAA*Þ—Aé¬A= NA >*üô>`U?*Þ—Aé¬A= NA¥÷Aÿÿ³A~zAA¡–Aÿÿ³A±œFAñ{v>z±é>ØH[?*Þ—Aé¬A= NA¡–Aÿÿ³A±œFAáAé¬A¦ÏRAp•]>*üô>ÜY?áAé¬A¦ÏRA¡–Aÿÿ³A±œFA Aÿÿ³A¢JA ?4>z±é>½F_?áAé¬A¦ÏRA Aÿÿ³A¢JA'ˆAé¬A@ÑUAg×>*üô>íc]?'ˆAé¬A@ÑUA Aÿÿ³A¢JA*}‡Aÿÿ³AN†MA:â=y±é>ûb?'ˆAé¬A@ÑUA*}‡Aÿÿ³AN†MA\€Aé¬A¾ WA…t²=*üô>Ì®_?\€Aé¬A¾ WA*}‡Aÿÿ³AN†MAHˆAÿÿ³AÑCOA—}4=z±é>¤c?\€Aé¬A¾ WAHˆAÿÿ³AÑCOApAé¬A‡;XAùê°<*üô>n¹`?pAé¬A‡;XAHˆAÿÿ³AÑCOApAÿÿ³A™ØOAV¸¼z±é>™´c?pAé¬A‡;XApAÿÿ³A™ØOAG×_Aé¬A¾ WA´|4½*üô>U‚`?G×_Aé¬A¾ WApAÿÿ³A™ØOA·w`Aÿÿ³AÑCOA–¶½z±é>£b?G×_Aé¬A¾ WA·w`Aÿÿ³AÑCOA°ÅOAé¬A@ÑUAA6à½*üô>Ñ _?°ÅOAé¬A@ÑUA·w`Aÿÿ³AÑCOA«QAÿÿ³AN†MA`€¾y±é>N`?°ÅOAé¬A@ÑUA«QAÿÿ³AN†MA<â?Aé¬A¦ÏRA”v2¾*üô>ýQ\?<â?Aé¬A¦ÏRA«QAÿÿ³AN†MAù¿AAÿÿ³A¢JAŠa¾z±é>m·\?<â?Aé¬A¦ÏRAù¿AAÿÿ³A¢JA¬C0Aé¬A= NAˆÒs¾*üô>½^X?¬C0Aé¬A= NAù¿AAÿÿ³A¢JA}¼2Aÿÿ³A±œFA6:‘¾y±é>ÍäW?¬C0Aé¬A= NA}¼2Aÿÿ³A±œFA[!Aé¬AIIAµè™¾*üô>¸5S?[!Aé¬AIIA}¼2Aÿÿ³A±œFA·$Aÿÿ³A~zAA¾±¾y±é>ÝQ?[!Aé¬AIIA·$Aÿÿ³A~zAA".Aé¬AœÑBAÎ ¹¾*üô>RÞL?".Aé¬AœÑBA·$Aÿÿ³A~zAA§ÑAÿÿ³AKC;A½õϾy±é>ï¨J?".Aé¬AœÑBA§ÑAÿÿ³AKC;A=âAé¬AKC;Aû%×¾*üô>žaE?=âAé¬AKC;A§ÑAÿÿ³AKC;A³Aÿÿ³A4A«í¾y±é>¢RB?=âAé¬AKC;A³Aÿÿ³A4A>bì@é¬Aâ¨2A# ô¾*üô>UÊbì@é¬Aâ¨2A³Aÿÿ³A4A Õõ@ÿÿ³A»+A¿z±é>!æ8?>bì@é¬Aâ¨2A Õõ@ÿÿ³A»+AÈ\Ò@é¬A²)AsÊ¿*üô>Å$3?È\Ò@é¬A²)A Õõ@ÿÿ³A»+AöÑÜ@ÿÿ³A)€"Ax¿y±é>êp.?È\Ò@é¬A²)AöÑÜ@ÿÿ³A)€"A[Ù¹@é¬Ay‚AnÌ¿*üô>»~(?[Ù¹@é¬Ay‚AöÑÜ@ÿÿ³A)€"AëAÅ@ÿÿ³Aª\Aq¿y±é>õ#?[Ù¹@é¬Ay‚AëAÅ@ÿÿ³Aª\Aû¢@é¬ARAaù ¿*üô>xç?û¢@é¬ARAëAÅ@ÿÿ³Aª\A«F¯@ÿÿ³A _ A Õ*¿z±é>¢©?û¢@é¬ARA«F¯@ÿÿ³A _ Aœâ@é¬A›ÑAÞ?,¿*üô>’o?œâ@é¬A›ÑA«F¯@ÿÿ³A _ A®ÿš@ÿÿ³A—A5¿y±é>œy ?œâ@é¬A›ÑA®ÿš@ÿÿ³A—Ax\u@é¬AÂó@À6¿*üô>ä(?x\u@é¬AÂó@®ÿš@ÿÿ³A—Aû‰ˆ@ÿÿ³Aò*ê@a?¿z±é>‹ ÷>x\u@é¬AÂó@û‰ˆ@ÿÿ³Aò*ê@ÓòR@é¬A‡;Ø@FÚ?¿*üô>ßLê>ÓòR@é¬A‡;Ø@û‰ˆ@ÿÿ³Aò*ê@ýÿo@ÿÿ³A™ØÏ@H¿y±é>1¾Ù>ÓòR@é¬A‡;Ø@ýÿo@ÿÿ³A™ØÏ@¹4@é¬Aº£»@!H¿)üô>†øÌ>¹4@é¬Aº£»@ýÿo@ÿÿ³A™ØÏ@ÓòR@ÿÿ³A²\´@´¦O¿z±é>;»>¹4@é¬Aº£»@ÓòR@ÿÿ³A²\´@÷Û@é¬AJÿ@+O¿*üô>»~®>÷Û@é¬AJÿ@ÓòR@ÿÿ³A²\´@:@ÿÿ³A’Þ—@V¿z±é>ù«›>÷Û@é¬AJÿ@:@ÿÿ³A’Þ—@ @é¬APñ~@`U¿*üô> > @é¬APñ~@:@ÿÿ³A’Þ—@:%@ÿÿ³A u@ØH[¿z±é>ñ{v> @é¬APñ~@:%@ÿÿ³A u@Ï‚é?é¬Aw@@ÜY¿*üô>p•]>Ï‚é?é¬Aw@@:%@ÿÿ³A u@Ìu@ÿÿ³A9@VŠX¿š?kÒ,=Y)@1™»Aµm?Ç,@ˆ¦·A5ÿ)¹ð@ÿÿ³AŠ„x?ÿ\¿­?}Ô°<¹ð@ÿÿ³AŠ„x?Ç,@ˆ¦·A5ÿ)m¬@@í³Ašª*c‘`¿ÛŽõ>*è°<¹ð@ÿÿ³AŠ„x?m¬@@í³Ašª*RÁ?z¬AË*VZ?Œ?ê°<Ë×ßA+ó³AëZ˜©AÛA®Ž»AÖÿŽ©é¡ßAÿÿ³AŠ„x?ð»V?Šô ?ËØ,=é¡ßAÿÿ³AŠ„x?AÛA®Ž»AÖÿŽ©ßÚA1™»Aµm?òOY?Œ?’¢®=é¡ßAÿÿ³AŠ„x?ßÚA1™»Aµm?'ÃÞAÿÿ³A¤Ò÷?ÚSU?ô ?+Ö='ÃÞAÿÿ³A¤Ò÷?ßÚA1™»Aµm? ÚA1™»Aüoì?ÆW?Œ?N>'ÃÞAÿÿ³A¤Ò÷? ÚA1™»Aüoì?FQÝAÿÿ³A9@ºR?ô ?c¿*>FQÝAÿÿ³A9@ ÚA1™»Aüoì?­©ØA1™»AO€0@°¡S?Œ?ªåW>FQÝAÿÿ³A9@­©ØA1™»AO€0@XNÛAÿÿ³A u@“òN?ô ?¾Bi>XNÛAÿÿ³A u@­©ØA1™»AO€0@g¾ÖA1™»AðËi@žO?Œ?÷F‹>XNÛAÿÿ³A u@g¾ÖA1™»AðËi@?½ØAÿÿ³A’Þ—@ÐJ?ô ?<“>?½ØAÿÿ³A’Þ—@g¾ÖA1™»AðËi@}KÔA1™»Alä@09I?Œ?´Ó©>?½ØAÿÿ³A’Þ—@}KÔA1™»Alä@¥¡ÕAÿÿ³A²\´@ØñC?ô ?ú±>¥¡ÕAÿÿ³A²\´@}KÔA1™»Alä@qTÑA1™»Ar¬@­PB?Œ?NmÇ>¥¡ÕAÿÿ³A²\´@qTÑA1™»Ar¬@ÒAÿÿ³A™ØÏ@YÈÒAÿÿ³A™ØÏ@qTÑA1™»Ar¬@ÝÍA1™»ALÆ@øQ:?Œ?géã>ÒAÿÿ³A™ØÏ@ÝÍA1™»ALÆ@ÝÍAÿÿ³Aò*ê@”4?ô ?Nré>ÝÍAÿÿ³Aò*ê@ÝÍA1™»ALÆ@£ëÉA1™»Aâhß@„H1?Œ?3ÿ>ÝÍAÿÿ³Aò*ê@£ëÉA1™»Aâhß@@ÉAÿÿ³A—ANV+?ô ?÷ã?@ÉAÿÿ³A—A£ëÉA1™»Aâhß@~„ÅA1™»AÐE÷@AA'?Œ?ás ?@ÉAÿÿ³A—A~„ÅA1™»AÐE÷@U.ÄAÿÿ³A _ A¼&!?ô ?ÓT?U.ÄAÿÿ³A _ A~„ÅA1™»AÐE÷@]®ÀA1™»A]àA‹J?Œ??U.ÄAÿÿ³A _ A]®ÀA1™»A]àA…¯¾Aÿÿ³Aª\Ar?ô ?èù?…¯¾Aÿÿ³Aª\A]®ÀA1™»A]àA.p»A1™»Aº\At?Œ?ÜÏ#?…¯¾Aÿÿ³Aª\A.p»A1™»Aº\AƒË¸Aÿÿ³A)€"AS# ?ô ?Â$?ƒË¸Aÿÿ³A)€"A.p»A1™»Aº\AtѵA1™»AûAÎÎ?Œ? &.?ƒË¸Aÿÿ³A)€"AtѵA1™»AûA¼Š²Aÿÿ³A»+AÞàú>ô ?QŸ.?¼Š²Aÿÿ³A»+AtѵA1™»AûA8Ú¯A1™»AG×#A¦Ùì>Œ?ƒ7?¼Š²Aÿÿ³A»+A8Ú¯A1™»AG×#A&ö«Aÿÿ³A4Aêà>ô ?‚7?&ö«Aÿÿ³A4A8Ú¯A1™»AG×#A“©A1™»A»+A›ÂÐ>Œ?IÙ??&ö«Aÿÿ³A4A“©A1™»A»+A,¥Aÿÿ³AKC;A*Ä>ô ? ^??,¥Aÿÿ³AKC;A“©A1™»A»+AÜ£A1™»Aâ¨2A°€³>Œ?×G?,¥Aÿÿ³AKC;AÜ£A1™»Aâ¨2A¥÷Aÿÿ³A~zAAÅߦ>ô ?3(F?¥÷Aÿÿ³A~zAAÜ£A1™»Aâ¨2A9œA1™»Aú–8AÊ=•>Œ?UCM?¥÷Aÿÿ³A~zAA9œA1™»Aú–8A¡–Aÿÿ³A±œFAyʈ>ô ?”ÖK?¡–Aÿÿ³A±œFA9œA1™»Aú–8A~9•A1™»AÎ|=AqJl>Œ?öCR?¡–Aÿÿ³A±œFA~9•A1™»AÎ|=A Aÿÿ³A¢JA¬âS>ô ?"aP? Aÿÿ³A¢JA~9•A1™»AÎ|=A ŽA1™»AYSAAÇ,>Œ?V? Aÿÿ³A¢JA ŽA1™»AYSAA*}‡Aÿÿ³AN†MA>ô ?\ÁS?*}‡Aÿÿ³AN†MA ŽA1™»AYSAAdžA1™»ADA€˜Ø=Œ?¨¸X?*}‡Aÿÿ³AN†MAdžA1™»ADAHˆAÿÿ³AÑCOA6”ª=ô ?mòU?HˆAÿÿ³AÑCOAdžA1™»ADA›Ñ~A1™»A)¾EA·Ù,=Œ?{#Z?HˆAÿÿ³AÑCOA›Ñ~A1™»A)¾EApAÿÿ³A™ØOAuȨ<ô ?1ñV?pAÿÿ³A™ØOA›Ñ~A1™»A)¾EApA1™»ALFAê°¼Œ?VZ?pAÿÿ³A™ØOApA1™»ALFA·w`Aÿÿ³AÑCOAÉØ,½ô ?<¼V?·w`Aÿÿ³AÑCOApA1™»ALFAe.aA1™»A)¾EA’¢®½Œ?òOY?·w`Aÿÿ³AÑCOAe.aA1™»A)¾EA«QAÿÿ³AN†MA+Ö½ô ?ÚSU?«QAÿÿ³AN†MAe.aA1™»A)¾EArRA1™»ADAN¾Œ?ÆW?«QAÿÿ³AN†MArRA1™»ADAù¿AAÿÿ³A¢JAc¿*¾ô ?ºR?ù¿AAÿÿ³A¢JArRA1™»ADAìßCA1™»AYSAAªåW¾Œ?°¡S?ù¿AAÿÿ³A¢JAìßCA1™»AYSAA}¼2Aÿÿ³A±œFA¾Bi¾ô ?“òN?}¼2Aÿÿ³A±œFAìßCA1™»AYSAA5A1™»AÎ|=A÷F‹¾Œ?žO?}¼2Aÿÿ³A±œFA5A1™»AÎ|=A·$Aÿÿ³A~zAA<“¾ô ?ÐJ?·$Aÿÿ³A~zAA5A1™»AÎ|=AÊ'A1™»Aú–8A´Ó©¾Œ?09I?·$Aÿÿ³A~zAAÊ'A1™»Aú–8A§ÑAÿÿ³AKC;Aú±¾ô ?ØñC?§ÑAÿÿ³AKC;AÊ'A1™»Aú–8AGöA1™»Aâ¨2ANmǾŒ?­PB?§ÑAÿÿ³AKC;AGöA1™»Aâ¨2A³Aÿÿ³A4AwÎ;ô ?YÈû‰ˆ@ÿÿ³Aò*ê@ î©@1™»AÐE÷@rQ˜@1™»Aâhß@ƒ7¿Œ?¦Ùì>û‰ˆ@ÿÿ³Aò*ê@rQ˜@1™»Aâhß@ýÿo@ÿÿ³A™ØÏ@‚7¿ô ?êà>ýÿo@ÿÿ³A™ØÏ@rQ˜@1™»Aâhß@û‰ˆ@1™»ALÆ@IÙ?¿Œ?›ÂÐ>ýÿo@ÿÿ³A™ØÏ@û‰ˆ@1™»ALÆ@ÓòR@ÿÿ³A²\´@ ^?¿ô ?*Ä>ÓòR@ÿÿ³A²\´@û‰ˆ@1™»ALÆ@x\u@1™»Ar¬@×G¿Œ?°€³>ÓòR@ÿÿ³A²\´@x\u@1™»Ar¬@:@ÿÿ³A’Þ—@3(F¿ô ?Åߦ>:@ÿÿ³A’Þ—@x\u@1™»Ar¬@¤]@1™»Alä@UCM¿Œ?Ê=•>:@ÿÿ³A’Þ—@¤]@1™»Alä@:%@ÿÿ³A u@”ÖK¿ô ?yʈ>:%@ÿÿ³A u@¤]@1™»Alä@Ç J@1™»AðËi@öCR¿Œ?qJl>:%@ÿÿ³A u@Ç J@1™»AðËi@Ìu@ÿÿ³A9@"aP¿ô ?¬âS>Ìu@ÿÿ³A9@Ç J@1™»AðËi@š²:@1™»AO€0@ÔÑC¿¶œ$?¸=u@èžÉAó[R?¡¶Q@ÊÂA¨Rï)\ŠS@›ÑÂAn[`?”qH¿6*?ΚŸ<\ŠS@›ÑÂAn[`?¡¶Q@ÊÂA¨Rï)éL@ZÂA †ð)('L¿?-;$=\ŠS@›ÑÂAn[`?éL@ZÂA †ð)Y)@1™»Aµm?øP¿vø?d¨ ÚA1™»Aüoì?›ÅÔA›ÑÂAÔºß?­©ØA1™»AO€0@„ôG?¯¢?Î">­©ØA1™»AO€0@›ÅÔA›ÑÂAÔºß?¯wÓA›ÑÂAÑ'@ý\I?Å?·zM>­©ØA1™»AO€0@¯wÓA›ÑÂAÑ'@g¾ÖA1™»AðËi@6^D?¯¢?e]>g¾ÖA1™»AðËi@¯wÓA›ÑÂAÑ'@ѦÑA›ÑÂA;]@öD?Å?VŒ„>g¾ÖA1™»AðËi@ѦÑA›ÑÂA;]@}KÔA1™»Alä@Æ®??¯¢?²¼‹>}KÔA1™»Alä@ѦÑA›ÑÂA;]@™UÏA›ÑÂA؉@9u??Æ?Ž¡>}KÔA1™»Alä@™UÏA›ÑÂA؉@qTÑA1™»Ar¬@êì9?¯¢?Ëþ§>qTÑA1™»Ar¬@™UÏA›ÑÂA؉@X‡ÌA›ÑÂA×Ó¢@?â8?Æ?cǽ>qTÑA1™»Ar¬@X‡ÌA›ÑÂA×Ó¢@ÝÍA1™»ALÆ@ß 3?®¢?aPÃ>ÝÍA1™»ALÆ@X‡ÌA›ÑÂA×Ó¢@@ÉA›ÑÂAº£»@•F1?Å?†áØ>ÝÍA1™»ALÆ@@ÉA›ÑÂAº£»@£ëÉA1™»Aâhß@aT+?¯¢?XŠÝ>£ëÉA1™»Aâhß@@ÉA›ÑÂAº£»@~„ÅA›ÑÂAúfÓ@­(?Æ?+Åò>£ëÉA1™»Aâhß@~„ÅA›ÑÂAúfÓ@~„ÅA1™»AÐE÷@š’"?¯¢?$‡ö>~„ÅA1™»AÐE÷@~„ÅA›ÑÂAúfÓ@ìYÁA›ÑÂA’ûé@+"?Æ?Ÿ¦?~„ÅA1™»AÐE÷@ìYÁA›ÑÂA’ûé@]®ÀA1™»A]àAè?®¢??]®ÀA1™»A]àAìYÁA›ÑÂA’ûé@WƼA›ÑÂA/Aÿ@e³?Å?Q+?]®ÀA1™»A]àAWƼA›ÑÂA/Aÿ@.p»A1™»Aº\A¥b?®¢? ?.p»A1™»Aº\AWƼA›ÑÂA/Aÿ@LзA›ÑÂA®Œ A¼o ?Æ?.à?.p»A1™»Aº\ALзA›ÑÂA®Œ AtѵA1™»AûA]?®¢?kY?tѵA1™»AûALзA›ÑÂA®Œ Aå~²A›ÑÂAسAžÎú>Å?ãµ%?tѵA1™»AûAå~²A›ÑÂAسA8Ú¯A1™»AG×#Aàî>®¢?ò´%?8Ú¯A1™»AG×#Aå~²A›ÑÂAسA¿Ù¬A›ÑÂAûA³Vá>Å?Yž.?8Ú¯A1™»AG×#A¿Ù¬A›ÑÂAûA“©A1™»A»+A=šÔ>®¢?<#.?“©A1™»A»+A¿Ù¬A›ÑÂAûAîè¦A›ÑÂA)€"A-œÆ>Æ?ÑŒ6?“©A1™»A»+Aîè¦A›ÑÂA)€"AÜ£A1™»Aâ¨2A<û¹>®¢?9˜5?Ü£A1™»Aâ¨2Aîè¦A›ÑÂA)€"Aö´ A›ÑÂA²)AOŪ>Å?ðu=?Ü£A1™»Aâ¨2Aö´ A›ÑÂA²)A9œA1™»Aú–8A÷Qž>®¢?: Å?ÑOC?9œA1™»Aú–8A¶FšA›ÑÂA2«.A~9•A1™»AÎ|=A Æ>¯¢?mA?~9•A1™»AÎ|=A¶FšA›ÑÂA2«.Ad§“A›ÑÂA¢M3A±Æ`>Å?H?~9•A1™»AÎ|=Ad§“A›ÑÂA¢M3A ŽA1™»AYSAA¢I>¯¢?ê»E? ŽA1™»AYSAAd§“A›ÑÂA¢M3AzàŒA›ÑÂA_ï6AªW$>Å?æµK? ŽA1™»AYSAAzàŒA›ÑÂA_ï6AdžA1™»ADAlU >®¢?µïH?džA1™»ADAzàŒA›ÑÂA_ï6A­û…A›ÑÂA5‹9A¶úÍ=Æ?6N?džA1™»ADA­û…A›ÑÂA5‹9A›Ñ~A1™»A)¾EAÁ¿¡=®¢?ÕK?›Ñ~A1™»A)¾EA­û…A›ÑÂA5‹9A·~A›ÑÂAi;Ag>$=Æ? O?›Ñ~A1™»A)¾EA·~A›ÑÂAi;ApA1™»ALFA_´Ÿ<¯¢?PõK?pA1™»ALFA·~A›ÑÂAi;ApA›ÑÂAº£;A†Ç¨¼Æ?Ú¾O?pA1™»ALFApA›ÑÂAº£;Ae.aA1™»A)¾EAw=$½®¢?ÊÂK?e.aA1™»A)¾EApA›ÑÂAº£;AIúaA›ÑÂAi;AŽF¦½Æ?=ÅN?e.aA1™»A)¾EAIúaA›ÑÂAi;ArRA1™»ADAþ´Ë½¯¢?ŽlJ?rRA1™»ADAIúaA›ÑÂAi;A¥TA›ÑÂA5‹9A–¶¾Å?™£L?rRA1™»ADA¥TA›ÑÂA5‹9AìßCA1™»AYSAAÎ"¾¯¢?„ôG?ìßCA1™»AYSAA¥TA›ÑÂA5‹9A ?FA›ÑÂA_ï6A·zM¾Å?ý\I?ìßCA1™»AYSAA ?FA›ÑÂA_ï6A5A1™»AÎ|=Ae]¾¯¢?6^D?5A1™»AÎ|=A ?FA›ÑÂA_ï6A8±8A›ÑÂA¢M3AVŒ„¾Å?öD?5A1™»AÎ|=A8±8A›ÑÂA¢M3AÊ'A1™»Aú–8A²¼‹¾¯¢?Æ®??Ê'A1™»Aú–8A8±8A›ÑÂA¢M3A”r+A›ÑÂA2«.AŽ¡¾Æ?9u??Ê'A1™»Aú–8A”r+A›ÑÂA2«.AGöA1™»Aâ¨2AËþ§¾¯¢?êì9?GöA1™»Aâ¨2A”r+A›ÑÂA2«.A–A›ÑÂA²)Acǽ¾Æ??â8?GöA1™»Aâ¨2A–A›ÑÂA²)AòÙ A1™»A»+AaPþ®¢?ß 3?òÙ A1™»A»+A–A›ÑÂA²)A".A›ÑÂA)€"A†áؾÅ?•F1?òÙ A1™»A»+A".A›ÑÂA)€"AKA1™»AG×#AXŠÝ¾¯¢?aT+?KA1™»AG×#A".A›ÑÂA)€"A‚LA›ÑÂAûA+Åò¾Æ?­(?KA1™»AG×#A‚LA›ÑÂAûA0ºè@1™»AûA$‡ö¾¯¢?š’"?0ºè@1™»AûA‚LA›ÑÂAûAmö@›ÑÂAسAŸ¦¿Æ?+"?0ºè@1™»AûAmö@›ÑÂAسAF?Ò@1™»Aº\A¿®¢?è?F?Ò@1™»Aº\Amö@›ÑÂAسAоà@›ÑÂA®Œ AQ+¿Å?e³?F?Ò@1™»Aº\Aоà@›ÑÂA®Œ A‹F½@1™»A]àA ¿®¢?¥b?‹F½@1™»A]àAоà@›ÑÂA®Œ A£æÌ@›ÑÂA/Aÿ@.à¿Æ?¼o ?‹F½@1™»A]àA£æÌ@›ÑÂA/Aÿ@ î©@1™»AÐE÷@kY¿®¢?]? î©@1™»AÐE÷@£æÌ@›ÑÂA/Aÿ@P˜º@›ÑÂA’ûé@ãµ%¿Å?žÎú> î©@1™»AÐE÷@P˜º@›ÑÂA’ûé@rQ˜@1™»Aâhß@ò´%¿®¢?àî>rQ˜@1™»Aâhß@P˜º@›ÑÂA’ûé@ î©@›ÑÂAúfÓ@Yž.¿Å?³Vá>rQ˜@1™»Aâhß@ î©@›ÑÂAúfÓ@û‰ˆ@1™»ALÆ@<#.¿®¢?=šÔ>û‰ˆ@1™»ALÆ@ î©@›ÑÂAúfÓ@®ÿš@›ÑÂAº£»@ÑŒ6¿Æ?-œÆ>û‰ˆ@1™»ALÆ@®ÿš@›ÑÂAº£»@x\u@1™»Ar¬@9˜5¿®¢?<û¹>x\u@1™»Ar¬@®ÿš@›ÑÂAº£»@œâ@›ÑÂA×Ó¢@ðu=¿Å?OŪ>x\u@1™»Ar¬@œâ@›ÑÂA×Ó¢@¤]@1™»Alä@: <¿®¢?÷Qž>¤]@1™»Alä@œâ@›ÑÂA×Ó¢@œ©‚@›ÑÂA؉@ÑOC¿Å?õù>¤]@1™»Alä@œ©‚@›ÑÂA؉@Ç J@1™»AðËi@mA¿¯¢? Æ>Ç J@1™»AðËi@œ©‚@›ÑÂA؉@uÉr@›ÑÂA;]@H¿Å?±Æ`>Ç J@1™»AðËi@uÉr@›ÑÂA;]@š²:@1™»AO€0@ê»E¿¯¢?¢I>š²:@1™»AO€0@uÉr@›ÑÂA;]@‚Bd@›ÑÂAÑ'@•E?o³"?«£Ÿ?|s)?V·¿=›ÅÔA›ÑÂAÔºß?b¸ÏAèžÉAó[R?ÕûÎAèžÉA^ÅÑ?–A?$?È•>›ÅÔA›ÑÂAÔºß?ÕûÎAèžÉA^ÅÑ?¯wÓA›ÑÂAÑ'@Þ¯wÓA›ÑÂAÑ'@ÕûÎAèžÉA^ÅÑ?¾ÂÍAèžÉA8˜@$ø=?$?ºéA>¯wÓA›ÑÂAÑ'@¾ÂÍAèžÉA8˜@ѦÑA›ÑÂA;]@à°8?|s)?¢JP>ѦÑA›ÑÂA;]@¾ÂÍAèžÉA8˜@âÌAèžÉA‘mO@¸Ð9?$?(z>ѦÑA›ÑÂA;]@âÌAèžÉA‘mO@™UÏA›ÑÂA؉@wH4?|s)?`uƒ>™UÏA›ÑÂA؉@âÌAèžÉA‘mO@­âÉAèžÉAùŒ€@GŸ4?$? €˜>™UÏA›ÑÂA؉@­âÉAèžÉAùŒ€@X‡ÌA›ÑÂA×Ó¢@ôÝ.?|s)?; ž>X‡ÌA›ÑÂA×Ó¢@­âÉAèžÉAùŒ€@X‡ÌA›ÑÂA×Ó¢@@ÉA›ÑÂAº£»@P˜º@›ÑÂA’ûé@”Þ@èžÉA3Tï@£æÌ@èžÉAZbÛ@‚X¿$?·˜ì>P˜º@›ÑÂA’ûé@£æÌ@èžÉAZbÛ@ î©@›ÑÂAúfÓ@yÝ¿}s)?KÜß> î©@›ÑÂAúfÓ@£æÌ@èžÉAZbÛ@‹F½@èžÉAj6Æ@¾¿$¿$?H‘Ô> î©@›ÑÂAúfÓ@‹F½@èžÉAj6Æ@®ÿš@›ÑÂAº£»@:Ë#¿|s)?^ðÇ>®ÿš@›ÑÂAº£»@‹F½@èžÉAj6Æ@«F¯@èžÉAµî¯@;,¿$?ˆY»>®ÿš@›ÑÂAº£»@«F¯@èžÉAµî¯@œâ@›ÑÂA×Ó¢@|Î*¿|s)?2æ®>œâ@›ÑÂA×Ó¢@«F¯@èžÉAµî¯@û¢@èžÉA «˜@ê¿2¿$?Ž¡>œâ@›ÑÂA×Ó¢@û¢@èžÉA «˜@œ©‚@›ÑÂA؉@5Ý0¿|s)?¢á”>œ©‚@›ÑÂA؉@û¢@èžÉA «˜@Lu˜@èžÉAùŒ€@ÎD8¿$?õê…>œ©‚@›ÑÂA؉@Lu˜@èžÉAùŒ€@uÉr@›ÑÂA;]@¸î5¿|s)?Öt>uÉr@›ÑÂA;]@Lu˜@èžÉAùŒ€@wÄ@èžÉA‘mO@âÁ<¿$?GT>uÉr@›ÑÂA;]@wÄ@èžÉA‘mO@‚Bd@›ÑÂAÑ'@Åû9¿|s)?þþ<>‚Bd@›ÑÂAÑ'@wÄ@èžÉA‘mO@õˆ@èžÉA8˜@|Š5¿NE4?O=nš@Z÷ÏAO/C?ʈ@=·ËAk³ß)u@èžÉAó[R?[$:¿h¯/?Ö¥•¾ÂÍAèžÉA8˜@‡µÈAZ÷ÏA–£Â?“ÇAZ÷ÏAoL@‡ƒ1?)Î2?VC5>¾ÂÍAèžÉA8˜@“ÇAZ÷ÏAoL@âÌAèžÉA‘mO@aû+?RQ7?FB>âÌAèžÉA‘mO@“ÇAZ÷ÏAoL@›þÅAZ÷ÏAw@@‡¡-?)Î2?”Ñi>âÌAèžÉA‘mO@›þÅAZ÷ÏAw@@­âÉAèžÉAùŒ€@Nà'?RQ7?ät>­âÉAèžÉAùŒ€@›þÅAZ÷ÏAw@@„úÃAZ÷ÏA"Žn@òÆ(?)Î2?‰ˆŽ>­âÉAèžÉAùŒ€@„úÃAZ÷ÏA"Žn@U.ÄAèžÉAµî¯@©‰ÁAZ÷ÏA×§@…¯¾AZ÷ÏAÐ=£@1E?)Î2?P@¿>U.ÄAèžÉAµî¯@…¯¾AZ÷ÏAÐ=£@]®ÀAèžÉAj6Æ@9 ?RQ7?aÂ>]®ÀAèžÉAj6Æ@…¯¾AZ÷ÏAÐ=£@.p»AZ÷ÏAê·@í¯?)Î2?˜Ö>]®ÀAèžÉAj6Æ@.p»AZ÷ÏAê·@WƼAèžÉAZbÛ@I_?RQ7?dø×>WƼAèžÉAZbÛ@.p»AZ÷ÏAê·@LзAZ÷ÏA Ë@ÊE ?)Î2?e²ë>WƼAèžÉAZbÛ@LзAZ÷ÏA Ë@Ú{¸AèžÉA3Tï@…ç?RQ7?6¥ì>Ú{¸AèžÉA3Tï@LзAZ÷ÏA Ë@ Õ³AZ÷ÏA•Þ@Õ?)Î2?a?Ú{¸AèžÉA3Tï@ Õ³AZ÷ÏA•Þ@ Õ³AèžÉAµ÷A`ù>RQ7?=ÿÿ> Õ³AèžÉAµ÷A Õ³AZ÷ÏA•Þ@%„¯AZ÷ÏA3Tï@rHò>)Î2?Op ? Õ³AèžÉAµ÷A%„¯AZ÷ÏA3Tï@–Ø®AèžÉA®Œ A Œå>RQ7?bõ?–Ø®AèžÉA®Œ A%„¯AZ÷ÏA3Tï@ÃãªAZ÷ÏA/Aÿ@[Ý>)Î2?y?–Ø®AèžÉA®Œ AÃãªAZ÷ÏA/Aÿ@š©AèžÉAº\AˆoÐ>RQ7?'?š©AèžÉAº\AÃãªAZ÷ÏA/Aÿ@…ú¥AZ÷ÏA]àAÉ›Æ>)Î2?võ?š©AèžÉAº\A…ú¥AZ÷ÏA]àA­û£AèžÉAª\A†(º>RQ7?òˆ?­û£AèžÉAª\A…ú¥AZ÷ÏA]àAtÏ AZ÷ÏA _ Aß ¯>)Î2? ó ?­û£AèžÉAª\AtÏ AZ÷ÏA _ AÈ*žAèžÉAy‚A×¢>RQ7?r?È*žAèžÉAy‚AtÏ AZ÷ÏA _ Aõi›AZ÷ÏARA[–>)Î2?. '?È*žAèžÉAy‚Aõi›AZ÷ÏARA>#˜AèžÉAZÅ#AZœŠ>RQ7?8´$?>#˜AèžÉAZÅ#Aõi›AZ÷ÏARAÄÑ•AZ÷ÏA õAÅ8z>)Î2?02,?>#˜AèžÉAZÅ#AÄÑ•AZ÷ÏA õA²í‘AèžÉAÄ(A…6c>RQ7?1l)?²í‘AèžÉAÄ(AÄÑ•AZ÷ÏA õAáAZ÷ÏA5ýA— F>)Î2?«c0?²í‘AèžÉAÄ(AáAZ÷ÏA5ýA“‹AèžÉA~…+A ï/>RQ7?1-?“‹AèžÉA~…+AáAZ÷ÏA5ýA)ŠAZ÷ÏA&AßÄ>)Î2?ž˜3?“‹AèžÉA~…+A)ŠAZ÷ÏA&AV…AèžÉAª÷-A_W÷=RQ7?ÿ/?V…AèžÉAª÷-A)ŠAZ÷ÏA&A:*„AZ÷ÏAk!AÉ[µ=)Î2?rÌ5?V…AèžÉAª÷-A:*„AZ÷ÏAk!A¿%}AèžÉAÅp/An=RQ7?•Ð1?¿%}AèžÉAÅp/A:*„AZ÷ÏAk!Aõ2|AZ÷ÏAõÈ"AaT=)Î2?ü6?¿%}AèžÉAÅp/Aõ2|AZ÷ÏAõÈ"ApAèžÉAµî/A 튔Þ@èžÉA3Tï@µ÷AZ÷ÏA3Tï@Ì«ð@Z÷ÏA•Þ@Op ¿)Î2?rHò>”Þ@èžÉA3Tï@Ì«ð@Z÷ÏA•Þ@£æÌ@èžÉAZbÛ@bõ¿RQ7? Œå>£æÌ@èžÉAZbÛ@Ì«ð@Z÷ÏA•Þ@оà@Z÷ÏA Ë@y¿)Î2?[Ý>£æÌ@èžÉAZbÛ@оà@Z÷ÏA Ë@‹F½@èžÉAj6Æ@'¿RQ7?ˆoÐ>‹F½@èžÉAj6Æ@оà@Z÷ÏA Ë@F?Ò@Z÷ÏAê·@võ¿)Î2?É›Æ>‹F½@èžÉAj6Æ@F?Ò@Z÷ÏAê·@«F¯@èžÉAµî¯@òˆ¿RQ7?†(º>«F¯@èžÉAµî¯@F?Ò@Z÷ÏAê·@ëAÅ@Z÷ÏAÐ=£@ ó ¿)Î2?ß ¯>«F¯@èžÉAµî¯@ëAÅ@Z÷ÏAÐ=£@û¢@èžÉA «˜@r¿RQ7?×¢>û¢@èžÉA «˜@ëAÅ@Z÷ÏAÐ=£@[Ù¹@Z÷ÏA×§@. '¿)Î2?[–>û¢@èžÉA «˜@[Ù¹@Z÷ÏA×§@Lu˜@èžÉAùŒ€@8´$¿RQ7?ZœŠ>Lu˜@èžÉAùŒ€@[Ù¹@Z÷ÏA×§@ë°@Z÷ÏA"Žn@02,¿)Î2?Å8z>Lu˜@èžÉAùŒ€@ë°@Z÷ÏA"Žn@wÄ@èžÉA‘mO@1l)¿RQ7?…6c>wÄ@èžÉA‘mO@ë°@Z÷ÏA"Žn@•¨@Z÷ÏAw@@«c0¿)Î2?— F>wÄ@èžÉA‘mO@•¨@Z÷ÏAw@@õˆ@èžÉA8˜@1-¿RQ7? ï/>õˆ@èžÉA8˜@•¨@Z÷ÏAw@@䳡@Z÷ÏAoL@@T¿SL?ócò<È\Ò@&ÛAÿ¦!?‚ö´@\½ÕAEÉ)̵@ÝÑÕA:ë2?uÅ ¿$.G?èˆ~<̵@ÝÑÕA:ë2?‚ö´@\½ÕAEÉ)ޤ­@MaÔA îÌ)F†%¿~C?º=̵@ÝÑÕA:ë2?ޤ­@MaÔA îÌ)nš@Z÷ÏAO/C?Ÿ}*¿Gë>?ƒâŠ<nš@Z÷ÏAO/C?ޤ­@MaÔA îÌ)<ú™@p×ÏA2ÃÖ)K)1¿ñ¾8?÷àŠ<nš@Z÷ÏAO/C?<ú™@p×ÏA2ÃÖ)ʈ@=·ËAk³ß)MÚ-?ÛÜ;?ŠÖŠ<œÉAˆôÏAOY©½eÉAB,ÐA¿yX©{dÉAZ÷ÏAO/C?(÷(?#@?›!={dÉAZ÷ÏAO/C?½eÉAB,ÐA¿yX© œÂAÝÑÕA:ë2?§z(?ÿþ??ŒÕ‡={dÉAZ÷ÏAO/C? œÂAÝÑÕA:ë2?‡µÈAZ÷ÏA–£Â?¤3#?h(D?*˜¤=‡µÈAZ÷ÏA–£Â? œÂAÝÑÕA:ë2?­ûÁAÝÑÕA'k²?8½&?ÿþ??’-ì=‡µÈAZ÷ÏA–£Â?­ûÁAÝÑÕA'k²?“ÇAZ÷ÏAoL@65!?h(D?õÙ>“ÇAZ÷ÏAoL@­ûÁAÝÑÕA'k²?cñÀAÝÑÕA 0@$?ÿþ??¾™'>“ÇAZ÷ÏAoL@cñÀAÝÑÕA 0@›þÅAZ÷ÏAw@@ýO?h(D?¬2>›þÅAZ÷ÏAw@@cñÀAÝÑÕA 0@«~¿AÝÑÕAÿl0@ z ?ÿþ??¾,X>›þÅAZ÷ÏAw@@«~¿AÝÑÕAÿl0@„úÃAZ÷ÏA"Žn@ˆ?h(D?=a>„úÃAZ÷ÏA"Žn@«~¿AÝÑÕAÿl0@—¥½AÝÑÕAɬZ@Eý?ÿþ??"Ń>„úÃAZ÷ÏA"Žn@—¥½AÝÑÕAɬZ@©‰ÁAZ÷ÏA×§@ã?g(D?“‡‡>©‰ÁAZ÷ÏA×§@—¥½AÝÑÕAɬZ@Îh»AÝÑÕAÁÙ@+¡?ÿþ??=·š>©‰ÁAZ÷ÏA×§@Îh»AÝÑÕAÁÙ@…¯¾AZ÷ÏAÐ=£@Pg?h(D?>…¯¾AZ÷ÏAÐ=£@Îh»AÝÑÕAÁÙ@ƒË¸AÝÑÕA6£•@jm?ÿþ??Ù˰>…¯¾AZ÷ÏAÐ=£@ƒË¸AÝÑÕA6£•@.p»AZ÷ÏAê·@á ?h(D?ܱ²>.p»AZ÷ÏAê·@ƒË¸AÝÑÕA6£•@tѵAÝÑÕAr–¨@åj ?ÿþ??YãÅ>.p»AZ÷ÏAê·@tѵAÝÑÕAr–¨@LзAZ÷ÏA Ë@¸ ?g(D?bÖÆ>LзAZ÷ÏA Ë@tѵAÝÑÕAr–¨@å~²AÝÑÕAP˜º@££?ÿþ??‰ßÙ>LзAZ÷ÏA Ë@å~²AÝÑÕAP˜º@ Õ³AZ÷ÏA•Þ@âö>h(D?@ÞÙ> Õ³AZ÷ÏA•Þ@å~²AÝÑÕAP˜º@–Ø®AÝÑÕA Ë@‘Eò>ÿþ??Ï£ì> Õ³AZ÷ÏA•Þ@–Ø®AÝÑÕA Ë@%„¯AZ÷ÏA3Tï@i‰å>h(D?5®ë>%„¯AZ÷ÏA3Tï@–Ø®AÝÑÕA Ë@ÃãªAÝÑÕAZbÛ@éß>ÿþ??Kþ>%„¯AZ÷ÏA3Tï@ÃãªAÝÑÕAZbÛ@ÃãªAZ÷ÏA/Aÿ@QHÓ>g(D?¾,ü>ÃãªAZ÷ÏA/Aÿ@ÃãªAÝÑÕAZbÛ@¦¦AÝÑÕA’ûé@ãKÌ>ÿþ??‚ ?ÃãªAZ÷ÏA/Aÿ@¦¦AÝÑÕA’ûé@…ú¥AZ÷ÏA]àA¿Ø¿>h(D?!¡?…ú¥AZ÷ÏA]àA¦¦AÝÑÕA’ûé@œ%¢AÝÑÕAÐE÷@HŠ·>ÿþ??O?…ú¥AZ÷ÏA]àAœ%¢AÝÑÕAÐE÷@tÏ AZ÷ÏA _ AƒV«>g(D?’l ?tÏ AZ÷ÏA _ Aœ%¢AÝÑÕAÐE÷@ÍhAÝÑÕA—AéÁ¡>ÿþ??ÌÄ?tÏ AZ÷ÏA _ AÍhAÝÑÕA—Aõi›AZ÷ÏARAüÞ•>h(D?ún?õi›AZ÷ÏARAÍhAÝÑÕA—Apv˜AÝÑÕA›ÑAõ‹>ÿþ??–e?õi›AZ÷ÏARApv˜AÝÑÕA›ÑAÄÑ•AZ÷ÏA õAÉ!>h(D?¾Ÿ?ÄÑ•AZ÷ÏA õApv˜AÝÑÕA›ÑA™U“AÝÑÕA.K AÐ5g>ÿþ??U)?ÄÑ•AZ÷ÏA õA™U“AÝÑÕA.K AáAZ÷ÏA5ýAWQ>g(D?n÷?áAZ÷ÏA5ýA™U“AÝÑÕA.K A  ŽAÝÑÕAUýA±ü6>ÿþ??7 #?áAZ÷ÏA5ýA  ŽAÝÑÕAUýA)ŠAZ÷ÏA&A‹ã!>h(D?Ôo?)ŠAZ÷ÏA&A  ŽAÝÑÕAUýA¦ˆAÝÑÕAÅâA›½>ÿþ??±ÿ%?)ŠAZ÷ÏA&A¦ˆAÝÑÕAÅâA:*„AZ÷ÏAk!Aóã=h(D?ø"?:*„AZ÷ÏAk!A¦ˆAÝÑÕAÅâA²&ƒAÝÑÕAZ÷A~§=ÿþ??‚(?:*„AZ÷ÏAk!A²&ƒAÝÑÕAZ÷Aõ2|AZ÷ÏAõÈ"A ‚=h(D?)°#?õ2|AZ÷ÏAõÈ"A²&ƒAÝÑÕAZ÷A´.{AÝÑÕA8AT"=ÿþ??à )?õ2|AZ÷ÏAõÈ"A´.{AÝÑÕA8ApAZ÷ÏAÐ=#A^¯~µ÷AZ÷ÏA3Tï@׳AÝÑÕA’ûé@z8 AÝÑÕAZbÛ@Ï£ì¾ÿþ??‘Eò>µ÷AZ÷ÏA3Tï@z8 AÝÑÕAZbÛ@Ì«ð@Z÷ÏA•Þ@5®ë¾h(D?i‰å>Ì«ð@Z÷ÏA•Þ@z8 AÝÑÕAZbÛ@ÓNAÝÑÕA Ë@Kþ¾ÿþ??éß>Ì«ð@Z÷ÏA•Þ@ÓNAÝÑÕA Ë@оà@Z÷ÏA Ë@¾,ü¾g(D?QHÓ>оà@Z÷ÏA Ë@ÓNAÝÑÕA Ë@mö@ÝÑÕAP˜º@‚ ¿ÿþ??ãKÌ>оà@Z÷ÏA Ë@mö@ÝÑÕAP˜º@F?Ò@Z÷ÏAê·@!¡¿h(D?¿Ø¿>F?Ò@Z÷ÏAê·@mö@ÝÑÕAP˜º@0ºè@ÝÑÕAr–¨@O¿ÿþ??HŠ·>F?Ò@Z÷ÏAê·@0ºè@ÝÑÕAr–¨@ëAÅ@Z÷ÏAÐ=£@’l ¿g(D?ƒV«>ëAÅ@Z÷ÏAÐ=£@0ºè@ÝÑÕAr–¨@öÑÜ@ÝÑÕA6£•@ÌÄ¿ÿþ??éÁ¡>ëAÅ@Z÷ÏAÐ=£@öÑÜ@ÝÑÕA6£•@[Ù¹@Z÷ÏA×§@ún¿h(D?üÞ•>[Ù¹@Z÷ÏA×§@öÑÜ@ÝÑÕA6£•@È\Ò@ÝÑÕAÁÙ@–e¿ÿþ??õ‹>[Ù¹@Z÷ÏA×§@È\Ò@ÝÑÕAÁÙ@ë°@Z÷ÏA"Žn@¾Ÿ¿h(D?É!>ë°@Z÷ÏA"Žn@È\Ò@ÝÑÕAÁÙ@£iÉ@ÝÑÕAɬZ@U)¿ÿþ??Ð5g>ë°@Z÷ÏA"Žn@£iÉ@ÝÑÕAɬZ@•¨@Z÷ÏAw@@n÷¿g(D?WQ>•¨@Z÷ÏAw@@£iÉ@ÝÑÕAɬZ@VÂ@ÝÑÕAÿl0@7 #¿ÿþ??±ü6>•¨@Z÷ÏAw@@VÂ@ÝÑÕAÿl0@䳡@Z÷ÏAoL@Ôo¿h(D?‹ã!>䳡@Z÷ÏAoL@VÂ@ÝÑÕAÿl0@t:¼@ÝÑÕA 0@Ê4?ƒJ?>Ž~<]¹ÂAž´ÕA>>©h¿ANSØAõÑ1© œÂAÝÑÕA:ë2?Yü?ÜM?»Yò< œÂAÝÑÕA:ë2?h¿ANSØAõÑ1©Îh»A&ÛAÿ¦!?~»?³L?Â-x= œÂAÝÑÕA:ë2?Îh»A&ÛAÿ¦!?­ûÁAÝÑÕA'k²?¨3?pæO?œ•=­ûÁAÝÑÕA'k²?Îh»A&ÛAÿ¦!?é׺A&ÛAH3¡?µ$?³L?_¦×=­ûÁAÝÑÕA'k²?é׺A&ÛAH3¡?cñÀAÝÑÕA 0@Èc?pæO?bÌí=cñÀAÝÑÕA 0@é׺A&ÛAH3¡?Qç¹A&ÛAH¬ð?´?³L?>cñÀAÝÑÕA 0@Qç¹A&ÛAH¬ð?«~¿AÝÑÕAÿl0@UÂ?pæO?[S">«~¿AÝÑÕAÿl0@Qç¹A&ÛAH¬ð?_˜¸A&ÛA\f@+m?³L?åRE>«~¿AÝÑÕAÿl0@_˜¸A&ÛA\f@—¥½AÝÑÕAɬZ@S ?pæO?ØL>—¥½AÝÑÕAɬZ@_˜¸A&ÛA\f@óì¶A&ÛA_’E@œT?³L?¹Šp>—¥½AÝÑÕAɬZ@óì¶A&ÛA_’E@Îh»AÝÑÕAÁÙ@ç?pæO? 7v>Îh»AÝÑÕAÁÙ@óì¶A&ÛA_’E@qç´A&ÛAˆ£j@Gp ?´L?5>Îh»AÝÑÕAÁÙ@qç´A&ÛAˆ£j@ƒË¸AÝÑÕA6£•@â?pæO?Q>ƒË¸AÝÑÕA6£•@qç´A&ÛAˆ£j@¼Š²A&ÛAc2‡@/Ç?³L?©Z¡>ƒË¸AÝÑÕA6£•@¼Š²A&ÛAc2‡@tѵAÝÑÕAr–¨@IÒú>pæO?ðM¢>tѵAÝÑÕAr–¨@¼Š²A&ÛAc2‡@8Ú¯A&ÛArQ˜@ÛÂú>³L?:™´>tѵAÝÑÕAr–¨@8Ú¯A&ÛArQ˜@å~²AÝÑÕAP˜º@µýí>pæO?2˜´>å~²AÝÑÕAP˜º@8Ú¯A&ÛArQ˜@¿Ù¬A&ÛAr–¨@Wì>´L?<ÕÆ>å~²AÝÑÕAP˜º@¿Ù¬A&ÛAr–¨@–Ø®AÝÑÕA Ë@iÔß>pæO?èßÅ>–Ø®AÝÑÕA Ë@¿Ù¬A&ÛAr–¨@š©A&ÛAê·@& Ý>´L?–ô×>–Ø®AÝÑÕA Ë@š©A&ÛAê·@ÃãªAÝÑÕAZbÛ@«jÐ>pæO?T Ö>ÃãªAÝÑÕAZbÛ@š©A&ÛAê·@…ú¥A&ÛAj6Æ@IÌ>³L?ÂÞç>ÃãªAÝÑÕAZbÛ@…ú¥A&ÛAj6Æ@¦¦AÝÑÕA’ûé@ŠÖ¿>pæO?Nå>¦¦AÝÑÕA’ûé@…ú¥A&ÛAj6Æ@œ%¢A&ÛAúfÓ@`cº>³L?ú|ö>¦¦AÝÑÕA’ûé@œ%¢A&ÛAúfÓ@œ%¢AÝÑÕAÐE÷@Å/®>pæO?e¸ò>œ%¢AÝÑÕAÐE÷@œ%¢A&ÛAúfÓ@\žA&ÛAâhß@ir§>´L?(Ý?œ%¢AÝÑÕAÐE÷@\žA&ÛAâhß@ÍhAÝÑÕA—A ›>pæO?ÿ>ÍhAÝÑÕA—A\žA&ÛAâhß@™Ì™A&ÛAò*ê@¹‘“>´L?æÁ?ÍhAÝÑÕA—A™Ì™A&ÛAò*ê@pv˜AÝÑÕA›ÑAĈ>pæO?9ü?pv˜AÝÑÕA›ÑA™Ì™A&ÛAò*ê@pT•A&ÛAÂó@†»}>³L?Jä ?pv˜AÝÑÕA›ÑApT•A&ÛAÂó@™U“AÝÑÕA.K A;žg>pæO?޲ ?™U“AÝÑÕA.K ApT•A&ÛAÂó@L²A&ÛA̳û@ZèR>´L?ø<?™U“AÝÑÕA.K AL²A&ÛA̳û@  ŽAÝÑÕAUýAQÏ=>pæO?Á£ ?  ŽAÝÑÕAUýAL²A&ÛA̳û@Ëì‹A&ÛA¾0A;ç&>´L?·Å?  ŽAÝÑÕAUýAËì‹A&ÛA¾0A¦ˆAÝÑÕAÅâA¬ð>pæO?,Ê?¦ˆAÝÑÕAÅâAËì‹A&ÛA¾0AÄ ‡A&ÛA¡ÎAQîó=´L?yy?¦ˆAÝÑÕAÅâAÄ ‡A&ÛA¡ÎA²&ƒAÝÑÕAZ÷ALÎ=pæO?M!?²&ƒAÝÑÕAZ÷AÄ ‡A&ÛA¡ÎA5‚A&ÛAѯAó°˜=³L?_T?²&ƒAÝÑÕAZ÷A5‚A&ÛAѯA´.{AÝÑÕA8ABëk=pæO?Ë¥?´.{AÝÑÕA8A5‚A&ÛAѯApzA&ÛA›ÑAïcò<³L?ÀS?´.{AÝÑÕA8ApzA&ÛA›ÑApAÝÑÕA6£A¬fA&ÛA̳û@¹Šp¾³L?œT?ÍT9AÝÑÕA.K Ah›>A&ÛA̳û@/AÝÑÕA›ÑA 7v¾pæO?ç?/AÝÑÕA›ÑAh›>A&ÛA̳û@W5A&ÛAÂó@5¾´L?Gp ?/AÝÑÕA›ÑAW5A&ÛAÂó@d.%AÝÑÕA—AQ¾pæO?â?d.%AÝÑÕA—AW5A&ÛAÂó@Îf,A&ÛAò*ê@©Z¡¾³L?/Ç?d.%AÝÑÕA—AÎf,A&ÛAò*ê@Ç´AÝÑÕAÐE÷@ðM¢¾pæO?IÒú>Ç´AÝÑÕAÐE÷@Îf,A&ÛAò*ê@G×#A&ÛAâhß@:™´¾³L?ÛÂú>Ç´AÝÑÕAÐE÷@G×#A&ÛAâhß@׳AÝÑÕA’ûé@2˜´¾pæO?µýí>׳AÝÑÕA’ûé@G×#A&ÛAâhß@Ç´A&ÛAúfÓ@<ÕÆ¾´L?Wì>׳AÝÑÕA’ûé@Ç´A&ÛAúfÓ@z8 AÝÑÕAZbÛ@èßžpæO?iÔß>z8 AÝÑÕAZbÛ@Ç´A&ÛAúfÓ@õ A&ÛAj6Æ@–ô×¾´L?& Ý>z8 AÝÑÕAZbÛ@õ A&ÛAj6Æ@ÓNAÝÑÕA Ë@T Ö¾pæO?«jÐ>ÓNAÝÑÕA Ë@õ A&ÛAj6Æ@Ëä A&ÛAê·@ÂÞç¾³L?IÌ>ÓNAÝÑÕA Ë@Ëä A&ÛAê·@mö@ÝÑÕAP˜º@Nå¾pæO?ŠÖ¿>mö@ÝÑÕAP˜º@Ëä A&ÛAê·@‚LA&ÛAr–¨@ú|ö¾³L?`cº>mö@ÝÑÕAP˜º@‚LA&ÛAr–¨@0ºè@ÝÑÕAr–¨@e¸ò¾pæO?Å/®>0ºè@ÝÑÕAr–¨@‚LA&ÛAr–¨@KA&ÛArQ˜@(Ý¿´L?ir§>0ºè@ÝÑÕAr–¨@KA&ÛArQ˜@öÑÜ@ÝÑÕA6£•@ÿ¾pæO? ›>öÑÜ@ÝÑÕA6£•@KA&ÛArQ˜@ Õõ@&ÛAc2‡@æÁ¿´L?¹‘“>öÑÜ@ÝÑÕA6£•@ Õõ@&ÛAc2‡@È\Ò@ÝÑÕAÁÙ@9ü¿pæO?Ĉ>È\Ò@ÝÑÕAÁÙ@ Õõ@&ÛAc2‡@>bì@&ÛAˆ£j@Jä ¿³L?†»}>È\Ò@ÝÑÕAÁÙ@>bì@&ÛAˆ£j@£iÉ@ÝÑÕAɬZ@޲ ¿pæO?;žg>£iÉ@ÝÑÕAɬZ@>bì@&ÛAˆ£j@3Lä@&ÛA_’E@ø<¿´L?ZèR>£iÉ@ÝÑÕAɬZ@3Lä@&ÛA_’E@VÂ@ÝÑÕAÿl0@Á£ ¿pæO?QÏ=>VÂ@ÝÑÕAÿl0@3Lä@&ÛA_’E@ƒžÝ@&ÛA\f@·Å¿´L?;ç&>VÂ@ÝÑÕAÿl0@ƒžÝ@&ÛA\f@t:¼@ÝÑÕA 0@,Ê¿pæO?¬ð>t:¼@ÝÑÕA 0@ƒžÝ@&ÛA\f@½bØ@&ÛAH¬ð?Á ¿¬«W?Ñ#Ù<Ì«ð@MìßAV{?í§Ö@hÿÛAYl¸)È\Ò@&ÛAÿ¦!?ç4¿Ò*T?^ôe<È\Ò@&ÛAÿ¦!?í§Ö@hÿÛAYl¸)ÊÆÑ@eÛAëܺ)ŒU¿aæO?·f<È\Ò@&ÛAÿ¦!?ÊÆÑ@eÛAëܺ)‚ö´@\½ÕAEÉ)Êk ?€¬V?Of<}‚»AÔÛA×á!©~ë´AñbßA*ú©Îh»A&ÛAÿ¦!?—æ?tZ?<$Ù<Îh»A&ÛAÿ¦!?~ë´AñbßA*ú© Õ³AMìßAV{?ª ?W?ÉM_=Îh»A&ÛAÿ¦!? Õ³AMìßAV{?é׺A&ÛAH3¡?î_?³zZ?JÍ…=é׺A&ÛAH3¡? Õ³AMìßAV{?qT³AMìßA¡?ɲ?W?ëÁ=é׺A&ÛAH3¡?qT³AMìßA¡?Qç¹A&ÛAH¬ð?3Á?³zZ?‘Ô=Qç¹A&ÛAH¬ð?qT³AMìßA¡?å~²AMìßA¿žÕ?4?W?ÂŒ >Qç¹A&ÛAH¬ð?å~²AMìßA¿žÕ?_˜¸A&ÛA\f@Hg?³zZ?J>_˜¸A&ÛA\f@å~²AMìßA¿žÕ?™U±AMìßA„{ @?W?_1>_˜¸A&ÛA\f@™U±AMìßA„{ @óì¶A&ÛA_’E@«ú>³zZ?W 7>óì¶A&ÛA_’E@™U±AMìßA„{ @8Ú¯AMìßA]/@#Áÿ>W?y3X>óì¶A&ÛA_’E@8Ú¯AMìßA]/@qç´A&ÛAˆ£j@® ó>³zZ?T\>qç´A&ÛAˆ£j@8Ú¯AMìßA]/@á®AMìßA£CP@ÿõö>W?VÒ}>qç´A&ÛAˆ£j@á®AMìßA£CP@¼Š²A&ÛAc2‡@;:ê>³zZ?Y¹>¼Š²A&ÛAc2‡@á®AMìßA£CP@&ö«AMìßAp@LÉì>W?è‘>¼Š²A&ÛAc2‡@&ö«AMìßAp@8Ú¯A&ÛArQ˜@sà>³zZ?!‘>8Ú¯A&ÛArQ˜@&ö«AMìßAp@“©AMìßAc2‡@šIá>W? M¢>8Ú¯A&ÛArQ˜@“©AMìßAc2‡@¿Ù¬A&ÛAr–¨@ôÔ>³zZ?üW¡>¿Ù¬A&ÛAr–¨@“©AMìßAc2‡@îè¦AMìßA6£•@_‡Ô>W?Ñ®²>¿Ù¬A&ÛAr–¨@îè¦AMìßA6£•@š©A&ÛAê·@&çÇ>³zZ?ÙÆ°>š©A&ÛAê·@îè¦AMìßA6£•@­û£AMìßAÐ=£@ß”Æ>W?ÇÂ>š©A&ÛAê·@­û£AMìßAÐ=£@…ú¥A&ÛAj6Æ@("º>³zZ?¡8¿>…ú¥A&ÛAj6Æ@­û£AMìßAÐ=£@tÏ AMìßAµî¯@†·>W?ç\Ð>…ú¥A&ÛAj6Æ@tÏ AMìßAµî¯@œ%¢A&ÛAúfÓ@®R«>³zZ?¦˜Ì>œ%¢A&ÛAúfÓ@tÏ AMìßAµî¯@ÍhAMìßAº£»@‡p§>W?¹~Ý>œ%¢A&ÛAúfÓ@ÍhAMìßAº£»@\žA&ÛAâhß@î›>³zZ?ÂÓØ>\žA&ÛAâhß@ÍhAMìßAº£»@™Ì™AMìßALÆ@Ek–>W?qcé>\žA&ÛAâhß@™Ì™AMìßALÆ@™Ì™A&ÛAò*ê@{êŠ>³zZ?qØã>™Ì™A&ÛAò*ê@™Ì™AMìßALÆ@ÿÿ•AMìßA™ØÏ@«Ž„>W?úó>™Ì™A&ÛAò*ê@ÿÿ•AMìßA™ØÏ@pT•A&ÛAÂó@Ms>³zZ?ï–í>pT•A&ÛAÂó@ÿÿ•AMìßA™ØÏ@t’AMìßA‡;Ø@’èc>W?S3ý>pT•A&ÛAÂó@t’AMìßA‡;Ø@L²A&ÛA̳û@¿ÏN>³zZ?Gö>L²A&ÛA̳û@t’AMìßA‡;Ø@£ëAMìßAâhß@…m=>W??L²A&ÛA̳û@£ëAMìßAâhß@Ëì‹A&ÛA¾0Aw)>³zZ?l ý>Ëì‹A&ÛA¾0A£ëAMìßAâhß@q¯‰AMìßAdVå@Eã>W?Ÿ­?Ëì‹A&ÛA¾0Aq¯‰AMìßAdVå@Ä ‡A&ÛA¡ÎAÛ+>³zZ?¦U?Ä ‡A&ÛA¡ÎAq¯‰AMìßAdVå@ìY…AMìßA’ûé@ÞÛ=W?Ï?Ä ‡A&ÛA¡ÎAìY…AMìßA’ûé@5‚A&ÛAѯA I¸=³zZ?ml?5‚A&ÛAѯAìY…AMìßA’ûé@Jñ€AMìßAÄQí@¤ ‰=W?"Å ?5‚A&ÛAѯAJñ€AMìßAÄQí@pzA&ÛA›ÑAegR=³zZ? Ç?pzA&ÛA›ÑAJñ€AMìßAÄQí@µ÷xAMìßA3Tï@á(Ù<W?8ª ?pzA&ÛA›ÑAµ÷xAMìßA3Tï@pA&ÛAc2AC9L<³zZ?”c?pA&ÛAc2Aµ÷xAMìßA3Tï@pAMìßAð@ff¼W?ÉÈ ?pA&ÛAc2ApAMìßAð@åeA&ÛA›ÑA·'Ù¼³zZ?$A?åeA&ÛA›ÑApAMìßAð@JgAMìßA3Tï@ÉM_½W?ª ?åeA&ÛA›ÑAJgAMìßA3Tï@—Ù[A&ÛAѯAJÍ…½³zZ?î_?—Ù[A&ÛAѯAJgAMìßA3Tï@k^AMìßAÄQí@ëÁ½W?ɲ?—Ù[A&ÛAѯAk^AMìßAÄQí@wêQA&ÛA¡ÎA‘Ô½³zZ?3Á?wêQA&ÛA¡ÎAk^AMìßAÄQí@(LUAMìßA’ûé@ÂŒ ¾W?4?wêQA&ÛA¡ÎA(LUAMìßA’ûé@i&HA&ÛA¾0AJ¾³zZ?Hg?i&HA&ÛA¾0A(LUAMìßA’ûé@¡LAMìßAdVå@_1¾W??i&HA&ÛA¾0A¡LAMìßAdVå@h›>A&ÛA̳û@W 7¾³zZ?«ú>h›>A&ÛA̳û@¡LAMìßAdVå@¸(DAMìßAâhß@y3X¾W?#Áÿ>h›>A&ÛA̳û@¸(DAMìßAâhß@W5A&ÛAÂó@T\¾³zZ?® ó>W5A&ÛAÂó@¸(DAMìßAâhß@ï;AMìßA‡;Ø@VÒ}¾W?ÿõö>W5A&ÛAÂó@ï;AMìßA‡;Ø@Îf,A&ÛAò*ê@Y¹¾³zZ?;:ê>Îf,A&ÛAò*ê@ï;AMìßA‡;Ø@ÿÿ3AMìßA™ØÏ@葾W?LÉì>Îf,A&ÛAò*ê@ÿÿ3AMìßA™ØÏ@G×#A&ÛAâhß@!‘¾³zZ?sà>G×#A&ÛAâhß@ÿÿ3AMìßA™ØÏ@Îf,AMìßALÆ@ M¢¾W?šIá>G×#A&ÛAâhß@Îf,AMìßALÆ@Ç´A&ÛAúfÓ@üW¡¾³zZ?ôÔ>Ç´A&ÛAúfÓ@Îf,AMìßALÆ@d.%AMìßAº£»@Ñ®²¾W?_‡Ô>Ç´A&ÛAúfÓ@d.%AMìßAº£»@õ A&ÛAj6Æ@ÙÆ°¾³zZ?&çÇ>õ A&ÛAj6Æ@d.%AMìßAº£»@aAMìßAµî¯@ǾW?ß”Æ>õ A&ÛAj6Æ@aAMìßAµî¯@Ëä A&ÛAê·@¡8¿¾³zZ?("º>Ëä A&ÛAê·@aAMìßAµî¯@¦AMìßAÐ=£@ç\оW?†·>Ëä A&ÛAê·@¦AMìßAÐ=£@‚LA&ÛAr–¨@¦˜Ì¾³zZ?®R«>‚LA&ÛAr–¨@¦AMìßAÐ=£@".AMìßA6£•@¹~ݾW?‡p§>‚LA&ÛAr–¨@".AMìßA6£•@KA&ÛArQ˜@ÂÓØ¾³zZ?î›>KA&ÛArQ˜@".AMìßA6£•@òÙ AMìßAc2‡@qcé¾W?Ek–>KA&ÛArQ˜@òÙ AMìßAc2‡@ Õõ@&ÛAc2‡@qØã¾³zZ?{êŠ> Õõ@&ÛAc2‡@òÙ AMìßAc2‡@³AMìßAp@úó¾W?«Ž„> Õõ@&ÛAc2‡@³AMìßAp@>bì@&ÛAˆ£j@ï–í¾³zZ?Ms>>bì@&ÛAˆ£j@³AMìßAp@=âAMìßA£CP@S3ý¾W?’èc>>bì@&ÛAˆ£j@=âAMìßA£CP@3Lä@&ÛA_’E@Gö¾³zZ?¿ÏN>3Lä@&ÛA_’E@=âAMìßA£CP@KAMìßA]/@¿W?…m=>3Lä@&ÛA_’E@KAMìßA]/@ƒžÝ@&ÛA\f@l ý¾³zZ?w)>ƒžÝ@&ÛA\f@KAMìßA]/@š©ú@MìßA„{ @Ÿ­¿W?Eã>ƒžÝ@&ÛA\f@š©ú@MìßA„{ @½bØ@&ÛAH¬ð?¦U¿³zZ?Û+>½bØ@&ÛAH¬ð?š©ú@MìßA„{ @mö@MìßA¿žÕ?ÿ9Ò¾„^i?6£<7Aq´çAÛ­Ñ>ŽûAfýãAÂÄ›)¸(AÃäA„ù>Ç£â¾O‰e?j1<¸(AÃäA„ù>ŽûAfýãAÂÄ›)yVAt{âA×i¢)6Æí¾6¤b?¯¾<¸(AÃäA„ù>yVAt{âA×i¢)Ì«ð@MìßAV{? 6ù¾ïš_?[#L<Ì«ð@MìßAV{?yVAt{âA×i¢)õUð@ÕÇßAV•«)Àv¿š [?/L<Ì«ð@MìßAV{?õUð@ÕÇßAV•«)í§Ö@hÿÛAYl¸)æ©ô>nÛ`?=8L<Þù³AàßARD©d¬A¿äAäíɨ Õ³AMìßAV{?(é>pÖc?µ¶¾< Õ³AMìßAV{?d¬A¿äAäíɨ£ë«AÃäA„ù> ó>TÛ`?Ô.E= Õ³AMìßAV{?£ë«AÃäA„ù>qT³AMìßA¡?Džç>%Öc?»{j=qT³AMìßA¡?£ë«AÃäA„ù> |«AÃäACRx?4ûð>TÛ`?§«=qT³AMìßA¡? |«AÃäACRx?å~²AMìßA¿žÕ?¼Çä>%Öc?4&º=å~²AMìßA¿žÕ? |«AÃäACRx?ºÂªAÃäAa_¹?\í>TÛ`?î¨ò=å~²AMìßA¿žÕ?ºÂªAÃäAa_¹?™U±AMìßA„{ @«©à>%Öc? þ=™U±AMìßA„{ @ºÂªAÃäAa_¹?¾À©AÃäA=Œõ?êç>TÛ`?çm>™U±AMìßA„{ @¾À©AÃäA=Œõ?8Ú¯AMìßA]/@õIÛ>%Öc?; >8Ú¯AMìßA]/@¾À©AÃäA=Œõ?‡w¨AÃäAÇ,@ºká>TÛ`?b§>>8Ú¯AMìßA]/@‡w¨AÃäAÇ,@á®AMìßA£CP@N°Ô>%Öc?ÍŽ@>á®AMìßA£CP@‡w¨AÃäAÇ,@îè¦AÃäA’¹4@­ªÙ>TÛ`?ëÏ_>á®AMìßA£CP@îè¦AÃäA’¹4@&ö«AMìßAp@'æÌ>%Öc?ÑÎ_>&ö«AMìßAp@îè¦AÃäA’¹4@,¥AÃäA£CP@ÿ±Ð>TÛ`?¸>&ö«AMìßAp@,¥AÃäA£CP@“©AMìßAc2‡@¨öÃ>%Öc?kÎ}>“©AMìßAc2‡@,¥AÃäA£CP@Ü£AÃäAˆ£j@ŠŽÆ>TÛ`?>“©AMìßAc2‡@Ü£AÃäAˆ£j@îè¦AMìßA6£•@œî¹>%Öc?S1>îè¦AMìßA6£•@Ü£AÃäAˆ£j@ö´ AÃäAÁÙ@ÒN»>TÛ`?(‰>îè¦AMìßA6£•@ö´ AÃäAÁÙ@­û£AMìßAÐ=£@_Ü®>%Öc?N±š>­û£AMìßAÐ=£@ö´ AÃäAÁÙ@È*žAÃäA×§@ð¯>TÛ`?Á«>­û£AMìßAÐ=£@È*žAÃäA×§@tÏ AMìßAµî¯@ËÏ¢>%Öc?ÒS§>tÏ AMìßAµî¯@È*žAÃäA×§@õi›AÃäA «˜@€¼¡>TÛ`?j±·>tÏ AMìßAµî¯@õi›AÃäA «˜@ÍhAMìßAº£»@Ú•>%Öc?dz>ÍhAMìßAº£»@õi›AÃäA «˜@pv˜AÃäA×Ó¢@ƒŽ“>TÛ`?DÃ>ÍhAMìßAº£»@pv˜AÃäA×Ó¢@™Ì™AMìßALÆ@ê ˆ>%Öc?m¹½>™Ì™AMìßALÆ@pv˜AÃäA×Ó¢@pT•AÃäAr¬@F„>TÛ`?2¿Í>™Ì™AMìßALÆ@pT•AÃäAr¬@ÿÿ•AMìßA™ØÏ@Úýr>%Öc?u\Ç>ÿÿ•AMìßA™ØÏ@pT•AÃäAr¬@t’AÃäA²\´@‡œi>TÛ`?Á×>ÿÿ•AMìßA™ØÏ@t’AÃäA²\´@t’AMìßA‡;Ø@þƒT>%Öc?âÏ>t’AMìßA‡;Ø@t’AÃäA²\´@2—ŽAÃäAº£»@ÐH>TÛ`?e4ß>t’AMìßA‡;Ø@2—ŽAÃäAº£»@£ëAMìßAâhß@âÙ4>%Öc?>×>£ëAMìßAâhß@2—ŽAÃäAº£»@™‹AÃäA ÞÁ@ä&>TÛ`?|æ>£ëAMìßAâhß@™‹AÃäA ÞÁ@q¯‰AMìßAdVå@Û,>%Öc?ìeÝ>q¯‰AMìßAdVå@™‹AÃäA ÞÁ@ÄX‡AÃäAøÇ@5 >TÛ`?,­ë>q¯‰AMìßAdVå@ÄX‡AÃäAøÇ@ìY…AMìßA’ûé@fWå=%Öc?ÍPâ>ìY…AMìßA’ûé@ÄX‡AÃäAøÇ@õ•ƒAÃäAç Ë@’âÀ=TÛ`?tóï>ìY…AMìßA’ûé@õ•ƒAÃäAç Ë@Jñ€AMìßAÄQí@¼ ¡=%Öc?­÷å>Jñ€AMìßAÄQí@õ•ƒAÃäAç Ë@$…AÃäA$ðÍ@*=q=TÛ`?4âò>Jñ€AMìßAÄQí@$…AÃäA$ðÍ@µ÷xAMìßA3Tï@·7=%Öc?QUè>µ÷xAMìßA3Tï@$…AÃäA$ðÍ@$ÈwAÃäAŽ®Ï@£·¾µ÷xAMìßA3Tï@$ÈwAÃäAŽ®Ï@pAMìßAð@261<%Öc?Ufé>pAMìßAð@$ÈwAÃäAŽ®Ï@pAÃäA£CÐ@58L¼TÛ`?Gªô>pAMìßAð@pAÃäA£CÐ@JgAMìßA3Tï@²¶¾¼%Öc?4)é>JgAMìßA3Tï@pAÃäA£CÐ@Û7hAÃäAŽ®Ï@Ô.E½TÛ`? ó>JgAMìßA3Tï@Û7hAÃäAŽ®Ï@k^AMìßAÄQí@»{j½%Öc?Džç>k^AMìßAÄQí@Û7hAÃäAŽ®Ï@Üz`AÃäA$ðÍ@§«½TÛ`?4ûð>k^AMìßAÄQí@Üz`AÃäA$ðÍ@(LUAMìßA’ûé@4&º½%Öc?¼Çä>(LUAMìßA’ûé@Üz`AÃäA$ðÍ@ÔXAÃäAç Ë@î¨ò½TÛ`?\í>(LUAMìßA’ûé@ÔXAÃäAç Ë@¡LAMìßAdVå@ þ½%Öc?«©à>¡LAMìßAdVå@ÔXAÃäAç Ë@xNQAÃäAøÇ@çm¾TÛ`?êç>¡LAMìßAdVå@xNQAÃäAøÇ@¸(DAMìßAâhß@; ¾%Öc?õIÛ>¸(DAMìßAâhß@xNQAÃäAøÇ@ÎôIAÃäA ÞÁ@b§>¾TÛ`?ºká>¸(DAMìßAâhß@ÎôIAÃäA ÞÁ@ï;AMìßA‡;Ø@ÍŽ@¾%Öc?N°Ô>ï;AMìßA‡;Ø@ÎôIAÃäA ÞÁ@›ÑBAÃäAº£»@ëÏ_¾TÛ`?­ªÙ>ï;AMìßA‡;Ø@›ÑBAÃäAº£»@ÿÿ3AMìßA™ØÏ@ÑÎ_¾%Öc?'æÌ>ÿÿ3AMìßA™ØÏ@›ÑBAÃäAº£»@ï;AÃäA²\´@¸¾TÛ`?ÿ±Ð>ÿÿ3AMìßA™ØÏ@ï;AÃäA²\´@Îf,AMìßALÆ@kÎ}¾%Öc?¨öÃ>Îf,AMìßALÆ@ï;AÃäA²\´@W5AÃäAr¬@¾TÛ`?ŠŽÆ>Îf,AMìßALÆ@W5AÃäAr¬@d.%AMìßAº£»@S1¾%Öc?œî¹>d.%AMìßAº£»@W5AÃäAr¬@/AÃäA×Ó¢@(‰¾TÛ`?ÒN»>d.%AMìßAº£»@/AÃäA×Ó¢@aAMìßAµî¯@N±š¾%Öc?_Ü®>aAMìßAµî¯@/AÃäA×Ó¢@,)AÃäA «˜@Á«¾TÛ`?ð¯>aAMìßAµî¯@,)AÃäA «˜@¦AMìßAÐ=£@ÒS§¾%Öc?ËÏ¢>¦AMìßAÐ=£@,)AÃäA «˜@pª#AÃäA×§@j±·¾TÛ`?€¼¡>¦AMìßAÐ=£@pª#AÃäA×§@".AMìßA6£•@dz¾%Öc?Ú•>".AMìßA6£•@pª#AÃäA×§@–AÃäAÁÙ@DþTÛ`?ƒŽ“>".AMìßA6£•@–AÃäAÁÙ@òÙ AMìßAc2‡@m¹½¾%Öc?ê ˆ>òÙ AMìßAc2‡@–AÃäAÁÙ@GöAÃäAˆ£j@2¿Í¾TÛ`?F„>òÙ AMìßAc2‡@GöAÃäAˆ£j@³AMìßAp@u\Ǿ%Öc?Úýr>³AMìßAp@GöAÃäAˆ£j@§ÑAÃäA£CP@Á×¾TÛ`?‡œi>³AMìßAp@§ÑAÃäA£CP@=âAMìßA£CP@âϾ%Öc?þƒT>=âAMìßA£CP@§ÑAÃäA£CP@".AÃäA’¹4@e4ß¾TÛ`?ÐH>=âAMìßA£CP@".AÃäA’¹4@KAMìßA]/@>×¾%Öc?âÙ4>KAMìßA]/@".AÃäA’¹4@ðAÃäAÇ,@|æ¾TÛ`?ä&>KAMìßA]/@ðAÃäAÇ,@š©ú@MìßA„{ @ìeݾ%Öc?Û,>š©ú@MìßA„{ @ðAÃäAÇ,@„~ AÃäA=Œõ?,­ë¾TÛ`?5 >š©ú@MìßA„{ @„~ AÃäA=Œõ?mö@MìßA¿žÕ?ÍPâ¾%Öc?fWå=mö@MìßA¿žÕ?„~ AÃäA=Œõ?Œz AÃäAa_¹?SrÚ>…ƒg?1â©Î>Ù)j?Z0£<£ë«AÃäA„ù>á•©A´FåA€×¶¨ä·£Aq´çAÛ­Ñ>eÑ>À^i?Lö)=£ë«AÃäA„ù>ä·£Aq´çAÛ­Ñ> |«AÃäACRx?ù1Å>|ëk?H= |«AÃäACRx?ä·£Aq´çAÛ­Ñ>ìY£Aq´çAÂQ?»8Ï>À^i?öU“= |«AÃäACRx?ìY£Aq´çAÂQ?ºÂªAÃäAa_¹?iÆÂ>|ëk?„±ž=ºÂªAÃäAa_¹?ìY£Aq´çAÂQ?â½¢Aq´çAŸœ?ºãË>À^i?×ÝÐ=ºÂªAÃäAa_¹?â½¢Aq´çAŸœ?¾À©AÃäA=Œõ?ÿC¿>|ëk?ÐxØ=¾À©AÃäA=Œõ?â½¢Aq´çAŸœ?¨ä¡Aq´çAçÁÎ?ÓjÇ>À^i?Y>¾À©AÃäA=Œõ?¨ä¡Aq´çAçÁÎ?‡w¨AÃäAÇ,@¯º>|ëk?…>‡w¨AÃäAÇ,@¨ä¡Aq´çAçÁÎ?tÏ Aq´çA–"@nÔÁ>À^i? $>‡w¨AÃäAÇ,@tÏ Aq´çA–"@îè¦AÃäA’¹4@@µ>|ëk?V $>îè¦AÃäA’¹4@tÏ Aq´çA–"@ÒŸAq´çAÇ,@ˆ(»>À^i?ç@>îè¦AÃäA’¹4@ÒŸAq´çAÇ,@,¥AÃäA£CP@„m®>|ëk?º¤>>,¥AÃäA£CP@ÒŸAq´çAÇ,@¥÷Aq´çA]/@°p³>À^i?ý[>,¥AÃäA£CP@¥÷Aq´çA]/@Ü£AÃäAˆ£j@Ѧ>|ëk?/.X>Ü£AÃäAˆ£j@¥÷Aq´çA]/@9œAq´çA_’E@ó·ª>À^i?Q1v>Ü£AÃäAˆ£j@9œAq´çA_’E@ö´ AÃäAÁÙ@ËEž>|ëk?$‚p>ö´ AÃäAÁÙ@9œAq´çA_’E@¶FšAq´çAɬZ@Î ¡>À^i?‹‚‡>ö´ AÃäAÁÙ@¶FšAq´çAɬZ@È*žAÃäA×§@í×”>|ëk?㾃>È*žAÃäA×§@¶FšAq´çAɬZ@>#˜Aq´çA"Žn@w–>À^i?m*“>È*žAÃäA×§@>#˜Aq´çA"Žn@õi›AÃäA «˜@÷”Š>|ëk?€Ž>õi›AÃäA «˜@>#˜Aq´çA"Žn@ÄÑ•Aq´çAùŒ€@ú ‹>À^i?ÿ>õi›AÃäA «˜@ÄÑ•Aq´çAùŒ€@pv˜AÃäA×Ó¢@4>|ëk?Hu˜>pv˜AÃäA×Ó¢@ÄÑ•Aq´çAùŒ€@™U“Aq´çA؉@”³}>À^i?›ò§>pv˜AÃäA×Ó¢@™U“Aq´çA؉@pT•AÃäAr¬@G—g>|ëk?4¡>pT•AÃäAr¬@™U“Aq´çA؉@L²Aq´çAlä@ýãc>À^i?'õ°>pT•AÃäAr¬@L²Aq´çAlä@t’AÃäA²\´@ÌËN>|ëk?Óé>t’AÃäA²\´@L²Aq´çAlä@£ëAq´çA’Þ—@$ÎH>À^i?[ú¸>t’AÃäA²\´@£ëAq´çA’Þ—@2—ŽAÃäAº£»@@Ø4>|ëk?g±>2—ŽAÃäAº£»@£ëAq´çA’Þ—@™‹Aq´çAJÿ@Θ,>À^i?½ö¿>2—ŽAÃäAº£»@™‹Aq´çAJÿ@™‹AÃäA ÞÁ@Íá>|ëk?ŒG·>™‹AÃäA ÞÁ@™‹Aq´çAJÿ@SˆAq´çAÐ=£@`l>À^i?KàÅ>™‹AÃäA ÞÁ@SˆAq´çAÐ=£@ÄX‡AÃäAøÇ@ü=|ëk?N„¼>ÄX‡AÃäAøÇ@SˆAq´çAÐ=£@ì„Aq´çA¢’§@8åâ=À^i?Ž®Ê>ÄX‡AÃäAøÇ@ì„Aq´çA¢’§@õ•ƒAÃäAç Ë@ Ã=|ëk?+³À>õ•ƒAÃäAç Ë@ì„Aq´çA¢’§@jÁAq´çAŠ÷ª@Ù¬¥=À^i?§ZÎ>õ•ƒAÃäAç Ë@jÁAq´çAŠ÷ª@$…AÃäA$ðÍ@èéˆ=|ëk?'ÎÃ>$…AÃäA$ðÍ@jÁAq´çAŠ÷ª@|}Aq´çA¯g­@•O=À^i?PßÐ>$…AÃäA$ðÍ@|}Aq´çA¯g­@$ÈwAÃäAŽ®Ï@W=|ëk?ÏÐÅ>$ÈwAÃäAŽ®Ï@|}Aq´çA¯g­@nvAq´çA“ß®@6£<À^i?ò8Ò>$ÈwAÃäAŽ®Ï@nvAq´çA“ß®@pAÃäA£CÐ@!6<|ëk?C¸Æ>pAÃäA£CÐ@nvAq´çA“ß®@pAq´çA]¯@_51¼À^i?œeÒ>pAÃäA£CÐ@pAq´çA]¯@Û7hAÃäAŽ®Ï@]5£¼|ëk?7ƒÆ>Û7hAÃäAŽ®Ï@pAq´çA]¯@‘riAq´çA“ß®@Lö)½À^i?eÑ>Û7hAÃäAŽ®Ï@‘riAq´çA“ß®@Üz`AÃäA$ðÍ@H½|ëk?ù1Å>Üz`AÃäA$ðÍ@‘riAq´çA“ß®@ƒîbAq´çA¯g­@öU“½À^i?»8Ï>Üz`AÃäA$ðÍ@ƒîbAq´çA¯g­@ÔXAÃäAç Ë@„±ž½|ëk?iÆÂ>ÔXAÃäAç Ë@ƒîbAq´çA¯g­@,}\Aq´çAŠ÷ª@×ÝнÀ^i?ºãË>ÔXAÃäAç Ë@,}\Aq´çAŠ÷ª@xNQAÃäAøÇ@Ðxؽ|ëk?ÿC¿>xNQAÃäAøÇ@,}\Aq´çAŠ÷ª@Ã'VAq´çA¢’§@Y¾À^i?ÓjÇ>xNQAÃäAøÇ@Ã'VAq´çA¢’§@ÎôIAÃäA ÞÁ@…¾|ëk?¯º>ÎôIAÃäA ÞÁ@Ã'VAq´çA¢’§@Z÷OAq´çAÐ=£@ $¾À^i?nÔÁ>ÎôIAÃäA ÞÁ@Z÷OAq´çAÐ=£@›ÑBAÃäAº£»@V $¾|ëk?@µ>›ÑBAÃäAº£»@Z÷OAq´çAÐ=£@ÎôIAq´çAJÿ@ç@¾À^i?ˆ(»>›ÑBAÃäAº£»@ÎôIAq´çAJÿ@ï;AÃäA²\´@º¤>¾|ëk?„m®>ï;AÃäA²\´@ÎôIAq´çAJÿ@¸(DAq´çA’Þ—@ý[¾À^i?°p³>ï;AÃäA²\´@¸(DAq´çA’Þ—@W5AÃäAr¬@/.X¾|ëk?Ѧ>W5AÃäAr¬@¸(DAq´çA’Þ—@h›>Aq´çAlä@Q1v¾À^i?ó·ª>W5AÃäAr¬@h›>Aq´çAlä@/AÃäA×Ó¢@$‚p¾|ëk?ËEž>/AÃäA×Ó¢@h›>Aq´çAlä@ÍT9Aq´çA؉@‹‚‡¾À^i?Î ¡>/AÃäA×Ó¢@ÍT9Aq´çA؉@,)AÃäA «˜@㾃¾|ëk?í×”>,)AÃäA «˜@ÍT9Aq´çA؉@w\4Aq´çAùŒ€@m*“¾À^i?w–>,)AÃäA «˜@w\4Aq´çAùŒ€@pª#AÃäA×§@€Ž¾|ëk?÷”Š>pª#AÃäA×§@w\4Aq´çAùŒ€@ƒ¹/Aq´çA"Žn@ÿ¾À^i?ú ‹>pª#AÃäA×§@ƒ¹/Aq´çA"Žn@–AÃäAÁÙ@Hu˜¾|ëk?4>–AÃäAÁÙ@ƒ¹/Aq´çA"Žn@”r+Aq´çAɬZ@›ò§¾À^i?”³}>–AÃäAÁÙ@”r+Aq´çAɬZ@GöAÃäAˆ£j@4¡¾|ëk?G—g>GöAÃäAˆ£j@”r+Aq´çAɬZ@Ê'Aq´çA_’E@'õ°¾À^i?ýãc>GöAÃäAˆ£j@Ê'Aq´çA_’E@§ÑAÃäA£CP@Óé¾|ëk?ÌËN>§ÑAÃäA£CP@Ê'Aq´çA_’E@·$Aq´çA]/@[ú¸¾À^i?$ÎH>§ÑAÃäA£CP@·$Aq´çA]/@".AÃäA’¹4@g±¾|ëk?@Ø4>".AÃäA’¹4@·$Aq´çA]/@[!Aq´çAÇ,@½ö¿¾À^i?Θ,>".AÃäA’¹4@[!Aq´çAÇ,@ðAÃäAÇ,@ŒG·¾|ëk?Íá>ðAÃäAÇ,@[!Aq´çAÇ,@aAq´çA–"@KàžÀ^i?`l>ðAÃäAÇ,@aAq´çA–"@„~ AÃäA=Œõ?N„¼¾|ëk?ü=„~ AÃäA=Œõ?aAq´çA–"@¯6Aq´çAçÁÎ?Ž®Ê¾À^i?8åâ=„~ AÃäA=Œõ?¯6Aq´çAçÁÎ?Œz AÃäAa_¹?+³À¾|ëk? Ã=Œz AÃäAa_¹?¯6Aq´çAçÁÎ?;„Aq´çAŸœ?zœ®¾§p?,ˆ<át)A2«êA+©>ù™A¦ÂçAW&‹)7Aq´çAÛ­Ñ>™±º¾ð\n?<7Aq´çAÛ­Ñ>ù™A¦ÂçAW&‹)$SA“²çA-m‹)/¹Æ¾Jëk?%6<7Aq´çAÛ­Ñ>$SA“²çA-m‹)ŽûAfýãAÂÄ›);4²>iûo?y* ¦>ß r?ðƆ<ä·£Aq´çAÛ­Ñ>o°AíéAß2¨E›A2«êA+©>(®>3”p?!Ë =ä·£Aq´çAÛ­Ñ>E›A2«êA+©>ìY£Aq´çAÂQ?2¬¡><¯r?Õ‚$=ìY£Aq´çAÂQ?E›A2«êA+©>¿ùšA2«êAé±(?rN¬>3”p?à}u=ìY£Aq´çAÂQ?¿ùšA2«êAé±(?â½¢Aq´çAŸœ?¯Ÿ><¯r?OZ‚=â½¢Aq´çAŸœ?¿ùšA2«êAé±(?Ú{šA2«êAÎÜ{? ˆ©>3”p?–è­=â½¢Aq´çAŸœ?Ú{šA2«êAÎÜ{?¨ä¡Aq´çAçÁÎ?OÍœ><¯r?•¸±=¨ä¡Aq´çAçÁÎ?Ú{šA2«êAÎÜ{?™Ì™A2«êAϦ?íÎ¥>3”p?@à=¨ä¡Aq´çAçÁÎ?™Ì™A2«êAϦ?tÏ Aq´çA–"@ ™><¯r?kà=tÏ Aq´çA–"@™Ì™A2«êAϦ?óì˜A2«êAçÁÎ?p(¡>3”p?‹„>tÏ Aq´çA–"@óì˜A2«êAçÁÎ?ÒŸAq´çAÇ,@½m”><¯r?·›>ÒŸAq´çAÇ,@óì˜A2«êAçÁÎ?*Þ—A2«êA=Œõ?8››>3”p?9 >ÒŸAq´çAÇ,@*Þ—A2«êA=Œõ?¥÷Aq´çA]/@æûŽ><¯r?‚j>¥÷Aq´çA]/@*Þ—A2«êA=Œõ?¡–A2«êA„{ @;/•>3”p?7>¥÷Aq´çA]/@¡–A2«êA„{ @9œAq´çA_’E@[½ˆ><¯r?]Y1>9œAq´çA_’E@¡–A2«êA„{ @~9•A2«êA\f@©í>3”p?'ÑL>9œAq´çA_’E@~9•A2«êA\f@¶FšAq´çAɬZ@ »><¯r?SJE>¶FšAq´çAɬZ@~9•A2«êA\f@d§“A2«êAÿl0@åà…>3”p?ùta>¶FšAq´çAɬZ@d§“A2«êAÿl0@>#˜Aq´çA"Žn@þs><¯r?Ó X>>#˜Aq´çA"Žn@d§“A2«êAÿl0@²í‘A2«êAw@@í(z>3”p?Öt>>#˜Aq´çA"Žn@²í‘A2«êAw@@ÄÑ•Aq´çAùŒ€@¥(c><¯r?éÁi>ÄÑ•Aq´çAùŒ€@²í‘A2«êAw@@áA2«êA‘mO@ì)g>3”p?Elƒ>ÄÑ•Aq´çAùŒ€@áA2«êA‘mO@™U“Aq´çA؉@ Q><¯r?Tz>™U“Aq´çA؉@áA2«êA‘mO@  ŽA2«êA;]@øßR>3”p?b±‹>™U“Aq´çA؉@  ŽA2«êA;]@L²Aq´çAlä@'È=><¯r?]€„>L²Aq´çAlä@  ŽA2«êA;]@Ëì‹A2«êAðËi@h=>3”p?€.“>L²Aq´çAlä@Ëì‹A2«êAðËi@£ëAq´çA’Þ—@r)><¯r?Ý8‹>£ëAq´çA’Þ—@Ëì‹A2«êAðËi@q¯‰A2«êA u@á&>3”p?çØ™>£ëAq´çA’Þ—@q¯‰A2«êA u@™‹Aq´çAJÿ@_*><¯r? *‘>™‹Aq´çAJÿ@q¯‰A2«êA u@ÄX‡A2«êAPñ~@+k>3”p? §Ÿ>™‹Aq´çAJÿ@ÄX‡A2«êAPñ~@SˆAq´çAÐ=£@!ü=<¯r?gK–>SˆAq´çAÐ=£@ÄX‡A2«êAPñ~@ì„A2«êA̳ƒ@ÒOî=3”p?¡¤>SˆAq´çAÐ=£@ì„A2«êA̳ƒ@ì„Aq´çA¢’§@”zÎ=<¯r?—•š>ì„Aq´çA¢’§@ì„A2«êA̳ƒ@ùl‚A2«êAc2‡@t¼=3”p?œŽ¨>ì„Aq´çA¢’§@ùl‚A2«êAc2‡@jÁAq´çAŠ÷ª@l±Ÿ=<¯r?xž>jÁAq´çAŠ÷ª@ùl‚A2«êAc2‡@νA2«êAkï‰@¡Š‰=3”p?G›«>jÁAq´çAŠ÷ª@νA2«êAkï‰@|}Aq´çA¯g­@I`=<¯r?! >|}Aq´çA¯g­@νA2«êAkï‰@‹zA2«êAùæ‹@o¸+=3”p?B²­>|}Aq´çA¯g­@‹zA2«êAùæ‹@nvAq´çA“ß®@ûÕþ<<¯r?ï1¢>nvAq´çA“ß®@‹zA2«êAùæ‹@XIuA2«êA>@ŠË†<3”p?‘Ю>nvAq´çA“ß®@XIuA2«êA>@pAq´çA]¯@9Âð;<¯r?ˆî¢>pAq´çA]¯@XIuA2«êA>@pA2«êA„{@†5¼3”p?™ô®>pAq´çA]¯@pA2«êA„{@‘riAq´çA“ß®@ ˆ¼<¯r?ÞÁ¢>‘riAq´çA“ß®@pA2«êA„{@¨¶jA2«êA>@!Ë ½3”p?(®>‘riAq´çA“ß®@¨¶jA2«êA>@ƒîbAq´çA¯g­@Õ‚$½<¯r?2¬¡>ƒîbAq´çA¯g­@¨¶jA2«êA>@áteA2«êAùæ‹@à}u½3”p?rN¬>ƒîbAq´çA¯g­@áteA2«êAùæ‹@,}\Aq´çAŠ÷ª@OZ‚½<¯r?¯Ÿ>,}\Aq´çAŠ÷ª@áteA2«êAùæ‹@3B`A2«êAkï‰@–è­½3”p? ˆ©>,}\Aq´çAŠ÷ª@3B`A2«êAkï‰@Ã'VAq´çA¢’§@•¸±½<¯r?OÍœ>Ã'VAq´çA¢’§@3B`A2«êAkï‰@&[A2«êAc2‡@@à½3”p?íÎ¥>Ã'VAq´çA¢’§@&[A2«êAc2‡@Z÷OAq´çAÐ=£@kà½<¯r? ™>Z÷OAq´çAÐ=£@&[A2«êAc2‡@Ã'VA2«êA̳ƒ@‹„¾3”p?p(¡>Z÷OAq´çAÐ=£@Ã'VA2«êA̳ƒ@ÎôIAq´çAJÿ@·›¾<¯r?½m”>ÎôIAq´çAJÿ@Ã'VA2«êA̳ƒ@xNQA2«êAPñ~@9 ¾3”p?8››>ÎôIAq´çAJÿ@xNQA2«êAPñ~@¸(DAq´çA’Þ—@‚j¾<¯r?æûŽ>¸(DAq´çA’Þ—@xNQA2«êAPñ~@¡LA2«êA u@7¾3”p?;/•>¸(DAq´çA’Þ—@¡LA2«êA u@h›>Aq´çAlä@]Y1¾<¯r?[½ˆ>h›>Aq´çAlä@¡LA2«êA u@i&HA2«êAðËi@'ÑL¾3”p?©í>h›>Aq´çAlä@i&HA2«êAðËi@ÍT9Aq´çA؉@SJE¾<¯r? »>ÍT9Aq´çA؉@i&HA2«êAðËi@ÀäCA2«êA;]@ùta¾3”p?åà…>ÍT9Aq´çA؉@ÀäCA2«êA;]@w\4Aq´çAùŒ€@Ó X¾<¯r?þs>w\4Aq´çAùŒ€@ÀäCA2«êA;]@<â?A2«êA‘mO@Öt¾3”p?í(z>w\4Aq´çAùŒ€@<â?A2«êA‘mO@ƒ¹/Aq´çA"Žn@éÁi¾<¯r?¥(c>ƒ¹/Aq´çA"Žn@<â?A2«êA‘mO@œ$ƒ¹/Aq´çA"Žn@œ$”r+Aq´çAɬZ@œ$”r+Aq´çAɬZ@8±8A2«êAÿl0@Ê'Aq´çA_’E@]€„¾<¯r?'È=>Ê'Aq´çA_’E@8±8A2«êAÿl0@5A2«êA\f@€.“¾3”p?h=>Ê'Aq´çA_’E@5A2«êA\f@·$Aq´çA]/@Ý8‹¾<¯r?r)>·$Aq´çA]/@5A2«êA\f@}¼2A2«êA„{ @çØ™¾3”p?á&>·$Aq´çA]/@}¼2A2«êA„{ @[!Aq´çAÇ,@ *‘¾<¯r?_*>[!Aq´çAÇ,@}¼2A2«êA„{ @¬C0A2«êA=Œõ? §Ÿ¾3”p?+k>[!Aq´çAÇ,@¬C0A2«êA=Œõ?aAq´çA–"@gK–¾<¯r?!ü=aAq´çA–"@¬C0A2«êA=Œõ?&.A2«êAçÁÎ?¡¤¾3”p?ÒOî=aAq´çA–"@&.A2«êAçÁÎ?¯6Aq´çAçÁÎ?—•š¾<¯r?”zÎ=¯6Aq´çAçÁÎ?&.A2«êAçÁÎ?Îf,A2«êAϦ?œŽ¨¾3”p?t¼=¯6Aq´çAçÁÎ?Îf,A2«êAϦ?;„Aq´çAŸœ?xž¾<¯r?l±Ÿ=;„Aq´çAŸœ?Îf,A2«êAϦ?J+A2«êAÎÜ{?v…¾l0w?¿8S<‹¾:AÉýìAïk>ûÚ0AªÅëA­Êe)át)A2«êA+©>•d‘¾ûÚ0AªÅëA­Êe)ŸY)A܇êAcÍt)¹¢¾5¸r?ðÀð;át)A2«êA+©>ŸY)A܇êAcÍt)ù™A¦ÂçAW&‹)*ŠŠ>iqv?tÁð;ÑW›AJ‘êAm» ¨v¯’A·íìA¼³¥E›A2«êA+©>”.|>îx?²@Sv¯’A·íìA¼³¥º ’AÉýìAïk>ÄÞ‰>qqv?1«áº ’AÉýìAïk>¿ùšA2«êAé±(?dz>Îx?Ñ =¿ùšA2«êAé±(?º ’AÉýìAïk>~g’AÉýìAµþ>?nˆ>qqv?yñB=¿ùšA2«êAé±(?~g’AÉýìAµþ>Ú{šA2«êAÎÜ{?¦gw>Îx?#’J=Ú{šA2«êAÎÜ{?~g’AÉýìAµþ>t’AÉýìAÈ#>?h:†>rqv?#û‰=Ú{šA2«êAÎÜ{?t’AÉýìAÈ#>?™Ì™A2«êAϦ?µír>Îx?¹ú‰=™Ì™A2«êAϦ?t’AÉýìAÈ#>?%„‘AÉýìAÎÜ{?fFƒ>rqv?ý·±=™Ì™A2«êAϦ?%„‘AÉýìAÎÜ{?óì˜A2«êAçÁÎ?ùm>Îx?׿­=óì˜A2«êAçÁÎ?%„‘AÉýìAÎÜ{?NÛAÉýìAŸœ?å,>qqv?hvØ=óì˜A2«êAçÁÎ?NÛAÉýìAŸœ?*Þ—A2«êA=Œõ?Ðîe>Îx?ýÙÐ=*Þ—A2«êA=Œõ?NÛAÉýìAŸœ?áAÉýìAa_¹?¬_v>qqv?íþý=*Þ—A2«êA=Œõ?áAÉýìAa_¹?¡–A2«êA„{ @u|]>Îx?!¢ò=¡–A2«êA„{ @áAÉýìAa_¹? AÉýìA¿žÕ?º1l>qqv?è >¡–A2«êA„{ @ AÉýìA¿žÕ?~9•A2«êA\f@ÍS>Îx?u‡ >~9•A2«êA\f@ AÉýìA¿žÕ? ŽAÉýìAH¬ð?¢±`>qqv?®L">~9•A2«êA\f@ ŽAÉýìAH¬ð?d§“A2«êAÿl0@YîH>Îx?òø>d§“A2«êAÿl0@ ŽAÉýìAH¬ð?zàŒAÉýìA 0@ÙïS>qqv?£2>d§“A2«êAÿl0@zàŒAÉýìA 0@²í‘A2«êAw@@ð<>Îx?q'>²í‘A2«êAw@@zàŒAÉýìA 0@“‹AÉýìAoL@§þE>qqv?ÆùA>²í‘A2«êAw@@“‹AÉýìAoL@áA2«êA‘mO@0ã/>Îx? 65>áA2«êA‘mO@“‹AÉýìAoL@)ŠAÉýìA8˜@ýñ6>qqv?½:P>áA2«êA‘mO@)ŠAÉýìA8˜@  ŽA2«êA;]@ŒÚ!>Îx?6ÙA>  ŽA2«êA;]@)ŠAÉýìA8˜@¦ˆAÉýìAÑ'@kß&>qqv?—Q]>  ŽA2«êA;]@¦ˆAÉýìAÑ'@Ëì‹A2«êAðËi@1ê>Îx?ÛfM>Ëì‹A2«êAðËi@¦ˆAÉýìAÑ'@Ä ‡AÉýìAO€0@ðÝ>qqv?—+i>Ëì‹A2«êAðËi@Ä ‡AÉýìAO€0@q¯‰A2«êA u@€'>Îx?pÎW>q¯‰A2«êA u@Ä ‡AÉýìAO€0@ìY…AÉýìA9@æ>qqv?Å·s>q¯‰A2«êA u@ìY…AÉýìA9@ÄX‡A2«êAPñ~@Rå=Îx?a>ÄX‡A2«êAPñ~@ìY…AÉýìA9@õ•ƒAÉýìAw@@´áâ=qqv?ç|>ÄX‡A2«êAPñ~@õ•ƒAÉýìAw@@ì„A2«êA̳ƒ@á Ã=Îx?ñh>ì„A2«êA̳ƒ@õ•ƒAÉýìAw@@jÁAÉýìAuÚF@Êr¼=qqv?V‚>ì„A2«êA̳ƒ@jÁAÉýìAuÚF@ùl‚A2«êAc2‡@j°Ÿ=Îx?Œ”o>ùl‚A2«êAc2‡@jÁAÉýìAuÚF@νAÉýìA+!L@ö”=rqv?~…>ùl‚A2«êAc2‡@νAÉýìA+!L@νA2«êAkï‰@ªÞv=Îx?Œàt>νA2«êAkï‰@νAÉýìA+!L@=â{AÉýìA£CP@;HY=qqv?þæ‡>νA2«êAkï‰@=â{AÉýìA£CP@‹zA2«êAùæ‹@û,=Îx?øÍx>‹zA2«êAùæ‹@=â{AÉýìA£CP@¨õwAÉýìAð;S@8m=qqv?O‰>‹zA2«êAùæ‹@¨õwAÉýìAð;S@XIuA2«êA>@ ?Ä<Îx?/W{>XIuA2«êA>@¨õwAÉýìAð;S@¯ýsAÉýìAÔU@PASXIuA2«êA>@¯ýsAÉýìAÔU@pA2«êA„{@«Àµ;Îx?’x|>pA2«êA„{@¯ýsAÉýìAÔU@pAÉýìA¿žU@jÁð»qqv?艊>pA2«êA„{@pAÉýìA¿žU@¨¶jA2«êA>@¯@S¼Îx?0|>¨¶jA2«êA>@pAÉýìA¿žU@PlAÉýìAÔU@1«á¼qqv?ÄÞ‰>¨¶jA2«êA>@PlAÉýìAÔU@áteA2«êAùæ‹@Ñ ½Îx?dz>áteA2«êAùæ‹@PlAÉýìAÔU@W hAÉýìAð;S@yñB½qqv??nˆ>áteA2«êAùæ‹@W hAÉýìAð;S@3B`A2«êAkï‰@#’J½Îx?¦gw>3B`A2«êAkï‰@W hAÉýìAð;S@ÃdAÉýìA£CP@#û‰½rqv?h:†>3B`A2«êAkï‰@ÃdAÉýìA£CP@&[A2«êAc2‡@¹ú‰½Îx?µír>&[A2«êAc2‡@ÃdAÉýìA£CP@3B`AÉýìA+!L@ý·±½rqv?fFƒ>&[A2«êAc2‡@3B`AÉýìA+!L@Ã'VA2«êA̳ƒ@׿­½Îx?ùm>Ã'VA2«êA̳ƒ@3B`AÉýìA+!L@,}\AÉýìAuÚF@hvؽqqv?å,>Ã'VA2«êA̳ƒ@,}\AÉýìAuÚF@xNQA2«êAPñ~@ýÙнÎx?Ðîe>xNQA2«êAPñ~@,}\AÉýìAuÚF@ÔXAÉýìAw@@íþý½qqv?¬_v>xNQA2«êAPñ~@ÔXAÉýìAw@@¡LA2«êA u@!¢ò½Îx?u|]>¡LA2«êA u@ÔXAÉýìAw@@(LUAÉýìA9@è ¾qqv?º1l>¡LA2«êA u@(LUAÉýìA9@i&HA2«êAðËi@u‡ ¾Îx?ÍS>i&HA2«êAðËi@(LUAÉýìA9@wêQAÉýìAO€0@®L"¾qqv?¢±`>i&HA2«êAðËi@wêQAÉýìAO€0@ÀäCA2«êA;]@òø¾Îx?YîH>ÀäCA2«êA;]@wêQAÉýìAO€0@׳NAÉýìAÑ'@£2¾qqv?ÙïS>ÀäCA2«êA;]@׳NAÉýìAÑ'@<â?A2«êA‘mO@q'¾Îx?ð<><â?A2«êA‘mO@׳NAÉýìAÑ'@ä¬KAÉýìA8˜@ÆùA¾qqv?§þE><â?A2«êA‘mO@ä¬KAÉýìA8˜@œ$œ$œ$8±8A2«êAÿl0@òÙHAÉýìAoL@ ?FAÉýìA 0@—Q]¾qqv?kß&>8±8A2«êAÿl0@ ?FAÉýìA 0@5A2«êA\f@ÛfM¾Îx?1ê>5A2«êA\f@ ?FAÉýìA 0@ìßCAÉýìAH¬ð?—+i¾qqv?ðÝ>5A2«êA\f@ìßCAÉýìAH¬ð?}¼2A2«êA„{ @pÎW¾Îx?€'>}¼2A2«êA„{ @ìßCAÉýìAH¬ð?ù¿AAÉýìA¿žÕ?Å·s¾qqv?æ>}¼2A2«êA„{ @ù¿AAÉýìA¿žÕ?¬C0A2«êA=Œõ?a¾Îx?Rå=¬C0A2«êA=Œõ?ù¿AAÉýìA¿žÕ?<â?AÉýìAa_¹?ç|¾qqv?´áâ=¬C0A2«êA=Œõ?<â?AÉýìAa_¹?&.A2«êAçÁÎ?ñh¾Îx?á Ã=&.A2«êAçÁÎ?<â?AÉýìAa_¹?cI>AÉýìAŸœ?V‚¾qqv?Êr¼=&.A2«êAçÁÎ?cI>AÉýìAŸœ?Îf,A2«êAϦ?Œ”o¾Îx?j°Ÿ=Îf,A2«êAϦ?cI>AÉýìAŸœ?µ÷?~Ù_>èÍy?&¤µ;v¯’A·íìA¼³¥¬]‘AÕIíAlgr&º ’AÉýìAïk>“¼F>{?ýº<º ’AÉýìAïk>¬]‘AÕIíAlgr&ÆÕ‰Aâ¨îA,+>TµI>,îz?!~¦<º ’AÉýìAïk>ÆÕ‰Aâ¨îA,+>~g’AÉýìAµþ>ø@0>ˆ|?+Àµ<~g’AÉýìAµþ>ÆÕ‰Aâ¨îA,+>q¯‰Aâ¨îA¶™ª>Ë–G>,îz?ìN=~g’AÉýìAµþ>q¯‰Aâ¨îA¶™ª>t’AÉýìAÈ#>?,.>ˆ|?N=t’AÉýìAÈ#>?q¯‰Aâ¨îA¶™ª>Éo‰Aâ¨îAµþ>…ZD>,îz?‘J=t’AÉýìAÈ#>?Éo‰Aâ¨îAµþ>%„‘AÉýìAÎÜ{?-æ*>ˆ|?øïB=%„‘AÉýìAÎÜ{?Éo‰Aâ¨îAµþ>*‰Aâ¨îAé±(?"@>,îz?&Y‚=%„‘AÉýìAÎÜ{?*‰Aâ¨îAé±(?NÛAÉýìAŸœ?‚Ç&>ˆ|??zu=NÛAÉýìAŸœ?*‰Aâ¨îAé±(?¦ˆAâ¨îAÂQ?Öœ:>,îz?ஞ=NÛAÉýìAŸœ?¦ˆAâ¨îAÂQ?áAÉýìAa_¹?º!>ˆ|?‹R“=áAÉýìAa_¹?¦ˆAâ¨îAÂQ?'ˆAâ¨îACRx?b)4>,îz?l!º=áAÉýìAa_¹?'ˆAâ¨îACRx? AÉýìA¿žÕ?Å>ˆ|? «= AÉýìA¿žÕ?'ˆAâ¨îACRx?*}‡Aâ¨îA¡?þ³,>,îz?‰Ô= AÉýìA¿žÕ?*}‡Aâ¨îA¡? ŽAÉýìAH¬ð?ñ>ˆ|?žâÁ= ŽAÉýìAH¬ð?*}‡Aâ¨îA¡?džAâ¨îAH3¡?[G$>,îz?JÁí= ŽAÉýìAH¬ð?džAâ¨îAH3¡?zàŒAÉýìA 0@åG >ˆ|?žš×=zàŒAÉýìA 0@džAâ¨îAH3¡?­û…Aâ¨îA'k²?‡ï>,îz?ZÒ>zàŒAÉýìA 0@­û…Aâ¨îA'k²?“‹AÉýìAoL@jÔ>ˆ|?ñì=“‹AÉýìAoL@­û…Aâ¨îA'k²?V…Aâ¨îA–£Â?â¹>,îz?Ã>“‹AÉýìAoL@V…Aâ¨îA–£Â?)ŠAÉýìA8˜@ˆE÷=ˆ|?:Oÿ=)ŠAÉýìA8˜@V…Aâ¨îA–£Â?:*„Aâ¨îA^ÅÑ? µ>,îz?Õs>)ŠAÉýìA8˜@:*„Aâ¨îA^ÅÑ?¦ˆAÉýìAÑ'@:€ã=ˆ|?€‰>¦ˆAÉýìAÑ'@:*„Aâ¨îA^ÅÑ?²&ƒAâ¨îAÔºß?Œáó=,îz?¤">¦ˆAÉýìAÑ'@²&ƒAâ¨îAÔºß?Ä ‡AÉýìAO€0@8uÎ=ˆ|?é§>Ä ‡AÉýìAO€0@²&ƒAâ¨îAÔºß?5‚Aâ¨îAüoì?ÝûÚ=,îz?~­*>Ä ‡AÉýìAO€0@5‚Aâ¨îAüoì?ìY…AÉýìA9@¢B¸=ˆ|?:÷>ìY…AÉýìA9@5‚Aâ¨îAüoì?Jñ€Aâ¨îA¤Ò÷?¬ÜÀ=,îz?b2>ìY…AÉýìA9@Jñ€Aâ¨îA¤Ò÷?õ•ƒAÉýìAw@@@¡=ˆ|?ûl>õ•ƒAÉýìAw@@Jñ€Aâ¨îA¤Ò÷?$…Aâ¨îA@é@^©¥=,îz?9>õ•ƒAÉýìAw@@$…Aâ¨îA@é@jÁAÉýìAuÚF@Tçˆ=ˆ|?ëÿ#>jÁAÉýìAuÚF@$…Aâ¨îA@é@|}Aâ¨îA 0@䈉=,îz?BÃ>>jÁAÉýìAuÚF@|}Aâ¨îA 0@νAÉýìA+!L@Î`=ˆ|?¨(>νAÉýìA+!L@|}Aâ¨îA 0@‹zAâ¨îAR¹@GY=,îz?I^C>νAÉýìA+!L@‹zAâ¨îAR¹@=â{AÉýìA£CP@=ú,=ˆ|?Ã^,>=â{AÉýìA£CP@‹zAâ¨îAR¹@¨õwAâ¨îAE~ @4E=,îz?áF>=â{AÉýìA£CP@¨õwAâ¨îAE~ @¨õwAÉýìAð;S@ðñ<ˆ|?­/>¨õwAÉýìAð;S@¨õwAâ¨îAE~ @ÍTuAâ¨îA„{ @–ÁÄ<,îz?6HI>¨õwAÉýìAð;S@ÍTuAâ¨îA„{ @¯ýsAÉýìAÔU@F‘ˆ<ˆ|?áã0>¯ýsAÉýìAÔU@ÍTuAâ¨îA„{ @P¬rAâ¨îA5®@)¾<,îz?¥ŽJ>¯ýsAÉýìAÔU@P¬rAâ¨îA5®@pAÉýìA¿žU@µws;ˆ|?׫1>pAÉýìA¿žU@P¬rAâ¨îA5®@pAâ¨îA¡@3Àµ»,îz?³J>pAÉýìA¿žU@pAâ¨îA¡@PlAÉýìAÔU@Õ½¼ˆ|?pu1>PlAÉýìAÔU@pAâ¨îA¡@¯SmAâ¨îA5®@!~¦¼,îz?TµI>PlAÉýìAÔU@¯SmAâ¨îA5®@W hAÉýìAð;S@+Àµ¼ˆ|?ø@0>W hAÉýìAð;S@¯SmAâ¨îA5®@2«jAâ¨îA„{ @ìN½,îz?Ë–G>W hAÉýìAð;S@2«jAâ¨îA„{ @ÃdAÉýìA£CP@N½ˆ|?,.>ÃdAÉýìA£CP@2«jAâ¨îA„{ @W hAâ¨îAE~ @‘J½,îz?…ZD>ÃdAÉýìA£CP@W hAâ¨îAE~ @3B`AÉýìA+!L@øïB½ˆ|?-æ*>3B`AÉýìA+!L@W hAâ¨îAE~ @áteAâ¨îAR¹@&Y‚½,îz?"@>3B`AÉýìA+!L@áteAâ¨îAR¹@,}\AÉýìAuÚF@?zu½ˆ|?‚Ç&>,}\AÉýìAuÚF@áteAâ¨îAR¹@ƒîbAâ¨îA 0@ஞ½,îz?Öœ:>,}\AÉýìAuÚF@ƒîbAâ¨îA 0@ÔXAÉýìAw@@‹R“½ˆ|?º!>ÔXAÉýìAw@@ƒîbAâ¨îA 0@Üz`Aâ¨îA@é@l!º½,îz?b)4>ÔXAÉýìAw@@Üz`Aâ¨îA@é@(LUAÉýìA9@ «½ˆ|?Å>(LUAÉýìA9@Üz`Aâ¨îA@é@k^Aâ¨îA¤Ò÷?‰Ô½,îz?þ³,>(LUAÉýìA9@k^Aâ¨îA¤Ò÷?wêQAÉýìAO€0@žâÁ½ˆ|?ñ>wêQAÉýìAO€0@k^Aâ¨îA¤Ò÷?—Ù[Aâ¨îAüoì?JÁí½,îz?[G$>wêQAÉýìAO€0@—Ù[Aâ¨îAüoì?׳NAÉýìAÑ'@žš×½ˆ|?åG >׳NAÉýìAÑ'@—Ù[Aâ¨îAüoì?›²YAâ¨îAÔºß?ZÒ¾,îz?‡ï>׳NAÉýìAÑ'@›²YAâ¨îAÔºß?ä¬KAÉýìA8˜@ñ콈|?jÔ>ä¬KAÉýìA8˜@›²YAâ¨îAÔºß?«WAâ¨îA^ÅÑ?þ,îz?â¹>ä¬KAÉýìA8˜@«WAâ¨îA^ÅÑ?òÙHAÉýìAoL@:Oÿ½ˆ|?ˆE÷=òÙHAÉýìAoL@«WAâ¨îA^ÅÑ?TÇUAâ¨îA–£Â?Õs¾,îz? µ>òÙHAÉýìAoL@TÇUAâ¨îA–£Â? ?FAÉýìA 0@€‰¾ˆ|?:€ã= ?FAÉýìA 0@TÇUAâ¨îA–£Â?¥TAâ¨îA'k²?¤"¾,îz?Œáó= ?FAÉýìA 0@¥TAâ¨îA'k²?ìßCAÉýìAH¬ð?é§¾ˆ|?8uÎ=ìßCAÉýìAH¬ð?¥TAâ¨îA'k²?rRAâ¨îAH3¡?~­*¾,îz?ÝûÚ=ìßCAÉýìAH¬ð?rRAâ¨îAH3¡?ù¿AAÉýìA¿žÕ?:÷¾ˆ|?¢B¸=ù¿AAÉýìA¿žÕ?rRAâ¨îAH3¡?«QAâ¨îA¡?b2¾,îz?¬ÜÀ=ù¿AAÉýìA¿žÕ?«QAâ¨îA¡?<â?AÉýìAa_¹?ûl¾ˆ|?@¡=<â?AÉýìAa_¹?«QAâ¨îA¡?°ÅOAâ¨îACRx?9¾,îz?^©¥=<â?AÉýìAa_¹?°ÅOAâ¨îACRx?cI>AÉýìAŸœ?ëÿ#¾ˆ|?Tçˆ=cI>AÉýìAŸœ?°ÅOAâ¨îACRx?׳NAâ¨îAÂQ?BÃ>¾,îz?䈉=cI>AÉýìAŸœ?׳NAâ¨îAÂQ?µ÷?Ã^,¾ˆ|?=ú,=ï;AÉýìAÈ#>?«ÑMAâ¨îAé±(?o MAâ¨îAµþ>.é >xª}?|]s;èÛ‰AuîAÓ0(VÁ„A÷QïAqU(ÆÕ‰Aâ¨îA,+>Sá=?r~?è½¶;ÆÕ‰Aâ¨îA,+>VÁ„A÷QïAqU(Jñ€AªïAûŽ«=Àý=~?ÇT<ÆÕ‰Aâ¨îA,+>Jñ€AªïAûŽ«=q¯‰Aâ¨îA¶™ª>0Ê=¶º~?ÊÆTJñ€AªïAûŽ«=Þ€AªïA,+>¾hú=~?Ú¿µÞ€AªïA,+>Éo‰Aâ¨îAµþ>º€Ç=¶º~?@}¦<Éo‰Aâ¨îAµþ>Þ€AªïA,+>&¾€AªïAïk>&¾€AªïAïk>*‰Aâ¨îAé±(?¦ÕÃ=¶º~?Á¨á<*‰Aâ¨îAé±(?&¾€AªïAïk>·‘€AªïA+©>×ð=~?¸€$=*‰Aâ¨îAé±(?·‘€AªïA+©>¦ˆAâ¨îAÂQ?2¿=¶º~?˜È =¦ˆAâ¨îAÂQ?·‘€AªïA+©>Y€AªïAÛ­Ñ>&ê=~?ò H=¦ˆAâ¨îAÂQ?Y€AªïAÛ­Ñ>'ˆAâ¨îACRx?3=¹=¶º~?Ôñ)='ˆAâ¨îACRx?Y€AªïAÛ­Ñ>\€AªïA„ù>+äá=~?Étj='ˆAâ¨îACRx?\€AªïA„ù>*}‡Aâ¨îA¡?_²=¶º~?Â'E=*}‡Aâ¨îA¡?\€AªïA„ù>HˆAªïAV{?ÊØ=~?úÇ…=*}‡Aâ¨îA¡?HˆAªïAV{?džAâ¨îAH3¡?pª=¶º~?mC_=džAâ¨îAH3¡?HˆAªïAV{?›Ñ~AªïAÿ¦!?uåÍ=~? –•=džAâ¨îAH3¡?›Ñ~AªïAÿ¦!?­û…Aâ¨îA'k²?ů¡=¶º~?vx=­û…Aâ¨îA'k²?›Ñ~AªïAÿ¦!?·~AªïA:ë2?[$Â=~?ó¤=­û…Aâ¨îA'k²?·~AªïA:ë2?V…Aâ¨îA–£Â? ö—=¶º~?#̇=V…Aâ¨îA–£Â?·~AªïA:ë2?¿%}AªïAO/C?NMµ=~?Dš²=V…Aâ¨îA–£Â?¿%}AªïAO/C?:*„Aâ¨îA^ÅÑ?êc=¶º~? Æ’=:*„Aâ¨îA^ÅÑ?¿%}AªïAO/C?õ2|AªïAó[R?²r§=~?㦿=:*„Aâ¨îA^ÅÑ?õ2|AªïAó[R?²&ƒAâ¨îAÔºß?Ê‚=¶º~?üíœ=²&ƒAâ¨îAÔºß?õ2|AªïAó[R?´.{AªïAn[`?[¨˜=~?!¡Ë=²&ƒAâ¨îAÔºß?´.{AªïAn[`?5‚Aâ¨îAüoì?ßk=¶º~?-5¦=5‚Aâ¨îAüoì?´.{AªïAn[`?pzAªïAµm?w‰=~?ØwÖ=5‚Aâ¨îAüoì?pzAªïAµm?Jñ€Aâ¨îA¤Ò÷?Ã^R=¶º~?jŽ®=Jñ€Aâ¨îA¤Ò÷?pzAªïAµm?µ÷xAªïAŠ„x?Õ4q=~?„à=Jñ€Aâ¨îA¤Ò÷?µ÷xAªïAŠ„x?$…Aâ¨îA@é@U±7=¶º~?¿íµ=$…Aâ¨îA@é@µ÷xAªïAŠ„x?$ÈwAªïAÊE?k O=~?W~è=$…Aâ¨îA@é@$ÈwAªïAÊE?|}Aâ¨îA 0@ëü=¶º~?ŸH¼=|}Aâ¨îA 0@$ÈwAªïAÊE?nvAªïA=…?—µ+=~?Q”ï=|}Aâ¨îA 0@nvAªïA=…?‹zAâ¨îAR¹@_Òþ<¶º~?ð•Á=‹zAâ¨îAR¹@nvAªïA=…?XIuAªïAw‰?ïk=~?LSõ=‹zAâ¨îAR¹@XIuAªïAw‰?¨õwAâ¨îAE~ @>Ä<¶º~?ÎÅ=¨õwAâ¨îAE~ @XIuAªïAw‰?¯ýsAªïAhâ‹?ÏÀÄ<~?³ù=¨õwAâ¨îAE~ @¯ýsAªïAhâ‹?ÍTuAâ¨îA„{ @Ùˆ<¶º~?ëÈ=ÍTuAâ¨îA„{ @¯ýsAªïAhâ‹?P¬rAªïAá?$ s<~?T­ü=ÍTuAâ¨îA„{ @P¬rAªïAá?P¬rAâ¨îA5®@2@<¶º~?kèÊ=P¬rAâ¨îA5®@P¬rAªïAá?WqAªïA¡?&Ŷ;~?Û=þ=P¬rAâ¨îA5®@WqAªïA¡?pAâ¨îA¡@¸%ô:¶º~?BÃË=pAâ¨îA¡@WqAªïA¡?pAªïAV{?Hws»~?fbþ=pAâ¨îA¡@pAªïAV{?¯SmAâ¨îA5®@èĶ»¶º~?azË=¯SmAâ¨îA5®@pAªïAV{?â¨nAªïA¡?ÇT¼~?Àý=¯SmAâ¨îA5®@â¨nAªïA¡?2«jAâ¨îA„{ @ÊÆT¼¶º~?0Ê=2«jAâ¨îA„{ @â¨nAªïA¡?¯SmAªïAá?Ú¿µ¼~?¾hú=2«jAâ¨îA„{ @¯SmAªïAá?W hAâ¨îAE~ @@}¦¼¶º~?º€Ç=W hAâ¨îAE~ @¯SmAªïAá?PlAªïAhâ‹?û ½~?W~è½~?k O=°ÅOAâ¨îACRx?G×_AªïA„ù>׳NAâ¨îAÂQ?ŸH¼½¶º~?ëü=׳NAâ¨îAÂQ?G×_AªïA„ù>øM_AªïAÛ­Ñ>Q”ï½~?—µ+=׳NAâ¨îAÂQ?øM_AªïAÛ­Ñ>«ÑMAâ¨îAé±(?ð•Á½¶º~?_Òþ<«ÑMAâ¨îAé±(?øM_AªïAÛ­Ñ>‘Ü^AªïA+©>LSõ½~?ïk=«ÑMAâ¨îAé±(?‘Ü^AªïA+©>o MAâ¨îAµþ>ÎŽ¶º~?>Ä‘Ü^AªïA+©>³ƒ^AªïAïk>¦.½cÄ?€ô:k^AªïAûŽ«=pAðABÏ(:cAvÔïA’ )²ÃJ½¡®¿¿Ä¶;pABÏ(ÝC^AxÌ+=,+>k^AxÌ+=ûŽ«=0ʽ¶º~¿ÊÆT¡LAòŽ+>¶™ª>Àý½~¿ÇT¶™ª>sTLAòŽ+>,+>ø@0¾ˆ|¿+Àµ,+>¡LAòŽ+>¶™ª>1;A´À>µþ>TµI¾,îz¿!~¦,+>1;A´À>µþ>‹¾:A´À>ïk>dz¾Îx¿Ñ =‹¾:A´À>ïk>1;A´À>µþ>ƒ *Aµ™*?é±(?ÄÞ‰¾qqv¿1«á<‹¾:A´À>ïk>ƒ *Aµ™*?é±(?át)Aµ™*?+©>2¬¡¾<¯r¿Õ‚$=át)Aµ™*?+©>ƒ *Aµ™*?é±(?(LA?ÂQ?(®¾3”p¿!Ë =át)Aµ™*?+©>(LA?ÂQ?7A?Û­Ñ>ù1ž|ëk¿H=7A?Û­Ñ>(LA?ÂQ?í AÈ#¾?CRx?eѾÀ^i¿Lö)=7A?Û­Ñ>í AÈ#¾?CRx?¸(AÈ#¾?„ù>Džç¾%Öc¿»{j=¸(AÈ#¾?„ù>í AÈ#¾?CRx?;®ò@™@¡? ó¾TÛ`¿Ô.E=¸(AÈ#¾?„ù>;®ò@™@¡?Ì«ð@™@V{?î_¿³zZ¿JÍ…=Ì«ð@™@V{?;®ò@™@¡?^ Ô@Ï&@H3¡?ª ¿W¿ÉM_=Ì«ð@™@V{?^ Ô@Ï&@H3¡?È\Ò@Ï&@ÿ¦!?¨3¿pæO¿œ•=È\Ò@Ï&@ÿ¦!?^ Ô@Ï&@H3¡?K¸@qQ@'k²?~»¿³L¿Â-x=È\Ò@Ï&@ÿ¦!?K¸@qQ@'k²?̵@qQ@:ë2?¤3#¿h(D¿*˜¤=̵@qQ@:ë2?K¸@qQ@'k²?ã)@•"€@–£Â?§z(¿ÿþ?¿ŒÕ‡=̵@qQ@:ë2?ã)@•"€@–£Â?nš@•"€@O/C?`J1¿RQ7¿x§²=nš@•"€@O/C?ã)@•"€@–£Â?¬„@_„™@^ÅÑ?ùH6¿)Î2¿ Ò’=nš@•"€@O/C?¬„@_„™@^ÅÑ?u@_„™@ó[R?žc>¿|s)¿V·¿=u@_„™@ó[R?¬„@_„™@^ÅÑ?+ÓY@’¹´@Ôºß?£C¿$¿–üœ=u@_„™@ó[R?+ÓY@’¹´@Ôºß?\ŠS@’¹´@n[`?ŽlJ¿¯¢¿þ´Ë=\ŠS@’¹´@n[`?+ÓY@’¹´@Ôºß?‡«/@:›Ñ@üoì?=ÅN¿Æ¿ŽF¦=\ŠS@’¹´@n[`?‡«/@:›Ñ@üoì?Y)@:›Ñ@µm?ÚSU¿ô ¿+Ö=Y)@:›Ñ@µm?‡«/@:›Ñ@üoì?Èæ @ð@¤Ò÷?òOY¿Œ¿’¢®=Y)@:›Ñ@µm?Èæ @ð@¤Ò÷?¹ð@ð@Š„x?Ñ _¿*üô¾A6à=¹ð@ð@Š„x?Èæ @ð@¤Ò÷?ûuÑ?.ÞA@é@£b¿z±é¾–¶=¹ð@ð@Š„x?ûuÑ?.ÞA@é@úÂ?.ÞAÊE?p€g¿Š°Ò¾Nœè=úÂ?.ÞAÊE?ûuÑ?.ÞA@é@P¯˜?rQA 0@¤²j¿Tûƾõa¼=úÂ?.ÞAÊE?P¯˜?rQA 0@Q¸‰?rQA=…?€«n¿i6¯¾6µï=Q¸‰?rQA=…?P¯˜?rQA 0@¦•S?=B)AR¹@Šqq¿x'£¾±Á=Q¸‰?rQA=…?¦•S?=B)AR¹@[Ü4?=B)Aw‰?¦€t¿¥Àо¸võ=[Ü4?=B)Aw‰?¦•S?=B)AR¹@R ?P˜:AE~ @…Öv¿Ò|¾…ëÅ=[Ü4?=B)Aw‰?R ?P˜:AE~ @q}Õ>P˜:Ahâ‹?t÷x¿K¾Øù=q}Õ>P˜:Ahâ‹?R ?P˜:AE~ @µ™ª>×:LA„{ @ÆÙz¿ë1¾ê É=q}Õ>P˜:Ahâ‹?µ™ª>×:LA„{ @BV>×:LAá?t |¿wÒþ½5Ôü=BV>×:LAá?µ™ª>×:LA„{ @BV>•^A5®@u}¿·̽.Ë=BV>×:LAá?BV>•^A5®@òŽ«=•^A¡?5²}¿QL½‹eþ=òŽ«=•^A¡?BV>•^A5®@òŽ+>pA¡@ï¥~¿Q̼mãË=òŽ«=•^A¡?òŽ+>pA¡@xÌ+=pAV{?Oï}¿QÌ<7Šþ=xÌ+=pAV{?òŽ+>pA¡@BV>µ÷€A5®@Xi~¿QL=išË=xÌ+=pAV{?BV>µ÷€A5®@òŽ«=µ÷€A¡?jÀ|¿·Ì=Bý=òŽ«=µ÷€A¡?BV>µ÷€A5®@µ™ª>”â‰A„{ @À|¿wÒþ=Œ-Ê=òŽ«=µ÷€A¡?µ™ª>”â‰A„{ @BV>”â‰Aá?;'z¿ë1>ÕŽú=BV>”â‰Aá?µ™ª>”â‰A„{ @R ?س’AE~ @Ьy¿K>éžÇ=BV>”â‰Aá?R ?س’AE~ @q}Õ>س’Ahâ‹?†'v¿Ò|>ˆtö=q}Õ>س’Ahâ‹?R ?س’AE~ @¦•S?á^›AR¹@03u¿¥ÀŠ>/òÃ=q}Õ>س’Ahâ‹?¦•S?á^›AR¹@[Ü4?á^›Aw‰?Çp¿x'£>ùð=[Ü4?á^›Aw‰?¦•S?á^›AR¹@P¯˜?G×£A 0@}Zo¿i6¯>¯,¿=[Ü4?á^›Aw‰?P¯˜?G×£A 0@Q¸‰?G×£A=…?§ j¿TûÆ>S$ê=Q¸‰?G×£A=…?P¯˜?G×£A 0@ûuÑ?é¬A@é@æ*h¿Š°Ò>QU¹=Q¸‰?G×£A=…?ûuÑ?é¬A@é@úÂ?é¬AÊE?ûb¿y±é>:â=úÂ?é¬AÊE?ûuÑ?é¬A@é@Èæ @ÿÿ³A¤Ò÷?Ì®_¿*üô>…t²=úÂ?é¬AÊE?Èæ @ÿÿ³A¤Ò÷?¹ð@ÿÿ³AŠ„x?¨¸X¿Œ?€˜Ø=¹ð@ÿÿ³AŠ„x?Èæ @ÿÿ³A¤Ò÷?‡«/@1™»Aüoì?mòU¿ô ?6”ª=¹ð@ÿÿ³AŠ„x?‡«/@1™»Aüoì?Y)@1™»Aµm?6N¿Æ?¶úÍ=Y)@1™»Aµm?‡«/@1™»Aüoì?+ÓY@›ÑÂAÔºß?ÕK¿®¢?Á¿¡=Y)@1™»Aµm?+ÓY@›ÑÂAÔºß?\ŠS@›ÑÂAn[`?lŒB¿$?)6Â=\ŠS@›ÑÂAn[`?+ÓY@›ÑÂAÔºß?¬„@èžÉA^ÅÑ?Ãò>¿|s)?Þ˜=\ŠS@›ÑÂAn[`?¬„@èžÉA^ÅÑ?u@èžÉAó[R?rÌ5¿)Î2?É[µ=u@èžÉAó[R?¬„@èžÉA^ÅÑ?ã)@Z÷ÏA–£Â?•Ð1¿RQ7?n=u@èžÉAó[R?ã)@Z÷ÏA–£Â?nš@Z÷ÏAO/C?‚(¿ÿþ??~§=nš@Z÷ÏAO/C?ã)@Z÷ÏA–£Â?K¸@ÝÑÕA'k²?)°#¿h(D? ‚=nš@Z÷ÏAO/C?K¸@ÝÑÕA'k²?̵@ÝÑÕA:ë2?_T¿³L?ó°˜=̵@ÝÑÕA:ë2?K¸@ÝÑÕA'k²?^ Ô@&ÛAH3¡?Ë¥¿pæO?Bëk=̵@ÝÑÕA:ë2?^ Ô@&ÛAH3¡?È\Ò@&ÛAÿ¦!?"Å ¿W?¤ ‰=È\Ò@&ÛAÿ¦!?^ Ô@&ÛAH3¡?;®ò@MìßA¡? Ç¿³zZ?egR=È\Ò@&ÛAÿ¦!?;®ò@MìßA¡?Ì«ð@MìßAV{?4âò¾TÛ`?*=q=Ì«ð@MìßAV{?;®ò@MìßA¡?í AÃäACRx?QUè¾%Öc?·7=Ì«ð@MìßAV{?í AÃäACRx?¸(AÃäA„ù>PßоÀ^i?•O=¸(AÃäA„ù>í AÃäACRx?(LAq´çAÂQ?ÏО|ëk?W=¸(AÃäA„ù>(LAq´çAÂQ?7Aq´çAÛ­Ñ>B²­¾3”p?o¸+=7Aq´çAÛ­Ñ>(LAq´çAÂQ?ƒ *A2«êAé±(?ï1¢¾<¯r?ûÕþ<7Aq´çAÛ­Ñ>ƒ *A2«êAé±(?át)A2«êA+©>O‰¾qqv?8m=át)A2«êA+©>ƒ *A2«êAé±(?1;AÉýìAµþ>/W{¾Îx? ?Ä<át)A2«êA+©>1;AÉýìAµþ>‹¾:AÉýìAïk>6HI¾,îz?–ÁÄ<‹¾:AÉýìAïk>1;AÉýìAµþ>¡LAâ¨îA¶™ª>áã0¾ˆ|?F‘ˆ<‹¾:AÉýìAïk>¡LAâ¨îA¶™ª>sTLAâ¨îA,+>T­ü½~?$ s¡LAâ¨îA¶™ª>ÝC^AªïA,+>kèʽ¶º~?2@ÝC^AªïA,+>k^AªïAûŽ«=²ÃJ½¡®?¿Ä¶;k^AªïAûŽ«=ÝC^AªïA,+>pAðABÏ(ª5н|j?ôô::cAvÔïA’ )^A&ŽïAƒS )k^AªïAûŽ«=ßÁ˽ºº~?Â%ô:k^AªïAûŽ«=^A&ŽïAƒS ) >LAö™îA‘/)ƒAþ½÷~?(Ŷ;k^AªïAûŽ«= >LAö™îA‘/)sTLAâ¨îA,+>¢è¾{}?~Qs;sTLAâ¨îA,+> >LAö™îA‘/)#ÓIAâxîAZÚ3)XÞ4¾Àö{? »#ÓIAâxîAZÚ3)‹¾:AÉýìAïk>cN¾æÁz?í¸µ;‹¾:AÉýìAïk>#ÓIAâxîAZÚ3)à©:A.ÕìAá,R)¦q¾_Åx?¯¬µ;‹¾:AÉýìAïk>à©:A.ÕìAá,R)ûÚ0AªÅëA­Êe)}}H½¡®¿:½<pABÏ(³ƒ^AxÌ+=ïk>ÝC^AxÌ+=,+>º€Ç½¶º~¿@}¦<ÝC^AxÌ+=,+>³ƒ^AxÌ+=ïk>o MAòŽ+>µþ>¾hú½~¿Ú¿µ<ÝC^AxÌ+=,+>o MAòŽ+>µþ>¡LAòŽ+>¶™ª>,.¾ˆ|¿N=¡LAòŽ+>¶™ª>o MAòŽ+>µþ>ï;A´À>È#>?Ë–G¾,îz¿ìN=¡LAòŽ+>¶™ª>ï;A´À>È#>?1;A´À>µþ>¦gw¾Îx¿#’J=1;A´À>µþ>ï;A´À>È#>?J+Aµ™*?ÎÜ{??nˆ¾qqv¿yñB=1;A´À>µþ>J+Aµ™*?ÎÜ{?ƒ *Aµ™*?é±(?¯Ÿ¾<¯r¿OZ‚=ƒ *Aµ™*?é±(?J+Aµ™*?ÎÜ{?;„A?Ÿœ?rN¬¾3”p¿à}u=ƒ *Aµ™*?é±(?;„A?Ÿœ?(LA?ÂQ?iÆÂ¾|ëk¿„±ž=(LA?ÂQ?;„A?Ÿœ?Œz AÈ#¾?a_¹?»8ϾÀ^i¿öU“=(LA?ÂQ?Œz AÈ#¾?a_¹?í AÈ#¾?CRx?¼Çä¾%Öc¿4&º=í AÈ#¾?CRx?Œz AÈ#¾?a_¹?mö@™@¿žÕ?4ûð¾TÛ`¿§«=í AÈ#¾?CRx?mö@™@¿žÕ?;®ò@™@¡?3Á¿³zZ¿‘Ô=;®ò@™@¡?mö@™@¿žÕ?½bØ@Ï&@H¬ð?ɲ¿W¿ëÁ=;®ò@™@¡?½bØ@Ï&@H¬ð?^ Ô@Ï&@H3¡?Èc¿pæO¿bÌí=^ Ô@Ï&@H3¡?½bØ@Ï&@H¬ð?t:¼@qQ@ 0@µ$¿³L¿_¦×=^ Ô@Ï&@H3¡?t:¼@qQ@ 0@K¸@qQ@'k²?65!¿h(D¿õÙ>K¸@qQ@'k²?t:¼@qQ@ 0@䳡@•"€@oL@8½&¿ÿþ?¿’-ì=K¸@qQ@'k²?䳡@•"€@oL@ã)@•"€@–£Â?< /¿RQ7¿´>ã)@•"€@–£Â?䳡@•"€@oL@õˆ@_„™@8˜@dg4¿)Î2¿+cÿ=ã)@•"€@–£Â?õˆ@_„™@8˜@¬„@_„™@^ÅÑ?Þ<¿|s)¿Q€>¬„@_„™@^ÅÑ?õˆ@_„™@8˜@‚Bd@’¹´@Ñ'@–A¿$¿È•>¬„@_„™@^ÅÑ?‚Bd@’¹´@Ñ'@+ÓY@’¹´@Ôºß?„ôG¿¯¢¿Î">+ÓY@’¹´@Ôºß?‚Bd@’¹´@Ñ'@š²:@:›Ñ@O€0@™£L¿Å¿–¶>+ÓY@’¹´@Ôºß?š²:@:›Ñ@O€0@‡«/@:›Ñ@üoì?ºR¿ô ¿c¿*>‡«/@:›Ñ@üoì?š²:@:›Ñ@O€0@Ìu@ð@9@ÆW¿Œ¿N>‡«/@:›Ñ@üoì?Ìu@ð@9@Èæ @ð@¤Ò÷?ýQ\¿*üô¾”v2>Èæ @ð@¤Ò÷?Ìu@ð@9@Ï‚é?.ÞAw@@N`¿y±é¾`€>Èæ @ð@¤Ò÷?Ï‚é?.ÞAw@@ûuÑ?.ÞA@é@w®d¿Š°Ò¾?.9>ûuÑ?.ÞA@é@Ï‚é?.ÞAw@@|ˆ±?rQAuÚF@&Hh¿Uûƾ{$>ûuÑ?.ÞA@é@|ˆ±?rQAuÚF@P¯˜?rQA 0@lÃk¿i6¯¾²Ü>>P¯˜?rQA 0@|ˆ±?rQAuÚF@ËLƒ?=B)A+!L@…õn¿x'£¾¿(>P¯˜?rQA 0@ËLƒ?=B)A+!L@¦•S?=B)AR¹@¢†q¿¤Àо¸yC>¦•S?=B)AR¹@ËLƒ?=B)A+!L@È#>?P˜:A£CP@‡Lt¿Ò|¾Úw,>¦•S?=B)AR¹@È#>?P˜:A£CP@R ?P˜:AE~ @Ãïu¿K¾¦þF>R ?P˜:AE~ @È#>?P˜:A£CP@R ?×:LAð;S@tEx¿ë1¾9/>R ?P˜:AE~ @R ?×:LAð;S@µ™ª>×:LA„{ @nøx¿wÒþ½dfI>µ™ª>×:LA„{ @R ?×:LAð;S@q}Õ>•^AÔU@Úz¿·̽ÿ0>µ™ª>×:LA„{ @q}Õ>•^AÔU@BV>•^A5®@@œz¿QL½w­J>BV>•^A5®@q}Õ>•^AÔU@´À>pA¿žU@|¿Q̼VÇ1>BV>•^A5®@´À>pA¿žU@òŽ+>pA¡@ÖØz¿QÌ<ÒJ>òŽ+>pA¡@´À>pA¿žU@q}Õ>µ÷€AÔU@VÌ{¿QL=Ò1>òŽ+>pA¡@q}Õ>µ÷€AÔU@BV>µ÷€A5®@Ú­y¿·Ì=×ÓI>BV>µ÷€A5®@q}Õ>µ÷€AÔU@R ?”â‰Að;S@¬'z¿wÒþ=Ç[0>BV>µ÷€A5®@R ?”â‰Að;S@µ™ª>”â‰A„{ @ýw¿ë1>^´G>µ™ª>”â‰A„{ @R ?”â‰Að;S@È#>?س’A£CP@sw¿K>ö).>µ™ª>”â‰A„{ @È#>?س’A£CP@R ?س’AE~ @õ)s¿Ò|>®vD>R ?س’AE~ @È#>?س’A£CP@ËLƒ?á^›A+!L@¯r¿¤ÀŠ>Œþ*>R ?س’AE~ @ËLƒ?á^›A+!L@¦•S?á^›AR¹@wÚm¿x'£>t@>¦•S?á^›AR¹@ËLƒ?á^›A+!L@|ˆ±?G×£AuÚF@üål¿i6¯>Þ&>¦•S?á^›AR¹@|ˆ±?G×£AuÚF@P¯˜?G×£A 0@26g¿UûÆ>ø´:>P¯˜?G×£A 0@|ˆ±?G×£AuÚF@Ï‚é?é¬Aw@@‚Ée¿Š°Ò>¡Î!>P¯˜?G×£A 0@Ï‚é?é¬Aw@@ûuÑ?é¬A@é@½F_¿z±é> ?4>ûuÑ?é¬A@é@Ï‚é?é¬Aw@@Ìu@ÿÿ³A9@íc]¿*üô>g×>ûuÑ?é¬A@é@Ìu@ÿÿ³A9@Èæ @ÿÿ³A¤Ò÷?V¿Œ?Ç,>Èæ @ÿÿ³A¤Ò÷?Ìu@ÿÿ³A9@š²:@1™»AO€0@\ÁS¿ô ?>Èæ @ÿÿ³A¤Ò÷?š²:@1™»AO€0@‡«/@1™»Aüoì?æµK¿Å?ªW$>‡«/@1™»Aüoì?š²:@1™»AO€0@‚Bd@›ÑÂAÑ'@µïH¿®¢?lU >‡«/@1™»Aüoì?‚Bd@›ÑÂAÑ'@+ÓY@›ÑÂAÔºß?º0@¿$? ý>+ÓY@›ÑÂAÔºß?‚Bd@›ÑÂAÑ'@õˆ@èžÉA8˜@þ<¿|s)?”ß>+ÓY@›ÑÂAÔºß?õˆ@èžÉA8˜@¬„@èžÉA^ÅÑ?ž˜3¿)Î2?ßÄ>¬„@èžÉA^ÅÑ?õˆ@èžÉA8˜@䳡@Z÷ÏAoL@ÿ/¿RQ7?_W÷=¬„@èžÉA^ÅÑ?䳡@Z÷ÏAoL@ã)@Z÷ÏA–£Â?±ÿ%¿ÿþ??›½>ã)@Z÷ÏA–£Â?䳡@Z÷ÏAoL@t:¼@ÝÑÕA 0@ø"¿h(D?óã=ã)@Z÷ÏA–£Â?t:¼@ÝÑÕA 0@K¸@ÝÑÕA'k²?yy¿´L?Qîó=K¸@ÝÑÕA'k²?t:¼@ÝÑÕA 0@½bØ@&ÛAH¬ð?M!¿pæO?LÎ=K¸@ÝÑÕA'k²?½bØ@&ÛAH¬ð?^ Ô@&ÛAH3¡?Ï¿W?ÞÛ=^ Ô@&ÛAH3¡?½bØ@&ÛAH¬ð?mö@MìßA¿žÕ?ml¿³zZ? I¸=^ Ô@&ÛAH3¡?mö@MìßA¿žÕ?;®ò@MìßA¡?tóï¾TÛ`?’âÀ=;®ò@MìßA¡?mö@MìßA¿žÕ?Œz AÃäAa_¹?­÷å¾%Öc?¼ ¡=;®ò@MìßA¡?Œz AÃäAa_¹?í AÃäACRx?§ZξÀ^i?Ù¬¥=í AÃäACRx?Œz AÃäAa_¹?;„Aq´çAŸœ?'Îþ|ëk?èéˆ=í AÃäACRx?;„Aq´çAŸœ?(LAq´çAÂQ?G›«¾3”p?¡Š‰=(LAq´çAÂQ?;„Aq´çAŸœ?J+A2«êAÎÜ{?! ¾<¯r?I`=(LAq´çAÂQ?J+A2«êAÎÜ{?ƒ *A2«êAé±(?þ懾qqv?;HY=ƒ *A2«êAé±(?J+A2«êAÎÜ{?ï;AÉýìAÈ#>?øÍx¾Îx?û,=ƒ *A2«êAé±(?ï;AÉýìAÈ#>?1;AÉýìAµþ>áF¾,îz?4E=1;AÉýìAµþ>ï;AÉýìAÈ#>?o MAâ¨îAµþ>­/¾ˆ|?ðñ<1;AÉýìAµþ>o MAâ¨îAµþ>¡LAâ¨îA¶™ª>³ù½~?ÏÀÄ<¡LAâ¨îA¶™ª>o MAâ¨îAµþ>³ƒ^AªïAïk>ëȽ¶º~?Ùˆ<¡LAâ¨îA¶™ª>³ƒ^AªïAïk>ÝC^AªïA,+>}}H½¡®?:½<ÝC^AªïA,+>³ƒ^AªïAïk>pAðABÏ(O–½"³¾o?4&_AAñAtÕ`AàÈ\AAñAR·`AøM_ArQAöÈ^Ag÷Ľ¯'·¾ÛÉm?øM_ArQAöÈ^AàÈ\AAñAR·`A׳NArQAê\AS$ê½Tûƾ§ j?øM_ArQAöÈ^A׳NArQAê\A°ÅOA.ÞA@ÑUA¡Î!¾Š°Ò¾‚Ée?°ÅOA.ÞA@ÑUA׳NArQAê\A<â?A.ÞA¦ÏRA ?4¾z±é¾½F_?°ÅOA.ÞA@ÑUA<â?A.ÞA¦ÏRAù¿AAð@¢JAp•]¾*üô¾ÜY?ù¿AAð@¢JA<â?A.ÞA¦ÏRA}¼2Að@±œFAqJl¾Œ¿öCR?ù¿AAð@¢JA}¼2Að@±œFA5A:›Ñ@Î|=Ayʈ¾ô ¿”ÖK?5A:›Ñ@Î|=A}¼2Að@±œFAÊ'A:›Ñ@ú–8Aõù¾Å¿ÑOC?5A:›Ñ@Î|=AÊ'A:›Ñ@ú–8A”r+A’¹´@2«.A÷Qž¾®¢¿: Ç´AqQ@ÐE÷@׳AqQ@’ûé@Ç´AÏ&@úfÓ@ŠÖ¿¾pæO¿Nå>Ç´AÏ&@úfÓ@׳AqQ@’ûé@õ AÏ&@j6Æ@†·¾W¿ç\Ð>Ç´AÏ&@úfÓ@õ AÏ&@j6Æ@aA™@µî¯@("º¾³zZ¿¡8¿>aA™@µî¯@õ AÏ&@j6Æ@¦A™@Ð=£@ð¯¾TÛ`¿Á«>aA™@µî¯@¦A™@Ð=£@pª#AÈ#¾?×§@_Ü®¾%Öc¿N±š>pª#AÈ#¾?×§@¦A™@Ð=£@–AÈ#¾?ÁÙ@Î ¡¾À^i¿‹‚‡>pª#AÈ#¾?×§@–AÈ#¾?ÁÙ@”r+A?ɬZ@ËEž¾|ëk¿$‚p>”r+A?ɬZ@–AÈ#¾?ÁÙ@Ê'A?_’E@©í¾3”p¿'ÑL>”r+A?ɬZ@Ê'A?_’E@5Aµ™*?\f@[½ˆ¾<¯r¿]Y1>5Aµ™*?\f@Ê'A?_’E@}¼2Aµ™*?„{ @º1l¾qqv¿è >5Aµ™*?\f@}¼2Aµ™*?„{ @ù¿AA´À>¿žÕ?u|]¾Îx¿!¢ò=ù¿AA´À>¿žÕ?}¼2Aµ™*?„{ @<â?A´À>a_¹?b)4¾,îz¿l!º=ù¿AA´À>¿žÕ?<â?A´À>a_¹?°ÅOAòŽ+>CRx?º!¾ˆ|¿‹R“=°ÅOAòŽ+>CRx?<â?A´À>a_¹?׳NAòŽ+>ÂQ?&ê½~¿ò H=°ÅOAòŽ+>CRx?׳NAòŽ+>ÂQ?øM_AxÌ+=Û­Ñ>2¿½¶º~¿˜È =øM_AxÌ+=Û­Ñ>׳NAòŽ+>ÂQ?‘Ü^AxÌ+=+©>Ô˜@½¡®¿Ɇ<øM_AxÌ+=Û­Ñ>‘Ü^AxÌ+=+©>pABÏ(v–û§€¿ê‹çA$qA,§©´FåA>Ô AÇ£©¿äA8ùAŽ ©v–û§€¿ÕIíA§D=AVȲ©·íìA¡:AG²©t¥A¾efAÑC“¨v–û§€¿t¥A¾efAÑC“¨·íìA¡:AG²©J‘êA^P)ADo­©v–û§€¿t¥A¾efAÑC“¨J‘êA^P)ADo­©ò¤A{I`AË‹¨v–û§€¿ò¤A{I`AË‹¨J‘êA^P)ADo­©íéA!Ÿ$AR-¬©v–û§€¿ò¤A{I`AË‹¨íéA!Ÿ$AR-¬©^y¢AòšZAÞÜ}¨v–û§€¿ÕIíA§D=AVȲ©t¥A¾efAÑC“¨uîA0HLAê(µ©v–û§€¿uîA0HLAê(µ©t¥A¾efAÑC“¨—¥AÅlAïq—¨v–û§€¿uîA0HLAê(µ©—¥AÅlAïq—¨÷QïAT}VA¬Æ¶©v–û§€¿—¥Að:sAïq—¨ðApA¾¸©—¥AÅlAïq—¨v–û§€¿—¥AÅlAïq—¨ðApA¾¸©À…ïAu^At,·©v–û§€¿—¥AÅlAïq—¨À…ïAu^At,·©÷QïAT}VA¬Æ¶©v–û§€¿ìíA<ŽA1´©ÜîA[݉A¥-µ©t¥AAšyAÑC“¨v–û§€¿t¥AAšyAÑC“¨ÜîA[݉A¥-µ©žïA“A@\·©v–û§€¿t¥AAšyAÑC“¨žïA“A@\·©—¥Að:sAïq—¨v–û§€¿—¥Að:sAïq—¨žïA“A@\·©H¤ïAz÷€Axh·©v–û§€¿—¥Að:sAïq—¨H¤ïAz÷€Axh·©ðApA¾¸©v–û§€¿žA*o‡A¹K9¨ŒÞÏA¿†ÉA¾êq©ùNÒAxÇAj{©v–û§€¿Ù'@â»AÊù)éL@ZÂA!Eí)¡¶Q@ÊÂA¨Rï)v–û§€¿)|¾?”¬Afø*gšA‡²‚A³]™)-©†?0Ê£A•u *v–û§€¿-©†?0Ê£A•u *gšA‡²‚A³]™)>‡A„¶AJcœ)v–û§€¿-©†?0Ê£A•u *>‡A„¶AJcœ)¶c?kµ AfÐ*v–û§€¿¶c?kµ AfÐ*>‡A„¶AJcœ)µ¼/?|R›ABb *v–û§€¿Pü„>܇CAéà *K«:A·*v–û§€¿ŠCÊ>K«:A·*‡A{I`AJcœ)v–û§€¿A@P3ð@ô·*<’ AÎUAaw•)ôU'@EÅÑ@Óêù)v–û§€¿ôU'@EÅÑ@Óêù)<’ AÎUAaw•)SA«!QAŽË)v–û§€¿ôU'@EÅÑ@Óêù)SA«!QAŽË)æm.@Ì@MÂô)v–û§€¿æm.@Ì@MÂô)SA«!QAŽË)x}R@í"µ@ò ï)v–û§€¿÷ý«A“À?@Ãɨ­¨¦Aº—?4ÕŸ¨Ì£Al”†?1Y‰¨v–û§€¿õUð@ÕÇßAV•«)yVAt{âA’ )ŽûAfýãAÂÄ›)v–û§€¿)|¾?”¬Afø*RÁ?z¬AÞî*gšA‡²‚A³]™)v–û§€¿gšA‡²‚A³]™)RÁ?z¬AÞî*m¬@@í³Ašª*v–û§€¿gšA‡²‚A³]™)m¬@@í³Ašª*<’ A?…Aaw•)v–û§€¿<’ A?…Aaw•)m¬@@í³Ašª*Ç,@ˆ¦·Ak³û)v–û§€¿<’ A?…Aaw•)Ç,@ˆ¦·Ak³û)SA*o‡AŽË)v–û§€¿Pü„>܇CAéà *T?>KELAb*KELAb*”ÞC=ñÙ\Aqn*v–û§€¿©xù¼Aæm.@ë£'©Åh›A™MAƨv–û§€¿Åh›A™MAƨxù¼Aæm.@ë£'©®Ž»AôU'@Ç"©v–û§€¿Åh›A™MAƨ®Ž»AôU'@Ç"©|s˜A»KA§„À§v–û§€¿ÔÛA öÑ@—ÝŽ©NSØA`¾Á@D”‰©t} AÎUALª^¨v–û§€¿t} AÎUALª^¨NSØA`¾Á@D”‰©ž´ÕAŒµ@n„©v–û§€¿t} AÎUALª^¨ž´ÕAŒµ@n„©žA«!QA¹K9¨v–û§€¿ñbßARì@¬z”A$p *µ¼/?|R›ABb *ÄÊÅ>䯒AýÈ*v–û§€¿ÄÊÅ>䯒AýÈ*µ¼/?|R›ABb *>‡A„¶AJcœ)v–û§€¿ÄÊÅ>䯒AýÈ*>‡A„¶AJcœ).À6>[Þ‰A¨r*v–û§€¿.À6>[Þ‰A¨r*>‡A„¶AJcœ)[Þ‰A¨r*Tí‡A—Ã*v–û§€¿Tä>Tí‡A—Ã*Tí‡A—Ã*^Að:sA’~Ÿ)è€=Dô€A@_*v–û§€¿è€=Dô€A@_*^Að:sA’~Ÿ)Ô‚<½pA„¿*v–û§€¿è€=Dô€A@_*Ô‚<½pA„¿*ð)®;cvAýÃ*v–û§€¿º—?¥®A ‡*l”†?áfAáv *gšAòšZA³]™)v–û§€¿gšAòšZA³]™)l”†?áfAáv *¿+?ÚH)A/‚ *v–û§€¿gšAòšZA³]™)¿+?ÚH)A/‚ *>‡A{I`AJcœ)v–û§€¿>‡A{I`AJcœ)¿+?ÚH)A/‚ *Ö#?Ķ*A<É *v–û§€¿>‡A{I`AJcœ)Ö#?Ķ*A<É *ŠCÊ>K«:A·*v–û§€¿xÇA2ˆm@›"O©D·ÂAx}R@É5>©¿†ÉAÑ…€@‚ûX©v–û§€¿¿†ÉAÑ…€@‚ûX©D·ÂAx}R@É5>©Åh›A™MAƨv–û§€¿¿†ÉAÑ…€@‚ûX©Åh›A™MAƨˆôÏA÷™@+Ar©v–û§€¿ˆôÏA÷™@+Ar©Åh›A™MAƨžA«!QA¹K9¨v–û§€¿ˆôÏA÷™@+Ar©žA«!QA¹K9¨B,ÐA iš@@s©v–û§€¿B,ÐA iš@@s©žA«!QA¹K9¨ž´ÕAŒµ@n„©v–û§€¿<ú™@p×ÏA2ÃÖ)ޤ­@MaÔA-JÊ)˜»At3‰AÙz‹)v–û§€¿˜»At3‰AÙz‹)ޤ­@MaÔA-JÊ)‚ö´@\½ÕAEÉ)v–û§€¿˜»At3‰AÙz‹)‚ö´@\½ÕAEÉ)*¦A£ŠAaª…)v–û§€¿`¾Á@•e=@›iÀ)Œµ@[R@ 3É)*¦A»KAaª…)v–û§€¿*¦A»KAaª…)Œµ@[R@ 3É) iš@æ~@€½Ó)v–û§€¿*¦A»KAaª…) iš@æ~@€½Ó)˜»A™MAÙz‹)v–û§€¿˜»A™MAÙz‹) iš@æ~@€½Ó)÷™@à-€@TøÖ)v–û§€¿˜»A™MAÙz‹)÷™@à-€@TøÖ)Ñ…€@å™@g}ã)v–û§€¿8ùA Ä¿?Ç›)ˆð@ü@ ´«)oé"A»jIA€)v–û§€¿oé"A»jIA€)ˆð@ü@ ´«)Rì@vè@·}«)v–û§€¿oé"A»jIA€)Rì@vè@·}«)*¦A»KAaª…)v–û§€¿*¦A»KAaª…)Rì@vè@·}«) öÑ@[á'@Jź)v–û§€¿*¦A»KAaª…) öÑ@[á'@Jź)`¾Á@•e=@›iÀ)v–û§€¿®Ž»AôU'@Ç"©+ó³AA@*©|s˜A»KA§„À§v–û§€¿|s˜A»KA§„À§+ó³AA@*©f%²Amtð?…%ú¨v–û§€¿|s˜A»KA§„À§f%²Amtð?…%ú¨ÚQ•A»jIA<§v–û§€¿ŒÞÏA¿†ÉA¾êq©žA*o‡A¹K9¨œÉAˆôÏAOY©v–û§€¿œÉAˆôÏAOY©žA*o‡A¹K9¨Åh›At3‰Aƨv–û§€¿œÉAˆôÏAOY©Åh›At3‰Aƨ½eÉAB,ÐA¿yX©v–û§€¿~ë´AñbßA*ú©|s˜A£ŠA§„À§Þù³AàßARD©v–û§€¿Þù³AàßARD©|s˜A£ŠA§„À§ÚQ•A¢J‹A<§v–û§€¿Þù³AàßARD©ÚQ•A¢J‹A<§d¬A¿äAäíɨv–û§€¿d¬A¿äAäíɨÚQ•A¢J‹A<§á•©A´FåA€×¶¨v–û§€¿‚ö´@\½ÕAEÉ)ÊÆÑ@eÛAëܺ)*¦A£ŠAaª…)v–û§€¿*¦A£ŠAaª…)ÊÆÑ@eÛAëܺ)í§Ö@hÿÛAø"¶)v–û§€¿*¦A£ŠAaª…)í§Ö@hÿÛAø"¶)oé"A¢J‹A€)v–û§€¿Êˆ@=·ËA»¼Ü)<ú™@p×ÏA2ÃÖ)W~€@ÕŠÉA$ã)v–û§€¿W~€@ÕŠÉA$ã)<ú™@p×ÏA2ÃÖ)˜»At3‰AÙz‹)v–û§€¿W~€@ÕŠÉA$ã)˜»At3‰AÙz‹)¡¶Q@ÊÂA¨Rï)v–û§€¿¡¶Q@ÊÂA¨Rï)˜»At3‰AÙz‹)SA*o‡AŽË)v–û§€¿¡¶Q@ÊÂA¨Rï)SA*o‡AŽË)Ù'@â»AÊù)v–û§€¿Ù'@â»AÊù)SA*o‡AŽË)Ç,@ˆ¦·Ak³û)v–û§€¿ž¤šAÖ#?±¹¨Zª’AŠCÊ>(©¥’[›A¿+?†ö ¨v–û§€¿’[›A¿+?†ö ¨Zª’AŠCÊ>(©¥¾’A(âHAðPf%v–û§€¿’[›A¿+?†ö ¨¾’A(âHAðPf%Ì£Al”†?1Y‰¨v–û§€¿Ì£Al”†?1Y‰¨¾’A(âHAðPf%ÚQ•A»jIA<§v–û§€¿Ì£Al”†?1Y‰¨ÚQ•A»jIA<§÷ý«A“À?@Ãɨv–û§€¿÷ý«A“À?@ÃɨÚQ•A»jIA<§f%²Amtð?…%ú¨v–û§€¿~ë´AñbßA*ú©}‚»AÔÛA×á!©|s˜A£ŠA§„À§v–û§€¿|s˜A£ŠA§„À§}‚»AÔÛA×á!©h¿ANSØAõÑ1©v–û§€¿|s˜A£ŠA§„À§h¿ANSØAõÑ1©Åh›At3‰Aƨv–û§€¿Åh›At3‰Aƨh¿ANSØAõÑ1©]¹ÂAž´ÕA>>©v–û§€¿Åh›At3‰Aƨ]¹ÂAž´ÕA>>©½eÉAB,ÐA¿yX©v–û§€¿Åõ€AÀ…ïA^ˆ(VÁ„A÷QïAqU(èÛ‰AuîAÓ0(v–û§€¿í§Ö@hÿÛAø"¶)õUð@ÕÇßAV•«)oé"A¢J‹A€)v–û§€¿oé"A¢J‹A€)õUð@ÕÇßAV•«)ŽûAfýãAÂÄ›)v–û§€¿oé"A¢J‹A€)ŽûAfýãAÂÄ›)¨Y)A쎋AÜ]r)v–û§€¿¨Y)A쎋AÜ]r)ŽûAfýãAÂÄ›)$SA“²çA-m‹)v–û§€¿8ùA Ä¿?Ç›)oé"A»jIA€)>Ô AÆ”«?6•)v–û§€¿>Ô AÆ”«?6•)oé"A»jIA€)¨Y)A(âHAÜ]r)v–û§€¿>Ô AÆ”«?6•)¨Y)A(âHAÜ]r)$qA^A‡?,O‹)v–û§€¿Zª’AŠCÊ>(©¥<ŽAPü„>,Æ€'¾’A(âHAðPf%v–û§€¿¾’A(âHAðPf%<ŽAPü„>,Æ€'[݉AT?> (v–û§€¿¾’A(âHAðPf%[݉AT?> (“A”ÞC=ûºƒ(v–û§€¿u^AÆ€t=·W )T}VA¼®=Û¤)¾’A(âHAðPf%v–û§€¿¾’A(âHAðPf%T}VA¼®=Û¤)0HLApE@>@ð.)v–û§€¿¾’A(âHAðPf%0HLApE@>@ð.)§D=AŠ­>¥7K)v–û§€¿v¯’A·íìA¼³¥ÑW›AJ‘êAm» ¨¾’A쎋AðPf%v–û§€¿¾’A쎋AðPf%ÑW›AJ‘êAm» ¨o°AíéAß2¨v–û§€¿¾’A쎋AðPf%o°AíéAß2¨ÚQ•A¢J‹A<§v–û§€¿ÚQ•A¢J‹A<§o°AíéAß2¨nÇ£Aê‹çAÞ0‰¨v–û§€¿ÚQ•A¢J‹A<§nÇ£Aê‹çAÞ0‰¨á•©A´FåA€×¶¨v–û§€¿§D=AŠ­>¥7K)¡:AD’Ä>y>R)¾’A(âHAðPf%v–û§€¿¾’A(âHAðPf%¡:AD’Ä>y>R)^P)A°Ö-?äßt)v–û§€¿¾’A(âHAðPf%^P)A°Ö-?äßt)¨Y)A(âHAÜ]r)v–û§€¿¨Y)A(âHAÜ]r)^P)A°Ö-?äßt)!Ÿ$A$PB?4©{)v–û§€¿¨Y)A(âHAÜ]r)!Ÿ$A$PB?4©{)$qA^A‡?,O‹)v–û§€¿à©:A.ÕìAá,R)¾’A쎋AðPf%ûÚ0AªÅëAtc)v–û§€¿ûÚ0AªÅëAtc)¾’A쎋AðPf%¨Y)A쎋AÜ]r)v–û§€¿ûÚ0AªÅëAtc)¨Y)A쎋AÜ]r)ŸY)A܇êAcÍt)v–û§€¿ŸY)A܇êAcÍt)¨Y)A쎋AÜ]r)$SA“²çA-m‹)v–û§€¿ŸY)A܇êAcÍt)$SA“²çA-m‹)ù™A¦ÂçA¸¤‰)v–û§€¿pABÏ(u^AÆ€t=·W )cvAð)®;Âãµ(v–û§€¿cvAð)®;Âãµ(u^AÆ€t=·W )¾’A(âHAðPf%v–û§€¿cvAð)®;Âãµ(¾’A(âHAðPf%‚÷€ApJ3=´ˆ(v–û§€¿‚÷€ApJ3=´ˆ(¾’A(âHAðPf%“A”ÞC=ûºƒ(v–û§€¿à©:A.ÕìAá,R)#ÓIAâxîAz‰2) >LAö™îA‘/)v–û§€¿à©:A.ÕìAá,R) >LAö™îA‘/)¾’A쎋AðPf%v–û§€¿¾’A쎋AðPf% >LAö™îA‘/)^A&ŽïAƒS )v–û§€¿¾’A쎋AðPf%^A&ŽïAƒS ):cAvÔïAÚ›)v–û§€¿¬]‘AÕIíAlgr&v¯’A·íìA¼³¥èÛ‰AuîAÓ0(v–û§€¿èÛ‰AuîAÓ0(v¯’A·íìA¼³¥¾’A쎋AðPf%v–û§€¿èÛ‰AuîAÓ0(¾’A쎋AðPf%Åõ€AÀ…ïA^ˆ(v–û§€¿Åõ€AÀ…ïA^ˆ(¾’A쎋AðPf%:cAvÔïAÚ›)v–û§€¿Åõ€AÀ…ïA^ˆ(:cAvÔïAÚ›)pAðABÏ(ÁÑ¿üG¿¦ž'õ²žAÉõ†A÷5/AýžAÒm‡AÙ/AžA*o‡A{ýR¨ƒ*©¾‚Ÿq¿ü)'õȘAlaŠA.5As˜A4~ŠAÒÚ5A|s˜A£ŠAözê§Ô <¾{¥{¿)À&ín–A„‹AŽò7AmQ•AWH‹Aý9AÚQ•A¢J‹Aöú«§¸–̼ë¿¥L%£“AÞ€‹A?â:A¾’A쎋Aƒ]þê&ÚQ•A¢J‹Aöú«§WÕ—A³ŠAA6Aín–A„‹AŽò7Aäá¿ü]R¿{Ê'žA*o‡A{ýR¨ýžAÒm‡AÙ/AÅh›At3‰A{½3¨ÿ ¿;S¿*êŽ'Åh›At3‰A{½3¨ýžAÒm‡AÙ/A4ÖAN¥‡A{$0Az! ¿J‰W¿QƒŠ'Åh›At3‰A{½3¨4ÖAN¥‡A{$0A[¨œAßvˆA–h1AM×þ¾; ^¿Ê_'[¨œAßvˆA–h1Aõk›A»1‰AÚ¹2AÅh›At3‰A{½3¨2Ëó¾ªa¿pr'Åh›At3‰A{½3¨õk›A»1‰AÚ¹2A·h›AV3‰AH½2A‰Ú¾a‚g¿dY'Åh›At3‰A{½3¨·h›AV3‰AH½2A|s˜A£ŠAözê§à/Ͼuj¿TˆL'|s˜A£ŠAözê§·h›AV3‰AH½2Ad!šAzÕ‰A•4AØõ·¾µçn¿+è6'|s˜A£ŠAözê§d!šAzÕ‰A•4AõȘAlaŠA.5AÚ—B¿mW&¿›yÂ'e£¡AûàƒAJÿ+AE½ Aqø„A…ü,At} A?…A{=r¨çp=¿­/,¿E¾'t} A?…A{=r¨E½ Aqø„A…ü,Aš{ AV=…AYD-A΄2¿`|7¿Û§²'t} A?…A{=r¨š{ AV=…AYD-AžA*o‡A{ýR¨†4/¿ §:¿Æð¯'žA*o‡A{ýR¨š{ AV=…AYD-AtŸAÿ…Aá.A''¿.åA¿k.§'žA*o‡A{ýR¨tŸAÿ…Aá.Aõ²žAÉõ†A÷5/Atc¿zxì¾eÇà'ñ¹£Az€Aa­)A^y¢A‡²‚A¾¾ˆ¨¤Að³AÛ^)Alld¿Ý(ç¾…¬á'¤Að³AÛ^)A^y¢A‡²‚A¾¾ˆ¨ò¤A„¶A¾^˜¨j®k¿9çǾåæ'¤Að³AÛ^)Aò¤A„¶A¾^˜¨ÒI¤A}b~A )A­¯^¿Åü¾FCÜ'ñ¹£Az€Aa­)Ai£AWºAi*A^y¢A‡²‚A¾¾ˆ¨ÂüX¿×¿ Å×'^y¢A‡²‚A¾¾ˆ¨i£AWºAi*A(y¢Af²‚A¾+AÆHN¿Ì™¿:Î'^y¢A‡²‚A¾¾ˆ¨(y¢Af²‚A¾+At} A?…A{=r¨‡2N¿¸¿»Ï't} A?…A{=r¨(y¢Af²‚A¾+A©t¢A¸¹‚A½+AqbJ¿ÙÄ¿,MË't} A?…A{=r¨©t¢A¸¹‚A½+Ae£¡AûàƒAJÿ+AW“}¿n˜ ¾¦Lü'—¥Að:sA¾þ§¨ª”¥A…:sA —'At¥AAšyA¾þ§¨2F}¿s¾$ý't¥AAšyA¾þ§¨ª”¥A…:sA —'Aµ‹¥Ak3tA.¡'Aœï{¿¼5¾ùÚü't¥AAšyA¾þ§¨µ‹¥Ak3tA.¡'AX¥AAývA—Û'AxÍy¿¶ó_¾rIø'X¥AAývA—Û'Au ¥AÑyAs(At¥AAšyA¾þ§¨Jvx¿8©v¾…ìó't¥AAšyA¾þ§¨u ¥AÑyAs(A~ ¥A+™yAØ/(A Ut¿“Ϙ¾ +ñ't¥AAšyA¾þ§¨~ ¥A+™yAØ/(Aò¤A„¶A¾^˜¨PÔr¿#¢¾òï'ò¤A„¶A¾^˜¨~ ¥A+™yAØ/(ARÁ¤A¿À{A¾…(A®!o¿–Ƕ¾¹[ë'ò¤A„¶A¾^˜¨RÁ¤A¿À{A¾…(AÒI¤A}b~A )A‚û¿YÄ?<†rþ'—¥AÅlA¾þ§¨—¥¥A:¡nA݃'A—¥Að:sA¾þ§¨pæ¿'Æä¼Ò ÿ'—¥Að:sA¾þ§¨—¥¥A:¡nA݃'Ae¥¥AÏiqA„'Aðó't¥A¾efA¾þ§¨‰ ¥AGgfAè0(A˜.¥AMjgA| (Aó”z¿«Q>ueø'˜.¥AMjgA| (A-q¥AV1jA6¿'At¥A¾efA¾þ§¨-h|¿0ö*>¸âü't¥A¾efA¾þ§¨-q¥AV1jA6¿'ApŒ¥A-ÚkA[ 'AJ}¿œ‘>§4ü't¥A¾efA¾þ§¨pŒ¥A-ÚkA[ 'A—¥AÅlA¾þ§¨¢ó~¿´&¹=bÁþ'—¥AÅlA¾þ§¨pŒ¥A-ÚkA[ 'A”¥AuÅlAí–'AÙm¿O³ˆ=ÏÍþ'—¥AÅlA¾þ§¨Â”¥AuÅlAí–'A—¥¥A:¡nA݃'A2w¿½…>-ùó'‰ ¥AGgfAè0(At¥A¾efA¾þ§¨:Ó¤Ai³dA‘q(Aâ's¿$ >ëñ':Ó¤Ai³dA‘q(At¥A¾efA¾þ§¨ò¤A{I`A¾^˜¨}Ûo¿bï²>Ÿ¬ï':Ó¤Ai³dA‘q(Aò¤A{I`A¾^˜¨x_¤Aî bAÐó(AÇöW¿ v ?¸×'^y¢AòšZA¾¾ˆ¨šv¢AžZAr+AZØ¢A[É[A©*A Î\¿ÖŠ?Ò,Ü'ZØ¢A[É[A©*A쉣A„I^Aã)A^y¢AòšZA¾¾ˆ¨òEa¿/6ó>ÞŸà'^y¢AòšZA¾¾ˆ¨ì‰£A„I^Aã)AnÓ£Aqw_AÚ)A?‡c¿#ªê>v—á'^y¢AòšZA¾¾ˆ¨nÓ£Aqw_AÚ)Aò¤A{I`A¾^˜¨F¤i¿áBÑ>®ßæ'ò¤A{I`A¾^˜¨nÓ£Aqw_AÚ)A\¤A­K`Ax^)A®l¿Æ>Ø.ë'ò¤A{I`A¾^˜¨\¤A­K`Ax^)Ax_¤Aî bAÐó(A’T¿ §?ÇuÓ'šv¢AžZAr+A^y¢AòšZA¾¾ˆ¨#¢AjhYA†+AûdL¿¦#?Ù½É'#¢AjhYA†+A^y¢AòšZA¾¾ˆ¨t} AÎUA{=r¨3ŸF¿t‚!?ΗÂ'#¢AjhYA†+At} AÎUA{=r¨ª4¡AÑ&WAQy,A¹) ¿˜µG?ƒž'žA«!QA{ýR¨žAÒ&QAÿÙ/A­ÆžAÑ5RAš /A¨á'¿$DA?3§'­ÆžAÑ5RAš /ADØŸA™+TA÷-AžA«!QA{ýR¨H†.¿J;? «'žA«!QA{ýR¨DØŸA™+TA÷-A-C AUUAI‚-AÚx1¿—8?:U®'žA«!QA{ýR¨-C AUUAI‚-At} AÎUA{=r¨‹[;¿qs.?Ϲ't} AÎUA{=r¨-C AUUAI‚-A­{ Aõ„UAKD-Aˆ?¿ Û)?!¾'t} AÎUA{=r¨­{ Aõ„UAKD-Aª4¡AÑ&WAQy,A‘5¿H•K?(<š'žAÒ&QAÿÙ/AžA«!QA{ýR¨¥A¦lPA^Y0AWÄ¿‡ÑS?Ú¹'¥A¦lPA^Y0AžA«!QA{ýR¨Åh›A™MA{½3¨4\¿+©X?Wˆ'¥A¦lPA^Y0AÅh›A™MA{½3¨tœAÐNA‰ 1AŒY­¾oáp?éF.'|s˜A»KAözê§br˜AKAHÛ5AÏB™Ab™KA”5AWPÀ¾¼û?ð\ˆ$¾’A(âHAÙ뻦¾’A(âHAƒ]rؽ÷~?‡AV&¾’A(âHAÙ뻦¨•AÛUIAœZ9AÚQ•A»jIAöú«§º$¾ÿ°|? {¦&ÚQ•A»jIAöú«§¨•AÛUIAœZ9AzQ•A¯nIAø9A =¾‡™{?À&ÚQ•A»jIAöú«§zQ•A¯nIAø9Ap}–AšáIA”ã7A,R{¨€¿A'ù¾’A쎋AšPø%¾’A쎋Aƒ]A,R{¨€¿A'ù,çCA쎋Añl>A¾’A쎋AšPø%AŒQA쎋AöAA„‚!?'ŸF?kž§^fA»RAúï"A&TA#QAHs$ASA«!QAP€‘)—«>]Iq?ü»%§¿‹AqfKA?,A¥§A KAÄ-A*¦A»KAPÈ…)ÚÅ<>Æœ{?*˜·¦#š AÊßIAúù/A?ê"A oIAœ§1Aoé"A»jIAPà)Ó¢Î<&ë?¨¥L¥¨Y)A(âHAý?6A¨Y)A(âHA¡ t)^d&AÔþHA-'4AP]¤=™,?Zå"¦^d&AÔþHA-'4A¨Y)A(âHA¡ t)oé"A»jIAPà)›]>ÌÑ}?S~„¦^d&AÔþHA-'4Aoé"A»jIAPà)•y#AÁSIAŸ2AØ¡#>Ûµ|?9{¦¦•y#AÁSIAŸ2Aoé"A»jIAPà)?ê"A oIAœ§1A4X‹>3Vv?ÏR§*¦A»KAPÈ…)¥§A KAÄ-Aoé"A»jIAPà)„W†>Ïw?šq§oé"A»jIAPà)¥§A KAÄ-A9ÇAa¢JA1ç-A9Úi>'ðž`?#qr§˜»A™MAP˜)ËJA×MAuH(Ac½A“œMAjŸ(Ah‰Ú>O‚g?SÎT§˜»A™MAP˜)c½A“œMAjŸ(A*¦A»KAPÈ…)žÑ>„¯i?;EH§*¦A»KAPÈ…)c½A“œMAjŸ(AÝA‡LAô;*AøÁ»>Y*n?Ûï6§*¦A»KAPÈ…)ÝA‡LAô;*A¿‹AqfKA?,AF¡K?Ö%?žT˧eÁ AðXAãlA<’ AÎUAPh•)ŠžA½ZA!€AäHN?¤™?<Î§ŠžA½ZA!€A<’ AÎUAPh•)gšAòšZAPP™)Œ5W?Ï£ ?‘²×§ŠžA½ZA!€AgšAòšZAPP™)‚2A\=[A0(A%E?Ç^#?±‰Â§eÁ AðXAãlA¾y AÀ¿VAZÐA<’ AÎUAPh•)÷Å>?~µ*?¾§<’ AÎUAPh•)¾y AÀ¿VAZÐAÏ– Aø…UAe´ A„2?|7?ا²§<’ AÎUAPh•)Ï– Aø…UAe´ ASA«!QAP€‘)~¸0?à79?Üú¯§SA«!QAP€‘)Ï– Aø…UAe´ A][ AŸ­TA Q!AçZ*?à??«B§§SA«!QAP€‘)][ AŸ­TA Q!A^fA»RAúï"A#çl?  Â>i@ë§T~A©åbAžAZ~AÒ]`ArîA>‡A{I`AP8)“ƒj?;RÍ>;Üæ§>‡A{I`AP8)Z~AÒ]`ArîAí‡AÏI`A\öAtld?¿(ç>†¬á§>‡A{I`AP8)í‡AÏI`A\öAgšAòšZAPP™)]½a?±yñ>-ºà§gšAòšZAPP™)í‡AÏI`A\öAÊ­Aã]A8éA›—[?e–?õ$ܧgšAòšZAPP™)Ê­Aã]A8éA‚2A\=[A0(Ab“}?/— >ªLü§^AÅlAP ¡)0bA~ÅlAËTAì ý§pø§ ™A‚¨jA…ƒAà AühAðáA ùó§+ñ§‡A{I`AP8)ó³s?UÇœ>Òð§>‡A{I`AP8)‰sAgfA:Aì¬AFzeA¯jA #q?ë«>eÇï§>‡A{I`AP8)ì¬AFzeA¯jAT~A©åbAžA=5?ú ½f¾þ§gaA”:sA"TAÖTA}ÃrAŠIA^Að:sAP ¡)=¨?YçS½·æþ§^Að:sAP ¡)ÖTA}ÃrAŠIAÔ;AÄpAq4Aýÿ?ë"$º©iþ§^Að:sAP ¡)Ô;AÄpAq4A^AÅlAP ¡)3°?ùJ=séþ§^AÅlAP ¡)Ô;AÄpAq4AqRA_mA†GA%;?|žž=¿þ§^AÅlAP ¡)qRA_mA†GA0bA~ÅlAËTAí~?ýÍϽØÔþ§gaA”:sA"TA^Að:sAP ¡)8AUquAŒ†A—Ü|?:Ù¾Q ü§8AUquAŒ†A^Að:sAP ¡)‡A„¶AP8)}Qr?î#¥¾|éï§>‡A„¶AP8);A×V|AˆáAƒuAѶyAE<A»At?×J™¾Õ'ñ§>‡A„¶AP8)ƒuAѶyAE<A‡A„¶AP8)zÅh?þÕ¾0ëæ§>‡A„¶AP8)ÆQAå³€AVA$ŒAL´A¹ùAÔ3k?„%ʾ…ßæ§>‡A„¶AP8)$ŒAL´A¹ùA/AJç~A²¬A¯üS?¬„¿"|Ó§ ŸA÷°‚A„€AgšA‡²‚APP™)J² AŸ}ƒA¤`A(ÃK?Rù¿H¸É§J² AŸ}ƒA¤`AgšA‡²‚APP™)<’ A?…APh•)šSE?ò#¿ŒÂ§J² AŸ}ƒA¤`A<’ A?…APh•)ºn A˜™„A€ÇAH1 ?‡¯G¿½ƒž§SA*o‡AP€‘)WA”l‡A(u$AhüA§ã†Af#AÊò'?@5A¿“3§§hüA§ã†Af#A_Ø Aè…A µ!ASA*o‡AP€‘)‰Ú-?wé;¿”«§SA*o‡AP€‘)_Ø Aè…A µ!ApU A&¦…AéL!AøÅ0?+9¿|N®§SA*o‡AP€‘)pU A&¦…AéL!A<’ A?…APh•)²:? (/¿Ðѹ§<’ A?…APh•)pU A&¦…AéL!AÜ– Aÿ<…Ao´ AËÞ>?¼™*¿Ð¾§<’ A?…APh•)Ü– Aÿ<…Ao´ Aºn A˜™„A€ÇA9?Ÿ’K¿<š§WA”l‡A(u$ASA*o‡AP€‘)RAAɇAE,%AûÇ?ÏS¿ð¹§RAAɇAE,%ASA*o‡AP€‘)˜»At3‰AP˜)í\?¶¨X¿kyЧRAAɇAE,%A˜»At3‰AP˜)s¦Ae˜ˆAj'A›,®>\»p¿1Ã%§*¦A£ŠAPÈ…)K¨A£|ŠA-A®×AÓ)ŠA—¸+Aá Â>âæl¿Úˆ?§®×AÓ)ŠA—¸+Ay$Am‰A°)A*¦A£ŠAPÈ…)VJÒ>ii¿ÉP§*¦A£ŠAPÈ…)y$Am‰A°)AÅ*AQ‰Aó(A®–Ø>]÷g¿«ÂT§*¦A£ŠAPÈ…)Å*AQ‰Aó(A˜»At3‰AP˜)Ëñ>•§a¿Šëi§˜»At3‰AP˜)Å*AQ‰Aó(A„½AÆ1‰A‰Ÿ(Avàü>ǘ^¿œ{§˜»At3‰AP˜)„½AÆ1‰A‰Ÿ(As¦Ae˜ˆAj'Añ¢>®Õr¿45§K¨A£|ŠA-A*¦A£ŠAPÈ…)`›A÷§ŠAËÆ-A=‡>dív¿ E§`›A÷§ŠAËÆ-A*¦A£ŠAPÈ…)oé"A¢J‹APà)¯ßl>{y¿/‘ó¦`›A÷§ŠAËÆ-Aoé"A¢J‹APà)1n A ‹AãÙ/AdÜ=<šû¿æ\ˆ¤¨Y)A쎋A¡ t)¨Y)A쎋Aý?6A”ý'Aå‹‹AJ5APE=볿œª¥”ý'Aå‹‹AJ5A%AÂp‹Aì33A¨Y)A쎋A¡ t) ­´=x¿ðÊ*¦¨Y)A쎋A¡ t)%AÂp‹Aì33AN#AÎR‹A‘ð1A.uÚ=Š~¿DV¦¨Y)A쎋A¡ t)N#AÎR‹A‘ð1Aoé"A¢J‹APà)ï%>›¦|¿¶z¦¦oé"A¢J‹APà)N#AÎR‹A‘ð1Aê"AI‹A™§1AœH>>Š{¿*¨È¦oé"A¢J‹APà)ê"AI‹A™§1A1n A ‹AãÙ/A,R{(€?A'ù¾’A(âHAšPø%¨Y)A(âHA¡ t)¨Y)A(âHAý?6A,R{(€?A'ùQW‹A(âHAN™?A¾’A(âHAƒ]A,R{(€?A'ù¾’A(âHAšPø%,çCA(âHAñl>AAŒQA(âHAöAA,R{(€?A'ùx {A(âHAÏ%CAÜ{„A(âHA ÝAAÒ:mA(âHAíqCA,R{(€?A'ùÒ:mA(âHAíqCAÜ{„A(âHA ÝAA¾’A(âHAšPø%,R{(€?A'ùÒ:mA(âHAíqCA¾’A(âHAšPø%ÂX_A(âHAÁBA,R{(€?A'ùÂX_A(âHAÁBA¾’A(âHAšPø%AŒQA(âHAöAA$Þ#=|¿×™#>±º’A»‹Aç@AJ×’AŸÓ‹AyµAAä‹A%Í‹Aœ EA‹¬¡=•r¿c¡>"X“AE@ŒAYWEAÚŽ“A‹ŒA:âFAŠlŒAé…ŒAŽSJAÜ í=@a¿…“ì>§î“AWAœ•IA0;”A=½Aù½KA—ìŒAž³AHOA>zêI¿ð¦?öz”A÷DŽA5ŠMAa×”ATA/%PAT`AMAœÂSAnÚW>G¿ëeV?›Å•AB_“ArÜVA'Ì•AV“A² WAJŽA°Ž“A6ÃZAŠ$оÉÎí=þ´t?Ë–Sr?¨ht?4&_A`¡AtÕ`AàÈ\A`¡AR·`Af©\A¾UžAa'bA½„¼û’>®6u?€ÿoA`¡AôqaA·ÍlA`¡AtƒaA{ÈlA¾UžAÒôbABv=Ï“>™¼t?l€A`¡A{Ì`A³Ö|A`¡A¡+aAºë|A¾UžAnœbAY&>J “>ûr?"̈A`¡Aùå^A‡g†A`¡AJ°_A†A¾UžAªaAè J>‚“>gôo?ý‘A`¡A-Á[AQŽA`¡AZ]AuŽA¾UžAr}^A˃d>!l>eor?uŽA¾UžAr}^AEM–AæTžA~¯ZAý‘A`¡A-Á[Aº;{>Vpu>xxp?ý‘A`¡A-Á[AEM–AæTžA~¯ZA‹I–AÈÁžAœ”ZAqùv>.s—>ôžl?ý‘A`¡A-Á[A‹I–AÈÁžAœ”ZA³–A`¡A5XYA 祾sû˜>©Êe?%{A`¡AÔIRAá AìžApkSAÓ¡-A`¡AÕŒWA'}¾,ˆx>é‡k?Ó¡-A`¡AÕŒWAá AìžApkSA5-A¾UžAáíXA[…¾¬ä’>Òÿk?Ó¡-A`¡AÕŒWA5-A¾UžAáíXAn=A`¡AǸ[Anx¾Bl>õAq?n=A`¡AǸ[A5-A¾UžAáíXAË=ún?n=A`¡AǸ[AË8¦½"x?ÊZ–A,šA[AÞ\–AºŽ›A [AéŽA„Ž›AJ÷^Aôóy>Å’<ä6x?éŽA„Ž›AJ÷^AÞ\–AºŽ›A [A^–A^jœA¢([Aå u>4ˆH¾ts?Ð?–A[º—AkNZAL–A(ɘAâ¦ZA–uŽANǘA,}^AM\w>õܾñ‰u?–uŽANǘA,}^AL–A(ɘAâ¦ZAÊZ–A,šA[AvTн_÷’>×s?àÈ\A`¡AR·`Amüv?f©\A¾UžAa'bA>ÿŸl?á AìžApkSAûA§TžA*”SA5-A¾UžAáíXAE¬¾h3>in?5-A¾UžAáíXAûA§TžA*”SAõÐA˜ÀœAÛTA첡¾\à©=È÷q?5-A¾UžAáíXAõÐA˜ÀœAÛTAŒ-A„Ž›A¬dYAÚ ­¾EqË<¿p?Œ-A„Ž›A¬dYAõÐA˜ÀœAÛTA™ÏAvŽ›A[TA¯¥­¾ß«¼…Äp?Œ-A„Ž›A¬dYA™ÏAvŽ›A[TAxÎAbšAFTAÉb.¾Ûí’>~Sq?èÜLA`¡ABÈ^AoÑ=A`¡A“Û[A[£LA¾UžA&5`A7\H¾Û-l>wt?[£LA¾UžA&5`AoÑ=A`¡A“Û[AËß±µ¾Kh?º –Aá{•AëäXAa–Av–AtGYAQŽA¶–AÏ]A„n>"ë¾^"l?QŽA¶–AÏ]Aa–Av–AtGYAÐ?–A[º—AkNZAxO^>;ì¾?C\?'Ì•AV“A² WAº –Aá{•AëäXAJŽA°Ž“A6ÃZAùùN>_3ѾŽÚc?JŽA°Ž“A6ÃZAº –Aá{•AëäXAQŽA¶–AÏ]AhW >æòå¾]0a?JŽA°Ž“A6ÃZAQŽA¶–AÏ]Aò@†A°Ž“A%Y]Aò =§“>Ò u?³Ö|A`¡A¡+aA€ÿoA`¡AôqaAºë|A¾UžAnœbAÏÊf<Úfl>ùy?ºë|A¾UžAnœbA€ÿoA`¡AôqaA{ÈlA¾UžAÒôbA%<ÉÎí=ÍA~?ºë|A¾UžAnœbA{ÈlA¾UžAÒôbA¸ÆlA„Ž›AqcAéW½K›m=ib?¸ÆlA„Ž›AqcA{ÈlA¾UžAÒôbAÏž\A„Ž›A9£bAO8{½Gjn½L?¸ÆlA„Ž›AqcAÏž\A„Ž›A9£bAm©\ANǘA'bAû ݽ¿5î½²Á|?m©\ANǘA'bAÏž\A„Ž›A9£bAf£LANǘAà4`Aá}¾°Kl¾‡év?m©\ANǘA'bAf£LANǘAà4`AþÜLA¶–A¶Ç^A(a/¾ý’¾—Eq?þÜLA¶–A¶Ç^Af£LANǘAà4`AŽ=A¶–A=¸[A¿=¾Ëäʾu4f?þÜLA¶–A¶Ç^AŽ=A¶–A=¸[A¶¦=A°Ž“ABlYA)åb¾æòå¾h•]?¶¦=A°Ž“ABlYAŽ=A¶–A=¸[A–S.A°Ž“A}KUAõ{g¾Ôº ¿zÞM?¶¦=A°Ž“ABlYA–S.A°Ž“A}KUAD/AäE‘A±pu?·ÍlA`¡AtƒaA4&_A`¡AtÕ`A{ÈlA¾UžAÒôbA)`f½kVl>¬x?{ÈlA¾UžAÒôbA4&_A`¡AtÕ`Af©\A¾UžAa'bATíz½ÉÎí=ÀÈ}?{ÈlA¾UžAÒôbAf©\A¾UžAa'bAÏž\A„Ž›A9£bAª¬Þ½K›m=t ~?Ïž\A„Ž›A9£bAf©\A¾UžAa'bAýLA„Ž›Aï¯`Aÿ(¾Gjn½ƒR}?Ïž\A„Ž›A9£bAýLA„Ž›Aï¯`Af£LANǘAà4`A´6¾¿5î½`'z?f£LANǘAà4`AýLA„Ž›Aï¯`A'Ë7-¿E×6?ú”A£¹AQAó^•AnH‘A•÷SA=ÄAäE‘AY WA²?@>h¼#¿ÌÔ>?=ÄAäE‘AY WAó^•AnH‘A•÷SAi•A@p‘AS@TA¤GI>©ò¿UG?i•A@p‘AS@TA›Å•AB_“ArÜVA=ÄAäE‘AY WAs;=>ê¯ ¿“æO?=ÄAäE‘AY WA›Å•AB_“ArÜVAJŽA°Ž“A6ÃZA[->Åó¿XJ?=ÄAäE‘AY WAJŽA°Ž“A6ÃZA£ †AäE‘AË,ZA %>Ôº ¿×[S?£ †AäE‘AË,ZAJŽA°Ž“A6ÃZAò@†A°Ž“A%Y]AH¹¬=Åó¿L%L?£ †AäE‘AË,ZAò@†A°Ž“A%Y]A¯…|AäE‘AÈž[A0p#>"îA¿¹ "?a×”ATA/%PAú”A£¹AQAT`AMAœÂSA×þ>ªå7¿d·-?T`AMAœÂSAú”A£¹AQA=ÄAäE‘AY WAE÷=yF:¿VÝ,?T`AMAœÂSA=ÄAäE‘AY WA&Ì…AMA[CVA3+ã=’º/¿+û7?&Ì…AMA[CVA=ÄAäE‘AY WA£ †AäE‘AË,ZA³\”=yF:¿ÈŸ.?&Ì…AMA[CVA£ †AäE‘AË,ZA4L|AMA·®WA´ûs=’º/¿³ˆ9?4L|AMA·®WA£ †AäE‘AË,ZA¯…|AäE‘AÈž[AÑÂç“>¿q?QŽA`¡AZ]A"̈A`¡Aùå^AuŽA¾UžAr}^A¡Ú>÷l>Âîu?uŽA¾UžAr}^A"̈A`¡Aùå^A†A¾UžAªaAãª>ÉÎí=pY{?uŽA¾UžAr}^A†A¾UžAªaA‡†A„Ž›Aò™aAæÆÔ=L›m=`.~?‡†A„Ž›Aò™aA†A¾UžAªaAÍò|A„Ž›A‡cA4û¤=Fjn½ˆ»~?‡†A„Ž›Aò™aAÍò|A„Ž›A‡cA¶ë|ANǘA&œbAF½=¿5î½ð~?¶ë|ANǘA&œbAÍò|A„Ž›A‡cA|ÈlANǘA‰ôbA~Ò<±Kl¾%y?¶ë|ANǘA&œbA|ÈlANǘA‰ôbA¹ÍlA¶–Aæ‚aA½ý’¾ u?¹ÍlA¶–Aæ‚aA|ÈlANǘA‰ôbAëÈ\A¶–AŶ`Aïe½Ëäʾߚj?¹ÍlA¶–Aæ‚aAëÈ\A¶–AŶ`AWü\A°Ž“Am]^AMáŽæòå¾2cc?Wü\A°Ž“Am]^AëÈ\A¶–AŶ`A;MA°Ž“AŒs\AÊà½Ôº ¿‹þS?Wü\A°Ž“Am]^A;MA°Ž“AŒs\A ºMAäE‘A|JYAšQ¾Åó¿¶ÿI? ºMAäE‘A|JYA;MA°Ž“AŒs\A~_>AäE‘APNVA´Ä¾’º/¿ùZ6? ºMAäE‘A|JYA~_>AäE‘APNVAIC?AMA£vRAy¬-¾yF:¿g'*?IC?AMA£vRA~_>AäE‘APNVA¼m0AMA±wNA«Ý$¾ßaM¿M(?IC?AMA£vRA¼m0AMA±wNAïÅ1Až³AÏJA<é—¾¼¹ø¾+zR?àAB”A»ÌPA[AI““AZPA–S.A°Ž“A}KUAˆ “¾]u¿°õL?–S.A°Ž“A}KUA[AI““AZPAIàAZa’AаNAŸà„¾Y翆ÙF?–S.A°Ž“A}KUAIàAZa’AаNAD/AäE‘A±T·s?‡g†A`¡AJ°_Al€A`¡A{Ì`A†A¾UžAªaA9»¬=´tl>Ð$x?†A¾UžAªaAl€A`¡A{Ì`Aºë|A¾UžAnœbA"§£=ÉÎí=®q}?†A¾UžAªaAºë|A¾UžAnœbAÍò|A„Ž›A‡cAŸr=K›m=¼m?Íò|A„Ž›A‡cAºë|A¾UžAnœbA¸ÆlA„Ž›AqcAhâAäE‘APNVAE_K¾Åó¿oãF?~_>AäE‘APNVA¶¦=A°Ž“ABlYAD/AäE‘A±AäE‘APNVAD/AäE‘A±åÑZ¿¢Ñ?0;”A=½Aù½KAöz”A÷DŽA5ŠMA—ìŒAž³AHOA'P>кR¿;Æ ?—ìŒAž³AHOAöz”A÷DŽA5ŠMAT`AMAœÂSA«®Æ=ïU¿”c ?—ìŒAž³AHOAT`AMAœÂSAr…Až³AD»QA#'»=ßaM¿ï?r…Až³AD»QAT`AMAœÂSA&Ì…AMA[CVAPÿn=ïU¿ØÍ ?r…Až³AD»QA&Ì…AMA[CVAŸ |Až³AðSA†¢I=ßaM¿ÎL?Ÿ |Až³AðSA&Ì…AMA[CVA4L|AMA·®WA¿×ž<ïU¿ƒ ?Ÿ |Až³AðSA4L|AMA·®WAÅmAž³AHqSAÈß;ßaM¿Ï?ÅmAž³AHqSA4L|AMA·®WA2ðlAMAÖXAÈ¡¼ïU¿w‚ ?ÅmAž³AHqSA2ðlAMAÖXAÎû]Až³Aã±RAKåº=0¹m¿l&¸>ÚŽ“A‹ŒA:âFA§î“AWAœ•IAŠlŒAé…ŒAŽSJAñhÀ=SÌg¿¨êÓ>ŠlŒAé…ŒAŽSJA§î“AWAœ•IA—ìŒAž³AHOA=|k¿MoÇ>ŠlŒAé…ŒAŽSJA—ìŒAž³AHOAË.…Aé…ŒA÷LAöu=Ëd¿Zôâ>Ë.…Aé…ŒA÷LA—ìŒAž³AHOAr…Až³AD»QA .=|k¿}É>Ë.…Aé…ŒA÷LAr…Až³AD»QAô¿{Aé…ŒAîNA¿+=Ëd¿Üää>ô¿{Aé…ŒAîNAr…Až³AD»QAŸ |Až³AðSA­l<|k¿Õ†Ê>ô¿{Aé…ŒAîNAŸ |Až³AðSAmAé…ŒANcNA#*µ;Ëd¿ ­å>mAé…ŒANcNAŸ |Až³AðSAÅmAž³AHqSA„a¼|k¿ù‰Ê>mAé…ŒANcNAÅmAž³AHqSAj^Aé…ŒA|¨MAý×¼Ëd¿ÜKå>j^Aé…ŒA|¨MAÅmAž³AHqSAÎû]Až³Aã±RAH+½|k¿ä†É>j^Aé…ŒA|¨MAÎû]Až³Aã±RAÅ×OAé…ŒAhãKA5†a>]·½û¨x?ÊZ–A,šA[AéŽA„Ž›AJ÷^A–uŽANǘA,}^Aµ1>¿5î½ÜYz?–uŽANǘA,}^AéŽA„Ž›AJ÷^A†ANǘAcaA->±Kl¾…6v?–uŽANǘA,}^A†ANǘAcaA~g†A¶–A¾¯_A½ Í=ý’¾ ás?~g†A¶–A¾¯_A†ANǘAcaA«Ö|A¶–A+aA´²˜=ËäʾèCj?~g†A¶–A¾¯_A«Ö|A¶–A+aAN´|A°Ž“A„Ð^A¥ø<æòå¾ï˜d?N´|A°Ž“A„Ð^A«Ö|A¶–A+aAGÖlA°Ž“Al'_As<Ôº ¿,ÖU?N´|A°Ž“A„Ð^AGÖlA°Ž“Al'_AâálAäE‘Aqô[A\Fò¼Åó¿%M?âálAäE‘Aqô[AGÖlA°Ž“Al'_A B]AäE‘AW-[A`[3½’º/¿_Ò9?âálAäE‘Aqô[A B]AäE‘AW-[A&˜]AMAN?WAoØ–½yF:¿E—.?&˜]AMAN?WA B]AäE‘AW-[AîWNAMAeUA¯}Ÿ½ßaM¿¸ƒ?&˜]AMAN?WAîWNAMAeUA(OAž³A·áPAº=ǽïU¿]` ?(OAž³A·áPAîWNAMAeUA*K@Až³ANA!}·½Ëd¿ñá>(OAž³A·áPA*K@Až³ANAoAAé…ŒA_IAzǽ|k¿§tÄ>oAAé…ŒA_IA*K@Až³ANA¿B3Aé…ŒAEEA4Ëœ½ Au¿@t>oAAé…ŒA_IA¿B3Aé…ŒAEEA›Ø4A%Í‹AÙ@A0^¾)ØD¿Ôø?ì!AiOAciIAê"A„,A $IA¼m0AMA±wNA–…O¾ÀL¿Ì¤?¼m0AMA±wNAê"A„,A $IAÍQ#AÅçA’ÎEA}«3¾®ÁT¿™?¼m0AMA±wNAÍQ#AÅçA’ÎEAïÅ1Až³AÏJAûE0¾ª\¿$ô>ïÅ1Až³AÏJAÍQ#AÅçA’ÎEA-“#A±¸Aì%EAà|!¾ƒ\b¿¡á>ïÅ1Až³AÏJA-“#A±¸Aì%EAª¹$A¤äŒA?.BAD¾åîh¿0‚É>ª¹$A¤äŒA?.BA¿B3Aé…ŒAEEAïÅ1Až³AÏJAs÷½Ëd¿ª<Ý>ïÅ1Až³AÏJA¿B3Aé…ŒAEEA*K@Až³ANAª´ ¾ïU¿­A?ïÅ1Až³AÏJA*K@Až³ANAIC?AMA£vRAA;õ½ßaM¿í¶?IC?AMA£vRA*K@Až³ANAîWNAMAeUAXºù½yF:¿3Ï,?IC?AMA£vRAîWNAMAeUA ºMAäE‘A|JYA×ý’º/¿#Ž8? ºMAäE‘A|JYAîWNAMAeUA B]AäE‘AW-[A ±½Åó¿xL? ºMAäE‘A|JYA B]AäE‘AW-[AWü\A°Ž“Am]^AîaO½Ôº ¿ˆtU?Wü\A°Ž“Am]^A B]AäE‘AW-[AGÖlA°Ž“Al'_AM2½çòå¾’d?Wü\A°Ž“Am]^AGÖlA°Ž“Al'_A¹ÍlA¶–Aæ‚aAòõ<Ëäʾ‡k?¹ÍlA¶–Aæ‚aAGÖlA°Ž“Al'_A«Ö|A¶–A+aAç=ý’¾®u?¹ÍlA¶–Aæ‚aA«Ö|A¶–A+aA¶ë|ANǘA&œbA½J¡=±Kl¾ Fx?¶ë|ANǘA&œbA«Ö|A¶–A+aA†ANǘAcaAÇ-Ô=¿5î½à|?¶ë|ANǘA&œbA†ANǘAcaA‡†A„Ž›Aò™aAB²>Gjn½pŸ|?‡†A„Ž›Aò™aA†ANǘAcaAéŽA„Ž›AJ÷^Aƒ`2>L›m=ñ¥{?‡†A„Ž›Aò™aAéŽA„Ž›AJ÷^AuŽA¾UžAr}^A¾Óa>z›=Šðx?uŽA¾UžAr}^AéŽA„Ž›AJ÷^A^–A^jœA¢([A”Üw>‰ > v?uŽA¾UžAr}^A^–A^jœA¢([AEM–AæTžA~¯ZAÔ°X= z¿GS>J×’AŸÓ‹AyµAA"X“AE@ŒAYWEAä‹A%Í‹Aœ EAv=¬‡v¿4†>ä‹A%Í‹Aœ EA"X“AE@ŒAYWEAŠlŒAé…ŒAŽSJA¡/*=My¿µh>ä‹A%Í‹Aœ EAŠlŒAé…ŒAŽSJAµÖ„A%Í‹AÖ_GAmö6= Au¿ÿý>µÖ„A%Í‹AÖ_GAŠlŒAé…ŒAŽSJAË.…Aé…ŒA÷LA{ϵքA%Í‹AÖ_GAË.…Aé…ŒA÷LArq{A%Í‹Añ±HA!È< Au¿<@’>rq{A%Í‹Añ±HAË.…Aé…ŒA÷LAô¿{Aé…ŒAîNAú]rq{A%Í‹Añ±HAô¿{Aé…ŒAîNA©&mA%Í‹A8IA7H…; Au¿!Å’>©&mA%Í‹A8IAô¿{Aé…ŒAîNAmAé…ŒANcNA•;ò»My¿°×k>©&mA%Í‹A8IAmAé…ŒANcNA‘ß^A%Í‹AGJHA¨…¼ Au¿Œ’>‘ß^A%Í‹AGJHAmAé…ŒANcNAj^Aé…ŒA|¨MAa~¼My¿Lµj>‘ß^A%Í‹AGJHAj^Aé…ŒA|¨MA¥®PA%Í‹A‘FA‰ú½ Au¿+•‘>¥®PA%Í‹A‘FAj^Aé…ŒA|¨MAÅ×OAé…ŒAhãKA¹#½My¿ ch>¥®PA%Í‹A‘FAÅ×OAé…ŒAhãKAE¦BA%Í‹A´ÖCAúW<¿°¿EB=¾’A쎋Aƒ]Ažsµ¼ûD~¿V\é=,çCA쎋Añl>A¥®PA%Í‹A‘FAE¦BA%Í‹A´ÖCAB©V¼c‘¿¦¾g=,çCA쎋Añl>AE¦BA%Í‹A´ÖCA.{6A쎋AcÏ:Aíâû½”µn¿ìì­>ª¹$A¤äŒA?.BAUg%A掌AAn@A¿B3Aé…ŒAEEAzܽ?¯r¿eh™>¿B3Aé…ŒAEEAUg%A掌AAn@AÂ7&Aþ'ŒA•T>A1Úª½{w¿l>¿B3Aé…ŒAEEAÂ7&Aþ'ŒA•T>A›Ø4A%Í‹AÙ@A³½q€z¿ZMF>›Ø4A%Í‹AÙ@AÂ7&Aþ'ŒA•T>A§X'AžÔ‹AYk;A]ë^½€¦|¿íj>›Ø4A%Í‹AÙ@A§X'AžÔ‹AYk;AéÄ'A_µ‹AT:A/[>K¾ñq?Ð?–A[º—AkNZA–uŽANǘA,}^AQŽA¶–AÏ]A.¢+>ý’¾­pq?QŽA¶–AÏ]A–uŽANǘA,}^A~g†A¶–A¾¯_A|À>ËäʾþPh?QŽA¶–AÏ]A~g†A¶–A¾¯_Aò@†A°Ž“A%Y]A+׿=æòå¾åwc?ò@†A°Ž“A%Y]A~g†A¶–A¾¯_AN´|A°Ž“A„Ð^A…v‹=Ôº ¿ù"U?ò@†A°Ž“A%Y]AN´|A°Ž“A„Ð^A¯…|AäE‘AÈž[Aõàà<Åó¿õ)M?¯…|AäE‘AÈž[AN´|A°Ž“A„Ð^AâálAäE‘Aqô[A‹”<’º/¿&:?¯…|AäE‘AÈž[AâálAäE‘Aqô[A2ðlAMAÖXAéÌ̼yF:¿O}/?2ðlAMAÖXAâálAäE‘Aqô[A&˜]AMAN?WABã½ßaM¿ZŒ?2ðlAMAÖXA&˜]AMAN?WAÎû]Až³Aã±RA] p½ïU¿èË ?Îû]Až³Aã±RA&˜]AMAN?WA(OAž³A·áPAƒn½Ëd¿ÕÁã>Îû]Až³Aã±RA(OAž³A·áPAÅ×OAé…ŒAhãKA¤¶Ž½|k¿é~Ç>Å×OAé…ŒAhãKA(OAž³A·áPAoAAé…ŒA_IAä^h½ Au¿Øá>Å×OAé…ŒAhãKAoAAé…ŒA_IAE¦BA%Í‹A´ÖCAê^e½My¿òãd>E¦BA%Í‹A´ÖCAoAAé…ŒA_IA›Ø4A%Í‹AÙ@AâT÷¼ûD~¿õ‹å=E¦BA%Í‹A´ÖCA›Ø4A%Í‹AÙ@A.{6A쎋AcÏ:AÙ› ½Ýž~¿ÔÜÈ=.{6A쎋AcÏ:A›Ø4A%Í‹AÙ@AéÄ'A_µ‹AT:AÑ2‡¼¥»¿xa.=.{6A쎋AcÏ:AéÄ'A_µ‹AT:A¨Y)A쎋Aý?6A¿y‡>xC¾ªýq?EM–A4V#A~¯ZA‹I–Ap|"Aœ”ZA¶¥—A]Ž"AÔYAÈ®„>ß'—¾¥kk?‹I–Ap|"Aœ”ZA³–AAñA5XYAƒŒ—AþA†ŒXA‹•ˆ>¼ø¾½¼u?°¦—AB'AÌrZA^–AE+'A¢([AEM–A4V#A~¯ZAY‡>¬zø=€ît?L–A°m.Aâ¦ZAÊZ–A¨ã+A[Ak—A,AôcZA;ˆ>CÚ=ýAv?k—A,AôcZAÊZ–A¨ã+A[AÞ\–A‹â(A [AŽ=„>ÀÃ_>hçp?k`—AB¬0AG¨YAÐ?–AJ‹0AkNZAL–A°m.Aâ¦ZAùt>Kå×>ø_?'Ì•ASß8A² WAº –A=5AëäXA¸—Aç,5AèCXAÙKz>޼>”¢e?¸—Aç,5AèCXAº –A=5AëäXAa–AÏ3AtGYAJõe>jK?»T?Ú¿–AŸh9A«>VA›Å•A}A9ArÜVA'Ì•ASß8A² WAÉ$^>.ì ?~±M?›Å•A}A9ArÜVAÚ¿–AŸh9A«>VAi•A=AS@TA`ð,>Òì??¤Í#?a×”AáWAA/%PAú”AºŒ@AQAÓ•A´@AY‚PAˆ8>ÕÁ5?£F.?Ó•A´@AY‚PAú”AºŒ@AQAó^•A$o=A•÷SAÍ>´®O?£Ú?CF•AÀšCAŒëLAöz”AvCA5ŠMAa×”AáWAA/%PA>ÜÅ=Öj?í¿Å>ÚŽ“AéàFA:âFA§î“AQËEAœ•IA¢®”ARëEA¶óHAR¬â=fƒd?\½ß>¢®”ARëEA¶óHA§î“AQËEAœ•IA0;”A†…DAù½KAg=¡Þw?íjy>J×’AÂXHAyµAA"X“AtGAYWEAw”AÁ˜GA-±DAÞ’=“»s?çE˜>w”AÁ˜GA-±DA"X“AtGAYWEAÚŽ“AéàFA:âFA)¬÷<æö|?­%>Bl“A™HAè;@A±º’AÿˆHAç@AJ×’AÂXHAyµAAÅ«r<‰Ð~?W‚Â=±º’AÿˆHAç@ABl“A™HAè;@A¾’A(âHAƒ]§q}¾/n?‹I–Ap|"Aœ”ZAƒŒ—AþA†ŒXA¶¥—A]Ž"AÔYA›mŠ>â”–¾,¯j?¶¥—A]Ž"AÔYAƒŒ—AþA†ŒXA{@™A=A ™WAA$Ž>ùw{¾Äm?¶¥—A]Ž"AÔYA{@™A=A ™WAŽˆšAj#Au:XAÇ£#¼s²?™õB=¾’A(âHAƒ]A¢%‘½,?–þD=™È’ACèHAý¬;A9ä”AhæHAœÎ>Aõ;”AìIAí3:Aš‚Ľ¨ž}?‡Å=õ;”AìIAí3:A9ä”AhæHAœÎ>AÔº•Aù+IAJü=A´ý½æ¹}?‹F=õ;”AìIAí3:AÔº•Aù+IAJü=A¨•AÛUIAœZ9AÜn‘>]Ó•¾ˆ¾i?{@™A=A ™WA‰—šA¢nAtÙVAŽˆšAj#Au:XAíÒ•>U–•¾•i?ŽˆšAj#Au:XA‰—šA¢nAtÙVA»UœA÷ãA´ÞUA÷´–>åhy¾q”l?ŽˆšAj#Au:XA»UœA÷ãA´ÞUAZ/œAµ{#AWNWAž>ž”¾èôg?Z/œAµ{#AWNWA»UœA÷ãA´ÞUAõRŸA Aù-TA^ Ÿ>Κu¾%vk?Z/œAµ{#AWNWAõRŸA Aù-TAÄŸA‘$A;·UA Ú§>¬‘¾¤f?ÄŸA‘$A;·UAõRŸA Aù-TAÂg¡A(!AGþRAj§>ñLp¾Òkj?ÄŸA‘$A;·UAÂg¡A(!AGþRAVÊ¡A3)&Aµ$TAlÙ¾S}?%F=¨•AÛUIAœZ9AÔº•Aù+IAJü=AzQ•A¯nIAø9A+p¾,Ä{? :Ç=zQ•A¯nIAø9AÔº•Aù+IAJü=A“)—A‰ÏIA´‘¨ƒ¾?¹e?Âg¡A(!AGþRA„B¢Až!A—RAVÊ¡A3)&Aµ$TAxà³>Dï¾ïd?VÊ¡A3)&Aµ$TA„B¢Až!A—RA#¥A±£#ApÚPAÁ=±>øi¾žþh?VÊ¡A3)&Aµ$TA#¥A±£#ApÚPAäAû(Až—RAc¾>4¦‰¾duc?äAû(Až—RA#¥A±£#ApÚPA>ó§A”&Aj9OAð¹>ûß`¾EÍg?äAû(Až—RA>ó§A”&Aj9OAÆ(§Ar|*AÓQA}Æ>J¹…¾FOb?Æ(§Ar|*AÓQA>ó§A”&Aj9OAï5©Aâ^'A}NA ¿>>E[¾Jg?Æ(§Ar|*AÓQAï5©Aâ^'A}NA¯X¨AŸ´+Aé`PA»®•¾}t?]…J=µã—A×¢JAPp6A˜A`¨JAE+;Abr˜AKAHÛ5A\’š¾v¹r?ÖšË=br˜AKAHÛ5A˜A`¨JAE+;Aºí™AݵKA½É9A'¸­¾Vyp?±L=br˜AKAHÛ5Aºí™AݵKA½É9AÏB™Ab™KA”5Aù—¹¾Õ2m?¹ÅÍ=ÏB™Ab™KA”5Aºí™AݵKA½É9AÛA›Aó÷LAám8AÉz̾WWj?ZéN=ÏB™Ab™KA”5AÛA›Aó÷LAám8AššA¦ÅLA)˜3Ae|Ö¾g?>`Ï=ššA¦ÅLA)˜3AÛA›Aó÷LAám8A­Ù›AxœMAPÑ7A%Áâ¾(e?œçO=ššA¦ÅLA)˜3A­Ù›AxœMAPÑ7Aò3›A¹`MALõ2AGåÉ>ÿ´ƒ¾õÙa?ï5©Aâ^'A}NA}¨©AYâ'Aj:NA¯X¨AŸ´+Aé`PA´*Ì>;-‚¾a?¯X¨AŸ´+Aé`PA}¨©AYâ'Aj:NA2ÛªAVB)AÒ†MA\hÄ> T¾ ef?¯X¨AŸ´+Aé`PA2ÛªAVB)AÒ†MA[ЪA–.A>ñNA¨Ôé¾_c?D P=ò3›A¹`MALõ2A­Ù›AxœMAPÑ7AÚg›AKœMA ¾2Aß"a?|+Ñ=Úg›AKœMA ¾2A­Ù›AxœMAPÑ7AZA~OA"Š6A¦ùÿ¾ÐQ]?êUR=Úg›AKœMA ¾2AZA~OA"Š6AtœAÐNA‰ 1Ay–¿:(X?9dÓ=tœAÐNA‰ 1AZA~OA"Š6A©>žA<ËPAŠP5A/(¿«ÐS?ï‡T=tœAÐNA‰ 1A©>žA<ËPAŠP5A¥A¦lPA^Y0A^fÑ>, ~¾OÎ`?2ÛªAVB)AÒ†MAeÕ«Axa*APôLA[ЪA–.A>ñNAìrÖ>~x¾@ `?[ЪA–.A>ñNAeÕ«Axa*APôLA\U®AþÂ-AÎzKAk{Í>¥ôG¾’e?[ЪA–.A>ñNA\U®AþÂ-AÎzKAs)­AsÏ1AÅMAØYß>;Éj¾Á^?s)­AsÏ1AÅMA\U®AþÂ-AÎzKAÕ´°A‚1AìJAEŸÔ>´<¾©d?s)­AsÏ1AÅMAÕ´°A‚1AìJAc¯AV_5AY@LA„gæ>^¾­Ä]?c¯AV_5AY@LAÕ´°A‚1AìJAN²Aþ 4AM=IABõÙ>Ö-1¾÷^c?c¯AV_5AY@LAN²Aþ 4AM=IAj|±A}E9AØKAÛg¿ØºN?.ÎT=¥A¦lPA^Y0A©>žA<ËPAŠP5AžAÒ&QAÿÙ/ArX¿¾ýK?xÕÕ=žAÒ&QAÿÙ/A©>žA<ËPAŠP5AEXŸAŸ¡RAH%4Als ¿^G? W=žAÒ&QAÿÙ/AEXŸAŸ¡RAH%4A­ÆžAÑ5RAš /A{;%¿ü©A?î×=­ÆžAÑ5RAš /AEXŸAŸ¡RAH%4Aß` AS¡TA! 3AÁô,¿@¡©T¾&]?N²Aþ 4AM=IAÁò²A¥ž5A£ºHAj|±A}E9AØKAßÜí>Ö6P¾±£\?j|±A}E9AØKAÁò²A¥ž5A£ºHAÓ³Ahg7Aß3HA‰ÜÞ>Ÿ'¾a¢b?j|±A}E9AØKAÓ³Ahg7Aß3HA!N²AÖõ:AƒJA7ªñ>©YG¾\?!N²AÖõ:AƒJAÓ³Ahg7Aß3HAÐ<µA˜:A†YGA,Öâ>¯Ž¾Zb?!N²AÖõ:AƒJAÐ<µA˜:A†YGAN'´A%/?A£gIA¦&8¿O1?€-Z=-C AUUAI‚-AÞÇ A~UA·™2A­{ Aõ„UAKD-A7Ã9¿].?ˆ&Û=­{ Aõ„UAKD-AÞÇ A~UA·™2A¤¯¡A¤WAH1A<¡@¿T (?ŸK\=­{ Aõ„UAKD-A¤¯¡A¤WAH1Aª4¡AÑ&WAQy,A—8E¿gÜ ?ZÝ=ª4¡AÑ&WAQy,A¤¯¡A¤WAH1A"‚¢ApæYAäµ0A4K¿?Â^=ª4¡AÑ&WAQy,A"‚¢ApæYAäµ0A#¢AjhYA†+AÍó> hνd¡_? »Aò:LAËÐCACE¹AÝ–OA‚LFA¶¸AÆDMA¤FAòêõ>³;=¾K[?Ð<µA˜:A†YGAŸÍµA³ß;A"GAN'´A%/?A£gIA“mù>]ê4¾ÕñZ?N'´A%/?A£gIAŸÍµA³ß;A"GAœ·A^›@AgéEA¢ é>0£ ¾-a?N'´A%/?A£gIAœ·A^›@AgéEA™ÖµA•¥CAXcHAãÿ>31#¾]Z?™ÖµA•¥CAXcHAœ·A^›@AgéEA>¹AɘEAdêDAôÈí>Dfý½N~`?™ÖµA•¥CAXcHA>¹AɘEAdêDA¶[·AWHAAwGAï“? ¡¾ƒ4Y?¶[·AWHAAwGA>¹AɘEAdêDA…²ºA³×JAÿDAÃùñ>Æ^Þ½ã_?¶[·AWHAAwGA…²ºA³×JAÿDA¶¸AÆDMA¤FAÜ*?¥o¾¯ºX?¶¸AÆDMA¤FA…²ºA³×JAÿDA3ͺABEKA–õCAöc?°i¾w«X?¶¸AÆDMA¤FA3ͺABEKA–õCA »Aò:LAËÐCA˜Q¿> ?â‚^=#¢AjhYA†+A"‚¢ApæYAäµ0Ašv¢AžZAr+AªcR¿Ò'?|Bß=šv¢AžZAr+A"‚¢ApæYAäµ0Ad?£A1D\Aä/A'X¿>“?úU`=šv¢AžZAr+Ad?£A1D\Aä/AZØ¢A[É[A©*AqßZ¿ÇÅ?˜Òà=ZØ¢A[É[A©*Ad?£A1D\Aä/AHç£AA½^Al(/AT`¿7ö>;¯a=ZØ¢A[É[A©*AHç£AA½^Al(/A쉣A„I^Aã)A2jb¿Ã(è>]øá=쉣A„I^Aã)AHç£AA½^Al(/A,¤Aªæ_A•Ú.AŸŸe¿9”à>þUb=쉣A„I^Aã)A,¤Aªæ_A•Ú.AnÓ£Aqw_AÚ)A[´g¿;Ú×>ÿÎb=nÓ£Aqw_AÚ)A,¤Aªæ_A•Ú.A\¤A­K`Ax^)A=|h¿i­Î>C\ã=\¤A­K`Ax^)A,¤Aªæ_A•Ú.A)°¤AüobAF.A°l¿þÀ>Æ>d=\¤A­K`Ax^)A)°¤AüobAF.Ax_¤Aî bAÐó(A±Ën¿Qw¯>vä=x_¤Aî bAÐó(A)°¤AüobAF.AŽ¥A4eAùÊ-Aður¿ÊÉ¡>{e=x_¤Aî bAÐó(AŽ¥A4eAùÊ-A:Ó¤Ai³dA‘q(Aenu¿T½Ž>ªe=:Ó¤Ai³dA‘q(AŽ¥A4eAùÊ-A‰ ¥AGgfAè0(A£u¿+B„>DÓå=‰ ¥AGgfAè0(AŽ¥A4eAùÊ-AÜq¥A#¬gA¯i-Aßx¿­"m>ƒzf=‰ ¥AGgfAè0(AÜq¥A#¬gA¯i-A˜.¥AMjgA| (A˜y¿æçM>¶iæ=˜.¥AMjgA| (AÜq¥A#¬gA¯i-AᯥAô^jA±"-A>§{¿¡Ò2>‡Äf=˜.¥AMjgA| (AᯥAô^jA±"-A-q¥AV1jA6¿'Avç{¿oJ >îÖæ=-q¥AV1jA6¿'AᯥAô^jA±"-A;É¥AûkAœ-Aø­}¿´ù=ƒüf=-q¥AV1jA6¿'A;É¥AûkAœ-ApŒ¥A-ÚkA[ 'AKõ?NDû½¤X? »Aò:LAËÐCA»L»AQMA#§CACE¹AÝ–OA‚LFA…ý?¯Ìè½C/X?CE¹AÝ–OA‚LFA»L»AQMA#§CA€r¼A·¼RAðñBA-÷>r°½i'_?CE¹AÝ–OA‚LFA€r¼A·¼RAðñBAÚUºAþªTAN¥EApÝ?MRÁ½,ŸW?ÚUºAþªTAN¥EA€r¼A·¼RAðñBATe½ALXA§[BA½ù>Çɽ¿Á^?ÚUºAþªTAN¥EATe½ALXA§[BAï6»A·ÞYAÊEA^b ?R™½!*W?ï6»A·ÞYAÊEATe½ALXA§[BA%¾A¼ý]A·äAAóåû>`^½øp^?ï6»A·ÞYAÊEA%¾A¼ý]A·äAAlè»A!1_AB­DA6Œ ?x±_½eÐV?lè»A!1_AB­DA%¾A¼ý]A·äAA­°¾ASÑcAÜAA‘ý>(Œ½5^?lè»A!1_AB­DA­°¾ASÑcAÜAA«i¼Aû¡dAU]DA»C ?·Ò½—V?«i¼Aû¡dAU]DA­°¾ASÑcAÜAAÛé¾AŠLgAAjAAðKþ>Ú¼l^?«i¼Aû¡dAU]DAÛé¾AŠLgAAjAAŽž¼AÈágA–0 E¼$^?Žž¼AÈágA–ÅQƒ8. ^?ZϼA†QmA[DAl¿ApA‚IAAøÎ¼AÄrA—DAôN~¿Ä’Ì=Œ}g=pŒ¥A-ÚkA[ 'A;É¥AûkAœ-A”¥AuÅlAí–'A=š}¿ëœ=Ésç=”¥AuÅlAí–'A;É¥AûkAœ-A›à¥A1¬nAÂê,AÔ?¿OüR=úÍg=”¥AuÅlAí–'A›à¥A1¬nAÂê,A—¥¥A:¡nA݃'A>X~¿ Â9<ß[ç=—¥¥A:¡nA݃'A›à¥A1¬nAÂê,Amà¥A^qAøê,Aæ‘¿b®S¼HZg=—¥¥A:¡nA݃'Amà¥A^qAøê,Ae¥¥AÏiqA„'AÞÀ ?[Ê;^{V?l¿ApA‚IAA7¿AþörA£IAAøÎ¼AÄrA—DAV´ ?Ü?—<±wV?øÎ¼AÄrA—DA7¿AþörA£IAATè¾AüÏxA6kAAIŽþ>“r§·q=k4^?$¼AÖ8xAw=DA |¾As©~Aš®AAú8¼A¦®}Av{DA2v ?™™c=}ÚV?ú8¼A¦®}Av{DA |¾As©~Aš®AA1$¾A¥÷€A4åAAïlü>Ñ1F=Ma^?ú8¼A¦®}Av{DA1$¾A¥÷€A4åAAøÌ»A߀A8¾DAA=¿V½>Ñg=e¥¥AÏiqA„'Amà¥A^qAøê,Aª”¥A…:sA —'Aà•}¿Ôªž½Ìtç=ª”¥A…:sA —'Amà¥A^qAøê,AÈ¥AtAc-AÐH~¿9xν„€g=ª”¥A…:sA —'AÈ¥AtAc-Aµ‹¥Ak3tA.¡'Al|¿~ ¾ûÏæ=µ‹¥Ak3tA.¡'AÈ¥AtAc-A…˜¥AØÆvAs=-Adb|¿D…!¾Ì†f=µ‹¥Ak3tA.¡'A…˜¥AØÆvAs=-AX¥AAývA—Û'AÃy¿ôðN¾î+æ=X¥AAývA—Û'A…˜¥AØÆvAs=-A­d¥A­ÊxA¿x-Aõsy¿ÒÏ^¾“Þe=X¥AAývA—Û'A­d¥A­ÊxA¿x-Au ¥AÑyAs(ATx¿¥›u¾m$f=u ¥AÑyAs(A­d¥A­ÊxA¿x-A~ ¥A+™yAØ/(Aru¿úwˆ¾ø•å=~ ¥A+™yAØ/(A­d¥A­ÊxA¿x-AÏ ¥A)j{AÞ-A”Õt¿}Ê’¾=e=~ ¥A+™yAØ/(AÏ ¥A)j{AÞ-ARÁ¤A¿À{A¾…(A½Ío¿ö㩾Qä=RÁ¤A¿À{A¾…(AÏ ¥A)j{AÞ-AÙ›¤A0ý}A].A^Oo¿š³¾ð°c=RÁ¤A¿À{A¾…(AÙ›¤A0ý}A].AÒI¤A}b~A )AVý ?-x„=nýV?1$¾A¥÷€A4åAAY¾A9A#÷AAøÌ»A߀A8¾DAaf ?ƽ—=$+W?øÌ»A߀A8¾DAY¾A9A#÷AAÃ?½AÔS„AïrBAæsú>ðÛ„=”©^?øÌ»A߀A8¾DAÃ?½AÔS„AïrBA!»A”‚ƒA<0EAå?!Õ¿=±ŸW?!»A”‚ƒA<0EAÃ?½AÔS„AïrBAE¼Aƒ‡Aþ CAì÷>¥=º_?!»A”‚ƒA<0EAE¼Aƒ‡Aþ CA½+ºAð†A.¿EA5 ?S#ç='/X?½+ºAð†A.¿EAE¼Aƒ‡Aþ CAB»A`ȉA ÈCA…Óô>h²Ä=µ|_?½+ºAð†A.¿EAB»A`ȉA ÈCAš¹AsžˆAæjFAê¾?r&ÿ=ÖŽX?B»A`ȉA ÈCA| »A‹â‰AÐCAš¹AsžˆAæjFAÉ{?;>lªX?š¹AsžˆAæjFA| »A‹â‰AÐCAVͺAÖTŠApõCA–ò>tÁ×=ƒÒ_?š¹AsžˆAæjFAVͺAÖTŠApõCA Ë·A ‹A{3GA}åk¿ïÔľ7d=ÒI¤A}b~A )AÙ›¤A0ý}A].A¤Að³AÛ^)AW g¿aƒÒ¾S)ã=¤Að³AÛ^)AÙ›¤A0ý}A].AޤA¥A€A–õ.A6Óf¿ƒ—Û¾ ¤b=¤Að³AÛ^)AޤA¥A€A–õ.Añ¹£Az€Aa­)AG¼`¿¡î¾àká=ñ¹£Az€Aa­)AޤA¥A€A–õ.Amu£AÏ}AÓ§/A…½_¿ð7÷¾‹–`=ñ¹£Az€Aa­)Amu£AÏ}AÓ§/Ai£AWºAi*AI?oE >¸Y?VͺAÖTŠApõCAºµ¹A)hŒA¡DA Ë·A ‹A{3GAÔr?N>ŒY? Ë·A ‹A{3GAºµ¹A)hŒA¡DAæl¸AãŽA*jEAâ€í>á}þ=nŒ`? Ë·A ‹A{3GAæl¸AãŽA*jEA™¶Aº AíGAä¼ý>Çx(>…SZ?™¶Aº AíGAæl¸AãŽA*jEAçµ¶AFëAVuFAŒúè>ÉU >¿4a?™¶Aº AíGAçµ¶AFëAVuFAµA"TA åHAnä÷>%$8>d6[?µA"TA åHAçµ¶AFëAVuFA >µA¶³’AÓXGAN<ä> ã>­ça?µA"TA åHA >µA¶³’AÓXGAu=³A~}‘A*ôIA†!Z¿]B¿Ý~`=i£AWºAi*Amu£AÏ}AÓ§/A(y¢Af²‚A¾+Ai1U¿ ï ¿0¼ß=(y¢Af²‚A¾+Amu£AÏ}AÓ§/AÍà¢A={‚A'M0AôŒT¿¿¼ó^=(y¢Af²‚A¾+AÍà¢A={‚A'M0A©t¢A¸¹‚A½+A´—N¿Ì›¿?"Þ=©t¢A¸¹‚A½+AÍà¢A={‚A'M0A}¢A衃A.)1A}DM¿OY¿Ê)]=©t¢A¸¹‚A½+A}¢A衃A.)1Ae£¡AûàƒAJÿ+AšC¿qy#¿T%Ü=e£¡AûàƒAJÿ+A}¢A衃A.)1A3=¡A³º„A92A}šA¿zî&¿[=e£¡AûàƒAJÿ+A3=¡A³º„A92AE½ Aqø„A…ü,Aa×ó>?rB>šÊ[? >µA¶³’AÓXGA'Ó´A„5“A†™GAu=³A~}‘A*ôIAâkð>HCJ>¶J\?u=³A~}‘A*ôIA'Ó´A„5“A†™GAÿIJA™]•AÖHA/õÝ>¥#)>Éb?u=³A~}‘A*ôIAÿIJA™]•AÖHAœQ±A͇“AaKALçê>á„U>Y]?œQ±A͇“AaKAÿIJA™]•AÖHAA²A9ú•A\=IA?¸Ù>vÇ1>fc?œQ±A͇“AaKAA²A9ú•A\=IAW<¯A–q•AQWLAh<¿Æ,¿þ8[=E½ Aqø„A…ü,A3=¡A³º„A92Aš{ AV=…AYD-Ag\5¿ˆ›2¿<%Ú=š{ AV=…AYD-A3=¡A³º„A92AÔK AÅ…AÖ3A¹3¿9Ì5¿³3Y=š{ AV=…AYD-AÔK AÅ…AÖ3AtŸAÿ…Aá.Aiä(¿H{>¿2á×=tŸAÿ…Aá.AÔK AÅ…AÖ3A%EŸAKÀ†A¶94Aš'¿²vA¿±ÄV=tŸAÿ…Aá.A%EŸAKÀ†A¶94Aõ²žAÉõ†A÷5/AHæ>eÌ^>Ð]?A²A9ú•A\=IAv‹°Ab—A”*JAW<¯A–q•AQWLA¡aá>"3g>z^?W<¯A–q•AQWLAv‹°Ab—A”*JA_¼®A5Ò˜AÉ=KAþþÑ>DJ@>cyd?W<¯A–q•AQWLA_¼®A5Ò˜AÉ=KAŠ­A¥Ï–AÙWMA€åÙ>*Ér>*‘_?Š­A¥Ï–AÙWMA_¼®A5Ò˜AÉ=KA+C¬AÕ‰šAÀ³LA–,Ë>öòJ> pe?Š­A¥Ï–AÙWMA+C¬AÕ‰šAÀ³LA†7«A°r˜Aì´NAÇWÒ>Ó|>n­`?†7«A°r˜Aì´NA+C¬AÕ‰šAÀ³LA…ÚªAÓ^›A4‡MAoÅ>S>øMf?†7«A°r˜Aì´NA…ÚªAÓ^›A4‡MAIǨAé™A» PABÿ6”G¿f»V=õ²žAÉõ†A÷5/A%EŸAKÀ†A¶94AýžAÒm‡AÙ/A(Õ¿d K¿MÔÕ=ýžAÒm‡AÙ/A%EŸAKÀ†A¶94A…nžAÐt‡Aç5A÷¿Ê|M¿%U=ýžAÒm‡AÙ/A…nžAÐt‡Aç5A4ÖAN¥‡A{$0A€ƒ¿ùS¿øæÓ=4ÖAN¥‡A{$0A…nžAÐt‡Aç5A¢GA4NˆAwT6Aˆ ¿®’U¿’ÃR=4ÖAN¥‡A{$0A¢GA4NˆAwT6A[¨œAßvˆA–h1A„ý¾Ô]¿ð Ñ=[¨œAßvˆA–h1A¢GA4NˆAwT6AÜœA,‰A3˜7AþÖø¾ûY_¿È}P=[¨œAßvˆA–h1AÜœA,‰A3˜7Aõk›A»1‰AÚ¹2A2–Ì>É‚>|a?…ÚªAÓ^›A4‡MAo«©AÓœAç8NAIǨAé™A» PA²õÊ>ø@ƒ>É­a?IǨAé™A» PAo«©AÓœAç8NAO¨©A^œA¹:NA«?¿>: [>ég?IǨAé™A» PAO¨©A^œA¹:NA:¦AS3›A‰šQAǯí¾`^b¿£NP=õk›A»1‰AÚ¹2AÜœA,‰A3˜7A·h›AV3‰AH½2AI…Û¾®Ñe¿æ\Ï=·h›AV3‰AH½2AÜœA,‰A3˜7AsÊšAÀ‰Atè8A(×¾4ôg¿#‚†>L‰b?O¨©A^œA¹:NAüõ¦AQiApÌOA:¦AS3›A‰šQAo ½>€ Š>%­c?:¦AS3›A‰šQAüõ¦AQiApÌOAq#¤A掞A¬mQA2à²>ž2g>ðÌh?:¦AS3›A‰šQAq#¤A掞A¬mQA‡£A~NœA¹!SAìØ³>¦Ô>®ôd?‡£A~NœA¹!SAq#¤A掞A¬mQAb$¢A :ŸAÔ’RA4 ¬>_öl>G¹i?‡£A~NœA¹!SAb$¢A :ŸAÔ’RAÞ­¡AlôœAæ4TA{@®>4 > Áe?Þ­¡AlôœAæ4TAb$¢A :ŸAÔ’RA¿g¡AOlŸARþRA Ò¦>ø|p>¶qj?Þ­¡AlôœAæ4TA¿g¡AOlŸARþRAöæžA¸A{ÇUAZ¥¾uòq¿åÕK=õȘAlaŠA.5A–t™A$WŠA¯D:As˜A4~ŠAÒÚ5Aß•¾yws¿ÅË=s˜A4~ŠAÒÚ5A–t™A$WŠA¯D:AÀ˜A¶°ŠA¯9;A•µ”¾%£t¿[`J=s˜A4~ŠAÒÚ5AÀ˜A¶°ŠA¯9;AWÕ—A³ŠAA6Aÿáw¾pw¿bÉ=WÕ—A³ŠAA6AÀ˜A¶°ŠA¯9;A—A‹A, çL¾ë÷s?EM–A4V#A~¯ZA¶¥—A]Ž"AÔYA°¦—AB'AÌrZAÜËŒ>Î*¾%"s?°¦—AB'AÌrZA¶¥—A]Ž"AÔYAŽˆšAj#Au:XAr½>ìb˽s­t?°¦—AB'AÌrZAŽˆšAj#Au:XAk_šAPÀ'AïXALß‘>.g¾~r?k_šAPÀ'AïXAŽˆšAj#Au:XAZ/œAµ{#AWNWAŽ£>…-ƽèQt?k_šAPÀ'AïXAZ/œAµ{#AWNWA²í›A›7(AêXAál–>â{¾èq?²í›A›7(AêXAZ/œAµ{#AWNWAÄŸA‘$A;·UAWt”>h¿½Ös?²í›A›7(AêXAÄŸA‘$A;·UAR—žAV)A£VAë;œ>Àʾž)q?R—žAV)A£VAÄŸA‘$A;·UAVÊ¡A3)&Aµ$TAub˜>ÉÁµ½%Ws?R—žAV)A£VAVÊ¡A3)&Aµ$TAë2¡A¤×*A/UA¢Ç¡>ŒR ¾'rp?ë2¡A¤×*A/UAVÊ¡A3)&Aµ$TAäAû(Až—RA œ>5‹«½càr?ë2¡A¤×*A/UAäAû(Až—RA@¿£Ap»,AdžSA³ §>a¾°Âo?@¿£Ap»,AdžSAäAû(Až—RAÆ(§Ar|*AÓQAôiŸ>Š| ½Vrr?@¿£Ap»,AdžSAÆ(§Ar|*AÓQA;¦A©/A/RAìÙª>É û½–Do?;¦A©/A/RAÆ(§Ar|*AÓQA¯X¨AŸ´+Aé`PA¡>Š™½j çñ½Õn?UW§A@,0Aè‰QA¯X¨AŸ´+Aé`PA[ЪA–.A>ñNA¹£>æe½<åq?UW§A@,0Aè‰QA[ЪA–.A>ñNAQ¥©AKë2A1PAT€²>ÍÝ⽦An?Q¥©AKë2A1PA[ЪA–.A>ñNAs)­AsÏ1AÅMAÍ?¦>°Vƒ½L’q?Q¥©AKë2A1PAs)­AsÏ1AÅMA¶Õ«AGû5A#çNAú~¶>{Ó½ºm?¶Õ«AGû5A#çNAs)­AsÏ1AÅMAc¯AV_5AY@LAËs¨>0n½õIq?¶Õ«AGû5A#çNAc¯AV_5AY@LAÈç­AmZ9A´¬MA€ º>k½d>m?Èç­AmZ9A´¬MAc¯AV_5AY@LAj|±A}E9AØKAgXª>·U½ð q?Èç­AmZ9A´¬MAj|±A}E9AØKAËÚ¯AI=A›‚LAƒ¼>!ºµ½îl?ËÚ¯AI=A›‚LAj|±A}E9AØKA!N²AÖõ:AƒJAø«>ú¡H½[öp?ËÚ¯AI=A›‚LA!N²AÖõ:AƒJAK°AjŸ>AÛ LAx–¾>@ª½×¥l?K°AjŸ>AÛ LA!N²AÖõ:AƒJAN'´A%/?A£gIA§w¬>æ«3½öÆp?K°AjŸ>AÛ LAN'´A%/?A£gIA‰S²A²—BAœKAÜBÁ>êÿ˜½"Jl?‰S²A²—BAœKAN'´A%/?A£gIA™ÖµA•¥CAXcHAòŸ­>Ñ¥½Ê¡p?‰S²A²—BAœKA™ÖµA•¥CAXcHA<â³A²ÆFAÃJAþ“Ã>Èœ‡½Œúk?<â³A²ÆFAÃJA™ÖµA•¥CAXcHA¶[·AWHAAwGAW‰®>+s½…p?<â³A²ÆFAÃJA¶[·AWHAAwGAIIµAÙ*KAÅ8IA›Å>¿>l½i¶k?IIµAÙ*KAÅ8IA¶[·AWHAAwGA¶¸AÆDMA¤FA¼;¯>ñ?⼋op?IIµAÙ*KAÅ8IA¶¸AÆDMA¤FAKˆ¶AàÃOA8uHAÊÆ>å8R½ðŒk?Kˆ¶AàÃOA8uHA¶¸AÆDMA¤FACE¹AÝ–OA‚LFA™f¯>i-ͼulp?Kˆ¶AàÃOA8uHACE¹AÝ–OA‚LFA ·AíQA,$HAÎÝÇ>Ú•9½Mgk? ·AíQA,$HACE¹AÝ–OA‚LFAÚUºAþªTAN¥EAè¯>˜Š¨¼ê[p? ·AíQA,$HAÚUºAþªTAN¥EA˜¸A~§VA¤‰GA¡É>‡£½G>k?˜¸A~§VA¤‰GAÚUºAþªTAN¥EAï6»A·ÞYAÊEA«0°>”탼YTp?˜¸A~§VA¤‰GAï6»A·ÞYAÊEA-Õ¸Aó|[AÆ GA‹þÉ>é켘k?-Õ¸Aó|[AÆ GAï6»A·ÞYAÊEAlè»A!1_AB­DAŽ]°>­TB¼CPp?-Õ¸Aó|[AÆ GAlè»A!1_AB­DAæw¹AJm`AŤFA˜¬Ê>x©¼Žk?æw¹AJm`AŤFAlè»A!1_AB­DA«i¼Aû¡dAU]DA&u°>rSÿ»¹Np?æw¹AJm`AŤFA«i¼Aû¡dAU]DAIî¹A‘xeA[FAî Ë>¸fh¼ûj?Iî¹A‘xeA[FA«i¼Aû¡dAU]DAŽž¼AÈágA–q ´»žPp?Iî¹A‘xeA[FAŽž¼AÈágA–ì,ÿ»Ãój?µºAC{hAöMYÛºÝOp?µºAC{hAö½39Nñj?\KºAJ„mA !FAZϼA†QmA[DAøÎ¼AÄrA—DAyn°> W;ëQp?\KºAJ„mA !FAøÎ¼AÄrA—DAKºA¶rAX!FAˆ8Ë>R<9öj?KºA¶rAX!FAøÎ¼AÄrA—DA$¼AÖ8xAw=DAÙX°>F¤½;ÞTp?KºA¶rAX!FA$¼AÖ8xAw=DAiºAfwAÅ=FAßÊ>˜ƒ<©k?iºAfwAÅ=FA$¼AÖ8xAw=DAú8¼A¦®}Av{DAŽ7°>u<êXp?iºAfwAÅ=FAú8¼A¦®}Av{DA²Á¹Aµ¬|AàvFA!hÊ>žD½¡M<·[p?²Á¹Aµ¬|AàvFAøÌ»A߀A8¾DA¾^¹AZ8€Ag´FAÛ¶É>ê ÷<$+k?¾^¹AZ8€Ag´FAøÌ»A߀A8¾DA!»A”‚ƒA<0EAøØ¯>Ј<Öcp?¾^¹AZ8€Ag´FA!»A”‚ƒA<0EA?µ¸AU«‚AGALºÈ>‹“=yMk??µ¸AU«‚AGA!»A”‚ƒA<0EA½+ºAð†A.¿EA\…¯>.±ª<”mp??µ¸AU«‚AGA½+ºAð†A.¿EAéß·A…A‹¡GAËzÇ>ï==Óxk?éß·A…A‹¡GA½+ºAð†A.¿EAš¹AsžˆAæjFAh¯>Œ^Ï<${p?éß·A…A‹¡GAš¹AsžˆAæjFAdÞ¶Aäk‡AH@HA¬ñÅ>B²_=®k?dÞ¶Aäk‡AH@HAš¹AsžˆAæjFA Ë·A ‹A{3GA™z®> Sö<·p?dÞ¶Aäk‡AH@HA Ë·A ‹A{3GA诵A¸‰A÷ùHA LÄ>W=jæk?诵A¸‰A÷ùHA Ë·A ‹A{3GA™¶Aº AíGA¼à­>?q = p?诵A¸‰A÷ùHA™¶Aº AíGA•´A°Ž‹Ai¦IA°VÂ>¬òŽ=¿*l?•´A°Ž‹Ai¦IA™¶Aº AíGAµA"TA åHA8è¬>R!=Ä¿p?•´A°Ž‹Ai¦IAµA"TA åHAò³Aù°A8ŒJA8ç¿>GãŸ=³~l?ò³Aù°A8ŒJAµA"TA åHAu=³A~}‘A*ôIAÖº«>ºi7=Þåp?ò³Aù°A8ŒJAu=³A~}‘A*ôIA {±Ab¸AXˆKAŽ>ÿ¬°=†Þl? {±Ab¸AXˆKAu=³A~}‘A*ôIAœQ±A͇“AaKAàIª>[;N=àq? {±Ab¸AXˆKAœQ±A͇“AaKA³¯Aó£‘AhšLA>ô¹>ë>Á=çJm?³¯Aó£‘AhšLAœQ±A͇“AaKAW<¯A–q•AQWLAr¨>t£e=ÅMq?³¯Aó£‘AhšLAW<¯A–q•AQWLAÀíA8r“A'ÂMA×¶>BíÏ= ´m?ÀíA8r“A'ÂMAW<¯A–q•AQWLAŠ­A¥Ï–AÙWMA¤ü¦>÷x=@€q?ÀíA8r“A'ÂMAŠ­A¥Ï–AÙWMA»/¬A„½”Aå±NA‰o³>}Ý=ô(n?»/¬A„½”Aå±NAŠ­A¥Ï–AÙWMA†7«A°r˜Aì´NA»¤>ù¬‡=@Ëq?»/¬A„½”Aå±NA†7«A°r˜Aì´NA”ªAGK–AžøOAº=¯>´ƒì=æ¶n?”ªAGK–AžøOA†7«A°r˜Aì´NAIǨAé™A» PAä!¢>®B“=| r?”ªAGK–AžøOAIǨAé™A» PA·¾§Ar°—A®MQAŸ¯ª>þ¦ú=;Po?·¾§Ar°—A®MQAIǨAé™A» PA:¦AS3›A‰šQA95Ÿ>©‚ž=3€r?·¾§Ar°—A®MQA:¦AS3›A‰šQA½[¥Aþë˜Aq°RAÄ¥>sä>çôo?½[¥Aþë˜Aq°RA:¦AS3›A‰šQA‡£A~NœA¹!SAÞò›>J©=€êr?½[¥Aþë˜Aq°RA‡£A~NœA¹!SAÝ¢Aeü™AT TA¤B¡>åA >‰p?Ý¢Aeü™AT TA‡£A~NœA¹!SAÞ­¡AlôœAæ4TAÆW™>ÏD±=Û=s?Ý¢Aeü™AT TAÞ­¡AlôœAæ4TA0¡AAp#UA´œ>Y• >‡!q?0¡AAp#UAÞ­¡AlôœAæ4TAöæžA¸A{ÇUA(Õ>Õ¹=õ²s?0¡AAp#UAöæžA¸A{ÇUA=|žA«[›AöžVAýú–>„Q>²Ýq?=|žA«[›AöžVAöæžA¸A{ÇUA?œA¦FžA^WAw¾‘>NTÂ=;4t?=|žA«[›AöžVA?œA¦FžA^WA9Ó›A³è›AÅXAb‘>m>>’ r?9Ó›A³è›AÅXA?œA¦FžA^WAÏ3™AžŸžAø÷XApy>ǸÉ=ͼt?9Ó›A³è›AÅXAÏ3™AžŸžAø÷XA4™AWCœA.¢YA+'…>P />ŒIs?L–A°m.Aâ¦ZAk—A,AôcZAk`—AB¬0AG¨YAun„>_ü>Ímt?k`—AB¬0AG¨YAk—A,AôcZA šA%„,AóXAŒ>zI>иr?k`—AB¬0AG¨YA šA%„,AóXAï™AŽ51AƒFXAÅÝ>áÔt?ï™AŽ51AƒFXA šA%„,AóXA>’›A(ü,AXA¶Ïu> ÒL>¥.s?ï™AŽ51AƒFXA>’›A(ü,AXA›A¤­1AW{WAÁz>t–>;$u?›A¤­1AW{WA>’›A(ü,AXA!žA¦.A+²VAé¸j>ZÂO>èµs?›A¤­1AW{WA!žA¦.A+²VATqA Ã2A VAƒìo>‡¾> ¦u?TqA Ã2A VA!žA¦.A+²VA× A/A^JUA¡´\>:R>\et?TqA Ã2A VA× A/A^JUAVµŸAO.4AøÅTAt)e>&ú!>ú2v?VµŸAO.4AøÅTA× A/A^JUA3à¢A›_1AkèSAmN>~sS>J u?VµŸAO.4AøÅTA3à¢A›_1AkèSAüé¡AÞí5AísSA¯ÐY>!-#>íÊv?üé¡AÞí5AísSA3à¢A›_1AkèSA0¥AÒŒ3ARAtè>>ONS>Âæu?üé¡AÞí5AísSA0¥AÒŒ3ARA9¤Ac8A¬(RAYO>Ï,#>Yw?9¤Ac8A¬(RA0¥AÒŒ3ARAA8¦Aw©4A#ñQA÷S4>®YR>~sv?9¤Ac8A¬(RAA8¦Aw©4A#ñQA¥AÓ9A ”QAí`H>yÏ">¶ºw?¥AÓ9A ”QAA8¦Aw©4A#ñQAÓ[¨A`E7Aå«PAx!(>2eP>Ñw?¥AÓ9A ”QAÓ[¨A`E7Aå«PA+ü¦A1ˆ;Ay^PAK*<>Sý >Äfx?+ü¦A1ˆ;Ay^PAÓ[¨A`E7Aå«PAÚbªA+:A uOA f>sL>lïw?+ü¦A1ˆ;Ay^PAÚbªA+:A uOA^Ú¨AƒC>A7OA;Á/>Ë>Éy?^Ú¨AƒC>A7OAÚbªA+:A uOAÀL¬AÁX=AMNA4™>UÏF>ÊËx?^Ú¨AƒC>A7OAÀL¬AÁX=AMNA±œªA¸?AA‘NA›;#> >vÏy?±œªA¸?AA‘NAÀL¬AÁX=AMNAî®A™Í@Aº5MAW©ñ=¾\?>Y«y?±œªA¸?AA‘NAî®A™Í@Aº5MA¶B¬Aé{DAzMA@Ž>žá>Êmz?¶B¬Aé{DAzMAî®A™Í@Aº5MAÌ®A9KBAJÈLAFnÝ=ƒœ9>³;z?¶B¬Aé{DAzMAÌ®A9KBAJÈLAªæ¬AHàEAç­LAÚ¶>-ë>ÕÓz?ªæ¬AHàEAç­LAÌ®A9KBAJÈLAé^°AØFAæÐKAŸyÆ=íÑ1> ãz?ªæ¬AHàEAç­LAé^°AØFAæÐKAìV®A VIAÄKAðÙ>µ¤>&‡{?ìV®A VIAÄKAé^°AØFAæÐKA­Ì±AÚèIAÞîJAý‰©=£*&>j·{?ìV®A VIAÄKA­Ì±AÚèIAÞîJAv¤¯A-öLA¬îJAÎõ=c·û=Ó4|?v¤¯A-öLA¬îJA­Ì±AÚèIAÞîJAb³A¼þMA‡"JAw&Ž=Ê¿>ë‚|?v¤¯A-öLA¬îJAb³A¼þMA‡"JA‹Ï°A?¿PA.JA« ß=Âå=HÚ|?‹Ï°A?¿PA.JAb³A¼þMA‡"JAÚ8´A3CRA]lIA!Di= >¥B}?‹Ï°A?¿PA.JAÚ8´A3CRA]lIA,رAò°TA¨‚IAÃkÎ=.BÏ=`}?,رAò°TA¨‚IAÚ8´A3CRA]lIA±´A:DTAñ IA4I=ëü=´º}?,رAò°TA¨‚IA±´A:DTAñ IA+E²ANŠVAÀ;IAÌ©Ã=j¿=>µ}?+E²ANŠVAÀ;IA±´A:DTAñ IAd•µAá£XAJ‘HA_(=3_á=x:~?+E²ANŠVAÀ;IAd•µAá£XAJ‘HAÛ³AÔ‘ZAÑ´HAk³=7¢=5~?Û³AÔ‘ZAÑ´HAd•µAá£XAJ‘HA]Q¶Aö]A‘HAð=LE¼=ÛÈ~?Û³AÔ‘ZAÑ´HA]Q¶Aö]A‘HAÁ½³A­^AnEHAªë¥=éKƒ=O¡~?Á½³A­^AnEHA]Q¶Aö]A‘HA<å¶A2©aAâ¼GA¸¸È< Ñ”=??Á½³A­^AnEHA<å¶A2©aAâ¼GA8C´A×ÛbAžíGAr%›=[ôD=¨÷~?8C´A×ÛbAžíGA<å¶A2©aAâ¼GA·P·AòNfA¢xGA¨™‰N¾0ˆ{?Âþ®AtŠAÚXKAݱA& ŒAe_KAÿ—¯ASòA>KLAf¾=³=.¾a%{?Âþ®AtŠAÚXKAÿ—¯ASòA>KLA8¡­Aw7ŒA¤7LAvÓ>Æt¾ ×z?8¡­Aw7ŒA¤7LAÿ—¯ASòA>KLAWô­AоA LMA®¡Û=lŒ8¾žNz?8¡­Aw7ŒA¤7LAWô­AоA LMA1!¬A2åAœ*MAóñ>Õ ¾æ"z?1!¬A2åAœ*MAWô­AоA LMAz+¬A4q‘A§aNABú=º!A¾¦sy?1!¬A2åAœ*MAz+¬A4q‘A§aNA%~ªAá{A¬1NA1“)>m5¾‘EG¾’´x?%~ªAá{A¬1NA¶ªAr©’A COAü&©A¡AŠOAšÂ3>ÙZ¾Tåx?ü&©A¡AŠOA¶ªAr©’A COAµ¨A‰!”A¤vPAÕÅ>WL¾¿ðw?ü&©A¡AŠOAµ¨A‰!”A¤vPAvN§At’AÓ+PA\ý?> !¾c7x?vN§At’AÓ+PAµ¨A‰!”A¤vPAI˜¦A›t•AJ¸QA‡`(>~íO¾pw?vN§At’AÓ+PAI˜¦A›t•AJ¸QAM[¥AZf"¾w?M[¥A—3R¾zLv?M[¥A«…"¾*ðv?ãM£AKb”AñûR¾Ð„u?ãM£AKb”A™Ç!¾»`v?w&¡A \•AUéSAh ¢AѦ—AgcTAäf A¸A˜AÑXUAU#S> ÁR¾3åt?w&¡A \•AUéSAäf A¸A˜AÑXUA'žŸAñ•AÉÓTA(qj>Ì. ¾1öu?'žŸAñ•AÉÓTAäf A¸A˜AÑXUAÎöA;û˜A¶ÀVAž_>ó0Q¾7It?'žŸAñ•AÉÓTAÎöA;û˜A¶ÀVAÂYAÕ¤–Aô+VAêÈt>ly¾Òpu?ÂYAÕ¤–Aô+VAÎöA;û˜A¶ÀVAsy›Ak†™A%-XAßfm>zN¾Ðs?ÂYAÕ¤–Aô+VAsy›Ak†™A%-XAô›A¥-—A݈WAR†~>ˆé¾Xöt?ô›A¥-—A݈WAsy›Ak†™A%-XAÓï˜A|â™ArYA’z>†ªJ¾Êýr?ô›A¥-—A݈WAÓï˜A|â™ArYA´©˜A–Š—AÞéXA¬dh>!ï>'ÉZ?'Ì•ASß8A² WA¸—Aç,5AèCXAÚ¿–AŸh9A«>VAW×`>üÛ>P:`?Ú¿–AŸh9A«>VA¸—Aç,5AèCXAS™A”¹5A>íVAÕüL>tó>®E[?Ú¿–AŸh9A«>VAS™A”¹5A>íVAИAJö9AÿîTAJdF>u.Þ>|>a?ИAJö9AÿîTAS™A”¹5A>íVAË–šAË06A“(VA•>4>Ò)õ>.\?ИAJö9AÿîTAË–šAË06A“(VA„ü™Ack:Ai.TAùŸ0>`;ß>b?„ü™Ack:Ai.TAË–šAË06A“(VA˜¾œAÇ?7A«ÖTA—>@ ö>*N]?„ü™Ack:Ai.TA˜¾œAÇ?7A«ÖTAü›Ar;A¥ãRAf'> Áß>Ôac?ü›Ar;A¥ãRA˜¾œAÇ?7A«ÖTA/ØžAž8A!ŠSA(è=Žâõ>ª^?ü›Ar;A¥ãRA/ØžAž8A!ŠSAœíAíÁ?³d?œíAíÁ `?œíAíÁA_PA ¡=^åÜ>f?2ПAŠY>A_PAŠâ A$J:A¸CRA­Ü¢A\C‰a?2ПAŠY>A_PA­Ü¢A\CV;g?Aý7@AÚ&OA­Ü¢A\C|}b?Aý7@AÚ&OAã½£ArC=AñtPANr¢Aµ)AAìšNA\¤=@×>/"h?Nr¢Aµ)AAìšNAã½£ArC=AñtPA7¥AC˜?AÍJOA4“ý»Vçé>*·c?Nr¢Aµ)AAìšNA7¥AC˜?AÍJOA'¤Ad[CAÒwMAfŒÅ9ÑŸÑ>ni?'¤Ad[CAÒwMA7¥AC˜?AÍJOAQF§A›)BA©.NAìŽ,½»÷â>í7e?'¤Ad[CAÒwMAQF§A›)BA©.NA ±¥AÔÃEA’bLA´Æû¼0~Ê> ÿj? ±¥AÔÃEA’bLAQF§A›)BA©.NAÞâ¨AQõDA!MAoŽ›½cÚ>õ¹f? ±¥AÔÃEA’bLAÞâ¨AQõDA!MAÅ*§AÓ`HA»[KA« {½YËÁ>ñnl?Å*§AÓ`HA»[KAÞâ¨AQõDA!MAdªASúGAµ"LAïYß½~Ð>;h?Å*§AÓ`HA»[KAdªASúGAµ"LA‹¨A41KAÖcJAÎí¯½§‰¹>™•m?‹¨A41KAÖcJAdªASúGAµ"LA&úªA3FIAf¿KAª`¾éÈ>!i?‹¨A41KAÖcJA&úªA3FIAf¿KA©AÝeLAJAØoÒ½©Þ²>Bln?©AÝeLAJA&úªA3FIAf¿KA’I¬AP}LAWßJA½¾¦Õ¾>Ij?©AÝeLAJA’I¬AP}LAWßJAEªAîaOA)IAâ8¾m ¦>ùÂo?EªAîaOA)IA’I¬AP}LAWßJAªx­A^ÙOA2JA"å:¾¦Ï°>ã©k?EªAîaOA)IAªx­A^ÙOA2JAoX«AA~RAjbHAE~¾…ð˜>J q?oX«AA~RAjbHAªx­A^ÙOA2JAЇ®AôXSA#[IAh¹V¾@?¡>ÿ÷l?oX«AA~RAjbHAЇ®AôXSA#[IAKN¬A€¹UA}¯GA°Ï7¾íΉ>‚;r?KN¬A€¹UA}¯GAЇ®AôXSA#[IA4w¯AËûVAz·HA¹Pp¾)$>/n?KN¬A€¹UA}¯GA4w¯AËûVAz·HAé&­AgYA~GA)™J¾”Wx>I#s?é&­AgYA~GA4w¯AËûVAz·HA§Ù¯Av¯XAØsHA£Ù¾F„>ån?é&­AgYA~GA§Ù¯Av¯XAØsHAÝ­AU¤ZAÐÎFA»ÿV¾±Íb>iÉs?Ý­AU¤ZAÐÎFA§Ù¯Av¯XAØsHA”°Aic\A:óGAÜEˆ¾;æi>Ó¼o?Ý­AU¤ZAÐÎFA”°Aic\A:óGA(®Aƒ ^AùQFAP»h¾?>¤®t?(®Aƒ ^AùQFA”°Aic\A:óGA-±A­'`A%‰GAÐS‘¾¸6B>Ÿp?(®Aƒ ^AùQFA-±A­'`A%‰GAì±®A;€aAëEAyw¾‘i>Ùnu?ì±®A;€aAëEA-±A­'`A%‰GA¥±A|ücA•5GA?º˜¾)”>vYq?ì±®A;€aAëEA¥±A|ücA•5GAã¯AãeAšEAŽ…¾0ä=Òv?ã¯AãeAšEA¥±A|ücA•5GAü±A´âgAÈøFA†`ž¾ZÚ=Öèq?ã¯AãeAšEAü±A´âgAÈøFAl¯A…”hA_EA–O…¾Dåœ= dv?l¯A…”hA_EAü±A´âgAÈøFA²AD5jAëßFALy¡¾P¨˜=G/r?l¯A…”hA_EA²AD5jAëßFAŒ¯A\´jAüFEAì1‡¾ÈÇC=Xœv?Œ¯A\´jAüFEA²AD5jAëßFAW@²AvnAüÈFA’v£¾b¹=$jr?Œ¯A\´jAüFEAW@²AvnAüÈFAb©¯Az@nAÂ0EAŸkˆ¾è;ø;é¼v?b©¯Az@nAÂ0EAW@²AvnAüÈFA@²AðøqA*ÉFA·#¤¾éÔ»‰{r?b©¯Az@nAÂ0EA@²AðøqA*ÉFA(©¯A›ÍqAï0EApÛ‡¾I3½A®v?(©¯A›ÍqAï0EA@²AðøqA*ÉFAª²AÀÝuA•àFAçᢾÔN½»[r?(©¯A›ÍqAï0EAª²AÀÝuA•àFA&‹¯A]uA¡GEAü~…¾Öl•½3pv?&‹¯A]uA¡GEAª²AÀÝuA•àFAWÛ±AÅyA¯GAf®Ÿ¾<À½ r?&‹¯A]uA¡GEAWÛ±AÅyA¯GA­N¯A¯ïxAGuEAÍ˾½¥à½A v?­N¯A¯ïxAGuEAWÛ±AÅyA¯GA‹’±At¯|A€BGAŠ—›¾Q ¾Fq?­N¯A¯ïxAGuEA‹’±At¯|A€BGA< ¯A‘š{A¦EA¼@z¾±ë¾P”u?< ¯A‘š{A¦EA‹’±At¯|A€BGAw±As>€A‹™GAò••¾^’+¾E q?< ¯A‘š{A¦EAw±As>€A‹™GA­œ®A¬AöúEA›?l¾È6¾ÓÝt?­œ®A¬AöúEAw±As>€A‹™GA]w°AׂAHAhu¾~0T¾?p?­œ®A¬AöúEA]w°AׂAHA2®AKCA@eFA[6[¾ÛZ¾“t?2®AKCA@eFA]w°AׂAHAŽ·¯AÒõƒAJ‹HAß¶ƒ¾¬Ùz¾—Mo?2®AKCA@eFAŽ·¯AÒõƒAJ‹HAa­A-õ‚A”åFAÖMG¾›ö|¾žs?a­A-õ‚A”åFAŽ·¯AÒõƒAJ‹HAûÔ®AöÅ…A&IAÞÝp¾ì®¾M8n?a­A-õ‚A”åFAûÔ®AöÅ…A&IA+”¬A¯ „AW|GAÞ2¾z§¾òq?+”¬A¯ „AW|GAûÔ®AöÅ…A&IAu®AÑ;‡A1·IAÆ‘Z¾3çž¾%m?+”¬A¯ „AW|GAu®AÑ;‡A1·IA¡Ó«A²ù…AõHA$j¾×™š¾ºåp?¡Ó«A²ù…AõHAu®AÑ;‡A1·IA.â¬AÄðˆAÂxJAWä@¾ˆž­¾iôk?¡Ó«A²ù…AõHA.â¬AÄðˆAÂxJAÅϪAʇA2ÅHAl¾¬ ¨¾\Ÿo?ÅϪAʇA2ÅHA.â¬AÄðˆAÂxJA,¤«A¨“ŠANKAß#¾ï仾e™j?ÅϪAʇA2ÅHA,¤«A¨“ŠANKAz®©A"‰AÅ”IA¯ ̽)´¾TIn?z®©A"‰AÅ”IA,¤«A¨“ŠANKA÷EªA˜#ŒAû6LA¿Š¾×¢È¾Ü.i?z®©A"‰AÅ”IA÷EªA˜#ŒAû6LA3o¨Aâ…ŠA•wJA«‘½¡¾¾ëæl?3o¨Aâ…ŠA•wJA÷EªA˜#ŒAû6LA鯍AHŸAu3MA“¸Ç½.×Ó¾¸g?3o¨Aâ…ŠA•wJA鯍AHŸAu3MA2§AÌç‹AmKAüí/½¬7Ǿè‘k?2§AÌç‹AmKA鯍AHŸAu3MA“Œ§AÚ±ŽAïNAr'޽ä2ܾMnf?2§AÌç‹AmKA“Œ§AÚ±ŽAïNAnñ¥AièŒAù5LAôËŒ¼*¶Í¾cj?nñ¥AièŒAù5LA“Œ§AÚ±ŽAïNAÙÚ¥A·þAOAf½B¸ã¾e?nñ¥AièŒAù5LAÙÚ¥A·þAOA›c¤Ac ŽA?HMAB]e< 'Ô¾öh?›c¤Ac ŽA?HMAÙÚ¥A·þAOA¤¤A@-‘AÆ@PAßF‡»Ftê¾€”c?›c¤Ac ŽA?HMA¤¤A@-‘AÆ@PAн¢A팆߾ác?ÂÙA‰¦‘AZ«QA·ÂžAѸ“Ay—SAº¨œAQf”AäTAyþ=àüõ¾C^?ÂÙA‰¦‘AZ«QAº¨œAQf”AäTAÏç›AùL’AÐðRAÖ?%>tß¾÷˜b?Ïç›AùL’AÐðRAº¨œAQf”AäTAPšAì”A©5VAøÅ!>Õµõ¾Gì\?Ïç›AùL’AÐðRAPšAì”A©5VA•è™AœÎ’A:;TAóë'Þ¾F^a?•è™AœÎ’A:;TAPšAì”A©5VAcM˜AøH•Aq‹WAéC>ô¾£[?•è™AœÎ’A:;TAcM˜AøH•Aq‹WAðÜ—Az*“Aò‰UAÚMO>ß?qîF?i•A=AS@TAÚ¿–AŸh9A«>VAÐQ–AœG=Aî£SAîE>@ý?ô‹N?ÐQ–AœG=Aî£SAÚ¿–AŸh9A«>VAИAJö9AÿîTAÍŒ,>ÅÉ?–H?ÐQ–AœG=Aî£SAИAJö9AÿîTA½<˜AXÓ=A:WRAO@">? ?}³O?½<˜AXÓ=A:WRAИAJö9AÿîTA„ü™Ack:Ai.TA8ó >ñ?3 I?½<˜AXÓ=A:WRA„ü™Ack:Ai.TAºS™AØD>AX˜QAöc>æo?ü¶P?ºS™AØD>AX˜QA„ü™Ack:Ai.TAü›Ar;A¥ãRA×Ï=å·?´NJ?ºS™AØD>AX˜QAü›Ar;A¥ãRA?.›Aï@?A‡PPAû9¸=bZ?])R??.›Aï@?A‡PPAü›Ar;A¥ãRAœíAíÁA_PAøÆ`<—Ó? YM?(ûœAà€@AOA2ПAŠY>A_PA”¹žABAÎÑMAž7<® ?Ö5U?”¹žABAÎÑMA2ПAŠY>A_PAAý7@AÚ&OA«8ú¼î~?±ñN?”¹žABAÎÑMAAý7@AÚ&OA¯h AlÆCAaœLAž‚Ù¼Õ ?‘€V?¯h AlÆCAaœLAAý7@AÚ&OANr¢Aµ)AAìšNAÊQs½y‚?%÷O?¯h AlÆCAaœLANr¢Aµ)AAìšNA(¡Aè©DA»LAl÷U½‹{ ?.‰W?(¡Aè©DA»LANr¢Aµ)AAìšNA'¤Ad[CAÒwMA&‘Á½0c?ÐPQ?(¡Aè©DA»LA'¤Ad[CAÒwMAG²¢AP¹FAMñJA¨y½½«„?À"Y?G²¢AP¹FAMñJA'¤Ad[CAÒwMA ±¥AÔÃEA’bLAaˆ ¾ï¹ ?çñR?G²¢AP¹FAMñJA ±¥AÔÃEA’bLAð$¤AŽúHAŸÞIAõ;¾,¡?“½Z?ð$¤AŽúHAŸÞIA ±¥AÔÃEA’bLAÅ*§AÓ`HA»[KA>\7¾^?>“T?ð$¤AŽúHAŸÞIAÅ*§AÓ`HA»[KAÚ¥AvkKA;ÚHA¸Î.¾-‘õ>hW\?Ú¥AvkKA;ÚHAÅ*§AÓ`HA»[KA‹¨A41KAÖcJA_a¾i?w2V?Ú¥AvkKA;ÚHA‹¨A41KAÖcJAæÂ¦AÏ NA«äGA=UN¾—¯ê>*™]?æÂ¦AÏ NA«äGA‹¨A41KAÖcJA©AÝeLAJAsEz¾!ª÷>Í$W?æÂ¦AÏ NA«äGA©AÝeLAJAÔ?§A*OAÜ„GA -d¾lÞá>fŒ^?Ô?§A*OAÜ„GA©AÝeLAJAEªAîaOA)IA"RŒ¾gËê>ØgX?Ô?§A*OAÜ„GAEªAîaOA)IA.W¨AïïQAÒ¬FAE˜ƒ¾>îÑ>k`?.W¨AïïQAÒ¬FAEªAîaOA)IAoX«AA~RAjbHA¯}ž¾Ù>âY?.W¨AïïQAÒ¬FAoX«AA~RAjbHAžR©AbÒTA!èEA’󓾓FÀ>uoa?žR©AbÒTA!èEAoX«AA~RAjbHAKN¬A€¹UA}¯GA~a¯¾Å> G[?žR©AbÒTA!èEAKN¬A€¹UA}¯GA±2ªAÐWAí6EA £¾Kè¬>˜Àb?±2ªAÐWAí6EAKN¬A€¹UA}¯GAé&­AgYA~GAMܾ¾%V°>j”\?±2ªAÐWAí6EAé&­AgYA~GAÊ÷ªAÜèZAy™DA=”®¾¥›>xºc?Ê÷ªAÜèZAy™DAé&­AgYA~GAÝ­AU¤ZAÐÎFAÄ(Ⱦh¸¡>oQ]?Ê÷ªAÜèZAy™DAÝ­AU¤ZAÐÎFA¢H«AêZ\ApXDAL¶¾ é>Oud?¢H«AêZ\ApXDAÝ­AU¤ZAÐÎFA(®Aƒ ^AùQFAïGҾĽŽ>Ã;^?¢H«AêZ\ApXDA(®Aƒ ^AùQFA`á«A-~_AÑÜCAª5Á¾½³n>ope?`á«A-~_AÑÜCA(®Aƒ ^AùQFAì±®A;€aAëEA’(ݾ=´l>m,_?`á«A-~_AÑÜCAì±®A;€aAëEAY^¬Aä¬bAêvCA:Bʾ@_?>±Bf?Y^¬Aä¬bAêvCAì±®A;€aAëEAã¯AãeAšEAbæ¾l²9>ò_?Y^¬Aä¬bAêvCAã¯AãeAšEA#À¬A”çeA­&CAUXѾs>´èf?#À¬A”çeA­&CAã¯AãeAšEAl¯A…”hA_EA}Éì¾D¨>¿Š`?#À¬A”çeA­&CAl¯A…”hA_EAê­AY/iARìBAêñÕ¾¬VÃ="Kg?ê­AY/iARìBAl¯A…”hA_EAŒ¯A\´jAüFEAÓrð¾–{¹=:Ò`?ê­AY/iARìBAŒ¯A\´jAüFEAÆ#­Aû"kAvÔBA[Eؾ6•r=d‹g?Æ#­Aû"kAvÔBAŒ¯A\´jAüFEAb©¯Az@nAÂ0EAÃÙò¾Ëa8=ea?Æ#­Aû"kAvÔBAb©¯Az@nAÂ0EAX>­A enAu¾BA3ÁÙ¾'³<‚®g?X>­A enAu¾BAb©¯Az@nAÂ0EA(©¯A›ÍqAï0EA÷¤ó¾÷¼q%a?X>­A enAu¾BA(©¯A›ÍqAï0EA">­Aæ§qA¡¾BAZ Ù¾L)½žg?">­Aæ§qA¡¾BA(©¯A›ÍqAï0EA&‹¯A]uA¡GEAöò¾¥™|½6a?">­Aæ§qA¡¾BA&‹¯A]uA¡GEA#­AþìtAÕBA˜#Ö¾²u»½¸Yg?#­AþìtAÕBA&‹¯A]uA¡GEA­N¯A¯ïxAGuEAïFî¾뽓¬`?#­AþìtAÕBA­N¯A¯ïxAGuEALì¬Ag5xALCAp–Ѿˢ ¾9èf?Lì¬Ag5xALCA­N¯A¯ïxAGuEA< ¯A‘š{A¦EA-\é¾÷"¾c6`?Lì¬Ag5xALCA< ¯A‘š{A¦EA±¬A6©zA3CA©×˾G•5¾#hf?±¬A6©zA3CA< ¯A‘š{A¦EA­œ®A¬AöúEA6%â¾H¼Q¾œ_?±¬A6©zA3CA­œ®A¬AöúEAK¬AÞ}A©†CA8Ã¾È e¾ºŸe?K¬AÞ}A©†CA­œ®A¬AöúEA2®AKCA@eFA©]ؾNžÀÂ^?K¬AÞ}A©†CA2®AKCA@eFAàÉ«A;„€AçïCA¾ùK‰¾¸­d?àÉ«A;„€AçïCA2®AKCA@eFAa­A-õ‚A”åFA‚žÌ¾ ™¾[À]?àÉ«A;„€AçïCAa­A-õ‚A”åFA¦,«A`‚AûnDAöf¬¾'ãž¾H•c?¦,«A`‚AûnDAa­A-õ‚A”åFA+”¬A¯ „AW|GAý¾¾u °¾ ˜\?¦,«A`‚AûnDA+”¬A¯ „AW|GANrªA:ŸƒAHEADAŸ¾Ù'²¾vhb?NrªA:ŸƒAHEA+”¬A¯ „AW|GA¡Ó«A²ù…AõHA±¾Ñý¾æp[?NrªA:ŸƒAHEA¡Ó«A²ù…AõHAñ©A\Þ„A‰EA—Æ‘¾¹Å¾ü@a?ñ©A\Þ„A‰EA¡Ó«A²ù…AõHAÅϪAʇA2ÅHA_㡾^jÕ¾&+Z?ñ©A\Þ„A‰EAÅϪAʇA2ÅHAçÕ¨A¿T†A÷IFAâU¾Ô¾>Ø_?çÕ¨A¿T†A÷IFAÅϪAʇA2ÅHAz®©A"‰AÅ”IAZ ¾`ç¾Ä¶X?çÕ¨A¿T†A÷IFAz®©A"‰AÅ”IA‘ͧA8½‡AGAlŽ_¾e½ã¾[]^?‘ͧA8½‡AGAz®©A"‰AÅ”IA3o¨Aâ…ŠA•wJAÆz¾Œ÷¾1W?‘ͧA8½‡AGA3o¨Aâ…ŠA•wJAQ©¦Aú‰A:øGAwk:¾µ§ñ¾ÈÓ\?Q©¦Aú‰A:øGA3o¨Aâ…ŠA•wJA2§AÌç‹AmKAêïQ¾¯õ¿1U?Q©¦Aú‰A:øGA2§AÌç‹AmKAch¥AÜ`ŠAóëHAu¾dý¾ÉW[?ch¥AÜ`ŠAóëHA2§AÌç‹AmKAnñ¥AièŒAù5LA#ƒ.¾\¿Ë8T?ch¥AÜ`ŠAóëHAnñ¥AièŒAù5LA`¤AˆP‹Ao²IA.Êé½ó¿ùZ?`¤AˆP‹Ao²IAnñ¥AièŒAù5LA›c¤Ac ŽA?HMAÀ(¾gV ¿uÁR?`¤AˆP‹Ao²IA›c¤Ac ŽA?HMA8ò¢AŒtŒA+ÂJAmZ˜½f¿8mX?8ò¢AŒtŒA+ÂJA›c¤Ac ŽA?HMAн¢Aíß;¢— ¿hEU?¶ÑŸA|pŽA2 MAgÿ AÒ6¿ÑO?:A™A»áA ¥QA•è™AœÎ’A:;TAðÜ—Az*“Aò‰UAt­!>¨ ¿nH?:A™A»áA ¥QAðÜ—Az*“Aò‰UAÚZ—A*;‘AÎðRAÌ>\TH?M¹?a×”AáWAA/%PAÓ•A´@AY‚PACF•AÀšCAŒëLA N>ìØF?Cõ?CF•AÀšCAŒëLAÓ•A´@AY‚PAuœ—AŽ:AAÐ4OAåÁ=?éN?nÈ?CF•AÀšCAŒëLAuœ—AŽ:AAÐ4OAÏò–A_DAÄ™KAÛÍŸ=Ÿ“G?<?Ïò–A_DAÄ™KAuœ—AŽ:AAÐ4OAE ˜A̦AAguNA W=©=O?7°?Ïò–A_DAÄ™KAE ˜A̦AAguNA5æ—A—}DAÑ×JA3O=)…G?Ç ?5æ—A—}DAÑ×JAE ˜A̦AAguNAéYšAù•BA”,MAU;)ÏN?õá?5æ—A—}DAÑ×JAéYšAù•BA”,MA÷ƒ™A_]EAlŠIA¢™¼3ŒF?®‡!?÷ƒ™A_]EAlŠIAéYšAù•BA”,MAŽœABÄCAéKA,Œg½PGM?F?÷ƒ™A_]EAlŠIAŽœABÄCAéKA”›ATxFABHA¯—š½sD?V#?”›ATxFABHAŽœABÄCAéKAb¥A0EA«JAj›ì½+’J?Yµ?”›ATxFABHAb¥A0EA«JAEšœAøÌGA¢ÿFAú¾0A?„$?EšœAøÌGA¢ÿFAb¥A0EA«JA¥5ŸASØFAºtIAà´2¾“£F?‚/?EšœAøÌGA¢ÿFA¥5ŸASØFAºtIA[žAfZIA¸ÃEAî—7¾* =?¾%?[žAfZIA¸ÃEA¥5ŸASØFAºtIA+çŸAÚ­GAléHA}Y¾'{C?I?[žAfZIA¸ÃEA+çŸAÚ­GAléHA»·žAr"JA6EAã¸[¾kI:?éÇ&?»·žAr"JA6EA+çŸAÚ­GAléHAÂT¡ARœIA†ÇGA¶Œ„¾»>?Þ^?»·žAr"JA6EAÂT¡ARœIA†ÇGAe AÊñKAåDAÚ¼‰¾È(4?U(?e AÊñKAåDAÂT¡ARœIA†ÇGA%¬¢A¶¸KAM³FA'¡¾|Þ7?÷Ý?e AÊñKAåDA%¬¢A¶¸KAM³FAPP¡AOìMAhõBAÿ⤾ÄÚ,?,â)?PP¡AOìMAhõBA%¬¢A¶¸KAM³FA<í£AôNAO­EA’Û¼¾VË/?Y\ ?PP¡AOìMAhõBA<í£AôNAO­EAd}¢APA!êAAv5¿¾×W$?Am+?d}¢APA!êAA<í£AôNAO­EAò¥AÚsPA¶DA°­×¾4y&?é×!?d}¢APA!êAAò¥AÚsPA¶DA•£A\RA¥í@A¡ÙÓ¾¶š?Á™,?•£A\RA¥í@Aò¥AÚsPA¶DAd‹¥AÒQA›UDA/™ç¾œ2 ?à¬"?•£A\RA¥í@Ad‹¥AÒQA›UDAÙ¤AgWSA‹@A@`â¾ÐZ?‘‹-?Ù¤AgWSA‹@Ad‹¥AÒQA›UDA\¦A´TAï{CAåû¾.k?ÒÚ#?Ù¤AgWSA‹@A\¦A´TAï{CAäó¤AoÄUAZ¬?Aü@ù¾‡A ?lö.?äó¤AoÄUAZ¬?A\¦A´TAï{CAVu§AÅVA¥µBA‡ ¿¼‰ ?‘2%?äó¤AoÄUAZ¬?AVu§AÅVA¥µBAšÍ¥AûIXAIá>AÅ>¿E@þ>\N0?šÍ¥AûIXAIá>AVu§AÅVA¥µBAâC¨AŽYAéBA¡¿¨:ý>êv&?šÍ¥AûIXAIá>AâC¨AŽYAéBA„¦AùæZA *>A˜ú¿7ðã>Ë1?„¦AùæZA *>AâC¨AŽYAéBAhù¨Ao\AdAA–K¿°Má>Q¤'?„¦AùæZA *>Ahù¨Ao\AdAAü9§A4›]Aô†=AQ¿/ÑÌ>ëu2?ü9§A4›]Aô†=Ahù¨Ao\AdAAÒC©AñÆ]AW"AAˆ#¿%_Î>SH(?ü9§A4›]Aô†=AÒC©AñÆ]AW"AAâ§A;Þ^A„C=AhR¿òSº>«.3?â§A;Þ^A„C=AÒC©AñÆ]AW"AAWЩAó°`A}¥@AŒW)¿_°µ>‚")?â§A;Þ^A„C=AWЩAó°`A}¥@Aç¨A2›aA3ÃÖ4?ç¨A2›aA3Ã@Aš 0¿L–>wû)?ç¨A2›aA3Ã@Aào¨AèadAKYñã4?ào¨AèadAKY@AªA¤fAní?Ae5¿`Mk>Ô­*?ào¨AèadAKYè€5?VĨAÞ2gAÑž6+?VĨAÞ2gAÑ_¨A=|A«i_¨A=|A«i_¨A=|A«iA«¡¿¿†0?Ò.¦AÖ9ƒA´…>AæÜ§A”ñƒAK\BAM§AN…AJCAtö ¿pW ¿¨j%?Ò.¦AÖ9ƒA´…>AM§AN…AJCA¢a¥A„AVF?AÝõ¾ ¿¾.?¢a¥A„AVF?AM§AN…AJCAO¦Až†A€çCA>_ÿ¾Z¿²$?¢a¥A„AVF?AO¦Až†A€çCA¬|¤AA¼…Ak@A9ÝÞ¾-꿤R-?¬|¤AA¼…Ak@AO¦Až†A€çCAN¥A‘à‡AËÉDA0ç¾÷P ¿Y´"?¬|¤AA¼…Ak@AN¥A‘à‡AËÉDA`£AÕê†AÅAA¢_ƾbÃ!¿GØ+?`£AÕê†AÅAAN¥A‘à‡AËÉDA†×£A¢‰A$¿EAy;œ8*¿C!?`£AÕê†AÅAA†×£A¢‰A$¿EAi¢AÀ ˆATüAAo‹®¾»ð)¿&i*?i¢AÀ ˆATüAA†×£A¢‰A$¿EAðâ¢A²ô‰AÛ†FA:­¶¾ÓÁ1¿’ü?i¢AÀ ˆATüAAðâ¢A²ô‰AÛ†FA°ƒ¡AÖ݈AÈBAù ˜¾£|0¿Ä#)?°ƒ¡AÖ݈AÈBAðâ¢A²ô‰AÛ†FA¡A‹A#˜GAs¾úí8¿¥?°ƒ¡AÖ݈AÈBA¡A‹A#˜GAòE AÞ‰A ÞCAUEy¾57¿é—'?òE AÞ‰A ÞCA¡A‹A#˜GA…' AOŒA²¶HA߃€¾Ì˜?¿œ'?òE AÞ‰A ÞCA…' AOŒA²¶HA ôžA”ÈŠAdEAD&A¾ßÂ<¿… &? ôžA”ÈŠAdEA…' AOŒA²¶HA„©žAvâŒA âIA·‹F¾5E¿ñ«? ôžA”ÈŠAdEA„©žAvâŒA âIA ŽAtœ‹Aß2FA å¾ê*A¿†$? ŽAtœ‹Aß2FA„©žAvâŒA âIAA«A½KAËÚ ¾½`I¿l3? ŽAtœ‹Aß2FAA«A½KAñœAHXŒA oGAU2§½ /D¿!#?ñœAHXŒA oGAA«A½KAxõ›A—$ŽAöKA[µ½™ûK¿Å?ñœAHXŒA oGAxõ›A—$ŽAöKA’›AÊŒAJOHA[·½žF¿«þ!?’›AÊŒAJOHAxõ›A—$ŽAöKApHšAlºŽA¬9MAau½ùñM¿È?’›AÊŒAJOHApHšAlºŽA¬9MAšs™A`VA³—IAüH¢<âSG¿ÂŽ ?šs™A`VA³—IApHšAlºŽA¬9MA ˜AŽ0A#‚NA1xº<ªO¿³h?šs™A`VA³—IA ˜AŽ0A#‚NAÖ—AæÄA¹äJA´Ù›=æG¿+?Ö—AæÄA¹äJA ˜AŽ0A#‚NAÊ–A †AËÎOAòe¦=ÙO¿ ?Ö—AæÄA¹äJAÊ–A †AËÎOA©-–AÑŽA¼5LAkp–=;Âo?bz¯>ÚŽ“AéàFA:âFA¢®”ARëEA¶óHAw”AÁ˜GA-±DAhH=u6m?xâ¾>w”AÁ˜GA-±DA¢®”ARëEA¶óHA–C–AW\FAÌšGAŽöK<õ³q?¦–¨>w”AÁ˜GA-±DA–C–AW\FAÌšGA½’•AqùGAÚNCAŸ¹¼Ø9m?neÀ>½’•AqùGAÚNCA–C–AW\FAÌšGAÅ)—A¹¸FA—ÔFAÕ½–Vq?œµ©>½’•AqùGAÚNCAÅ)—A¹¸FA—ÔFA;o–A;KHA ƒBAŸm½ùzl?ìÖÁ>;o–A;KHA ƒBAÅ)—A¹¸FA—ÔFAa±˜A¥†GA™EA®ÅŽüo?tA«>;o–A;KHA ƒBAa±˜A¥†GA™EAç—AýIA$AA6 ¾iXj?LÌÃ>ç—AýIA$AAa±˜A¥†GA™EAê-šA¾ŒHAn/DA,d)¾l0m?­>ç—AýIA$AAê-šA¾ŒHAn/DA U™AîôIAžÉ?AʤE¾©äf?'ÑÅ> U™AîôIAžÉ?Aê-šA¾ŒHAn/DA¬ž›A»ÉIAÖäBAbio¾j i?\Ö®> U™AîôIAžÉ?A¬ž›A»ÉIAÖäBA¤¸šAKAjt>A…¾lb?åÇ>¤¸šAKAjt>A¬ž›A»ÉIAÖäBAýA㤸šAKAjt>AýAã.œAòsLA8%=AýAã.œAòsLA8%=A4¡A øKAòAA|ªœAD#MAŠŽ|ªœAD#MAŠŽ|ªœAD#MAŠŽAçAß»NA T;AlçžA­ªMAhß?A\ Aè†OAx½>Aþ§ë¾GfP?9Zµ>AçAß»NA T;A\ Aè†OAx½>A8ŸAþ}PA'':A>Kõ¾0eG?Þ8Ï>8ŸAþ}PA'':A\ Aè†OAx½>Aå9¡A!‹QA©=AN¿ŒlF?ñ;·>8ŸAþ}PA'':Aå9¡A!‹QA©=A,+ A:hRA†9AX“ ¿(Ó,+ A:hRA†9Aå9¡A!‹QA©=AìE¢Ao¶SAè¤,+ A:hRA†9AìE¢Ao¶SAè¤ï1¡AìyTAÞø7AìE¢Ao¶SAè¤ï1¡AìyTAÞø7A©­¢A7¤TAæ>ß—¡Aj]UA~Ž7A©­¢A7¤TAæ>ß—¡Aj]UA~Ž7AÍ•£A‚ðVA[X;A†|¢AÛ‘WAË6A*¿ñ•?{ Ö>†|¢AÛ‘WAË6AÍ•£A‚ðVA[X;Aüf¤A=UYAÈ…:AÒ4¿dx?€O½>†|¢AÛ‘WAË6Aüf¤A=UYAÈ…:A?K£AüßYAŽÁ5AÎÐ5¿ K?ãò×>?K£AüßYAŽÁ5Aüf¤A=UYAÈ…:AŸ!¥AjÑ[A{Ç9Au?¿©š ? æ¾>?K£AüßYAŽÁ5AŸ!¥AjÑ[A{Ç9AJ¤AæF\A/ú4A®ƒ@¿mö?[¦Ù>J¤AæF\A/ú4AŸ!¥AjÑ[A{Ç9AûÅ¥AÞd^Aß9AqÑI¿¢mù>u_À>J¤AæF\A/ú4AûÅ¥AÞd^Aß9A§¤AvÆ^A4H4AÁxH¿FÕÚ>§¤AvÆ^A4H4AûÅ¥AÞd^Aß9Au ¦Aù˜_A«×8Aâ×O¿l!ä>2%Á>§¤AvÆ^A4H4Au ¦Aù˜_A«×8Aë¤Aóñ_Atþ3A‹ûM¿aÿÑ>×Û>ë¤Aóñ_Atþ3Au ¦Aù˜_A«×8A ‰¦AM6bAøQ8Aû¢V¿—YÈ>ä<Â>ë¤Aóñ_Atþ3A ‰¦AM6bAøQ8Apj¥Aè}bAÚq3A÷…U¿žÂ¯>¥Ý>pj¥Aè}bAÚq3A ‰¦AM6bAøQ8Aˆñ¦AÞÝdA€ã7A¼]¿=X¥>•KÃ>pj¥Aè}bAÚq3Aˆñ¦AÞÝdA€ã7A Ó¥A~eAˆý2A¡¹[¿DHŒ>%Þ> Ó¥A~eAˆý2Aˆñ¦AÞÝdA€ã7A^C§AgAXŒ7A.zc¿'>Ä)Ä> Ó¥A~eAˆý2A^C§AgAXŒ7A&%¦AÕ¸gA«¡2AŒ`¿(JO>`øÞ>&%¦AÕ¸gA«¡2A^C§AgAXŒ7A£~§A”MjAÛL7A¡Òg¿¶±7>ÁÓÄ>&%¦AÕ¸gA«¡2A£~§A”MjAÛL7A·`¦AvhjA±^2Ah“c¿ú^>àiß>·`¦AvhjA±^2A£~§A”MjAÛL7AÏ–§A'ïkAß27Aøj¿æT>?Å>·`¦AvhjA±^2AÏ–§A'ïkAß27A y¦A$lAEC2Aß6e¿¨¯=çÄß> y¦A$lAEC2AÏ–§A'ïkAß27A­§Ag¨nAæ7A‹®k¿¢v{=ýiÅ> y¦A$lAEC2A­§Ag¨nAæ7Aq¦Aœ®nAô)2A 2f¿øËB<…ïß>q¦Aœ®nAô)2A­§Ag¨nAæ7A欧AibqA7Aý*l¿ZQ¼ú{Å>q¦Aœ®nAô)2A欧AibqA7AD¦A\qA'*2A\±e¿òS}½ Øß>D¦A\qA'*2A欧AibqA7A*–§A3tA‘37A°+k¿0D²½SÅ>D¦A\qA'*2A*–§A3tA‘37Acx¦Aö tAD2Aü±c¿tÅ ¾5~ß>cx¦Aö tAD2A*–§A3tA‘37AWh§A‚ÜvAÇd7Aܬh¿G %¾íîÄ>cx¦Aö tAD2AWh§A‚ÜvAÇd7ALJ¦AÒ»vAîw2Ax`¿nO¾æÞ>LJ¦AÒ»vAîw2AWh§A‚ÜvAÇd7A½6§AæèxAÓ™7Aùue¿š¹c¾£dÄ>LJ¦AÒ»vAîw2A½6§AæèxAÓ™7Az¦A”½xAã¯2AN¡\¿QH†¾ÌCÞ>z¦A”½xAã¯2A½6§AæèxAÓ™7Amá¦A–{A–ô7ASÊ`¿^“¾Ð¶Ã>z¦A”½xAã¯2Amá¦A–{A–ô7AèÂ¥AÉ[{A‰3A-¯V¿Ï©¾@Ý>èÂ¥AÉ[{A‰3Amá¦A–{A–ô7Afu¦Aï9~A¢f8A eZ¿þض¾Ì¾Â>èÂ¥AÉ[{A‰3Afu¦Aï9~A¢f8AÌV¥AŠï}A˜‡3AZdO¿“,̾€Ü>ÌV¥AŠï}A˜‡3Afu¦Aï9~A¢f8Aò¥AVj€Að8A<¨R¿š)Ù¾˜Á>ÌV¥AŠï}A˜‡3Aò¥AVj€Að8A¸Ó¤AW<€A 4AËÇF¿+Gí¾›Ú>¸Ó¤AW<€A 4Aò¥AVj€Að8A¥V¥Aê²Aù9AB™I¿¢6ú¾ FÀ>¸Ó¤AW<€A 4A¥V¥Aê²Aù9Aø8¤AO{AÁ4A$=¿‹”¿,Ù>ø8¤AO{AÁ4A¥V¥Aê²Aù9AƒÄ¤A0¼‚Aµ&:AK@¿ ¿uô¾>ø8¤AO{AÁ4AƒÄ¤A0¼‚Aµ&:Aç§£A|‚Aÿ]5A„á3¿bÕ¿°”×>ç§£A|‚Aÿ]5AƒÄ¤A0¼‚Aµ&:A1ÿ£AóƒA›î:Aö5¿õ ¿˜€½>ç§£A|‚Aÿ]5A1ÿ£AóƒA›î:A˜ä¢Aû§ƒA>/6AD(¿ûá ¿÷¾Õ>˜ä¢Aû§ƒA>/6A1ÿ£AóƒA›î:Ai#£Aï…A[Ê;A:·)¿'¿-Ö»>˜ä¢Aû§ƒA>/6Ai#£Aï…A[Ê;A ¢AOÇ„Aà7A0¿×â-¿uÐÓ> ¢AOÇ„Aà7Ai#£Aï…A[Ê;A±0¢AF<†A¸¹Â ¢AOÇ„Aà7A±0¢AF<†A¸¹¡A~Ù…AŽ8A±0¢AF<†A¸¹¡A~Ù…AŽ8Ap&¡AM‡A‹¼=A" A§Ý†A9Aèÿ¾½ÝC¿®ÙÏ>" A§Ý†A9Ap&¡AM‡A‹¼=AcK AˆA¿Ž>A?°¿;ïH¿î«¶>" A§Ý†A9AcK AˆA¿Ž>ABŸA»™‡Aö9Aß<æ¾UL¿ˆÎ>BŸA»™‡Aö9AcK AˆA¿Ž>AYŸA‰A¸­?Aõ»æ¾pÚQ¿¼ù´>BŸA»™‡Aö9AYŸA‰A¸­?A¾žA«}ˆA… ;AtÀƾü»T¿\Ì>¾žA«}ˆA… ;AYŸA‰A¸­?A•ÚA'à‰AâÙ@AɊƾ9QZ¿‚³>¾žA«}ˆA… ;A•ÚA'à‰AâÙ@A"âœAÍL‰A™W"âœAÍL‰A™W"âœAÍL‰A™Wd˜›ATŠAE›=A/†œAh¦ŠA³BA.›AU‹A²WCAÒƒ¾Þhg¿h]¯>d˜›ATŠAE›=A.›AU‹A²WCA˜=šA1©ŠAë>AÔNL¾ƒf¿UçÅ>˜=šA1©ŠAë>A.›AU‹A²WCA½šAx¿‹Aï˜=šA1©ŠAë>A½šAx¿‹AïnF™Aè ‹A‹×?A½šAx¿‹AïnF™Aè ‹A‹×?AࡘAZAŒA0EA!Ø—A‹A2AAr0¡½Ñùk¿ `Â>!Ø—A‹A2AAࡘAZAŒA0EA—A§ŒAÉáFA,ï’½`­p¿¯ª>!Ø—A‹A2AA—A§ŒAÉáFA™`–AhÝ‹AŸBAÕþ3¼5m¿wÀ>™`–AhÝ‹AŸBA—A§ŒAÉáFA?‰•A´ïŒA:HA',»ö«q¿íá¨>™`–AhÝ‹AŸBA?‰•A´ïŒA:HAoà”A7ŒAŒòCA•§>5¨‘>Ǭf?¿g¡AOlŸARþRA„4ŸAf AA?TAöæžA¸A{ÇUA-8 >w“>”±g?öæžA¸A{ÇUA„4ŸAf AA?TA8œA†’ AjïUAbjš>gw>õl?öæžA¸A{ÇUA8œA†’ AjïUA?œA¦FžA^WA”*•>ät•>î6i??œA¦FžA^WA8œA†’ AjïUAx@™A è Aq™WAoý>:äz>±_m??œA¦FžA^WAx@™A è Aq™WAÏ3™AžŸžAø÷XA–2Ž>âz–>ò"j?Ï3™AžŸžAø÷XAx@™A è Aq™WA&0™Aãé A—¢WA'¼‰>Í®–>Åj?Ï3™AžŸžAø÷XA&0™Aãé A—¢WA³–A`¡A5XYAê-‡>œ}>ò«n?³–A`¡A5XYA‹I–AÈÁžAœ”ZAÏ3™AžŸžAø÷XAéˆ>' C>sÏq?Ï3™AžŸžAø÷XA‹I–AÈÁžAœ”ZAEM–AæTžA~¯ZA“ýŠ>5A>¬»s?Ï3™AžŸžAø÷XAEM–AæTžA~¯ZA4™AWCœA.¢YAï‰>½½=Í‚u?4™AWCœA.¢YAEM–AæTžA~¯ZA^–A^jœA¢([A0–‰>/È =¢lv?4™AWCœA.¢YA^–A^jœA¢([AÞ\–AºŽ›A [AЈ>ª¨ƒ¼¨v?Þ\–AºŽ›A [AÓï˜A|â™ArYA4™AWCœA.¢YA"ã†>sèM½ãžv?4™AWCœA.¢YAÓï˜A|â™ArYAsy›Ak†™A%-XA䯉> •íºµ‘v?4™AWCœA.¢YAsy›Ak†™A%-XA9Ó›A³è›AÅXAv¿…>v$]½g¹v?9Ó›A³è›AÅXAsy›Ak†™A%-XAÎöA;û˜A¶ÀVA(FŠ>9™´»Â{v?9Ó›A³è›AÅXAÎöA;û˜A¶ÀVA=|žA«[›AöžVAAS„>qHk½iÝv?=|žA«[›AöžVAÎöA;û˜A¶ÀVAäf A¸A˜AÑXUAØ•Š>’¼»nv?=|žA«[›AöžVAäf A¸A˜AÑXUA0¡AAp#UAƒ>Z*w½¾þv?0¡AAp#UAäf A¸A˜AÑXUAh ¢AѦ—AgcTA¹ÕŠ>ŒF¼cv?0¡AAp#UAh ¢AѦ—AgcTAÝ¢Aeü™AT TAŸE>¿½Š0w?Ý¢Aeü™AT TAh ¢AѦ—AgcTAI`¤A¡–AaSAëxŠ>Ë x¼Ýmv?Ý¢Aeü™AT TAI`¤A¡–AaSA½[¥Aþë˜Aq°RAö8~>/‘„½Tnw?½[¥Aþë˜Aq°RAI`¤A¡–AaSAI˜¦A›t•AJ¸QAÌ Š>;&–¼Ðyv?½[¥Aþë˜Aq°RAI˜¦A›t•AJ¸QA·¾§Ar°—A®MQA¾ny>oý‡½Ü´w?·¾§Ar°—A®MQAI˜¦A›t•AJ¸QAµ¨A‰!”A¤vPA@W‰>ïO­¼óŽv?·¾§Ar°—A®MQAµ¨A‰!”A¤vPA”ªAGK–AžøOA{7t>û‰½‘x?”ªAGK–AžøOAµ¨A‰!”A¤vPA¶ªAr©’A COAæeˆ>½æÀ¼Ì¬v?”ªAGK–AžøOA¶ªAr©’A COA»/¬A„½”Aå±NAJYo>ÑŠ½—Mx?»/¬A„½”Aå±NA¶ªAr©’A COAz+¬A4q‘A§aNA^‘‡>-«Ï¼Çv?»/¬A„½”Aå±NAz+¬A4q‘A§aNAÀíA8r“A'ÂMAº,j>1ƒ‰½_Ÿx?ÀíA8r“A'ÂMAz+¬A4q‘A§aNAWô­AоA LMAQ9†>ŽÝؼôv?ÀíA8r“A'ÂMAWô­AоA LMA³¯Aó£‘AhšLA}8d>[ņ½æýx?³¯Aó£‘AhšLAWô­AоA LMAÿ—¯ASòA>KLAÈ„>»qß¼‰$w?³¯Aó£‘AhšLAÿ—¯ASòA>KLA {±Ab¸AXˆKA^8^>K!‚½‹^y? {±Ab¸AXˆKAÿ—¯ASòA>KLAݱA& ŒAe_KA=ƒ>yà¼Yw? {±Ab¸AXˆKAݱA& ŒAe_KAò³Aù°A8ŒJA;FX>ïw½†¿y?ò³Aù°A8ŒJAݱA& ŒAe_KAq²A?ŠAʈJA½£>±¾Û¼w?ò³Aù°A8ŒJAq²A?ŠAʈJA•´A°Ž‹Ai¦IAóR>Äóg½Õz?•´A°Ž‹Ai¦IAq²A?ŠAʈJA4s³AÅZˆAþçIAïI€>jjÔ¼¤¾w?•´A°Ž‹Ai¦IA4s³AÅZˆAþçIA诵A¸‰A÷ùHAóòM>FÙT½ujz?诵A¸‰A÷ùHA4s³AÅZˆAþçIAk‡´AD9†A;IAÚ}>·ļ¯ôw?诵A¸‰A÷ùHAk‡´AD9†A;IAdÞ¶Aäk‡AH@HAGÜH>ë<½º¿z?dÞ¶Aäk‡AH@HAk‡´AD9†A;IA)rµA* „A~§HAý—z>¨o¯¼Ë'x?dÞ¶Aäk‡AH@HA)rµA* „A~§HAéß·A…A‹¡GA‹YD>Z½!½Ù {?éß·A…A‹¡GA)rµA* „A~§HAS4¶A2ÔAî,HAx>Æ×•¼§Ux?éß·A…A‹¡GAS4¶A2ÔAî,HA?µ¸AU«‚AGA¤ƒ@>× ½ðL{??µ¸AU«‚AGAS4¶A2ÔAî,HAcζAx#AaËGAâÍu>'µo¼¥|x??µ¸AU«‚AGAcζAx#AaËGA¾^¹AZ8€Ag´FA³=>hPμw|{?¾^¹AZ8€Ag´FAcζAx#AaËGA?(·A«{AY’GAact>]=¼´•x?¾^¹AZ8€Ag´FA?(·A«{AY’GA²Á¹Aµ¬|AàvFA>°;>G“‘¼:Ÿ{?²Á¹Aµ¬|AàvFA?(·A«{AY’GAw{·A wAq]GAH$s>ÚAê» ¬x?²Á¹Aµ¬|AàvFAw{·A wAq]GAiºAfwAÅ=FA7-:>0÷¼¹{?iºAfwAÅ=FAw{·A wAq]GAÕ¤·Ag[rACGAílr>}&»¼¸x?iºAfwAÅ=FAÕ¤·Ag[rACGAKºA¶rAX!FAw¢9>£( ¹Â{?KºA¶rAX!FAÕ¤·Ag[rACGA%¥·A·mAëBGATr>µå ;Oºx?KºA¶rAX!FA%¥·A·mAëBGA\KºAJ„mA !FAþ:>Pü<|º{?\KºAJ„mA !FA%¥·A·mAëBGA¤|·A“iA²\GAEÚr>•ß;¹°x?\KºAJ„mA !FA¤|·A“iA²\GAµºAC{hAö—D<ì¨{?µºAC{hAöi"<ó¤x?µºAC{hAö@¹<à‹{?Iî¹A‘xeA[FA·P·AòNfA¢xGA<å¶A2©aAâ¼GApôt>3d<ÀŠx?Iî¹A‘xeA[FA<å¶A2©aAâ¼GAæw¹AJm`AŤFA¡£?>­¡ü<]Z{?æw¹AJm`AŤFA<å¶A2©aAâ¼GA]Q¶Aö]A‘HAûv>Ī’V‚=\{?-Õ¸Aó|[AÆ GA]Q¶Aö]A‘HAd•µAá£XAJ‘HA.vy>ˆB¯<:x?-Õ¸Aó|[AÆ GAd•µAá£XAJ‘HA˜¸A~§VA¤‰GAå·G>žÖ9= Ðz?˜¸A~§VA¤‰GAd•µAá£XAJ‘HA±´A:DTAñ IAQ|>ú7Ç<]x?˜¸A~§VA¤‰GA±´A:DTAñ IA ·AíQA,$HA`K>zL=“z? ·AíQA,$HA±´A:DTAñ IAÚ8´A3CRA]lIA^ï}>ž.Ï€ž]=mQz?Kˆ¶AàÃOA8uHAÚ8´A3CRA]lIAb³A¼þMA‡"JA‚€>½á<‚´w?Kˆ¶AàÃOA8uHAb³A¼þMA‡"JAIIµAÙ*KAÅ8IAÛÿT>T”q=éñy?IIµAÙ*KAÅ8IAb³A¼þMA‡"JA­Ì±AÚèIAÞîJAò1‚>lë<Ãyw?IIµAÙ*KAÅ8IA­Ì±AÚèIAÞîJA<â³A²ÆFAÃJAûZ>#¿€=9y?<â³A²ÆFAÃJA­Ì±AÚèIAÞîJAé^°AØFAæÐKAàƒ>—Ïï<¿?w?<â³A²ÆFAÃJAé^°AØFAæÐKA‰S²A²—BAœKA{a>»³†=n+y?‰S²A²—BAœKAé^°AØFAæÐKAÌ®A9KBAJÈLA¾€…>¦Yî<+w?‰S²A²—BAœKAÌ®A9KBAJÈLAK°AjŸ>AÛ LAµwe>ãE‰=æx?K°AjŸ>AÛ LAÌ®A9KBAJÈLAî®A™Í@Aº5MA¹+†>W!ç<¹òv?K°AjŸ>AÛ LAî®A™Í@Aº5MAËÚ¯AI=A›‚LA2Õi>)΋=iŸx?ËÚ¯AI=A›‚LAî®A™Í@Aº5MAÀL¬AÁX=AMNAÛ¤‡>ØŸâ<=Àv?ËÚ¯AI=A›‚LAÀL¬AÁX=AMNAÈç­AmZ9A´¬MA·Úo>,=«@x?Èç­AmZ9A´¬MAÀL¬AÁX=AMNAÚbªA+:A uOA½òˆ>PãÓ!‘Œ=Nèw?¶Õ«AGû5A#çNAÚbªA+:A uOAÓ[¨A`E7Aå«PAÒ Š>2ªÀ”lŠ=N—w?Q¥©AKë2A1PAÓ[¨A`E7Aå«PAA8¦Aw©4A#ñQAÙãŠ>YŒ©< Xv?Q¥©AKë2A1PAA8¦Aw©4A#ñQAUW§A@,0Aè‰QA™j~>¡?‡=Vew?UW§A@,0Aè‰QAA8¦Aw©4A#ñQA0¥AÒŒ3ARAž‹>nN—<«Vv?UW§A@,0Aè‰QA0¥AÒŒ3ARA;¦A©/A/RAi>ò¬„=R/w?;¦A©/A/RA0¥AÒŒ3ARA3à¢A›_1AkèSAK«‹>„Î<áAv?;¦A©/A/RA3à¢A›_1AkèSA@¿£Ap»,AdžSA‡ƒ>²d~=æóv?@¿£Ap»,AdžSA3à¢A›_1AkèSA× A/A^JUAF׋>ÞG<#?v?@¿£Ap»,AdžSA× A/A^JUAë2¡A¤×*A/UADí„>µ…q=±Âv?ë2¡A¤×*A/UA× A/A^JUA!žA¦.A+²VAš¹‹>Õ: <Fv?ë2¡A¤×*A/UA!žA¦.A+²VAR—žAV)A£VAës†>Lc=u›v?R—žAV)A£VA!žA¦.A+²VA>’›A(ü,AXAS‹>—_“;,Vv?R—žAV)A£VA>’›A(ü,AXA²í›A›7(AêXA+M‡> áU=”‰v?²í›A›7(AêXA>’›A(ü,AXA šA%„,AóXAÒ¢Š>ù6à:®ov?²í›A›7(AêXA šA%„,AóXAk_šAPÀ'AïXAýEˆ>îJ=Aqv?k_šAPÀ'AïXA šA%„,AóXAk—A,AôcZA$Š>¿Íº}v?k_šAPÀ'AïXAk—A,AôcZA°¦—AB'AÌrZAžÉˆ>$ºp<‚ªv?°¦—AB'AÌrZAk—A,AôcZAÞ\–A‹â(A [A1‰>’@½À|v?°¦—AB'AÌrZAÞ\–A‹â(A [A^–AE+'A¢([Aˇ>îpƒ½Ov?Þ\–AºŽ›A [AÊZ–A,šA[AÓï˜A|â™ArYA!à†>/ú½Àøt?Óï˜A|â™ArYAÊZ–A,šA[AL–A(ɘAâ¦ZAö?ƒ>ÕÆ0¾–ws?Óï˜A|â™ArYAL–A(ɘAâ¦ZA´©˜A–Š—AÞéXAïÏ‚>E·`¾" q?´©˜A–Š—AÞéXAL–A(ɘAâ¦ZAÐ?–A[º—AkNZA×€>6¾}m?´©˜A–Š—AÞéXAÐ?–A[º—AkNZAa–Av–AtGYAØt>Ï[¦¾Ž>j?a–Av–AtGYAcM˜AøH•Aq‹WA´©˜A–Š—AÞéXAóÃa>ƪ®¾îi?´©˜A–Š—AÞéXAcM˜AøH•Aq‹WAPšAì”A©5VAlòc>OA—¾¤×m?´©˜A–Š—AÞéXAPšAì”A©5VAô›A¥-—A݈WA>äI>Ù{°¾eój?ô›A¥-—A݈WAPšAì”A©5VAº¨œAQf”AäTAMfO>éØ˜¾íÂn?ô›A¥-—A݈WAº¨œAQf”AäTAÂYAÕ¤–Aô+VAa1> Z±¾€l?ÂYAÕ¤–Aô+VAº¨œAQf”AäTA·ÂžAѸ“Ay—SAy8:>¿š™¾¦ºo?ÂYAÕ¤–Aô+VA·ÂžAѸ“Ay—SA'žŸAñ•AÉÓTA6A>]±¾Üýl?'žŸAñ•AÉÓTA·ÂžAѸ“Ay—SAÇ- A*“A µRA])>´¦™¾q€p?'žŸAñ•AÉÓTAÇ- A*“A µRAw&¡A \•AUéSAÒœ>ú{°¾]ñm?w&¡A \•AUéSAÇ- A*“A µRA:+¢A@<’A–tQAU%>¸Î˜¾Œxq?w&¡A \•AUéSA:+¢A@<’A–tQAãM£AKb”AôÐ=E1”¾v¥s?M[¥Aöy?Âþ®AtŠAÚXKAu®AÑ;‡A1·IA):°A⛈AoŽJA{N˜½çl¾~Sx?):°A⛈AoŽJAu®AÑ;‡A1·IAûÔ®AöÅ…A&IAVñ½J¾ŒÏz?):°A⛈AoŽJAûÔ®AöÅ…A&IAÈ$±Aô‡AúöIAl3º½î…V¾Ý¾#õz?ýó²A· ƒAªÉHA]w°AׂAHAw±As>€A‹™GA¦Ñ–½ŠG¾Ä/}?ýó²A· ƒAªÉHAw±As>€A‹™GA‡£³ACA§VHAh— ¾JŒ¾y¢{?‡£³ACA§VHAw±As>€A‹™GA‹’±At¯|A€BGAËx«½>KнÙÄ}?‡£³ACA§VHA‹’±At¯|A€BGA›.´Aûß}A3ûGA¯Ê¾•ǽí|?›.´Aûß}A3ûGA‹’±At¯|A€BGAWÛ±AÅyA¯GAµ;¹½Nž¡½*&~?›.´Aûß}A3ûGAWÛ±AÅyA¯GA¤´Aé°zAÆÅGAÚ¾mä½Ý{|?¤´Aé°zAÆÅGAWÛ±AÅyA¯GAª²AÀÝuA•àFA×0Ľá>V½yx~?¤´Aé°zAÆÅGAª²AÀÝuA•àFA£Ê´AxkvA=”GA*ù¾ƒ½×À|?£Ê´AxkvA=”GAª²AÀÝuA•àFA@²AðøqA*ÉFA€$˽õ†¾¼þª~?£Ê´AxkvA=”GA@²AðøqA*ÉFAäï´Aª(rAš{GAœá¾öß’»˜Û|?äï´Aª(rAš{GA@²AðøqA*ÉFAW@²AvnAüÈFAý¿Ì½ ôÁ;¶~?äï´Aª(rAš{GAW@²AvnAüÈFA-ð´A2èmAi{GAsξ]cé<*Ì|?-ð´A2èmAi{GAW@²AvnAüÈFA²AD5jAëßFAh ɽm`=!›~?-ð´A2èmAi{GA²AD5jAëßFA³Ë´AT©iAŠ“GA¾ˆìf=õ›|?³Ë´AT©iAŠ“GA²AD5jAëßFAü±A´âgAÈøFA:výfíc=Ôn~?³Ë´AT©iAŠ“GAü±A´âgAÈøFA¤´AùgA±­GA1ê¾V)¥=Š\|?¤´AùgA±­GAü±A´âgAÈøFA¥±A|ücA•5GA4¸½š¤¥=,~?¤´AùgA±­GA¥±A|ücA•5GA8C´A×ÛbAžíGAù0¾Aæ=á{?8C´A×ÛbAžíGA¥±A|ücA•5GA-±A­'`A%‰GA¿Û¦½D5Þ=î¡}?8C´A×ÛbAžíGA-±A­'`A%‰GAÁ½³A­^AnEHA̾ù<>ÔA{?Á½³A­^AnEHA-±A­'`A%‰GA”°Aic\A:óGAÈ‘½N >ñ}?Á½³A­^AnEHA”°Aic\A:óGAÛ³AÔ‘ZAÑ´HAÌé½uÁ/>‰€z?Û³AÔ‘ZAÑ´HA”°Aic\A:óGA§Ù¯Av¯XAØsHAŸm½7p#> H|?Û³AÔ‘ZAÑ´HA§Ù¯Av¯XAØsHA+E²ANŠVAÀ;IAu|н'EF>ºÌy?+E²ANŠVAÀ;IA§Ù¯Av¯XAØsHA4w¯AËûVAz·HAÏ“I½y2>JÄ{?+E²ANŠVAÀ;IA4w¯AËûVAz·HA,رAò°TA¨‚IA‰¸½†èW>ð-y?,رAò°TA¨‚IA4w¯AËûVAz·HAЇ®AôXSA#[IAdù½õÏE>#{?,رAò°TA¨‚IAЇ®AôXSA#[IA‹Ï°A?¿PA.JA² ‘½ãëp>£%x?‹Ï°A?¿PA.JAЇ®AôXSA#[IAªx­A^ÙOA2JA¹ð•¼×ÚZ>y z?‹Ï°A?¿PA.JAªx­A^ÙOA2JAv¤¯A-öLA¬îJAO½ »ƒ> w?v¤¯A-öLA¬îJAªx­A^ÙOA2JA’I¬AP}LAWßJA8E§9.§m>™y?v¤¯A-öLA¬îJA’I¬AP}LAWßJAìV®A VIAÄKAÇbê¼–Ä>·áu?ìV®A VIAÄKA’I¬AP}LAWßJA&úªA3FIAf¿KAŸ:¤<ƒ6~>Éîw?ìV®A VIAÄKA&úªA3FIAf¿KAªæ¬AHàEAç­LA ›/¼Õ”>ît?ªæ¬AHàEAç­LA&úªA3FIAf¿KAdªASúGAµ"LAzë=œzƒ>ªGw?ªæ¬AHàEAç­LAdªASúGAµ"LA¶B¬Aé{DAzMAå©”;]ç™>j(t?¶B¬Aé{DAzMAdªASúGAµ"LAÞâ¨AQõDA!MA¡ŸK=òöˆ>wWv?¶B¬Aé{DAzMAÞâ¨AQõDA!MA±œªA¸?AA‘NAñiîkçr?±œªA¸?AA‘NAÞâ¨AQõDA!MAQF§A›)BA©.NA],’=S†Ž>œ3u?±œªA¸?AA‘NAQF§A›)BA©.NA^Ú¨AƒC>A7OAE[]=Ó¶¦>.§q?^Ú¨AƒC>A7OAQF§A›)BA©.NA7¥AC˜?AÍJOAàù¾=<ê’>æt?^Ú¨AƒC>A7OA7¥AC˜?AÍJOA+ü¦A1ˆ;Ay^PAº>¢=)0«>²ip?+ü¦A1ˆ;Ay^PA7¥AC˜?AÍJOAã½£ArC=AñtPAûë=a1–>ôr?+ü¦A1ˆ;Ay^PAã½£ArC=AñtPA¥AÓ9A ”QAé“Ë=¯ñ­>Élo?¥AÓ9A ”QAã½£ArC=AñtPA­Ü¢A\C,¶—>JEr?¥AÓ9A ”QA­Ü¢A\Ce n?9¤Ac8A¬(RA­Ü¢A\C™>iZq?9¤Ac8A¬(RAŠâ A$J:A¸CRAüé¡AÞí5AísSAé >D!±>~pm?üé¡AÞí5AísSAŠâ A$J:A¸CRA/ØžAž8A!ŠSA¥2->¦Ñ™>ÝMp?üé¡AÞí5AísSA/ØžAž8A!ŠSAVµŸAO.4AøÅTAªa*>¸“±>Ml?VµŸAO.4AøÅTA/ØžAž8A!ŠSA˜¾œAÇ?7A«ÖTAÏB>K™™>”Mo?VµŸAO.4AøÅTA˜¾œAÇ?7A«ÖTATqA Ã2A VA³$C>ùü°>M6k?TqA Ã2A VA˜¾œAÇ?7A«ÖTAË–šAË06A“(VAÉÒW>)€˜>‘Yn?TqA Ã2A VAË–šAË06A“(VA›A¤­1AW{WA¢vW>±Å¯>tTj?›A¤­1AW{WAË–šAË06A“(VAS™A”¹5A>íVA{f>YB—>Ù¶m?›A¤­1AW{WAS™A”¹5A>íVAï™AŽ51AƒFXAÜh>P®>™i?ï™AŽ51AƒFXAS™A”¹5A>íVA¸—Aç,5AèCXAÌ–w>f"•>¿òl?ï™AŽ51AƒFXA¸—Aç,5AèCXAk`—AB¬0AG¨YA¬w|>[¥>têi?k`—AB¬0AG¨YA¸—Aç,5AèCXAa–AÏ3AtGYAÑF‚>轌>Ê\m?k`—AB¬0AG¨YAa–AÏ3AtGYAÐ?–AJ‹0AkNZA:u>½¾ñ×e?a–Av–AtGYAº –Aá{•AëäXAcM˜AøH•Aq‹WAÿ?o>clؾ†)`?cM˜AøH•Aq‹WAº –Aá{•AëäXA'Ì•AV“A² WA˜]>i3ð¾%8[?cM˜AøH•Aq‹WA'Ì•AV“A² WAðÜ—Az*“Aò‰UAo_>ü•¿vüT?ðÜ—Az*“Aò‰UA'Ì•AV“A² WA›Å•AB_“ArÜVAAOH>ÜÔ¿ÏvN?ðÜ—Az*“Aò‰UA›Å•AB_“ArÜVAÚZ—A*;‘AÎðRAtÌL>N›¿ôG?ÚZ—A*;‘AÎðRA›Å•AB_“ArÜVAi•A@p‘AS@TA'ÇC>ˆh#¿Gã>?ÚZ—A*;‘AÎðRAi•A@p‘AS@TAó^•AnH‘A•÷SA®Ì(>†ƒ-¿/o7?ó^•AnH‘A•÷SAÊ–A †AËÎOAÚZ—A*;‘AÎðRA ¦÷=*™6¿d¼0?ÚZ—A*;‘AÎðRAÊ–A †AËÎOA ˜AŽ0A#‚NA¾¿ð=h¿-¿ü•9?ÚZ—A*;‘AÎðRA ˜AŽ0A#‚NA:A™A»áA ¥QAcçŽ=:õ6¿£*2?:A™A»áA ¥QA ˜AŽ0A#‚NApHšAlºŽA¬9MAj6=Íä-¿6 ;?:A™A»áA ¥QApHšAlºŽA¬9MAw›A@eA“]PA•<R6¿ð¥3?w›A@eA“]PApHšAlºŽA¬9MAxõ›A—$ŽAöKAæÛ¢<-¿Î­Aæ§qA¡¾BAο¿æ!¼™WI?">­Aæ§qA¡¾BAÊ«AéˆqA:„?Aú«AƒnA„?Anm¿3 '<ÌøQ?">­Aæ§qA¡¾BAú«AƒnA„?AX>­A enAu¾BA€¤¿ÐÁR=2FI?X>­A enAu¾BAú«AƒnA„?A—øªAó}kANš?A¡”¿M8=»ÕQ?X>­A enAu¾BA—øªAó}kANš?AÆ#­Aû"kAvÔBAE¿ÿÔ=ÁI?Æ#­Aû"kAvÔBA—øªAó}kANš?AÞªAÀ®iAo²?A®:¿ô0ä=_’Q?Æ#­Aû"kAvÔBAÞªAÀ®iAo²?Aê­AY/iARìBAÆ8¿-Z>>ÀH?ê­AY/iARìBAÞªAÀ®iAo²?AªA¤fAní?Aªš ¿™ô%>)2Q?ê­AY/iARìBAªA¤fAní?A#À¬A”çeA­&CAýe¿p‰U>ƒ*H?#À¬A”çeA­&CAªA¤fAní?A;CªA!¥cA‡>@AN† ¿-ç_>´ŠP?#À¬A”çeA­&CA;CªA!¥cA‡>@AY^¬Aä¬bAêvCA#_¿x@ˆ>lgG?Y^¬Aä¬bAêvCA;CªA!¥cA‡>@AWЩAó°`A}¥@A@N¿.Ï‹>q¶O?Y^¬Aä¬bAêvCAWЩAó°`A}¥@A`á«A-~_AÑÜCA2 ¿®†¤>CzF?`á«A-~_AÑÜCAWЩAó°`A}¥@AÒC©AñÆ]AW"AAjÿû¾•s¦>±¸N?`á«A-~_AÑÜCAÒC©AñÆ]AW"AA¢H«AêZ\ApXDA8g¿å¦º>KE?¢H«AêZ\ApXDAÒC©AñÆ]AW"AAhù¨Ao\AdAADþò¾rǶ> ÷M?¢H«AêZ\ApXDAhù¨Ao\AdAAÊ÷ªAÜèZAy™DA£#¿õ¤Ë>»ØD?Ê÷ªAÜèZAy™DAhù¨Ao\AdAAâC¨AŽYAéBA!«å¾:;Ë>ùþL?Ê÷ªAÜèZAy™DAâC¨AŽYAéBA±2ªAÐWAí6EAÖ—î¾ä>êC?±2ªAÐWAí6EAâC¨AŽYAéBAVu§AÅVA¥µBA‚Ô¾±[â>@©K?±2ªAÐWAí6EAVu§AÅVA¥µBAžR©AbÒTA!èEA¤=Û¾8€û>L.B?žR©AbÒTA!èEAVu§AÅVA¥µBA\¦A´TAï{CAÏÁ¾î÷>â;J?žR©AbÒTA!èEA\¦A´TAï{CA.W¨AïïQAÒ¬FA[ƾÄ;?Ê·@?.W¨AïïQAÒ¬FA\¦A´TAï{CAd‹¥AÒQA›UDA󇬾‡l?½ºH?.W¨AïïQAÒ¬FAd‹¥AÒQA›UDAÔ?§A*OAÜ„GA¨Ã´¾„ì?s??Ô?§A*OAÜ„GAd‹¥AÒQA›UDAò¥AÚsPA¶DA¾žÏ ?¾G?Ô?§A*OAÜ„GAò¥AÚsPA¶DAæÂ¦AÏ NA«äGA¿J¦¾g??‡>?æÂ¦AÏ NA«äGAò¥AÚsPA¶DA<í£AôNAO­EA &¾¿v?«{F?æÂ¦AÏ NA«äGA<í£AôNAO­EAÚ¥AvkKA;ÚHA޾Gy?®êAX˜QA¬ïÄ=ñ6?L`1?ºS™AØD>AX˜QAE ˜A̦AAguNAuœ—AŽ:AAÐ4OA}éô=2Å-?Åz9?ºS™AØD>AX˜QAuœ—AŽ:AAÐ4OA½<˜AXÓ=A:WRA€D>a6?³c0?½<˜AXÓ=A:WRAuœ—AŽ:AAÐ4OAÓ•A´@AY‚PA %>ûÓ,?"K8?½<˜AXÓ=A:WRAÓ•A´@AY‚PAÐQ–AœG=Aî£SAí»:>‡ð,?µã6?ÐQ–AœG=Aî£SAÓ•A´@AY‚PAó^•A$o=A•÷SAáöK>¼#?Ä›>?ÐQ–AœG=Aî£SAó^•A$o=A•÷SAi•A=AS@TAeØ.>)6¿Ž“.?ó^•AnH‘A•÷SAú”A£¹AQAÊ–A †AËÎOA@#>•7@¿$?Ê–A †AËÎOAú”A£¹AQAa×”ATA/%PAQV>šÚH¿-=?Ê–A †AËÎOAa×”ATA/%PA©-–AÑŽA¼5LA#Ñ >EøO¿Q!?©-–AÑŽA¼5LAa×”ATA/%PAöz”A÷DŽA5ŠMAXIý=üKX¿ù9?©-–AÑŽA¼5LAöz”A÷DŽA5ŠMA0;”A=½Aù½KAàõ¸=Ç7_¿,`ö>0;”A=½Aù½KA?‰•A´ïŒA:HA©-–AÑŽA¼5LA™×"=èèb¿&,ì>©-–AÑŽA¼5LA?‰•A´ïŒA:HA—A§ŒAÉáFA_ß=OÞ\¿Á(?©-–AÑŽA¼5LA—A§ŒAÉáFAÖ—AæÄA¹äJAóʼvb¿©kî>Ö—AæÄA¹äJA—A§ŒAÉáFAࡘAZAŒA0EAB ô¼µ.\¿æ_?Ö—AæÄA¹äJAࡘAZAŒA0EAšs™A`VA³—IARÿ¶½Æ`¿¢¾ð>šs™A`VA³—IAࡘAZAŒA0EA½šAx¿‹Aï’›AÊŒAJOHA½šAx¿‹AïñœAHXŒA oGA.›AU‹A²WCA/†œAh¦ŠA³BAáAK¾ƒ:T¿ÙÖ?ñœAHXŒA oGA/†œAh¦ŠA³BA ŽAtœ‹Aß2FA ï…¾âéU¿ßR÷> ŽAtœ‹Aß2FA/†œAh¦ŠA³BA•ÚA'à‰AâÙ@AÏ…¾ùN¿T,? ŽAtœ‹Aß2FA•ÚA'à‰AâÙ@A ôžA”ÈŠAdEAܘ¥¾¤ŒO¿DÔù> ôžA”ÈŠAdEA•ÚA'à‰AâÙ@AYŸA‰A¸­?AÀ£¾*}H¿&„? ôžA”ÈŠAdEAYŸA‰A¸­?AòE AÞ‰A ÞCA¢gľŽîG¿gXü>òE AÞ‰A ÞCAYŸA‰A¸­?AcK AˆA¿Ž>AŠžÁ¾WÃ@¿Ý ?òE AÞ‰A ÞCAcK AˆA¿Ž>A°ƒ¡AÖ݈AÈBAGêß¾ìÑ?¿5œþ>°ƒ¡AÖ݈AÈBAcK AˆA¿Ž>Ap&¡AM‡A‹¼=A‡ Ú¾‚M9¿8ø ?°ƒ¡AÖ݈AÈBAp&¡AM‡A‹¼=Ai¢AÀ ˆATüAAUNø¾•i7¿Äa?i¢AÀ ˆATüAAp&¡AM‡A‹¼=A±0¢AF<†A¸¹Aˆ -¿ò¿gÚ?Ò.¦AÖ9ƒA´…>AƒÄ¤A0¼‚Aµ&:A¥V¥Aê²Aù9A2A(¿jàþ¾lÝ?Ò.¦AÖ9ƒA´…>A¥V¥Aê²Aù9A‹Æ¦A#‚A›õ=A;î5¿!Bñ¾ð¼?‹Æ¦A#‚A›õ=A¥V¥Aê²Aù9Aò¥AVj€Að8AuE1¿X¡â¾%Ø?‹Æ¦A#‚A›õ=Aò¥AVj€Að8A±g§AYÊ€AåZ=AÌÙ>¿â§Ñ¾?Ÿ?±g§AYÊ€AåZ=Aò¥AVj€Að8Afu¦Aï9~A¢f8A·©9¿]<þdÀ?±g§AYÊ€AåZ=Afu¦Aï9~A¢f8A˜ï§AGÚ~A×_¨A=|A«i_¨A=|A«i_¨A=|A«i<Š>?1©A…qqAs™;A­§Ag¨nAæ7AM1©AÀ™nAE™;AS›W¿6Êt=’+ ?M1©AÀ™nAE™;A­§Ag¨nAæ7AÏ–§A'ïkAß27AIO¿ z¨=²"?M1©AÀ™nAE™;AÏ–§A'ïkAß27A^©AªÂkA3°;AV¿ù=Mö?^©AªÂkA3°;AÏ–§A'ïkAß27A£~§A”MjAÛL7AŠhM¿¢Å>é?^©AªÂkA3°;A£~§A”MjAÛL7At©AjAÉ;A`ÃS¿b>2>¹Å?t©AjAÉ;A£~§A”MjAÛL7A^C§AgAXŒ7AñiJ¿UG>Ìž?t©AjAÉ;A^C§AgAXŒ7AVĨAÞ2gAÑS?VĨAÞ2gAÑ?VĨAÞ2gAÑv½?ào¨AèadAKY§j?ào¨AèadAKYX?ç¨A2›aA3Ã[œ?ç¨A2›aA3ÃÅM?â§A;Þ^A„C=Au ¦Aù˜_A«×8AûÅ¥AÞd^Aß9A†ã2¿´$Ý>œù?â§A;Þ^A„C=AûÅ¥AÞd^Aß9Aü9§A4›]Aô†=Aæ6¿aµð>\Æ?ü9§A4›]Aô†=AûÅ¥AÞd^Aß9AŸ!¥AjÑ[A{Ç9AR+¿9Wö>Ò4?ü9§A4›]Aô†=AŸ!¥AjÑ[A{Ç9A„¦AùæZA *>Aöç+¿¥x?îÈ?„¦AùæZA *>AŸ!¥AjÑ[A{Ç9Aüf¤A=UYAÈ…:A» ¿Þ— ?ë?„¦AùæZA *>Aüf¤A=UYAÈ…:AšÍ¥AûIXAIá>A±³ ¿0‰?¸?šÍ¥AûIXAIá>Aüf¤A=UYAÈ…:AÍ•£A‚ðVA[X;A˜^¿”ö?Wó?šÍ¥AûIXAIá>AÍ•£A‚ðVA[X;Aäó¤AoÄUAZ¬?A¡ˆ¿ ‹"?–?äó¤AoÄUAZ¬?AÍ•£A‚ðVA[X;A©­¢A7¤TAæ>d}¢APA!êAAå9¡A!‹QA©=A\ Aè†OAx½>AÄϾ¦APP¡AOìMAhõBAòȾeªF?+Åü>PP¡AOìMAhõBA\ Aè†OAx½>AlçžA­ªMAhß?A@²¾ŸèD?$/ ?PP¡AOìMAhõBAlçžA­ªMAhß?Ae AÊñKAåDA—*ª¾qN?o>ú>e AÊñKAåDAlçžA­ªMAhß?A4¡A øKAòAA Ô“¾ìL?Õ?e AÊñKAåDA4¡A øKAòAA»·žAr"JA6EAA[¾eþS?~ø>»·žAr"JA6EA4¡A øKAòAAýAã[žAfZIA¸ÃEAýAãEšœAøÌGA¢ÿFA¬ž›A»ÉIAÖäBAê-šA¾ŒHAn/DA‘ ¾4>X?·ˆ?EšœAøÌGA¢ÿFAê-šA¾ŒHAn/DA”›ATxFABHA8úå½yÜ_?5 ñ>”›ATxFABHAê-šA¾ŒHAn/DAa±˜A¥†GA™EA•½×ÿZ?|??”›ATxFABHAa±˜A¥†GA™EA÷ƒ™A_]EAlŠIA¥#C½Lÿa? Eï>÷ƒ™A_]EAlŠIAa±˜A¥†GA™EAÅ)—A¹¸FA—ÔFAVv%¼…\?H?÷ƒ™A_]EAlŠIAÅ)—A¹¸FA—ÔFA5æ—A—}DAÑ×JAuªú;ÀÚb?5:í>5æ—A—}DAÑ×JAÅ)—A¹¸FA—ÔFA–C–AW\FAÌšGAË0=‹ã\?ò?5æ—A—}DAÑ×JA–C–AW\FAÌšGAÏò–A_DAÄ™KAèÜ]=¨Õb?¼µë>Ïò–A_DAÄ™KA–C–AW\FAÌšGA¢®”ARëEA¶óHA=jµ=%x\??Ïò–A_DAÄ™KA¢®”ARëEA¶óHACF•AÀšCAŒëLA¥4ç=îÉ^?‹|õ>CF•AÀšCAŒëLA¢®”ARëEA¶óHA0;”A†…DAù½KAw£ >X?Ôø?CF•AÀšCAŒëLA0;”A†…DAù½KAöz”AvCA5ŠMAyÊ=3Ád¿¥2à>0;”A=½Aù½KA§î“AWAœ•IA?‰•A´ïŒA:HAáµ­=ï k¿è*Æ>?‰•A´ïŒA:HA§î“AWAœ•IAÚŽ“A‹ŒA:âFA5ÕH=ï p¿Œ(°>?‰•A´ïŒA:HAÚŽ“A‹ŒA:âFAoà”A7ŒAŒòCAÝÀp=Åæs¿ˆ™˜>oà”A7ŒAŒòCAÚŽ“A‹ŒA:âFA"X“AE@ŒAYWEAÅx3=çÿw¿òz>oà”A7ŒAŒòCA"X“AE@ŒAYWEAJ×’AŸÓ‹AyµAAÔµ=”Ñz?éPJ>J×’AÂXHAyµAAw”AÁ˜GA-±DABl“A™HAè;@A53Bl“A™HAè;@Aw”AÁ˜GA-±DA½’•AqùGAÚNCA ò¼ª.{?ËeC>Bl“A™HAè;@A½’•AqùGAÚNCA9ä”AhæHAœÎ>A›/Z½8x? ‰t>9ä”AhæHAœÎ>A½’•AqùGAÚNCA;o–A;KHA ƒBAó§½]z?F³D>9ä”AhæHAœÎ>A;o–A;KHA ƒBAÔº•Aù+IAJü=AR´Õ½®w?ëwv>Ôº•Aù+IAJü=A;o–A;KHA ƒBAç—AýIA$AA[µ¾rx?w”F>Ôº•Aù+IAJü=Aç—AýIA$AA“)—A‰ÏIA´‘“)—A‰ÏIA´‘“)—A‰ÏIA´‘˜A`¨JAE+;A U™AîôIAžÉ?A¤¸šAKAjt>A’¾p?±ÙJ>˜A`¨JAE+;A¤¸šAKAjt>Aºí™AݵKA½É9AcN¡¾7}j?3n~>ºí™AݵKA½É9A¤¸šAKAjt>A.œAòsLA8%=Aªµ¾ÎÉi?ÿM>ºí™AݵKA½É9A.œAòsLA8%=AÛA›Aó÷LAám8Aʾ¾õâd?iD€>ÛA›Aó÷LAám8A.œAòsLA8%=A|ªœAD#MAŠŽÛA›Aó÷LAám8A|ªœAD#MAŠŽ­Ù›AxœMAPÑ7A|ªœAD#MAŠŽ^?‰\P>­Ù›AxœMAPÑ7AAçAß»NA T;AZA~OA"Š6AŒÑô¾$W?Ý¢‚>ZA~OA"Š6AAçAß»NA T;A8ŸAþ}PA'':A·-¿ÒT?c›R>ZA~OA"Š6A8ŸAþ}PA'':A©>žA<ËPAŠP5Aæ? ¿DM?„>©>žA<ËPAŠP5A8ŸAþ}PA'':A,+ A:hRA†9A3Ë¿x$J?YØT>©>žA<ËPAŠP5A,+ A:hRA†9AEXŸAŸ¡RAH%4AÒi¿ÈA?ûf…>EXŸAŸ¡RAH%4A,+ A:hRA†9Aï1¡AìyTAÞø7AE±"¿p3>?FW>EXŸAŸ¡RAH%4Aï1¡AìyTAÞø7Aß` AS¡TA! 3A%¿ZÇ7?že†>ß` AS¡TA! 3Aï1¡AìyTAÞø7Aß—¡Aj]UA~Ž7AœW+¿Þ\6?­5X>ß` AS¡TA! 3Aß—¡Aj]UA~Ž7AÞÇ A~UA·™2A$^-¿‘Ë/?žI‡>ÞÇ A~UA·™2Aß—¡Aj]UA~Ž7A†|¢AÛ‘WAË6A˜ 6¿V†+?ØZ>ÞÇ A~UA·™2A†|¢AÛ‘WAË6A¤¯¡A¤WAH1A¿*:¿Rê!?Œˆ>¤¯¡A¤WAH1A†|¢AÛ‘WAË6A?K£AüßYAŽÁ5AãnB¿±-?–\>¤¯¡A¤WAH1A?K£AüßYAŽÁ5A"‚¢ApæYAäµ0A@ëE¿€ ?I½‰>"‚¢ApæYAäµ0A?K£AüßYAŽÁ5AJ¤AæF\A/ú4A¾M¿éÞ ?«ñ]>"‚¢ApæYAäµ0AJ¤AæF\A/ú4Ad?£A1D\Aä/A2•P¿ /?ÚŠ>d?£A1D\Aä/AJ¤AæF\A/ú4A§¤AvÆ^A4H4A/ñW¿Ý7û>Û°_>d?£A1D\Aä/A§¤AvÆ^A4H4AHç£AA½^Al(/AhvX¿ë>;œ‹>Hç£AA½^Al(/A§¤AvÆ^A4H4Aë¤Aóñ_Atþ3AôÔ]¿–å>Ù’`>Hç£AA½^Al(/Aë¤Aóñ_Atþ3A,¤Aªæ_A•Ú.AÇò]¿Õ>0HŒ>,¤Aªæ_A•Ú.Aë¤Aóñ_Atþ3Apj¥Aè}bAÚq3A0d¿ŸQÉ>`åa>,¤Aªæ_A•Ú.Apj¥Aè}bAÚq3A)°¤AüobAF.AEge¿™!²>ð>)°¤AüobAF.Apj¥Aè}bAÚq3A Ó¥A~eAˆý2A$ok¿¶ê¥>ø$c>)°¤AüobAF.A Ó¥A~eAˆý2AŽ¥A4eAùÊ-AÚ„k¿kŽ>ÓÈ>Ž¥A4eAùÊ-A Ó¥A~eAˆý2A&%¦AÕ¸gA«¡2A£q¿åp>À*d>Ž¥A4eAùÊ-A&%¦AÕ¸gA«¡2AÜq¥A#¬gA¯i-ACp¿²—Q>,RŽ>Üq¥A#¬gA¯i-A&%¦AÕ¸gA«¡2A·`¦AvhjA±^2At?u¿›ã7>Tòd>Üq¥A#¬gA¯i-A·`¦AvhjA±^2AᯥAô^jA±"-A[9s¿Oä>¾šŽ>ᯥAô^jA±"-A·`¦AvhjA±^2A y¦A$lAEC2AEmw¿¼n>¬Be>ᯥAô^jA±"-A y¦A$lAEC2A;É¥AûkAœ-Aø×t¿¡Š°=NÖŽ>;É¥AûkAœ-A y¦A$lAEC2Aq¦Aœ®nAô)2Aªüx¿}êz=³ e>;É¥AûkAœ-Aq¦Aœ®nAô)2A›à¥A1¬nAÂê,AiÍu¿„ A<ñŽ>›à¥A1¬nAÂê,Aq¦Aœ®nAô)2AD¦A\qA'*2A,ty¿ï•U¼|³e>›à¥A1¬nAÂê,AD¦A\qA'*2Amà¥A^qAøê,AÚMu¿Qš€½“àŽ>mà¥A^qAøê,AD¦A\qA'*2Acx¦Aö tAD2AC{x¿ç³½;€e>mà¥A^qAøê,Acx¦Aö tAD2AÈ¥AtAc-ADVs¿º¥ ¾›¤Ž>È¥AtAc-Acx¦Aö tAD2ALJ¦AÒ»vAîw2AÒ v¿õ§%¾ºe>È¥AtAc-ALJ¦AÒ»vAîw2A…˜¥AØÆvAs=-A6=p¿á9R¾É@Ž>…˜¥AØÆvAs=-ALJ¦AÒ»vAîw2Az¦A”½xAã¯2Ayìr¿t‡d¾kbd>…˜¥AØÆvAs=-Az¦A”½xAã¯2A­d¥A­ÊxA¿x-AJ`l¿î"ˆ¾ÞÔ>­d¥A­ÊxA¿x-Az¦A”½xAã¯2AèÂ¥AÉ[{A‰3Añ_n¿F”¾Ìc>­d¥A­ÊxA¿x-AèÂ¥AÉ[{A‰3AÏ ¥A)j{AÞ-AËf¿ªI¬¾Ä)>Ï ¥A)j{AÞ-AèÂ¥AÉ[{A‰3AÌV¥AŠï}A˜‡3A˜!h¿øÑ·¾ûfb>Ï ¥A)j{AÞ-AÌV¥AŠï}A˜‡3AÙ›¤A0ý}A].AÿJ_¿=`Ͼ†[Œ>Ù›¤A0ý}A].AÌV¥AŠï}A˜‡3A¸Ó¤AW<€A 4AúŽ`¿T•Ú¾Ìa>Ù›¤A0ý}A].A¸Ó¤AW<€A 4AޤA¥A€A–õ.A5ÀV¿ÌPñ¾l‹>ޤA¥A€A–õ.A¸Ó¤AW<€A 4Aø8¤AO{AÁ4AzªW¿8ü¾=s_>ޤA¥A€A–õ.Aø8¤AO{AÁ4Amu£AÏ}AÓ§/A†M¿( ¿\lŠ>mu£AÏ}AÓ§/Aø8¤AO{AÁ4Aç§£A|‚Aÿ]5AFÂN¿d ¿ã]>mu£AÏ}AÓ§/Aç§£A|‚Aÿ]5AÍà¢A={‚A'M0AƒêC¿ÀÄ¿p‰>Íà¢A={‚A'M0Aç§£A|‚Aÿ]5A˜ä¢Aû§ƒA>/6AÞID¿üØ¿w%\>Íà¢A={‚A'M0A˜ä¢Aû§ƒA>/6A}¢A衃A.)1A 8¿4f$¿º;ˆ>}¢A衃A.)1A˜ä¢Aû§ƒA>/6A ¢AOÇ„Aà7A3#8¿ëF)¿ƒ)Z>}¢A衃A.)1A ¢AOÇ„Aà7A3=¡A³º„A92AÛ +¿x 2¿)÷†>3=¡A³º„A92A ¢AOÇ„Aà7A¡A~Ù…AŽ8Aõ*¿¾»6¿èX>3=¡A³º„A92A¡A~Ù…AŽ8AÔK AÅ…AÖ3AÑ9¿ª¨>¿¥…>ÔK AÅ…AÖ3A¡A~Ù…AŽ8A" A§Ý†A9AVÅ¿c0C¿âëU>ÔK AÅ…AÖ3A" A§Ý†A9A%EŸAKÀ†A¶94A‘¿[I¿_„>%EŸAKÀ†A¶94A" A§Ý†A9ABŸA»™‡Aö9Aˆ¿=ÝL¿¶T>%EŸAKÀ†A¶94ABŸA»™‡Aö9A…nžAÐt‡Aç5A.|¿¸?R¿Ç9ƒ>…nžAÐt‡Aç5ABŸA»™‡Aö9A¾žA«}ˆA… ;A ™¿…pV¿nþQ>…nžAÐt‡Aç5A¾žA«}ˆA… ;A¢GA4NˆAwT6AéÁä¾%¢[¿V×>¢GA4NˆAwT6A¾žA«}ˆA… ;A"âœAÍL‰A™W¢GA4NˆAwT6A"âœAÍL‰A™WÜœA,‰A3˜7A"âœAÍL‰A™WÜœA,‰A3˜7Ad˜›ATŠAE›=AsÊšAÀ‰Atè8AÉØ ¾Õ•j¿ä,~>sÊšAÀ‰Atè8Ad˜›ATŠAE›=A˜=šA1©ŠAë>A+‘¾•6n¿:QK>sÊšAÀ‰Atè8A˜=šA1©ŠAë>A–t™A$WŠA¯D:Aº¾o¿‡°{>–t™A$WŠA¯D:A˜=šA1©ŠAë>AnF™Aè ‹A‹×?A^¾År¿8ŽI>–t™A$WŠA¯D:AnF™Aè ‹A‹×?AÀ˜A¶°ŠA¯9;A0I¾í s¿ñ y>À˜A¶°ŠA¯9;AnF™Aè ‹A‹×?A!Ø—A‹A2AA$A¾6fv¿ô¬G>À˜A¶°ŠA¯9;A!Ø—A‹A2AA—A‹A, —A‹A, —A‹A, A Ú_½3x¿ ˆt>“¬•Ažl‹AM >A™`–AhÝ‹AŸBAoà”A7ŒAŒòCA8½Â{¿ššC>“¬•Ažl‹AM >Aoà”A7ŒAŒòCAú6”A¢‹Aow?Aj'Ò;Ùçz¿O)K>ú6”A¢‹Aow?Aoà”A7ŒAŒòCAJ×’AŸÓ‹AyµAAhŒ<*}¿V|>ú6”A¢‹Aow?AJ×’AŸÓ‹AyµAA±º’A»‹Aç@A–A¾{¿k)H=ín–A„‹AŽò7A—A‹A, Ahí¾û'}¿'F=mQ•AWH‹Aý9A“¬•Ažl‹AM >Aƒ•A8W‹Ai9AeÒÆ½p˜}¿¦5Å=ƒ•A8W‹Ai9A“¬•Ažl‹AM >Aú6”A¢‹Aow?A¨°½9À~¿•3D=ƒ•A8W‹Ai9Aú6”A¢‹Aow?A£“AÞ€‹A?â:A—`¿¼šÃ~¿:9Ã=£“AÞ€‹A?â:Aú6”A¢‹Aow?A±º’A»‹Aç@A¿úB¼±¿¡?B=£“AÞ€‹A?â:A±º’A»‹Aç@A¾’A쎋Aƒ]¦¯c?%{A`¡AÔIRAšAk¡A\òQAá AìžApkSAÑö´¾_)‚>°vf?á AìžApkSAšAk¡A\òQAcPAfâžA›]RAGö¾¡vJ>w·i?á AìžApkSAcPAfâžA›]RAûA§TžA*”SA§¸¾u`Û=û0m?!8Ay³œAžÿRAõÐA˜ÀœAÛTAûA§TžA*”SAÙ¸¾¦ðͽ3~m?ÔùAȘAh—SAxÎAbšAFTA¥XAß~šAöSA׸¾:C.½˜|n?¥XAß~šAöSAxÎAbšAFTA™ÏAvŽ›A[TAÀá´¾&×C¾"oj?P±AYO˜AR‘RAuAùb˜A“~SAÔùAȘAh—SAí´²¾‘Åy¾€¡g?uAùb˜A“~SAP±AYO˜AR‘RAïnAÍE–ASiRAŽø ¾½ìñ¾tÆR?[AI““AZPAàAB”A»ÌPAPAÅ)”AzëOAÆ¥¾œJ×¾šùX?PAÅ)”AzëOAàAB”A»ÌPAu}A÷–AÝCRA¬¥—¾™ ¿Ã®G?:öAëG’A.ÒMAIàAZa’AаNA[AI““AZPAU}¾06¿ûQ(?ì!AiOAciIA:ß AȬAãLAŒA"“AmAKAP†¾øm+¿Îè1?ŒA"“AmAKA:ß AȬAãLAŒ‚ A}K‘Aø MAêc¾TåE¿¦&?ØX A¹A¶EHAê"A„,A $IAì!AiOAciIA–ŠT¾Ø¼M¿[Æ?ê"A„,A $IAØX A¹A¶EHAÍQ#AÅçA’ÎEA­‰¾:m¿Õ¶>Ug%A掌AAn@Aª¹$A¤äŒA?.BA:#A ÑŒAFIAA 7¾4ÿf¿+…Ï>:#A ÑŒAFIAAª¹$A¤äŒA?.BA-“#A±¸Aì%EAùzš½ÌÍx¿f`d>§X'AžÔ‹AYk;AÂ7&Aþ'ŒA•T>AúÈ$AËŒAj=A9Ľát¿0ûŒ>úÈ$AËŒAj=AÂ7&Aþ'ŒA•T>AUg%A掌AAn@A]M.½áE}¿$Ž>b&A¸«‹AGd9AéÄ'A_µ‹AT:A§X'AžÔ‹AYk;A¦‡±¼+¿üâ®=éÄ'A_µ‹AT:Ab&A¸«‹AGd9A¨Y)A쎋Aý?6A,Ó;…¿ng/=¨Y)A쎋Aý?6Ab&A¸«‹AGd9A”ý'Aå‹‹AJ5A=\Ó<öõ~¿Òœ°=”ý'Aå‹‹AJ5Ab&A¸«‹AGd9AÑh#A¹‹A\7A—nŠ=6,¿ÉÇ1=”ý'Aå‹‹AJ5AÑh#A¹‹A\7A%AÂp‹Aì33AfЏ= û}¿qy²=%AÂp‹Aì33AÑh#A¹‹A\7A#¢!A‹Z‹A}!6A¾›ú=AÔ}¿63=%AÂp‹Aì33A#¢!A‹Z‹A}!6AN#AÎR‹A‘ð1Aù§´¾»¥˜>´ c?šAk¡A\òQAó A¡A.QAcPAfâžA›]RA rº¾”[˜>êìa?cPAfâžA›]RAó A¡A.QAµ|AÈ AÂÅNAº ¿¾)>{d?cPAfâžA›]RAµ|AÈ AÂÅNA±qA2¤žA/PA`ľü'—>`?±qA2¤žA/PAµ|AÈ AÂÅNA«ÍAB‰ A§PMA»Wƾ ³>H0c?±qA2¤žA/PA«ÍAB‰ A§PMAGíA|cžA²NAÈ˾O¢•>|«^?GíA|cžA²NA«ÍAB‰ A§PMAðà AL' Aa¿KAn¯Í¾·š{>Öa?GíA|cžA²NAðà AL' Aa¿KA, AÌA5iLAf >64}¿|;3=N#AÎR‹A‘ð1A#¢!A‹Z‹A}!6Aê"AI‹A™§1A5>Ÿ/|¿—‡´=ê"AI‹A™§1A#¢!A‹Z‹A}!6A®¼A@‹Aö4Am>B>Y{¿<Ç5=ê"AI‹A™§1A®¼A@‹Aö4A1n A ‹AãÙ/AŠ^>±Ôx¿` ·=1n A ‹AãÙ/A®¼A@‹Aö4A+éA»ŠAÈ2A¬­„>yüv¿ v8=1n A ‹AãÙ/A+éA»ŠAÈ2A`›A÷§ŠAËÆ-Aæ¦Ò¾.í“>ÀK]?ðà AL' Aa¿KAôÄ A¦òŸA¸çJA, AÌA5iLAÎeؾ©°’>Î\?, AÌA5iLAôÄ A¦òŸA¸çJA¨ØAà"ŸAê‚HA¿õؾ7>u>‹ _?, AÌA5iLA¨ØAà"ŸAê‚HAû‡ADþœA%JAÑzã¾ÿŽ>iêY?û‡ADþœA%JA¨ØAà"ŸAê‚HA ACžAÂ#FA‡mâ¾D¥m>$É]?û‡ADþœA%JA ACžAÂ#FAwAÀú›A2çGA#–ë¾tp‹>:UX?wAÀú›A2çGA ACžAÂ#FA(%ü@ªAREAÑæè¾|™f>A’\?wAÀú›A2çGA(%ü@ªAREAœH÷@SÁšAó°EA«6•>‘t¿+”8=`›A÷§ŠAËÆ-A+éA»ŠAÈ2AK¨A£|ŠA-A¦V˜>SLs¿¢ò¹=K¨A£|ŠA-A+éA»ŠAÈ2AD)AoŠAJ0ACr­>”p¿§m¿Ñ¼¼=®×AÓ)ŠA—¸+AD)AoŠAJ0Ak~Aƒ[‰A¶".A­4Í>Ý=®×AÓ)ŠA—¸+Ak~Aƒ[‰A¶".Ay$Am‰A°)Ai€Ô>¥¯g¿ç¶¾=y$Am‰A°)Ak~Aƒ[‰A¶".AòˆA‰Aðk-Aˆ•á>q€e¿µE?=y$Am‰A°)AòˆA‰Aðk-AÅ*AQ‰Aó(A³#ò¾Q7ˆ>”W?(%ü@ªAREA&Äô@xØœA¥ËCAœH÷@SÁšAó°EA7Dö¾†>!V?œH÷@SÁšAó°EA&Äô@xØœA¥ËCAƒ¬ð@šSœAñBA+mð¾'_>«[?œH÷@SÁšAó°EAƒ¬ð@šSœAñBA¤gó@h@šAûâDAðú¾Ö¤ƒ>K7U?¤gó@h@šAûâDAƒ¬ð@šSœAñBA·ê@Õ^›Aö‰AA‡äõ¾tªW>«ùY?¤gó@h@šAûâDA·ê@Õ^›Aö‰AAúhé@ÁɘAÌBA³{¿f¼>åýS?·ê@Õ^›Aö‰AAAæ@)КA¢¸@Aúhé@ÁɘAÌBA\ÿ¿­´y>EæR?úhé@ÁɘAÌBAAæ@)КA¢¸@ARÜ@4™Aý—>A‡Fÿ¾§æJ>8 X?úhé@ÁɘAÌBARÜ@4™Aý—>ASëß@ '—A5Ê@A¡Æç>ôc¿Tp?=Å*AQ‰Aó(AòˆA‰Aðk-A„½AÆ1‰A‰Ÿ(A~eê>üPb¿ÏéÀ=„½AÆ1‰A‰Ÿ(AòˆA‰Aðk-A¸A·QˆAN‘+Aœþ>lê]¿”uB=„½AÆ1‰A‰Ÿ(A¸A·QˆAN‘+As¦Ae˜ˆAj'Ao×?(vY¿åÃ=s¦Ae˜ˆAj'A¸A·QˆAN‘+A¿Acw‡A—É)AGM?ŠrT¿pE=s¦Ae˜ˆAj'A¿Acw‡A—É)ARAAɇAE,%Ap“?—cO¿‡ÎE=RAAɇAE,%A¿Acw‡A—É)AWA”l‡A(u$ACÂ?meM¿:Ç=WA”l‡A(u$A¿Acw‡A—É)A$A㈆A&(A‰±?ʰG¿àäH=WA”l‡A(u$A$A㈆A&(AhüA§ã†Af#A±Ð#?0C¿Ý.Ê=hüA§ã†Af#A$A㈆A&(A¿„ A‰†…Ax&AÃN,?Ùæ<¿¢ÅK=hüA§ã†Af#A¿„ A‰†…Ax&A_Ø Aè…A µ!A•.?!}9¿ZÌ=_Ø Aè…A µ!A¿„ A‰†…Ax&A^ AIC…A­&AÑ?3?$S6¿êL=_Ø Aè…A µ!A^ AIC…A­&ApU A&¦…AéL!A[Õ¿ ^q>î¸Q?RÜ@4™Aý—>AÕÜ@B™A‹•>ASëß@ '—A5Ê@A=Œ¿…l>`Q?Sëß@ '—A5Ê@AÕÜ@B™A‹•>A“‹Ò@ø;—A|‰>²ƒV?Sëß@ '—A5Ê@A“‹Ò@ø;—A|‰A7Ñ ¿ã]>Ä3O?“òÖ@€Y•Aß>A“‹Ò@ø;—A|‰½U?“òÖ@€Y•Aß>AHÉ@G,•AÒ•:A Î@Za“A÷ =A™®¿l»Q>jûM? Î@Za“A÷ =AHÉ@G,•AÒ•:AõjÇ@í¡”A«:A­H¿b*>6{T? Î@Za“A÷ =AõjÇ@í¡”A«:Ao}Ì@vÝ’AΛ"9M?o}Ì@vÝ’AΛٔS?o}Ì@vÝ’AΛ·JL?ÎkÀ@ij’AŒ“8Añp¿@n’AY\8AÃÅ@•ÅAù:AÛ‰¿|®:>ÙïK?ÃÅ@•ÅAù:Añp¿@n’AY\8Ab»@®"‘Aªu7Aî¿ ¿²> ¦R?ÃÅ@•ÅAù:Ab»@®"‘Aªu7Aº4¾@ÍŽAx9A6?Ì3¿æM=pU A&¦…AéL!A^ AIC…A­&AÜ– Aÿ<…Ao´ A‹7?à1¿í]Î=Ü– Aÿ<…Ao´ A^ AIC…A­&An< AJ3„A˜¡$Ab¤>? \*¿P=Ü– Aÿ<…Ao´ An< AJ3„A˜¡$Aºn A˜™„A€ÇA~B?ÊÝ$¿h%Ñ=ºn A˜™„A€ÇAn< AJ3„A˜¡$Aö›A¡ƒA•L#A·I?ïß¿¦£R=ºn A˜™„A€ÇAö›A¡ƒA•L#AJ² AŸ}ƒA¤`AöRO?%˜¿O8S=J² AŸ}ƒA¤`Aö›A¡ƒA•L#A ŸA÷°‚A„€A×,P?Õ›¿áiÔ= ŸA÷°‚A„€Aö›A¡ƒA•L#Ai&AííAc"APdV?B ¿ÉûU= ŸA÷°‚A„€Ai&AííAc"AN AºR‚AOAƒHX?ZL¿NäÖ=N AºR‚AOAi&AííAc"A4ÛA4¹€Aºÿ AL÷]?¦ý¾ ?X=N AºR‚AOA4ÛA4¹€Aºÿ Aú¸AÞAoòAŒž_?3Jó¾"”Ø=ú¸AÞAoòA4ÛA4¹€Aºÿ A–|ArV€At¯ A¢Ñb?b×ë¾zûX=ú¸AÞAoòA–|ArV€At¯ AÆQAå³€AVA¦¿¾ÿ/>~K?b»@®"‘Aªu7AH(¸@ØAH¾6Aº4¾@ÍŽAx9AoS¿_&>é@J?º4¾@ÍŽAx9AH(¸@ØAH¾6A¾‘±@×§A–D5AüпªT>dMQ?º4¾@ÍŽAx9A¾‘±@×§A–D5A7¸@<@ŒA¹8Aâ"¿ò>¿I?7¸@<@ŒA¹8A¾‘±@×§A–D5A&®«@l‹AXð3ATó¿Ûvã=œcP?7¸@<@ŒA¹8A&®«@l‹AXð3A–²@ÜÓ‰AðÞ6ALü¿»>¬3H?–²@ÜÓ‰AðÞ6A&®«@l‹AXð3A)ý©@žAŠA)Ž3Aä¿ ÐÓ=PüO?–²@ÜÓ‰AðÞ6A)ý©@žAŠA)Ž3A±@ª ‰A=„6A ƒ¿˜B>LýG?±@ª ‰A=„6A)ý©@žAŠA)Ž3AvP©@yâ‰A×f3A¿ÈÇÆ=©ÀO?±@ª ‰A=„6AvP©@yâ‰A×f3Ae™¬@ó•†A"„5A‡e?ßá¾²Y=ÆQAå³€AVA–|ArV€At¯ A$ŒAL´A¹ùA+f?eºÙ¾–Ú=$ŒAL´A¹ùA–|ArV€At¯ AWsA°=~AÐÌAA«j?‹ÁʾÅò[=$ŒAL´A¹ùAWsA°=~AÐÌA/AJç~A²¬AÐãk?"!¿¾ sÜ=/AJç~A²¬AWsA°=~AÐÌA)–AˆÃ{Aê A|ïo?+[°¾Èx]=/AJç~A²¬A)–AˆÃ{Aê A;A×V|AˆáA6r?€+œ¾ªYÞ=;A×V|AˆáA)–AˆÃ{Aê A"äAS>yAðrA¬žu?[˜¾ë4_=;A×V|AˆáA"äAS>yAðrAƒuAѶyAE<AêÁ¿!vë={tG?vP©@yâ‰A×f3A¯9¥@Ë¡‡Ax2Ae™¬@ó•†A"„5A=¿ xÏ=AÃF?e™¬@ó•†A"„5A¯9¥@Ë¡‡Ax2Aß9¡@Bñ„AŽ1A0°¿·¥š=NÆN?e™¬@ó•†A"„5Aß9¡@Bñ„AŽ1A1æ¨@„A\¬4A¤Ø ¿ _¨=T F?1æ¨@„A\¬4Aß9¡@Bñ„AŽ1Aîü@a0‚AcÏ0A Ô¿YÈu=SGN?1æ¨@„A\¬4Aîü@a0‚AcÏ0A¶è¥@S~A'ý3AÄÅ!¿v‰=©E?¶è¥@S~A'ý3Aîü@a0‚AcÏ0A¢êœ@÷€A 0A=\¿ÉdG=—N?¶è¥@S~A'ý3A¢êœ@÷€A 0A{¡£@‹º}A)w3A!Fw?-‘¾ã?_=ƒuAѶyAE<A"äAS>yAðrA4oA šyAø6A?Rw? {o¾Ñöß=4oA šyAø6A"äAS>yAðrAò\AR­vAqüA z?èR¾¤±`=4oA šyAø6Aò\AR­vAqüA½ÞA wA¯½A5z?Œ_1¾®Îà=½ÞA wA¯½Aò\AR­vAqüA`"Aø*uAâÈATy|?–¿¾Ða=½ÞA wA¯½A`"Aø*uAâÈA8AUquAŒ†Aef"¿NÆb=åbE?¢êœ@÷€A 0A_„›@ù½~AS=0A{¡£@‹º}A)w3A<í"¿¿>=‡E?{¡£@‹º}A)w3A_„›@ù½~AS=0Azqš@äj{Aµý/A!'¿¬\ =DzM?{¡£@‹º}A)w3Azqš@äj{Aµý/AG¤¢@Y¡zAÚ<3A•>#¿u=§ÿD?G¤¢@Y¡zAÚ<3Azqš@äj{Aµý/A(¸™@òüwAÁÒ/A\¿‹¹<-¤M?G¤¢@Y¡zAÚ<3A(¸™@òüwAÁÒ/AºŒ¡@veuAcü2AŠŠ#¿=˼<6ÝD?(¸™@òüwAÁÒ/AÊA™@&ÌuAQ·/AºŒ¡@veuAcü2AÉ#¿ÝG<†¹D?ºŒ¡@veuAcü2AÊA™@&ÌuAQ·/AÞØ˜@^'pAùž/AR¸¿–·‰;ItM?ºŒ¡@veuAcü2AÞØ˜@^'pAùž/A3,¡@¤$pAæ2A¦Þ#¿ÕN¦9à­D?3,¡@¤$pAæ2AÞØ˜@^'pAùž/ArÛ˜@pA’Ÿ/A¶¿¢ik»'vM?3,¡@¤$pAæ2ArÛ˜@pA’Ÿ/Aƒ¡@ÞjABú2AS¥}?ý½¥a=8AUquAŒ†A`"Aø*uAâÈAgaA”:sA"TA‹}?À;ѽiÄá=gaA”:sA"TA`"Aø*uAâÈAÏáACŸrAàAoÜ~?ÝWœ½Ž8b=gaA”:sA"TAÏáACŸrAàAÖTA}ÃrAŠIA;~?\iJ½Äüá=ÖTA}ÃrAŠIAÏáACŸrAàA‰ËAÍpA,|A¯‡? 6̼³b=ÖTA}ÃrAŠIA‰ËAÍpA,|AÔ;AÄpAq4Aâ^~?°¹<@â=Ô;AÄpAq4A‰ËAÍpA,|A®ßA•mAþAW?Z;=.åa=Ô;AÄpAq4A®ßA•mAþAqRA_mA†GA­È#¿Ñf:¼ªºD?rÛ˜@pA’Ÿ/AÁ7™@q|jAý´/Aƒ¡@ÞjABú2Aï‹#¿¬·¼CÝD?ƒ¡@ÞjABú2AÁ7™@q|jAý´/A(¸™@ê hAÁÒ/A"]¿¥z¶¼n¤M?ƒ¡@ÞjABú2A(¸™@ê hAÁÒ/Ab–¢@'‘eA§93Aè~?ïw—=ÍZb=qRA_mA†GA®ßA•mAþA0bA~ÅlAËTAœ%}?ÐØÌ=àØá=0bA~ÅlAËTA®ßA•mAþA*AíjAÆA¨³}?zsù=qÇa=0bA~ÅlAËTA*AíjAÆA ™A‚¨jA…ƒA’ãz?¤Ç)>q¼à= ™A‚¨jA…ƒA*AíjAÆAƒAó~hA]A)3{?©==>7`= ™A‚¨jA…ƒAƒAó~hA]Aà AühAðáAA#¿£ ½õþD?(¸™@ê hAÁÒ/Abbš@QËdA6ú/Ab–¢@'‘eA§93A5æ"¿TR=½!E?b–¢@'‘eA§93Abbš@QËdA6ú/AY9œ@_p_A)g0AÊ¿6@+½ÞM?b–¢@'‘eA§93AY9œ@_p_A)g0A@H¤@9“`A†3A?"¿pdr½¢pE?@H¤@9“`A†3AY9œ@_p_A)g0AÂãœ@Ð^AxŽ0AD¿f…Q½äN?@H¤@9“`A†3AÂãœ@Ð^AxŽ0AB¿¦@ôm[AV.4ACy? }b>Ô`=à AühAðáAƒAó~hA]A‰sAgfA:AãZv?ô~>vÍß=‰sAgfA:AƒAó~hA]AöAgûeApžAlJv?¢Ùˆ>:^_=‰sAgfA:AöAgûeApžAì¬AFzeA¯jATTr?½y›>ÌãÝ=ì¬AFzeA¯jAöAgûeApžA÷ÒA €cA’BAAr?Ö¤>%ú\=ì¬AFzeA¯jA÷ÒA €cA’BAT~A©åbAžA´l?õ¾>ËìÛ=T~A©åbAžA÷ÒA €cA’BAw»Aó aA® A2±k?‡øÅ>ÚZ=T~A©åbAžAw»Aó aA® AZ~AÒ]`ArîAN’!¿ ͽ°¾E?Âãœ@Ð^AxŽ0Ahåž@/íYAò1AB¿¦@ôm[AV.4A« ¿^8¬½ #F?B¿¦@ôm[AV.4Ahåž@/íYAò1AøS¢@]ƒTAÊÎ1ASæ¿-ü“½–²N?B¿¦@ôm[AV.4AøS¢@]ƒTAÊÎ1Aþê©@^VAáç4AŠ ¿W½Ò½ãÝF?þê©@^VAáç4AøS¢@]ƒTAÊÎ1A$†¦@Y4OA]Ä2A¤¿¸³½ÚHO?þê©@^VAáç4A$†¦@Y4OA]Ä2AcÍ­@\dQA Ê5Aè^¿-óñ½£G?cÍ­@\dQA Ê5A$†¦@Y4OA]Ä2Al^©@E;LAäi3A˜9¿Ž<˽âO?cÍ­@\dQA Ê5Al^©@E;LAäi3A€j²@g‚LAÕ6AØ>i? >Ñ>ôÄZ=Z~AÒ]`ArîAw»Aó aA® Aí‡AÏI`A\öAg†d?ž?à>;±Ù=í‡AÏI`A\öAw»Aó aA® AñÐA€¢^A÷ A”ôc?nlç>„X=í‡AÏI`A\öAñÐA€¢^A÷ AÊ­Aã]A8éAã‰[?–ç?ˆ×=Ê­Aã]A8éAñÐA€¢^A÷ AB7AO\Ay$"A ƒZ?P´?sŠU=Ê­Aã]A8éAB7AO\Ay$"A‚2A\=[A0(A<¿Ïn¾64H?l^©@E;LAäi3A;«@íJA·å3A€j²@g‚LAÕ6AR£¿m¿¾ÏÓH?€j²@g‚LAÕ6A;«@íJA·å3AÞ±@sDAÂU5A`Ö¿=ðò½gäP?€j²@g‚LAÕ6AÞ±@sDAÂU5AVW¸@ÁEGA¡)8A¾É¿Ù #¾„J?VW¸@ÁEGA¡)8AÞ±@sDAÂU5A¦g¸@Éž?AjÌ6A Œ¿óæ¾ ÞQ?VW¸@ÁEGA¡)8A¦g¸@Éž?AjÌ6Aäo¾@1µBA%…9A5q¿Dg0¾úK?äo¾@1µBA%…9A¦g¸@Éž?AjÌ6A'b»@¸¹=A±u7Aœ¶ ¿“_¾b©R?äo¾@1µBA%…9A'b»@¸¹=A±u7A/Å@ÔZ>A…;AV?™Â ?ÂÊU=‚2A\=[A0(AB7AO\Ay$"AŠžA½ZA!€A$ßO?¾ ?gEÔ=ŠžA½ZA!€AB7AO\Ay$"AªA ¾YA4X#AO?Kô? S=ŠžA½ZA!€AªA ¾YA4X#AeÁ AðXAãlAm¦E? • ?Ö1Ñ=eÁ AðXAãlAªA ¾YA4X#AÌF ADŒWAª$AÜËD?­6#?εO=eÁ AðXAãlAÌF ADŒWAª$A¾y AÀ¿VAZÐA~¿@ò:¾‹ôK?'b»@¸¹=A±u7A'Ÿ¿@~;Af8A/Å@ÔZ>A…;Aë¡¿¶“?¾hNL?/Å@ÔZ>A…;A'Ÿ¿@~;Af8AóhÀ@o˜:Aõ’8Ags ¿¨ï¾–S?/Å@ÔZ>A…;AóhÀ@o˜:Aõ’8AÀ”Ì@ï8:Aâ ?ƒ”*?ûO=¾y AÀ¿VAZÐAÌF ADŒWAª$AÏ– Aø…UAe´ Aéé6?=1?uOÎ=Ï– Aø…UAe´ AÌF ADŒWAª$Aý A?sUA,&AOù5?uš3?ëýL=Ï– Aø…UAe´ Aý A?sUA,&A][ AŸ­TA Q!A›-,?/½;?»"Ë=][ AŸ­TA Q!Aý A?sUA,&AiA¹tSA¥'A/+?î=?[–I=][ AŸ­TA Q!AiA¹tSA¥'A^fA»RAúï"Aýz¿Ô³I¾s:M?óhÀ@o˜:Aõ’8A΃Ç@g¯6A#:AÀ”Ì@ï8:Aâ AdÅ ¿Ù d¾ P?D¢Ô@¯R6A—_>AÐ@—™2A4A_àØ@Ë÷.Ažæ=AVéÜ@ Ø2A)&@Aô±¿§n¾.hQ?VéÜ@ Ø2A)&@A_àØ@Ë÷.Ažæ=AbÜ@"Ñ-A&—>AÜH¿X%H¾9ÐW?VéÜ@ Ø2A)&@AbÜ@"Ñ-A&—>Ae-æ@ {/A¥BA–í¿E•v¾|ŒR?bÜ@"Ñ-A&—>A«±â@Mx+Aÿ?Ae-æ@ {/A¥BABw¿ƒ}¾™—S?e-æ@ {/A¥BA«±â@Mx+Aÿ?Aúé@SB)A­ˆAAXl÷¾"~U¾ÿ¬Y?e-æ@ {/A¥BAúé@SB)A­ˆAAžíï@‡u,A—)DA!["?‘‡E?ƒI=^fA»RAúï"AiA¹tSA¥'A&TA#QAHs$A$Ò?òK?LÿÇ=&TA#QAHs$AiA¹tSA¥'A§A«©QA8)A¿ò?péL?ˆF=&TA#QAHs$A§A«©QA8)A·~AÛÿPA«”$A[p?ÓšR?ŽÅ=·~AÛÿPA«”$A§A«©QA8)A GAêOA¤ö*AF?yT?:‰C=·~AÛÿPA«”$A GAêOA¤ö*AÂÕAúTOAŸe&Asäþ>T±\?0Â=ÂÕAúTOAŸe&A GAêOA¤ö*AW­ATNAqÇ,Asü>d^?œ‚@=ÂÕAúTOAŸe&AW­ATNAqÇ,AËJA×MAuH(A| ý¾ùj‚¾iÇT?úé@SB)A­ˆAAÑí@%W(A8,BAžíï@‡u,A—)DA3ø¾85…¾ÆU?žíï@‡u,A—)DAÑí@%W(A8,BA^Ê÷@N–%AlDAî¾ga¾_‰[?žíï@‡u,A—)DA^Ê÷@N–%AlDAå&ú@ÆÉ)A®HFA/dð¾ð ‰¾ë`W?å&ú@ÆÉ)A®HFA^Ê÷@N–%AlDA"%ü@ ¬$A‡REAÍ“ç¾kh¾Ò\?å&ú@ÆÉ)A®HFA"%ü@ ¬$A‡REAbkA{'AÆyHAz~ï>gòa?ão@=ËJA×MAuH(AW­ATNAqÇ,Ac½A“œMAjŸ(AÑŽÛ>êf?î¿=c½A“œMAjŸ(AW­ATNAqÇ,A?4A=éLA^©.AîØ>7•g?$¥==c½A“œMAjŸ(A?4A=éLA^©.AÝA‡LAô;*A#åº>,m?!¼=ÝA‡LAô;*A?4A=éLA^©.AîÛA‹«KAh›0Am¸>…›n?²:=ÝA‡LAô;*AîÛA‹«KAh›0A¿‹AqfKA?,AƒA§>–¬q?):=¿‹AqfKA?,AîÛA‹«KAh›0A¥§A KAÄ-A z”>[æs?¢y¹=¥§A KAÄ-AîÛA‹«KAh›0AïA÷ÎJA/62A…¹“>…×t?d8=¥§A KAÄ-AïA÷ÎJA/62A9ÇAa¢JA1ç-AUôr>o¢w?¢·=9ÇAa¢JA1ç-AïA÷ÎJA/62AÐèAqíIA94A˜al>˜Óx?<Ë5=9ÇAa¢JA1ç-AÐèAqíIA94A#š AÊßIAúù/A.à龄/Œ¾­X?"%ü@ ¬$A‡REAÐ…AÓ8#Aï¾FAbkA{'AÆyHA< ä¾|‘޾!ÑY?bkA{'AÆyHAÐ…AÓ8#Aï¾FA¤4A‡!AL¨HAÑ5ݾ)’q¾¤Õ^?bkA{'AÆyHA¤4A‡!AL¨HAƒßA+ç%AqHJAmrÚ¾UÖ‘¾r¿[?ƒßA+ç%AqHJA¤4A‡!AL¨HA%! AT A½ KA¤&Ô¾ïw¾Ó—`?ƒßA+ç%AqHJA%! AT A½ KA߃ A®R$AJŒLAp:Ò¾/”¾„_]?߃ A®R$AJŒLA%! AT A½ KAðà A°Au¿KA¦Z;vÛ{¾Tåa?߃ A®R$AJŒLAðà A°Au¿KAqCAØ*#AÔNAS츾ÞÅ>t…k?ûA§TžA*”SAcPAfâžA›]RA!8Ay³œAžÿRA­Ù¼¾¥ò&>§Bj?!8Ay³œAžÿRAcPAfâžA›]RA±qA2¤žA/PAß½¾¾é{í=¾µk?!8Ay³œAžÿRA±qA2¤žA/PAT£AÈoœAÒPA羆~#>¹+i?T£AÈoœAÒPA±qA2¤žA/PAGíA|cžA²NAv¨Â¾Þ­æ=™k?T£AÈoœAÒPAGíA|cžA²NA9LA-œAOA€>Ⱦêß>­1h?9LA-œAOAGíA|cžA²NA, AÌA5iLAý|ǾåÝ=H#j?9LA-œAOA, AÌA5iLAåÖ A¼”›A8UMA0Ͼ[*>bóf?åÖ A¼”›A8UMA, AÌA5iLAû‡ADþœA%JA/‹Ì¾j¤Ñ=S7i?åÖ A¼”›A8UMAû‡ADþœA%JA¹AÉšA¶.KAqÕ¾"‹>˜Àe?¹AÉšA¶.KAû‡ADþœA%JAwAÀú›A2çGAÈAѾ$†Ä=þXh?¹AÉšA¶.KAwAÀú›A2çGAçIAêÊ™AIA‹Û¾u >Ášd?çIAêÊ™AIAwAÀú›A2çGAœH÷@SÁšAó°EAY›Õ¾>K¶=³‰g?çIAêÊ™AIAœH÷@SÁšAó°EAypú@1š˜A£÷FAÆËß¾%â>ÁÍc?ypú@1š˜A£÷FAœH÷@SÁšAó°EA¤gó@h@šAûâDA¯¤×¾ç®=*g?ypú@1š˜A£÷FA¤gó@h@šAûâDA™Éö@b˜A&5FAg9ã¾½®>D$c?™Éö@b˜A&5FA¤gó@h@šAûâDAúhé@ÁɘAÌBAÏÕÚ¾•²¡=ãf?™Éö@b˜A&5FAúhé@ÁɘAÌBAˆdí@´–A¼A`êà¾õ®‚=Oee?p~ä@"•A[YBA“òÖ@€Y•Aß>A®Ü@i“ArŒ@AžØð¾âÒÉ=Ÿ~`?®Ü@i“ArŒ@A“òÖ@€Y•Aß>A Î@Za“A÷ =AMã¾UA’Fó¾„B¼=ú`?;Ô@N‰‘A!×>A Î@Za“A÷ =Ao}Ì@vÝ’AΛAo}Ì@vÝ’AΛAå;õ¾‡j±=¤ _?*[Ò@ ‘AOn>Ao}Ì@vÝ’AΛAÃÅ@•ÅAù:A@iË@«AŽçwª@Ø!pAâq5AC(¿‡%l»D]?>wª@Ø!pAâq5A3,¡@¤$pAæ2Aƒ¡@ÞjABú2A)|é¾J&Y»uÔc?>wª@Ø!pAâq5Aƒ¡@ÞjABú2A—ƪ@FBkAQ„5Aß¿¥•1¼‹]?—ƪ@FBkAQ„5Aƒ¡@ÞjABú2Ab–¢@'‘eA§93AYp龊µÑ»aÖc?—ƪ@FBkAQ„5Ab–¢@'‘eA§93A•À«@ \fAS¾5A˜ã¿æf“¼#]?•À«@ \fAS¾5Ab–¢@'‘eA§93A@H¤@9“`A†3Aåeé¾Y¼A×c?•À«@ \fAS¾5A@H¤@9“`A†3A”K­@нaAÌ6A{Ÿ¿ëϼA?]?”K­@нaAÌ6A@H¤@9“`A†3AB¿¦@ôm[AV.4A'Qé¾ U¼¥Ùc?”K­@нaAÌ6AB¿¦@ôm[AV.4A犯@°ø\Ažž6A@¿‰Å½Ëe]?犯@°ø\Ažž6AB¿¦@ôm[AV.4Aþê©@^VAáç4A\-é¾lм†Þc?犯@°ø\Ažž6Aþê©@^VAáç4A}p²@EXAI7Aˆƒÿ¾X'½Å˜]?}p²@EXAI7Aþê©@^VAáç4AcÍ­@\dQA Ê5AØíè¾t®¼ªèc?}p²@EXAI7AcÍ­@\dQA Ê5A ÿµ@5£SA\8A«>þ¾Å¥H½LÚ]? ÿµ@5£SA\8AcÍ­@\dQA Ê5A€j²@g‚LAÕ6A~…è¾ÙÏÕ¼Öúc? ÿµ@5£SA\8A€j²@g‚LAÕ6A_;º@OAÛ9A6‹ü¾ÿ,m½‡2^?_;º@OAÛ9A€j²@g‚LAÕ6AVW¸@ÁEGA¡)8AÎç¾7 ½Ëd?_;º@OAÛ9AVW¸@ÁEGA¡)8A °¿@!,JAþJ:Aòyú¾ß—‰½`œ^? °¿@!,JAþJ:AVW¸@ÁEGA¡)8Aäo¾@1µBA%…9AVêæ¾Ç¡½4Gd? °¿@!,JAþJ:Aäo¾@1µBA%…9AlQÅ@~áEA„;Aø¾àù›½„_?lQÅ@~áEA„;Aäo¾@1µBA%…9A/Å@ÔZ>A…;AU²å¾©5½£‚d?lQÅ@~áEA„;A/Å@ÔZ>A…;Aa‘Ë@ÆAAjðA…;AÀ”Ì@ï8:Aâ A ò¾yIÁ½ÊJ`?ÛpÒ@AÜ=As>AÀ”Ì@ï8:Aâ A (â¾Ðn½›0e?ÛpÒ@AÜ=As>AD¢Ô@¯R6A—_>AÉñÙ@E':Aô@A›cӽMa?ÉñÙ@E':Aô@AD¢Ô@¯R6A—_>AVéÜ@ Ø2A)&@AµÞß¾Z…½˜ e?ÉñÙ@E':Aô@AVéÜ@ Ø2A)&@AÀ­á@?Õ6AE¿AAwGê¾Ewå½,Ða?À­á@?Õ6AE¿AAVéÜ@ Ø2A)&@Ae-æ@ {/A¥BA_ݾÜ;”½ë)f?À­á@?Õ6AE¿AAe-æ@ {/A¥BAê[ê@œ3A’˜CA}™å¾ÒC÷½,¸b?ê[ê@œ3A’˜CAe-æ@ {/A¥BAžíï@‡u,A—)DA ÐÙ¾ô(£½µÇf?ê[ê@œ3A’˜CAžíï@‡u,A—)DAX„ó@A³0A:†EAãwà¾*¾3´c?X„ó@A³0A:†EAžíï@‡u,A—)DAå&ú@ÆÉ)A®HFAx Ö¾×¶±½3yg?X„ó@A³0A:†EAå&ú@ÆÉ)A®HFAN$ý@m.A‡GA·âÚ¾á ¾¯Ãd?N$ý@m.A‡GAå&ú@ÆÉ)A®HFAbkA{'AÆyHAûÒ¾B²¿½þ=h?N$ý@m.A‡GAbkA{'AÆyHAÍœAÞ+AÑ™IAObվШ¾'Ëe?ÍœAÞ+AÑ™IAbkA{'AÆyHAƒßA+ç%AqHJA‹0ξ1˽[ñh?ÍœAÞ+AÑ™IAƒßA+ç%AqHJA†ÒAæQ*A?PKAO½Ï¾¯™¾ŽÙf?†ÒAæQ*A?PKAƒßA+ç%AqHJA߃ A®R$AJŒLA°ŠÉ¾Ê¦Ö½-Ìi?†ÒAæQ*A?PKA߃ A®R$AJŒLA** AEÁ(A‰vMAÀɾTc¾?h?** AEÁ(A‰vMA߃ A®R$AJŒLAqCAØ*#AÔNAraľ¸žá½|»j?** AEÁ(A‰vMAqCAØ*#AÔNAžAH—'Am¡OA&¾9#¾Wi?žAH—'Am¡OAqCAØ*#AÔNAµAq"A»QAwê¾¾&"ë½%¶k?žAH—'Am¡OAµAq"A»QA+A”Õ&AÎÏQA;¶¾¤¾ã@l?ÔùAȘAh—SA¥XAß~šAöSAP±AYO˜AR‘RAkж¾tïæ½N`m?P±AYO˜AR‘RA¥XAß~šAöSA¤Aè5šA…ûPA¼³¾;$¾ÅDl?P±AYO˜AR‘RA¤Aè5šA…ûPA€·A³˜AçPAî´¾³øñ½š¢m?€·A³˜AçPA¤Aè5šA…ûPAšèAnñ™A‹¹OAÛ㯾{e)¾©l?€·A³˜AçPAšèAnñ™A‹¹OAP¿AÍ»—AQZOAóÀ²¾ø¤ú½!Öm?P¿AÍ»—AQZOAšèAnñ™A‹¹OA! ArX™Aë¦MAÎ.¬¾rp.¾Ým?P¿AÍ»—AQZOA! ArX™Aë¦MAèèAÖ"—A¥\MAt°¯¾‘Ö¾ª8n?èèAÖ"—A¥\MA! ArX™Aë¦MA®ºAP˜A<šKAAL§¾&•3¾¿m?èèAÖ"—A¥\MA®ºAP˜A<šKA<2 AÏ\–AdeKA(4¬¾€´¾Þ¯n?<2 AÏ\–AdeKA®ºAP˜A<šKA^ÕAÓ–—Aö”IAù¡¾êÃ7¾˜wn?<2 AÏ\–AdeKA^ÕAÓ–—Aö”IATžA¦j•AvIAcH¨¾þÆ ¾=o?TžA¦j•AvIA^ÕAÓ–—Aö”IAÛ)þ@Fo–A}˜GA52œ¾¿Ñ:¾êGo?TžA¦j•AvIAÛ)þ@Fo–A}˜GA×/AÖL”AñGA”¤¾ƒ6¾|Ëo?×/AÖL”AñGAÛ)þ@Fo–A}˜GA ¿ú@¿ö•A àFA¬U˜¾³ï;¾Ùo?×/AÖL”AñGA ¿ú@¿ö•A àFAW1ÿ@ÍØ“AØßFA;¢¾T·¾à"p?W1ÿ@ÍØ“AØßFA ¿ú@¿ö•A àFA—øñ@.›”A`EA®“¾·É<¾rˆp?W1ÿ@ÍØ“AØßFA—øñ@.›”A`EAY ÷@€‹’AhEA‹p¾¦$¾ñàp?Y ÷@€‹’AhEA—øñ@.›”A`EA¾®é@™“A©9CA€"¾Íd<¾Wˆq?Y ÷@€‹’AhEA¾®é@™“A©9CA%]ï@¢‘AÜeCAV˜¾Î2¾²q?%]ï@¢‘AÜeCA¾®é@™“A©9CAOäá@‹v‘A9‡AAcR†¾1G:¾žšr?%]ï@¢‘AÜeCAOäá@‹v‘A9‡AA,è@ÞArÉAAîô’¾¹¶¾•r?,è@ÞArÉAAOäá@‹v‘A9‡AA’šÚ@­¯Aì?A&’~¾Ú@6¾¦½s?,è@ÞArÉAA’šÚ@­¯Aì?A®wá@ àAD@A¶j޾ ¾’Zs?®wá@ àAD@A’šÚ@­¯Aì?AHߨ@L9A¸‰?A ¯v¾n$3¾dt?®wá@ àAD@AHߨ@L9A¸‰?AÔàß@}pAç?AÇú‹¾ u ¾Äs?Ôàß@}pAç?AHߨ@L9A¸‰?AqxÒ@ÀZA>A)âl¾j.¾–5u?Ôàß@}pAç?AqxÒ@ÀZA>A$Ú@Å®‹A{>A(l†¾“¾Í»t?$Ú@Å®‹A{>AqxÒ@ÀZA>A?­Ì@Kf‹AèÌA?­Ì@Kf‹AèÌfA y9AÅDY¾ à–½˜uy?»–Ä@>fA y9A@Òº@jE‚A£¯8AÝZ¸@^€A^8A³Ó!¾^¤¬½4Ü{?»–Ä@>fA y9AÝZ¸@^€A^8AdaÂ@³À~AEï8A™ÐR¾[Öm½z?daÂ@³À~AEï8AÝZ¸@^€A^8A¾{¶@§{A`ª7A­¾a߃½t†|?daÂ@³À~AEï8A¾{¶@§{A`ª7AqµÀ@d¥zAw†8A°7N¾ ×0½î‚z?qµÀ@d¥zAw†8A¾{¶@§{A`ª7AG¬µ@~yARy7Aég¾ÿ¼G½cê|?qµÀ@d¥zAw†8AG¬µ@~yARy7Apü¿@tÈ@qXAX[:A•,h¾gÈ=Hx?;>È@qXAX[:Arã¾@§áUAš¢9Ae½Â@º¥QAø†:A*›:¾€Ú>yœy?;>È@qXAX[:Ae½Â@º¥QAø†:A{·Ë@&TA¢0;Añr¾_ýß=Ù*w?{·Ë@&TA¢0;Ae½Â@º¥QAø†:A³·Ç@MAë;AiG¾à>"yx?{·Ë@&TA¢0;A³·Ç@MAë;A39Ð@\çOAÔBˆKw?39Ð@\çOAÔB¡4u?ÅèÔ@)LA ]=AoßÌ@IAIØAB4b¾n|'>Å#v?ÅèÔ@)LA ]=A^Ò@^3EAç#>Aå%Ú@ÂŒHAM•>A¼O‰¾½a>ö@t?å%Ú@ÂŒHAM•>A^Ò@^3EAç#>APóØ@ƒ‚AA+Ž?A+âo¾G`/>ìût?å%Ú@ÂŒHAM•>APóØ@ƒ‚AA+Ž?A5óß@ÄEAJë?Az½Ž¾d§ >Rs?5óß@ÄEAJë?APóØ@ƒ‚AA+Ž?Aéãß@Âÿ=AÈAA~¨}¾ªG5>{Øs?5óß@ÄEAJë?Aéãß@Âÿ=AÈAATæ@vÄAAÜ^AA”¾àG>Hor?Tæ@vÄAAÜ^AAéãß@Âÿ=AÈAAÐç@O×:AM¨BA¶}…¾g;9>ÄÄr?Tæ@vÄAAÜ^AAÐç@O×:AM¨BAòì@ Æ>AÂÛBAþ ™¾]L>Gžq?òì@ Æ>AÂÛBAÐç@O×:AM¨BA$ï@ôÂ7A&gDA™Œ¾Ði;>¨»q?òì@ Æ>AÂÛBA$ï@ôÂ7A&gDAkô@<×;A›„DA þ¾w÷>Õp?kô@<×;A›„DA$ï@ôÂ7A&gDAQ°÷@Ý÷4AH:FA(‘’¾·<>Ò½p?kô@<×;A›„DAQ°÷@Ý÷4AH:FAyYü@Á*9A°AFAPŸ¢¾VT>"p?yYü@Á*9A°AFAQ°÷@Ý÷4AH:FAåXAëx2AŠ HA"¾˜¾w;>xÓo?yYü@Á*9A°AFAåXAëx2AŠ HA­]A½Ã6AëHAö禾jŠ >ü|o?­]A½Ã6AëHAåXAëx2AŠ HA‹AØI0AçJAd–ž¾R»8>!ýn?­]A½Ã6AëHA‹AØI0AçJAÇA¦4ANôIA;´ª¾>añn?ÇA¦4ANôIA‹AØI0AçJA“ AÿÅ.A+ºKAЀ£¾WÇ5>Mn?ÇA¦4ANôIA“ AÿÅ.A+ºKA*{ A“+3A„KA{²­¾>+‹n?*{ A“+3A„KA“ AÿÅ.A+ºKA¡Aó9-A³ÆMAÅ/¨¾+1>'¯m?*{ A“+3A„KA¡Aó9-A³ÆMA’2AY¥1A&{MA´á°¾Îý=@"n?’2AY¥1A&{MA¡Aó9-A³ÆMAÚ5Ag,AnØOAÀ笾C,>¯m?’2AY¥1A&{MAÚ5Ag,AnØOAóA~y0AxOAå§³¾Yò=Ím?óA~y0AxOAÚ5Ag,AnØOA¿uA=E+A<îQAÎ3±¾¾1&>ÆŽl?óA~y0AxOA¿uA=E+A<îQAÞøAª/AnyQA ꮾî.”¾Ççd?ïnAÍE–ASiRAP±AYO˜AR‘RAq@Aˆ/–AƒQA„}®¾Èµ~¾h?q@Aˆ/–AƒQAP±AYO˜AR‘RA€·A³˜AçPAD¨¾g—¾Âªe?q@Aˆ/–AƒQA€·A³˜AçPA¢”A5Þ•AE‘OA=ú§¾h‡‚¾lÛh?¢”A5Þ•AE‘OA€·A³˜AçPAP¿AÍ»—AQZOA-¡¾Åš¾õrf?¢”A5Þ•AE‘OAP¿AÍ»—AQZOAÌAx—•AOeNA¢¾žÊ„¾æi?ÌAx—•AOeNAP¿AÍ»—AQZOAèèAÖ"—A¥\MA>%™¾l—œ¾mdg?ÌAx—•AOeNAèèAÖ"—A¥\MA1EAxÿ”AçwLAŸkš¾ b‡¾3j?1EAxÿ”AçwLAèèAÖ"—A¥\MA<2 AÏ\–AdeKA >¾æÔž¾Ó—h?1EAxÿ”AçwLA<2 AÏ\–AdeKAƒÞ Al=”AJ‘JAà‘¾ÌB‰¾Ä˜k?ƒÞ Al=”AJ‘JA<2 AÏ\–AdeKATžA¦j•AvIA\Þ„¾93 ¾æäi?ƒÞ Al=”AJ‘JATžA¦j•AvIAñšA`R“Aí²HAÆÝˆ¾aUоåÉl?ñšA`R“Aí²HATžA¦j•AvIA×/AÖL”AñGAo t¾Ï— ¾ðLk?ñšA`R“Aí²HA×/AÖL”AñGA }Aú>’A/ÞFAF¾…‡Š¾xØm? }Aú>’A/ÞFA×/AÖL”AñGAW1ÿ@ÍØ“AØßFA®of¾V ¾3l? }Aú>’A/ÞFAW1ÿ@ÍØ“AØßFA‰A¤Ï‘A4FAe½w¾ìLоX“n?‰A¤Ï‘A4FAW1ÿ@ÍØ“AØßFAY ÷@€‹’AhEA\MU¾[Ÿ¾A^m?‰A¤Ï‘A4FAY ÷@€‹’AhEA|ü@‘AR~DAKd¾V‰¾Döo?|ü@‘AR~DAY ÷@€‹’AhEA%]ï@¢‘AÜeCAÚ|>¾L¾gõn?|ü@‘AR~DA%]ï@¢‘AÜeCAšgõ@+4AëÜBAkP¾T¸†¾–kq?šgõ@+4AëÜBA%]ï@¢‘AÜeCA,è@ÞArÉAA2['¾Óy™¾žp?šgõ@+4AëÜBA,è@ÞArÉAALËî@¹ºA„QAA9<¾(ƒ¾cñr?LËî@¹ºA„QAA,è@ÞArÉAA®wá@ àAD@Ag¾‹~”¾Vr?LËî@¹ºA„QAA®wá@ àAD@Az§è@µ%ŒAüÜ?A\:,¾ø~¾ˆ+t?z§è@µ%ŒAüÜ?A®wá@ àAD@AÔàß@}pAç?A©¾âU‘¾#As?z§è@µ%ŒAüÜ?AÔàß@}pAç?AÇ3ç@伋A„?A“ú"¾œÉy¾‡æt?Ç3ç@伋A„?AÔàß@}pAç?A$Ú@Å®‹A{>A¡×æ½4OŒ¾Á€t?Ç3ç@伋A„?A$Ú@Å®‹A{>AÜá@qŠAO:>Az¾þl¾õsv?Üá@qŠAO:>A$Ú@Å®‹A{>A»Ô@tÚ‰AZR=AEߺ½6„¾L6v?Üá@qŠAO:>A»Ô@tÚ‰AZR=A³Ý@fbˆAA=A£1ù½_]¾Ùüw?³Ý@fbˆAA=A»Ô@tÚ‰AZR=AÕÐ@Åô‡Aø5¾Eq{?<úÓ@l9„AË:A¿WÇ@=eƒAÆ#:A«Ñ@Çh‚A5 :A“½Ý¾Æ‹|?«Ñ@Çh‚A5 :A¿WÇ@=eƒAÆ#:A»–Ä@>fA y9AüÝV¼<‹"¾b»|?«Ñ@Çh‚A5 :A»–Ä@>fA y9ARŒÎ@““€A*i9A™xh½Tý½Ÿ}?RŒÎ@““€A*i9A»–Ä@>fA y9AdaÂ@³À~AEï8A¸ü­¹°¾z×}?RŒÎ@““€A*i9AdaÂ@³À~AEï8AE•Ì@Òr}Atç8A"¡?½5öŽ…~?E•Ì@Òr}Atç8AdaÂ@³À~AEï8AqµÀ@d¥zAw†8A(#<ìžÉ½a¾~?E•Ì@Òr}Atç8AqµÀ@d¥zAw†8A~Ë@Ÿ²yAí„8A× #½ø’½ö"?~Ë@Ÿ²yAí„8AqµÀ@d¥zAw†8Apü¿@tZ8A¸i½¶ËQ½x?™uÊ@€wA>Z8Apü¿@tZ8A¿0¿@I-tAß&8A\ÁÉ@\ÍsA.+8AÕŽ8³¼]Í?\ÁÉ@\ÍsA.+8A¿0¿@I-tAß&8Aê¾@YpA‘8AGy½<å®Z¼¡è?\ÁÉ@\ÍsA.+8Aê¾@YpA‘8ANƒÉ@ÎpAñ8AG2½Ÿ|@}?¾!Í@bjaAÄ 9ADXÅ@I\A¨9AÞ8Ï@»Â]As•9AFω½ÊÑ>²|?Þ8Ï@»Â]As•9ADXÅ@I\A¨9A;>È@qXAX[:A_I­¼Æ×1>+ |?Þ8Ï@»Â]As•9A;>È@qXAX[:AÞÏÑ@Ä ZA¯>:AÚ¥½i,>~{?ÞÏÑ@Ä ZA¯>:A;>È@qXAX[:A{·Ë@&TA¢0;AY€½À L>D¯z?ÞÏÑ@Ä ZA¯>:A{·Ë@&TA¢0;AbíÔ@j„VAd;A¬oƽùaB>Mz?bíÔ@j„VAd;A{·Ë@&TA¢0;A39Ð@\çOAÔBéy?bíÔ@j„VAd;A39Ð@\çOAÔBÛ’x?UüØ@U–RAK Zjw?UüØ@U–RAK ªw?9Ý@OAo=AÅèÔ@)LA ]=Aå%Ú@ÂŒHAM•>A·ǽŠ{†>Áu?9Ý@OAo=Aå%Ú@ÂŒHAM•>A»úá@Ò¼KAÃA>Ap¾‘‡t>óu?»úá@Ò¼KAÃA>Aå%Ú@ÂŒHAM•>A5óß@ÄEAJë?A¥Úò½ÛŽ>4t?»úá@Ò¼KAÃA>A5óß@ÄEAJë?ADç@–|HA ˆ?A©{.¾Cœ>-t?Dç@–|HA ˆ?A5óß@ÄEAJë?ATæ@vÄAAÜ^AAºÜ¾²F”>4`r?Dç@–|HA ˆ?ATæ@vÄAAÜ^AA{í@(^EAuë@A¯öA¾Ç„>·ˆr?{í@(^EAuë@ATæ@vÄAAÜ^AAòì@ Æ>AÂÛBAçù%¾… ™>î¾p?{í@(^EAuë@Aòì@ Æ>AÂÛBAÜ-ó@´‰BAoXBAýU¾u"‡>Xq?Ü-ó@´‰BAoXBAòì@ Æ>AÂÛBAkô@<×;A›„DA^q<¾4–œ>1#o?Ü-ó@´‰BAoXBAkô@<×;A›„DAPú@ÐÀ?ADðCA¨¬h¾Q.‰>Á®o?Pú@ÐÀ?ADðCAkô@<×;A›„DAyYü@Á*9A°AFA9S¾ùöž>.m?Pú@ÐÀ?ADðCAyYü@Á*9A°AFA{²A¹3=AKœEA´Å{¾5'Š>=Un?{²A¹3=AKœEAyYü@Á*9A°AFA­]A½Ã6AëHAr;i¾q* >—l?{²A¹3=AKœEA­]A½Ã6AëHA%•A¾å:As[GA,)‡¾$Š>¾m?%•A¾å:As[GA­]A½Ã6AëHAÇA¦4ANôIA)ä~¾RG >K¢j?%•A¾å:As[GAÇA¦4ANôIAˆ¯AåÚ8AÎ,IAF¬¾‡Z‰>ðëk?ˆ¯AåÚ8AÎ,IAÇA¦4ANôIA*{ A“+3A„KAÚ¼ˆ¾gšŸ>0pi?ˆ¯AåÚ8AÎ,IA*{ A“+3A„KA‡" Ak7AÞ®JAÅ—¾ä‡>ùùj?‡" Ak7AÞ®JA*{ A“+3A„KA’2AY¥1A&{MAp ’¾[ÿ>MIh?‡" Ak7AÞ®JA’2AY¥1A&{MA ŠA^ì5Al•LAkFŸ¾Š’…>¬ói? ŠA^ì5Al•LA’2AY¥1A&{MAóA~y0AxOA Ö›¾Í†›>Ig? ŠA^ì5Al•LAóA~y0AxOA"AÂ4A‚NAà§¾„™‚>Ñi?"AÂ4A‚NAóA~y0AxOAÞøAª/AnyQA»¥¾GM˜>; f?"AÂ4A‚NAÞøAª/AnyQA^²Anî3A§sPADÙ™¾‚”¿½®M?[AI““AZPAPAÅ)”AzëOA:öAëG’A.ÒMAž”¾-ÿ¿£^P?:öAëG’A.ÒMAPAÅ)”AzëOA·£A#Ö“A—NAÁ^ˆ¾EË ¿SUK?:öAëG’A.ÒMA·£A#Ö“A—NAsßAªó‘A¡ñKAñ5…¾Ê¿@¿Q?sßAªó‘A¡ñKA·£A#Ö“A—NA‘ AX“AbßLAQu¾Z0 ¿öL?sßAªó‘A¡ñKA‘ AX“AbßLAsqAÈ­‘APÐJAÙ;q¾™Ü¿+úR?sqAÈ­‘APÐJA‘ AX“AbßLAàÏAˆù’AbýJAùnT¾z@¿FN?sqAÈ­‘APÐJAàÏAˆù’AbýJAÞ€AŸ‘AÐôHAÖ«M¾ É¿¡¾T?Þ€AŸ‘AÐôHAàÏAˆù’AbýJA€¶ A<’Ac"IAQ-¾­Ó¿uúO?Þ€AŸ‘AÐôHA€¶ A<’Ac"IAK°AeAc GA()¾ü¿MŸV?K°AeAc GA€¶ A<’Ac"IA<À A‘Y‘AÚOGA¦¥¾.š¿föQ?K°AeAc GA<À A‘Y‘AÚOGA[ A‹AzTEA“´¾‡f¿bX?[ A‹AzTEA<À A‘Y‘AÚOGA}ïATQA&‡EA¹½Bƒ ¿JT?[ A‹AzTEA}ïATQA&‡EAUyAÐŽŽAn’CA­éɽ]¿ŸEZ?UyAÐŽŽAn’CA}ïATQA&‡EAK’AéæAþáDA›°ˆ½| ¿…SU?UyAÐŽŽAn’CAK’AéæAþáDAT6A…)ŽA»ïBAÔž½$9¿ ‚[?T6A…)ŽA»ïBAK’AéæAþáDAýAr·ŽA¦7CAä½™‰ ¿ŒW?T6A…)ŽA»ïBAýAr·ŽA¦7CAOÿA AÜKAAÃ%½Ô1ÿ¾L±]?OÿA AÜKAAýAr·ŽA¦7CAç©û@£lA ¢AAsC„;u?¿»ZY?OÿA AÜKAAç©û@£lA ¢AAEÿA´Ð‹A¼?A+tb»ø¾mñ_?EÿA´Ð‹A¼?Aç©û@£lA ¢AA ™õ@JŒAP"@A§«2=ÿò¿–°[?EÿA´Ð‹A¼?A ™õ@JŒAP"@AMmü@÷€ŠAC>A~ƒ=Öóî¾Á?b?Mmü@÷€ŠAC>A ™õ@JŒAP"@Aýï@‹ŠAF¹>AÉš©=ƒ&û¾A^?Mmü@÷€ŠAC>Aýï@‹ŠAF¹>AhJ÷@q‰Aàd?hJ÷@q‰AàAªî@5)ŠA6c>A÷™Ò=[æô¾×D_?hJ÷@q‰AàAÜö@W¿ˆA‹AåÍé@ôžˆA-$=A>GÙê¾ a?Üö@W¿ˆA‹Ó¾ukg?ܦñ@·N‡A R;AåÍé@ôžˆA-$=Aâtå@°‡AZ͘۾¢Wc?ܦñ@·N‡A R;Aâtå@°‡AZËþ›¡i?ò³í@(Ó…Au5:Aâtå@°‡AZCʾ”e?ò³í@(Ó…Au5:Aûšá@¤d…AÎý:A¯7ê@ÙM„AÉ59AA3>Q²¾)Âk?¯7ê@ÙM„AÉ59Aûšá@¤d…AÎý:AÞ;Þ@¶ƒAy:A89l>3̶¾˜¸g?¯7ê@ÙM„AÉ59AÞ;Þ@¶ƒAy:Aa-ç@¿‚AîR8A)J>CM£¾JOm?a-ç@¿‚AîR8AÞ;Þ@¶ƒAy:A[GÝ@{-ƒAZÔ9AÜ3}>(;«¾‹Îh?a-ç@¿‚AîR8A[GÝ@{-ƒAZÔ9AlQæ@Ò@‚A8AÎX>3„˜¾PVn?lQæ@Ò@‚A8A[GÝ@{-ƒAZÔ9AAŸÚ@³Aü9A×Úˆ>#”š¾ÑCj?lQæ@Ò@‚A8AAŸÚ@³Aü9Aÿîã@%¶€A{\7A– p>‰Iƒ¾¡ p?ÿîã@%¶€A{\7AAŸÚ@³Aü9A†nØ@¦Ar€8A’ø”>Îlƒ¾Çñk?ÿîã@%¶€A{\7A†nØ@¦Ar€8A^ùá@ÀS~A#Å6A“O‚>í'Y¾@‹q?^ùá@ÀS~A#Å6A†nØ@¦Ar€8AůÖ@$B|A"8A1Ÿ>U¾Ïam?^ùá@ÀS~A#Å6AůÖ@$B|A"8Aàjà@è6{AuK6A϶Š>%ÿ(¾áÆr?àjà@è6{AuK6AůÖ@$B|A"8An_Õ@SÕxAÍ¥7A\§>®}!¾†‹n?àjà@è6{AuK6An_Õ@SÕxAÍ¥7A ?ß@…xA+ï5A’|>2“ú½ê–s? ?ß@…xA+ï5An_Õ@SÕxAÍ¥7AŠÎÔ@QÔvAö|7Am ¬>æ]ô½™+o? ?ß@…xA+ï5AŠÎÔ@QÔvAö|7Aí¾Þ@ >vA9Ç5A ¸“>ÉD±½t?í¾Þ@ >vA9Ç5AŠÎÔ@QÔvAö|7Af/Ô@vsAõO7Aù˜¯>#‚—½ï¹o?í¾Þ@ >vA9Ç5Af/Ô@vsAõO7A·1Þ@)sA6›5ADw–>j½…t?·1Þ@)sA6›5Af/Ô@vsAõO7A¤øÓ@|pAp@7A»²±>½5§¼Áp?·1Þ@)sA6›5A¤øÓ@|pAp@7A+Þ@upA Œ5AÉò–>o<È—t?+Þ@upA Œ5A¤øÓ@|pAp@7A(*Ô@bµlAyN7Aïf±>;` =ýo?+Þ@upA Œ5A(*Ô@bµlAyN7A-Þ@ þlA™5Au#•>s*†=ëRt?-Þ@ þlA™5A(*Ô@bµlAyN7AÆÔ@FLiA¹z7A®®>þ³=¿˜o?-Þ@ þlA™5AÆÔ@FLiA¹z7Aâ·Þ@ÂßiAÅ5A®$‘>¿ë= ¹s?â·Þ@ÂßiAÅ5AÆÔ@FLiA¹z7A=¿Õ@ÅfA½À7A‘Ë©>> >3ãn?â·Þ@ÂßiAÅ5A=¿Õ@ÅfA½À7AÍ”ß@VêfA… 6AO$‹>6&>,×r?Í”ß@VêfA… 6A=¿Õ@ÅfA½À7Ad,×@ï³bAë&8A¾©¢>ÞWA>+àm?Í”ß@VêfA… 6Ad,×@ï³bAë&8AìÙà@$ÕcA€m6A¶ù‚>ÂU>´¤q?ìÙà@$ÕcA€m6Ad,×@ï³bAë&8AÙ@áZ_Aìª8A[™>Ì's>°l?ìÙà@$ÕcA€m6AÙ@áZ_Aìª8A‘‚â@ÍÁ`A¹î6A±Õq> z>½/p?‘‚â@ÍÁ`A¹î6AÙ@áZ_Aìª8AbWÛ@œ\AdM9AAŽ>š)‘>´ýj?‘‚â@ÍÁ`A¹î6AbWÛ@œ\AdM9A”ä@!¯]AÛ7A3Z>Õµ–>Ón?”ä@!¯]AÛ7AbWÛ@œ\AdM9AL!Þ@İXAM:ARý€>•J§>à1i?”ä@!¯]AÛ7AL!Þ@İXAM:Axç@–œZAæK8AÞb>>ÿª>\l?xç@–œZAæK8AL!Þ@İXAM:A,Çá@<UA‘ ;Aµ]b>l ½>g?xç@–œZAæK8A,Çá@<UA‘ ;A›_ê@Á>WARA9A >Ç+¾>•[j?›_ê@Á>WARA9A,Çá@<UA‘ ;ATšå@0ÓQA- —9Ð>¼Úd?›_ê@Á>WARA9ATšå@0ÓQA- TA?:Aký=ˆÎ>¯3h?äÕí@M>TA?:ATšå@0ÓQA- m¨à>Ÿb?äÕí@M>TA?:AÄéé@&¯NAa+=A9Àñ@âPQAY;AÕq¹=àÜ>²ûe?9Àñ@âPQAY;AÄéé@&¯NAa+=Aa¹î@¤KAg>Aò ó=ï>¹T`?9Àñ@âPQAY;Aa¹î@¤KAg>AÓ"ö@ÝxNATdºc?Ó"ö@ÝxNATAƒ ô@«¶HAZ¿?A¥ð¦=ä~û>S^?Ó"ö@ÝxNAT}a?Uû@b¹KAÅá=Aƒ ô@«¶HAZ¿?A¶žù@‘ FAj!AALŒ5=l×?¨¾[?Uû@b¹KAÅá=A¶žù@‘ FAj!AAØAv6IA >?A0Hg¼­>ú>WO_?ØAv6IA >?A¶žù@‘ FAj!AAûòÿ@›hCAŽ­BA9¦½;w ?czY?ØAv6IA >?Aûòÿ@›hCAŽ­BA(øA¹FAéÃ@A>mP½mb?¿]?(øA¹FAéÃ@Aûòÿ@›hCAŽ­BAÕZAû@AÏMDAøþ ½CZ ?¢8W?(øA¹FAéÃ@AÕZAû@AÏMDA|AJlDAÆ]BA_q³½W¼?WôZ?|AJlDAÆ]BAÕZAû@AÏMDAÔòA®Ç>A(FAÞ•½È¶ ?d U?|AJlDAÆ]BAÔòA®Ç>A(FAji A¶SBA£ DAT_þ½=:?šãX?ji A¶SBA£ DAÔòA®Ç>A(FAÿÀ A8ÑIAv¦e¾;/?•S?°¼Aµ=A>IAA©ø9A5KA'IAhÒ8A}ûLAf}a¾Õ ?'‡M?°¼Aµ=A>IA'IAhÒ8A}ûLAʬAË•¿™¤ ?ì!AiOAciIAŒA"“AmAKAØX A¹A¶EHA‚\¾z8¿s·(?ØX A¹A¶EHAŒA"“AmAKA§AA9@AÆbIAKd<¾{A¿«O!?ØX A¹A¶EHA§AA9@AÆbIAfÃAUÄŽAÖdFAÅ0¾à:¿î6*?fÃAUÄŽAÖdFA§AA9@AÆbIA‘üAZüA’BHAχ¾w;B¿z“"?fÃAUÄŽAÖdFA‘üAZüA’BHA£A®ƒŽA*CEA0 ¾*Ð:¿6—+?£A®ƒŽA*CEA‘üAZüA’BHAVOAoAÙhFA4äʽqÂB¿3$?£A®ƒŽA*CEAVOAoAÙhFAÐ1AïýAÎfCAï9«½èÿ:¿…-?Ð1AïýAÎfCAVOAoAÙhFAEÁA¨ÀŽA–DA’”8½ÖmB¿"&?Ð1AïýAÎfCAEÁA¨ÀŽA–DASÞAVXA$‘AA°%½M&:¿Ì/?SÞAVXA$‘AAEÁA¨ÀŽA–DAÙTAþðAºËBA5<¸ÿ@¿µ+(?SÞAVXA$‘AAÙTAþðAºËBAäªA ”ŒA™Ã?Aåå­¿ÛP*?äªA ”ŒA™Ã?A1 AhA AA|™ A䱋A~ÿ=A&{‚=Þ5¿mm3?|™ A䱋A~ÿ=A1 AhA AAˆà Ak¡ŒAåh@A4›Ç=÷\<¿S+?|™ A䱋A~ÿ=Aˆà Ak¡ŒAåh@A¬ A_W‹Aí[=AÀ=U¨3¿zÈ4?¬ A_W‹Aí[=Aˆà Ak¡ŒAåh@AûåA ‘‹A6Æ>AÃc>°é8¿}_-?¬ A_W‹Aí[=AûåA ‘‹A6Æ>Aº A±VŠAxµ;Aç?>ü.¿™7?º A±VŠAxµ;AûåA ‘‹A6Æ>AËAjŠAü7=ApjF>~3¿ª/?º A±VŠAxµ;AËAjŠAü7=AÆ#Aó@‰A@#:AÒ¸I>)¿ w9?Æ#Aó@‰A@#:AËAjŠAü7=AAŽA.‰AP¿;Ai†|>?Ð,¿h2?Æ#Aó@‰A@#:AAŽA.‰AP¿;A$¿AÖˆAd¦8AE}>˜ó!¿á;?$¿AÖˆAd¦8AAŽA.‰AP¿;Abþ@‚Þ‡A]:A˜>ÝÏ$¿ëb4?$¿AÖˆAd¦8Abþ@‚Þ‡A]:A»‹At܆A¶?7A/Õ‘>d¸¿œ¨=?»‹At܆A¶?7Abþ@‚Þ‡A]:A{Eý@/ˆ‡A:Aùú¥>3M ¿ç†5?»‹At܆A¶?7A{Eý@/ˆ‡A:A`A^‹†A)ê6A¿°>&@¿Sæ>?`A^‹†A)ê6A{Eý@/ˆ‡A:A­4ù@$/†A‘Ï8A.;¸>T¿ S7?`A^‹†A)ê6A­4ù@$/†A‘Ï8A}#AkG…AЬ5A¤é´>Ät ¿Ù>A?}#AkG…AЬ5A­4ù@$/†A‘Ï8A,—õ@¤Ì„AL³7Aÿ½Ï>*x¿ëš9?}#AkG…AЬ5A,—õ@¤Ì„AL³7A1ëü@ÓúƒA6Œ4A¿ÍÊ>gy¿z†C?1ëü@ÓúƒA6Œ4A,—õ@¤Ì„AL³7Afhò@ÐaƒAг6AËÊå>üž¿©Ï;?1ëü@ÓúƒA6Œ4Afhò@ÐaƒAг6Aööù@¢¦‚A{ˆ3A¥2ß>”ì¾ÔµE?ööù@¢¦‚A{ˆ3Afhò@ÐaƒAг6AŒ£ï@ôîA Ñ5AÕ6ú>ë¾áé=?ööù@¢¦‚A{ˆ3AŒ£ï@ôîA Ñ5Aže÷@KA¡2Axî>GؾAG?že÷@KA¡2AŒ£ï@ôîA Ñ5A‘Ûî@«yA:5Ab^? ÙÛ¾½ï>?že÷@KA¡2A‘Ûî@«yA:5AH¬ö@BÝ€A”_2AQ&÷>mCɾ”XH?H¬ö@BÝ€A”_2A‘Ûî@«yA:5A|±ì@‰ €AÚ4AÁà?vΞòf@?H¬ö@BÝ€A”_2A|±ì@‰ €AÚ4A«ô@Ñ AR¦1A`P?¡¬¾[J?«ô@Ñ AR¦1A|±ì@‰ €AÚ4A8ëê@"9}A%C4An?è§¾œ B?«ô@Ñ AR¦1A8ëê@"9}A%C4A’ó@Þ]|A· 1AÅå ?ÎN޾aœK?’ó@Þ]|A· 1A8ëê@"9}A%C4A!ƒé@[XzA]É3AðÃ?ëć¾qC?’ó@Þ]|A· 1A!ƒé@[XzA]É3A€¹ñ@„¬yA<0AF??úÔ\¾šÜL?€¹ñ@„¬yA<0A!ƒé@[XzA]É3A5uè@}rwAùl3AÚÍ?sÂL¾ƒ’D?€¹ñ@„¬yA<0A5uè@}rwAùl3Aú¿ð@žövAµ00AÝ?º‡#¾»¨M?ú¿ð@žövAµ00A5uè@}rwAùl3ADè@TÁuAúD3A™¤?¸Ï¾ò'E?ú¿ð@žövAµ00ADè@TÁuAúD3AÔTð@‹auAÃ0Aò?wlæ½&5N?ÔTð@‹auAÃ0ADè@TÁuAúD3A&‚ç@HêrAç3AÛ ?ñ¿½·E?ÔTð@‹auAÃ0A&‚ç@HêrAç3Aeßï@»¹rA Ú/AÄ«?Ô%?½‹žN?eßï@»¹rA Ú/A&‚ç@HêrAç3AzVç@ÇpAµ 3Aa""?0çμ¸F?eßï@»¹rA Ú/AzVç@ÇpAµ 3A·ï@~pAË/Aªö?CË¡ÁËM?ùNð@+¸jA„0Aíúç@,ZjAÈB3AþÁè@9ŸgA[‡3Aå;?Ê-5>^áD?ùNð@+¸jA„0AþÁè@9ŸgA[‡3Aññ@†*hAµK0AÅn?ç\Z>·åL?ññ@†*hAµK0AþÁè@9ŸgA[‡3Afçé@0ÆdApë3AÒ?XÒv>oäC?ññ@†*hAµK0Afçé@0ÆdApë3A9ò@’€eA²0AY6 ?„´Œ> ­K?9ò@’€eA²0Afçé@0ÆdApë3A[gë@àíaAÂl4A ?x›>=›B?9ò@’€eA²0A[gë@àíaAÂl4Apyó@×bA961A–Á?íÕª>20J?pyó@×bA961A[gë@àíaAÂl4A-Gí@_Aô 5Aä ?œº>¨A?pyó@×bA961A-Gí@_Aô 5A¦5õ@È,`A·Ø1AžBø> lÇ>„vH?¦5õ@È,`A·Ø1A-Gí@_Aô 5AÌï@ù:\AÊ5A Í?Î×>ÎN??¦5õ@È,`A·Ø1AÌï@ù:\AÊ5AvQ÷@]Atš2A÷/æ>eã>zF?vQ÷@]Atš2AÌï@ù:\AÊ5AÐŒò@iYAX¿6Aa¢ó>Ðô><=?vQ÷@]Atš2AÐŒò@iYAX¿6A¼ú@õ‘ZA6”3A[Ñ>ã›ý>F6D?¼ú@õ‘ZA6”3AÐŒò@iYAX¿6A6¶õ@*MVAî¼7AA?Þ>gì?¼ ;?¼ú@õ‘ZA6”3A6¶õ@*MVAî¼7Aý@aòWAÿ•4Aé1¼> ?/ýA?ý@aòWAÿ•4A6¶õ@*MVAî¼7AíKù@/‘SA¡Ö8A½õÇ>‹5?Õ8?ý@aòWAÿ•4AíKù@/‘SA¡Ö8AK.A£aUAû³5A¯¥>ã?g±??K.A£aUAû³5AíKù@/‘SA¡Ö8APRý@·çPA` :A"M°>=R? 6?K.A£aUAû³5APRý@·çPA` :AX AÓáRAî6Aù>“û?ŽY=?X AÓáRAî6APRý@·çPA` :AçAÁSNA1^;ANi—>eD%?õ@4?X AÓáRAî6AçAÁSNA1^;An#AÁuPAD8A,k>z£$?;?n#AÁuPAD8AçAÁSNA1^;AÉAAA÷KA¶¹ßÓ,?,þ1?n#AÁuPAD8AÉAAA÷KA¶¹Ê +?.º8?ßTAW=NAž£9AÉAAA÷KA¶¹>AËÊG>rW3?„¸/?ßTAW=NAž£9A|òA…žIAŸ>>AæÖAýLA‘,;A™<>þ„0?¹d6?æÖAýLA‘,;A|òA…žIAŸ>>A¬ÕADrGA\×?A6>Á8?”r-?æÖAýLA‘,;A¬ÕADrGA\×?Aˆ AüûIA ÉA;ð×< ò7?Íê1?¤iAHAMx>Aë AâuEAñ‚AAg2AM­CAu@CA  =W@?)?¤iAHAMx>Ag2AM­CAu@CAùyAqmFA-9@A>#º¼Öé9?žä/?ùyAqmFA-9@Ag2AM­CAu@CAøA]gBAr²DA³i¼ÆA?ŒA'?ùyAqmFA-9@AøA]gBAr²DA’AA9EA°­AA~"‹½Ã×:?Ä".?’AA9EA°­AAøA]gBAr²DA‡AAA,…FA4Є½cªB?m%?’AA9EA°­AA‡AAA,…FAfA3òCALƒCAÁ‡ô½”ö:?v.,?fA3òCALƒCA‡AAA,…FAû3Aù?A1^HAž¡ò½µ›B? ‰#?fA3òCALƒCAû3Aù?A1^HA÷ÖA&ëBAð^EA¤ .¾::?ÁT*?÷ÖA&ëBAð^EAû3Aù?A1^HAüAè*?AbAÙ¬=÷O¿‰4?üA 3ŒAÊ!>ASÞAVXA$‘AAäªA ”ŒA™Ã?AŸ¤=µCT¿u¡ ?üA 3ŒAÊ!>AäªA ”ŒA™Ã?A•÷AÅ{‹AÔL ÕP¿ò“?•÷AÅ{‹AÔL„SI¿UÊ?ÃA±§ŠAÚ€:A|™ A䱋A~ÿ=A¬ A_W‹Aí[=AÆz5>!BN¿Š°?ÃA±§ŠAÚ€:A¬ A_W‹Aí[=A¹ A¼RŠADÚ9AæŠ5>t’F¿½?¹ A¼RŠADÚ9A¬ A_W‹Aí[=Aº A±VŠAxµ;A‹e>t J¿Y?¹ A¼RŠADÚ9Aº A±VŠAxµ;AÛj A¦a‰A–+8AzŠp>¿â@¿¦5?Ûj A¦a‰A–+8Aº A±VŠAxµ;AÆ#Aó@‰A@#:A­â>¥™C¿¢k?Ûj A¦a‰A–+8AÆ#Aó@‰A@#:A#ù A|\ˆAà6A7•>”ç9¿g?#ù A|\ˆAà6AÆ#Aó@‰A@#:A$¿AÖˆAd¦8A‘W®>¸Ñ;¿F‰?#ù A|\ˆAà6A$¿AÖˆAd¦8AǵAÍD‡AI 5A²€±>œ“1¿v¢!?ǵAÍD‡AI 5A$¿AÖˆAd¦8A»‹At܆A¶?7Ad Ë>§2¿p¯?ǵAÍD‡AI 5A»‹At܆A¶?7Ah A”†A³›3A#dÆ>Åk*¿ÚA#?h A”†A³›3A»‹At܆A¶?7A`A^‹†A)ê6A¥8Ù>[‹-¿Ü±?h A”†A³›3A`A^‹†A)ê6A#AÏ…AêC3A¦cÓ>lQ%¿l$?#AÏ…AêC3A`A^‹†A)ê6A}#AkG…AЬ5Aäîì>ìr%¿=U?#AÏ…AêC3A}#AkG…AЬ5A@XAZ„AÜý1A—ì>Û>¿˜•&?@XAZ„AÜý1A}#AkG…AЬ5A1ëü@ÓúƒA6Œ4Añ?€–¿èb?@XAZ„AÜý1A1ëü@ÓúƒA6Œ4A$ÀA cƒA»Ô0A(?ƒó ¿¯(?$ÀA cƒA»Ô0A1ëü@ÓúƒA6Œ4Aööù@¢¦‚A{ˆ3AœÐ?‘€ ¿ê^?$ÀA cƒA»Ô0Aööù@¢¦‚A{ˆ3A°XA&!‚A¿È/A¡ ?cl¿¢±*?°XA&!‚A¿È/Aööù@¢¦‚A{ˆ3Aže÷@KA¡2At¨?òYü¾ªB!?°XA&!‚A¿È/Aže÷@KA¡2AŽ?þ@ä×€A Ú.Aÿü?G꾌,?Ž?þ@ä×€A Ú.Aže÷@KA¡2AH¬ö@BÝ€A”_2Aj0?Çë¾â)"?Ž?þ@ä×€A Ú.AH¬ö@BÝ€A”_2AëŽý@µo€A¨•.AÅê?åõÙ¾w-?ëŽý@µo€A¨•.AH¬ö@BÝ€A”_2A«ô@Ñ AR¦1AÆ&?NÐÓ¾{~#?ëŽý@µo€A¨•.A«ô@Ñ AR¦1AS¥û@T~A“Õ-A4,"?¤º¾ƒ¸.?S¥û@T~A“Õ-A«ô@Ñ AR¦1A’ó@Þ]|A· 1AË .?2³¾îö$?S¥û@T~A“Õ-A’ó@Þ]|A· 1A§ú@ÓÇ{Aø4-Aß,)?~¡™¾p0?§ú@ÓÇ{Aø4-A’ó@Þ]|A· 1A€¹ñ@„¬yA<0Añ´4?ñ¾E8&?§ú@ÓÇ{Aø4-A€¹ñ@„¬yA<0AÕø@ 8yAp³,AðÙ.?nn¾õA1?Õø@ 8yAp³,A€¹ñ@„¬yA<0Aú¿ð@žövAµ00ATü9?·NZ¾ƒ;'?Õø@ 8yAp³,Aú¿ð@žövAµ00Aæ÷@H£vAïP,A¡¨2?30¾¼ú1?æ÷@H£vAïP,Aú¿ð@žövAµ00AÔTð@‹auAÃ0A©î?Änô=Â(? ÷@I‡mAõ+AùNð@+¸jA„0AÌy÷@/÷jAá#,Aû3?ÏK'>O2?Ìy÷@/÷jAá#,AùNð@+¸jA„0Aññ@†*hAµK0At;?o”A>,'?Ìy÷@/÷jAá#,Aññ@†*hAµK0A*ø@qˆhAm,A˜/?/îk>êF1?*ø@qˆhAm,Aññ@†*hAµK0A9ò@’€eA²0AðÓ6?Aîƒ>ä›&?*ø@qˆhAm,A9ò@’€eA²0AÌ-ù@?ÿeA·×,A†w)?ç#˜>|'0?Ì-ù@?ÿeA·×,A9ò@’€eA²0Apyó@×bA961A¢Á0?Z¦> t%?Ì-ù@?ÿeA·×,Apyó@×bA961Asú@ wcA)a-A¯—"?­ì¸>gÉ.?sú@ wcA)a-Apyó@×bA961A¦5õ@È,`A·Ø1A[)?¬YÇ>S$?sú@ wcA)a-A¦5õ@È,`A·Ø1A¡)ü@ÿî`AÝ .Axs?Ù+Ø>L3-?¡)ü@ÿî`AÝ .A¦5õ@È,`A·Ø1AvQ÷@]Atš2Ae® ?Èæ>}"?¡)ü@ÿî`AÝ .AvQ÷@]Atš2AX,þ@Rf^A Ò.AóÅ?P¢ö>+`+?X,þ@Rf^A Ò.AvQ÷@]Atš2A¼ú@õ‘ZA6”3Aü?;+?èŸ ?X,þ@Rf^A Ò.A¼ú@õ‘ZA6”3AÂhAªž[AÝÔ/An“?z÷ ?éI)?ÂhAªž[AÝÔ/A¼ú@õ‘ZA6”3Aý@aòWAÿ•4AL¹ ? V?Ó¥?ÂhAªž[AÝÔ/Aý@aòWAÿ•4AÖÍA=#YAÑÞ0A?Oô>>{?³='?ÖÍA=#YAÑÞ0Aý@aòWAÿ•4AK.A£aUAû³5A’¢ý>—Ô?b©?ÖÍA=#YAÑÞ0AK.A£aUAû³5A€bA¢¶VA<2AÃçÛ>µÍ!?Ñ%?€bA¢¶VA<2AK.A£aUAû³5AX AÓáRAî6A>ä>ã!)?î?€bA¢¶VA<2AX AÓáRAî6Aª(AÆZTAãG3AõÂ>óï+?Gö"?ª(AÆZTAãG3AX AÓáRAî6An#AÁuPAD8AÌgÉ>=>3?èˆ?ª(AÆZTAãG3An#AÁuPAD8Al"A<RA¤¦4AEf§>¹Á4?`Í ?l"A<RA¤¦4An#AÁuPAD8AßTAW=NAž£9Aè&®>¥å;?|~?l"A<RA¤¦4AßTAW=NAž£9A‰5 AüúOAe6A= Œ>D{C?òp?‰5 AüúOAe6AæÖAýLA‘,;AS” A0çMAߟ7A¾g^>hÊB?=‡?S” A0çMAߟ7AæÖAýLA‘,;Aˆ AüûIA ÉCéI?’b?S” A0çMAߟ7Aˆ AüûIA ɳ H?çk?–AÓúKA¯D9Aˆ AüûIA ÉAŒd*>$O?èa?–AÓúKA¯D9A¤iAHAMx>A%×AÖ8JAÒû:A^Ð=ÔL?ë_?%×AÖ8JAÒû:A¤iAHAMx>AùyAqmFA-9@AÁ‡Ù=$øR?"p?%×AÖ8JAÒû:AùyAqmFA-9@A׺A«¤HAZÄ=KÀN?ú}?׺A«¤HAZÄ>A‡’»FEP?Û?b,A„GAÆ>>A’AA9EA°­AAfA3òCALƒCAÞãZ»ÄçV?• ?b,A„GAÆ>>AfA3òCALƒCA¡OAQRFAV@A|˜€½xòP?q?¡OAQRFAV@AfA3òCALƒCA÷ÖA&ëBAð^EA‰‚½úeW?c ?¡OAQRFAV@A÷ÖA&ëBAð^EAjAê\EA€ýAAåºö½‰P?ãM?jAê\EA€ýAA÷ÖA&ëBAð^EAqbAt&BA}?GAq$ü½½V? Á?jAê\EA€ýAAqbAt&BA}?GAðãA¦DA/äCALϽ¿tq¿¢>Ug%A掌AAn@A:#A ÑŒAFIAAúÈ$AËŒAj=Aã„›½?p¿‚¬>úÈ$AËŒAj=A:#A ÑŒAFIAAà A³ŒA„Y?Awß½9t¿yd˜>úÈ$AËŒAj=Aà A³ŒA„Y?AA¸!Aÿá‹Aho;A¾÷ˆ¼N©p¿‡Z®>A¸!Aÿá‹Aho;Aà A³ŒA„Y?A2 ANYŒAb.>Aø‡y<³%t¿|Ê™>A¸!Aÿá‹Aho;A2 ANYŒAb.>AåA ²‹A=:A> =!9p¿M!°>åA ²‹A=:A2 ANYŒAb.>A$ APç‹A”AåA ²‹A=:A$ APç‹A”AØíA1M‹AÊC8A$ APç‹A”A©¬p¿NÝ>ØíA1M‹AÊC8A*A¨X‹A€Z:An A ÌŠA–O6Aût.>Vrk¿Öµ>n A ÌŠA–O6A*A¨X‹A€Z:A;.A?®ŠAˆz8Aé«[>pÞl¿* >n A ÌŠA–O6A;.A?®ŠAˆz8AžBAå/ŠAÑa4AGt>Äg¿´Ã·>žBAå/ŠAÑa4A;.A?®ŠAˆz8AjA¶è‰A÷¢6AÓ!‘>¨¦g¿6”¢>žBAå/ŠAÑa4AjA¶è‰A÷¢6Aö‘A)y‰A¿{2A^¡•>b¿Ö¹>ö‘A)y‰A¿{2AjA¶è‰A÷¢6A,mAX™‰Aø÷5AÉ}¥>Ñùc¿Šç£>ö‘A)y‰A¿{2A,mAX™‰Aø÷5Ah›AU/‰A<Ë1A·7©>Rª^¿—»>h›AU/‰A<Ë1A,mAX™‰Aø÷5A¹èA‚·ˆAJ=4A1À>ÜI^¿5¦>h›AU/‰A<Ë1A¹èA‚·ˆAJ=4A %A+\ˆA™0A2BÊ>­ W¿¶r¾> %A+\ˆA™0A¹èA‚·ˆAJ=4AéŽ AöÁ‡AB–2A(á>ƒéU¿Œ¨> %A+\ˆA™0AéŽ AöÁ‡AB–2A™ÕAÿt‡AAK.APê>—N¿Û]Á>™ÕAÿt‡AAK.AéŽ AöÁ‡AB–2Aÿ_ A º†A1Aåƒ?[1L¿•,«>™ÕAÿt‡AAK.Aÿ_ A º†A1A}­ Aéz†A~©,Aɤ?x·C¿-UÄ>}­ Aéz†A~©,Aÿ_ A º†A1AÁ[A˜ …A¼‡/AoÜ?ãA¿>Ò­>}­ Aéz†A~©,AÁ[A˜ …A¼‡/A²¬ An…AR+Ahã?Ç ;¿‹lÆ>²¬ An…AR+AÁ[A˜ …A¼‡/AâAX…AÁ,/A]M?Z ;¿¯>²¬ An…AR+AâAX…AÁ,/Al3 A)…Ac¾*A%ö?èó4¿ùÈ>l3 A)…Ac¾*AâAX…AÁ,/A$A15„ALÚ-AÄ¿!?I”1¿±>l3 A)…Ac¾*A$A15„ALÚ-AuAŠ„A \)A8l$?eõ'¿ÕãÊ>uAŠ„A \)A$A15„ALÚ-AÊ•A+ ƒA¥,AØà.?Mû#¿Z˜³>uAŠ„A \)AÊ•A+ ƒA¥,AäAzï‚Ax(A|í0?ÅÏ¿fªÍ>äAzï‚Ax(AÊ•A+ ƒA¥,A’5AÏÔAj+AŽ;?C¿,¶>äAzï‚Ax(A’5AÏÔAj+A0A–ÃAzò&Ak0A–ÃAzò&A’5AÏÔAj+A³AH˜€A¦“*A!F?Zk¿ŠW¸>0A–ÃAzò&A³AH˜€A¦“*A=EAö€A!ë%A D?Ôêû¾¸Ò>=EAö€A!ë%A³AH˜€A¦“*A‘ªAæ3€AúK*A’¢K?:Ìø¾g¹>=EAö€A!ë%A‘ªAæ3€AúK*AìAg+€AjŸ%AáµI?Ëé¾|‚Ó>ìAg+€AjŸ%A‘ªAæ3€AúK*Aj¸A\ó}AR‚)AÕ«R?ãÀÞ¾»>ìAg+€AjŸ%Aj¸A\ó}AR‚)AóA¨ë}AÊ$AÒ0R?°xǾdŸÕ>óA¨ë}AÊ$Aj¸A\ó}AR‚)Aÿáÿ@{{APÙ(A¤Z?Æ»¾uݼ>óA¨ë}AÊ$Aÿáÿ@{{APÙ(AÓ$Aœy{A·$AöUY?ª£¾s×>Ó$Aœy{A·$Aÿáÿ@{{APÙ(AФþ@þxA¸P(ABCa?re—¾òd¾>Ó$Aœy{A·$AФþ@þxA¸P(A×A/yAz…#A$_?¿è|¾-ôØ>×A/yAz…#AФþ@þxA¸P(A½µý@¿zvA©è'AÊ|f?-bc¾ ¿>×A/yAz…#A½µý@¿zvA©è'A.A ~vA¡#A­æb?é:¾zâÙ>.A ~vA¡#A½µý@¿zvA©è'AéNý@iuA»'A%[i?›¬+¾0=À>.A ~vA¡#AéNý@iuA»'AZÍA¨uAtæ"Að+e? ¾úÚ>ZÍA¨uAtæ"AéNý@iuA»'AÞü@á‰rA¢‰'A­k?öžÒ½7ÜÀ>ZÍA¨uAtæ"AÞü@á‰rA¢‰'A#’Aâ‹rA;±"Aþþf?.fW½u Û>#’Aâ‹rA;±"AÞü@á‰rA¢‰'A-·ü@:pAlx'Apúl?£…ß¼+Á>#’Aâ‹rA;±"A-·ü@:pAlx'A½}AHpAÙž"A#Kg?f;¿<8Û>½}AHpAÙž"A-·ü@:pAlx'AIÚü@ò•mAý‡'AÄl?ï`G=ŠÁ>½}AHpAÙž"AIÚü@ò•mAý‡'A/A”mAy¯"AØ f?JËË=ÁÆÚ>/A”mAy¯"AIÚü@ò•mAý‡'AIIý@kA¹'A0k?–•ÿ=€¬À>/A”mAy¯"AIIý@kA¹'AhÊAGkAÏã"AlNc?§22>Ú>hÊAGkAÏã"AIIý@kA¹'A¿ùý@o¶hAj(ASâg?X]J>)æ¿>hÊAGkAÏã"A¿ùý@o¶hAj(A»&A<³hAW6#AŠ2_?;{>•ìØ>»&A<³hAW6#A¿ùý@o¶hAj(Aýþ@Ë>fAw(AîLc?WŠ>é;>»&A<³hAW6#Aýþ@Ë>fAw(Aì­A€=fA7®#AŽY?ƒ¢>ðo×>ì­A€=fA7®#Aýþ@Ë>fAw(A”'AÂÉcAÚ)AaA]?݈®>b½>ì­A€=fA7®#A”'AÂÉcAÚ)Aa]AÂÌcA!H$A!‡R?å Æ>¯ Õ>a]AÂÌcA!H$A”'AÂÉcAÚ)AòùA„VaAD¹)A\ØU?¦ÂÑ>S¯»>a]AÂÌcA!H$AòùA„VaAD¹)A6A—`aA7%Ai'J?þ<è>k‡Ó>6A—`aA7%AòùA„VaAD¹)A:øA¸ä^Aâ‹*AhM?¯ó>r½¹>6A—`aA7%A:øA¸ä^Aâ‹*AŒ;Aõø^Aíâ%A@ @?‹?±Ñ>Œ;Aõø^Aíâ%A:øA¸ä^Aâ‹*AYEA™8\Aš+AäWB?ø ?6r·>Œ;Aõø^Aíâ%AYEA™8\Aš+A9AÉ[\AÍÿ&Aþk4?úu?lZÎ>9AÉ[\AÍÿ&AYEA™8\Aš+A,£Aü×YA’¯,Aüª6?¬×?¢µ>9AÉ[\AÍÿ&A,£Aü×YA’¯,A–ñA ZA#(A*_(?4Ä#?]¤Ë>–ñA ZA#(A,£Aü×YA’¯,A.A§‡WAöá-AT*?½ø(?Ô”²>–ñA ZA#(A.A§‡WAöá-AAvÏWA¦d)A+_?~ó0?_ÖÈ>AvÏWA¦d)A.A§‡WAöá-AšçAOIUAß0/AÔ?—6?1°>AvÏWA¦d)AšçAOIUAß0/Aå8 A‘§UA°Â*AZy ?j=?FøÅ>å8 A‘§UA°Â*AšçAOIUAß0/AŽÑ AESA œ0AlÔ?žîA?I­>å8 A‘§UA°Â*AŽÑ AESA œ0AJ Ac–SA9=,Aíý>Í¿G?£Ã>J Ac–SA9=,AŽÑ AESA œ0AgÒ A®%QA¬2A«??äeL?kþª>J Ac–SA9=,AgÒ A®%QA¬2A¶Aa¶QA’¿-Aïß>Z-Q?vKÀ>¶Aa¶QA’¿-AgÒ A®%QA¬2A”A1OA{­3Alá>õÜU?v¨>¶Aa¶QA’¿-A”A1OA{­3AÇZA ÞOAµl/AìÇ¿>&¦Y?Xk½>ÇZA ÞOAµl/A”A1OA{­3AÓ‹AFcMAR^5Aà¸À>N0^?©ì¥>ÇZA ÞOAµl/AÓ‹AFcMAR^5AN¿A8-NAƒ,1A<½ž>-Ê`?¾œº>N¿A8-NAƒ,1AÓ‹AFcMAR^5Aè%AؾKA!7AýŸ>Ö1e?as£>N¿A8-NAƒ,1Aè%AؾKA!7AóHA¦LAàý2A,Ây>÷f?‘á·>óHA¦LAàý2Aè%AؾKA!7A¥èAÖFJAðô8A!y>¨ãj?´ ¡>óHA¦LAàý2A¥èAÖFJAðô8Ao÷AüJKAÓß4A@9>ãj?¦^µ>o÷AüJKAÓß4A¥èAÖFJAðô8A3=A˜;IA#x:A…È;>ÿÅn?ýž>o÷AüJKAÓß4A3=A˜;IA#x:Aí8A‡VJA n6A‚«ø=Êm?ù,³>í8A‡VJA n6A3=A˜;IA#x:Að9A"HA_í8A‡VJA n6Að9A"HA_ïAÔWIAb8Að9A"HA_ANI=š²s?ƒÈš>ïAÔWIAb8AŸNAýAGAK>A« AºHAvZ:A¼–y¼B¨p?li®>« AºHAvZ:AŸNAýAGAK>A y!AlFA;@A—ѧ¼ëHt?êÀ˜>« AºHAvZ:A y!AlFA;@A§#AÆHA7VÀ¾²³€¾3`d?qCAØ*#AÔNA†FAh-AoÞOAµAq"A»QA¥«¸¾K-˜¾ìQb?µAq"A»QA†FAh-AoÞOA1šAÆùAòQA•¶¾'Ѿk1f?1šAÆùAòQAá AÝ'"ApkSAµAq"A»QA—]¸¾ðI¾!ni?µAq"A»QAá AÝ'"ApkSAûA²V#A*”SAfL»¾Üp¾Ek?µAq"A»QAûA²V#A*”SA+A”Õ&AÎÏQAžl¹¾DÄÙ½vm?+A”Õ&AÎÏQAûA²V#A*”SAõÐAÏ~&AÛTA¡Aº¾¿øE½‚#n?+A”Õ&AÎÏQAõÐAÏ~&AÛTA™ÏAã(A[TADTº¾_Î3ºrn?™ÏAã(A[TA¿uA=E+A<îQA+A”Õ&AÎÏQAtÞ¹¾4mÄ<Ýtn?+A”Õ&AÎÏQA¿uA=E+A<îQAÚ5Ag,AnØOAäÁ¼¾„Ù©¼˜èm?+A”Õ&AÎÏQAÚ5Ag,AnØOAžAH—'Am¡OA–‚º¾ô6ð<ÊJn?žAH—'Am¡OAÚ5Ag,AnØOA¡Aó9-A³ÆMAê¾¾ˆl~¼m?žAH—'Am¡OA¡Aó9-A³ÆMA** AEÁ(A‰vMA$ɺ¾Œï =÷0n?** AEÁ(A‰vMA¡Aó9-A³ÆMA“ AÿÅ.A+ºKA¸À¾@â%¼“(m?** AEÁ(A‰vMA“ AÿÅ.A+ºKA†ÒAæQ*A?PKASѺ¾x"=‚"n?†ÒAæQ*A?PKA“ AÿÅ.A+ºKA‹AØI0AçJAT¾t®»¸âl?†ÒAæQ*A?PKA‹AØI0AçJAÍœAÞ+AÑ™IARNº¾¨´3=‚/n?ÍœAÞ+AÑ™IA‹AØI0AçJAåXAëx2AŠ HA þ"Þo¹Ë³l?ÍœAÞ+AÑ™IAåXAëx2AŠ HAN$ý@m.A‡GAÉ|¹¾X˜F=dIn?N$ý@m.A‡GAåXAëx2AŠ HAQ°÷@Ý÷4AH:FA›ºÃ¾(È¥;Rl?N$ý@m.A‡GAQ°÷@Ý÷4AH:FAX„ó@A³0A:†EAxG¸¾ºHW=àvn?X„ó@A³0A:†EAQ°÷@Ý÷4AH:FA$ï@ôÂ7A&gDA, ľý’$Aõ4°¾f6y=IÛo?ÛpÒ@AÜ=As>APóØ@ƒ‚AA+Ž?A^Ò@^3EAç#>A‰´Á¾ÝÖÆ<ããl?ÛpÒ@AÜ=As>A^Ò@^3EAç#>Aa‘Ë@ÆAAjðAoßÌ@IAIØ›; ñs?—ƪ@FBkAQ„5AÀ´@*¦kA]A7AÄx´@pAt07AÅêµ¾„†9ÂKo?—ƪ@FBkAQ„5AÄx´@pAt07A>wª@Ø!pAâq5AË?›¾kž»Æñs?>wª@Ø!pAâq5AÄx´@pAt07A Ç´@&“tA'C7Aq ¶¾4Ò§» Do?>wª@Ø!pAâq5A Ç´@&“tA'C7AûΪ@+ütAD†5A†Ä›¾˜øi¼hÖs?ûΪ@+ütAD†5A Ç´@&“tA'C7AG¬µ@~yARy7A§‡¶¾œ])¼$*o?ûΪ@+ütAD†5AG¬µ@~yARy7A9Í«@¬ÒyABÁ5A Šœ¾ …±¼Š­s?9Í«@¬ÒyABÁ5AG¬µ@~yARy7A¾{¶@§{A`ª7Ad·¾Nµ[¼[o?9Í«@¬ÒyABÁ5A¾{¶@§{A`ª7A¯³¬@z°|A§ö5AꩾÖ6ê¼AÒ¹Á¾ñÞ¼qÝl?²Å@ÚûŒAR;AqxÒ@ÀZA>A@iË@«AŽçAHߨ@L9A¸‰?AHþúˆÍ¼Âl?@iË@«AŽçACÚ±¾ÿä|½¤‰o?*[Ò@ ‘AOn>AHߨ@L9A¸‰?A’šÚ@­¯Aì?A<þ33¾¼?•l?*[Ò@ ‘AOn>A’šÚ@­¯Aì?A;Ô@N‰‘A!×>Aàw³¾Eq|½òA’šÚ@­¯Aì?AOäá@‹v‘A9‡AAWCľWL­¼bl?;Ô@N‰‘A!×>AOäá@‹v‘A9‡AA®Ü@i“ArŒ@A‡Æµ¾ÐÅt½WÕn?®Ü@i“ArŒ@AOäá@‹v‘A9‡AA¾®é@™“A©9CAeßľ=VŒ¼ Gl?®Ü@i“ArŒ@A¾®é@™“A©9CAp~ä@"•A[YBAŒ¿·¾‘7i½;€n?p~ä@"•A[YBA¾®é@™“A©9CA—øñ@.›”A`EA žDM¼w?l?p~ä@"•A[YBA—øñ@.›”A`EAˆdí@´–A¼n?ˆdí@´–A¼@^l?¿uA=E+A<îQAÔùAäo.Ah—SAÞøAª/AnyQAwå³¾$*E>åj?ÞøAª/AnyQAÔùAäo.Ah—SAuA:/A“~SA¦T®¾¥~>Ü+h?ÞøAª/AnyQAuA:/A“~SA^²Anî3A§sPAmâ­¾ëb”>e?^²Anî3A§sPAuA:/A“~SAïnAft3ASiRAK«¾}š¬>ÉVa?^²Anî3A§sPAïnAft3ASiRAu}AÒ3AÝCRAËÿ¢¾0Ä>èü]?u}AÒ3AÝCRA®žA'ý7AôáNA^²Anî3A§sPAŠÀ•¾œ‹Ú>f[?^²Anî3A§sPA®žA'ý7AôáNA'IAhÒ8A}ûLAN—¾ Æ>×§_?^²Anî3A§sPA'IAhÒ8A}ûLA"AÂ4A‚NA†¦‡¾1ÐÝ>Ôˆ\?"AÂ4A‚NA'IAhÒ8A}ûLAA©ø9A5KAsо¤ÿÈ>´ a?"AÂ4A‚NAA©ø9A5KA ŠA^ì5Al•LA7r¾Æ÷ß>Š^? ŠA^ì5Al•LAA©ø9A5KAÈõ A†m;A@?IAÚ›z¾(íÊ>º‡b? ŠA^ì5Al•LAÈõ A†m;A@?IA‡" Ak7AÞ®JA¼+V¾Êóà>Ð¥_?‡" Ak7AÞ®JAÈõ A†m;A@?IAÿÀ A8ѯâc?‡" Ak7AÞ®JAÿÀ A8Ѹ6a?ˆ¯AåÚ8AÎ,IAÿÀ A8ÑA(FA ñH¾|‚Ë>Vye?ˆ¯AåÚ8AÎ,IAÔòA®Ç>A(FA%•A¾å:As[GA³Ï¾«Cß>Àc?%•A¾å:As[GAÔòA®Ç>A(FAÕZAû@AÏMDA]­,¾JÊ>˜9g?%•A¾å:As[GAÕZAû@AÏMDA{²A¹3=AKœEA\bø½eTÜ>ýd?{²A¹3=AKœEAÕZAû@AÏMDAûòÿ@›hCAŽ­BA~ ¾ ?Ç>á i?{²A¹3=AKœEAûòÿ@›hCAŽ­BAPú@ÐÀ?ADðCA¥«¸½ÝÖ×>€ýf?Pú@ÐÀ?ADðCAûòÿ@›hCAŽ­BA¶žù@‘ FAj!AAXAæ½<÷Â>ðôj?Pú@ÐÀ?ADðCA¶žù@‘ FAj!AAÜ-ó@´‰BAoXBAÉt½‰ÙÑ>Âi?Ü-ó@´‰BAoXBA¶žù@‘ FAj!AAƒ ô@«¶HAZ¿?As®½ic½>7×l?Ü-ó@´‰BAoXBAƒ ô@«¶HAZ¿?A{í@(^EAuë@A–ô¼¬TÊ>â k?{í@(^EAuë@Aƒ ô@«¶HAZ¿?Aa¹î@¤KAg>AFçl½-¶>ÂÉn?{í@(^EAuë@Aa¹î@¤KAg>ADç@–|HA ˆ?AŽ8÷ñÀ>k m?Dç@–|HA ˆ?Aa¹î@¤KAg>AÄéé@&¯NAa+=AÆ[ü¼.O­>?Âp?Dç@–|HA ˆ?AÄéé@&¯NAa+=A»úá@Ò¼KAÃA>A©Ôì<ÑÙµ>­1o?»úá@Ò¼KAÃA>AÄéé@&¯NAa+=ATšå@0ÓQA- Ñ´r?»úá@Ò¼KAÃA>ATšå@0ÓQA- ‚7q?9Ý@OAo=ATšå@0ÓQA- -›t?9Ý@OAo=A,Çá@<UA‘ ;AUüØ@U–RAK G=s?UüØ@U–RAK „v?UüØ@U–RAK N*u?bíÔ@j„VAd;AL!Þ@İXAM:AbWÛ@œ\AdM9A‰='p>7Fx?bíÔ@j„VAd;AbWÛ@œ\AdM9AÞÏÑ@Ä ZA¯>:A$>·;m>Îv?ÞÏÑ@Ä ZA¯>:AbWÛ@œ\AdM9AÙ@áZ_Aìª8A#>¯=ù£N>QÆy?ÞÏÑ@Ä ZA¯>:AÙ@áZ_Aìª8AÞ8Ï@»Â]As•9AЯ>êøF>¯=x?Þ8Ï@»Â]As•9AÙ@áZ_Aìª8Ad,×@ï³bAë&8AÊÙÏ=vÏ*>–{?Þ8Ï@»Â]As•9Ad,×@ï³bAë&8A¾!Í@bjaAÄ 9AÎ&'>:\>¶qy?¾!Í@bjaAÄ 9Ad,×@ï³bAë&8A=¿Õ@ÅfA½À7A®dê=lÕ>ï#|?¾!Í@bjaAÄ 9A=¿Õ@ÅfA½À7AÅ…Ë@teA¡8AK3>úÊè=:_z?Å…Ë@teA¡8A=¿Õ@ÅfA½À7AÆÔ@FLiA¹z7A%îý=ðм=Ïí|?Å…Ë@teA¡8AÆÔ@FLiA¹z7A lÊ@¿£hAæW8Ay(;>Õ“’={? lÊ@¿£hAæW8AÆÔ@FLiA¹z7A(*Ô@bµlAyN7Aªw>ÑV=™v}? lÊ@¿£hAæW8A(*Ô@bµlAyN7Am»É@KblA )8A{¯?>•Pß<½`{?m»É@KblA )8A(*Ô@bµlAyN7A¤øÓ@|pAp@7A´f>ßf:<´³}?m»É@KblA )8A¤øÓ@|pAp@7ANƒÉ@ÎpAñ8Aæ'@>*1Œ¼j{?NƒÉ@ÎpAñ8A¤øÓ@|pAp@7Af/Ô@vsAõO7A¿•>Dñ¼M¢}?NƒÉ@ÎpAñ8Af/Ô@vsAõO7A\ÁÉ@\ÍsA.+8A ž<>D{z½Ù!{?\ÁÉ@\ÍsA.+8Af/Ô@vsAõO7AŠÎÔ@QÔvAö|7AÑ>u½“C}?\ÁÉ@\ÍsA.+8AŠÎÔ@QÔvAö|7A™uÊ@€wA>Z8AÁº6>¼>ɽÀ¡z?™uÊ@€wA>Z8AŠÎÔ@QÔvAö|7An_Õ@SÕxAÍ¥7A–¡û=)„ɽúÎ|?™uÊ@€wA>Z8An_Õ@SÕxAÍ¥7A~Ë@Ÿ²yAí„8AãÐ.>ô¾× z?~Ë@Ÿ²yAí„8An_Õ@SÕxAÍ¥7AůÖ@$B|A"8A¥è=~Ó¾æ|?~Ë@Ÿ²yAí„8AůÖ@$B|A"8AE•Ì@Òr}Atç8A¥.!>¡{/¾ ùx?E•Ì@Òr}Atç8AůÖ@$B|A"8A†nØ@¦Ar€8Aó<Í=æ*.¾Göz?E•Ì@Òr}Atç8A†nØ@¦Ar€8ARŒÎ@““€A*i9Aû+>Œ“W¾V§w?RŒÎ@““€A*i9A†nØ@¦Ar€8AAŸÚ@³Aü9A8Ì«=ˆ!R¾H¡y?RŒÎ@““€A*i9AAŸÚ@³Aü9A«Ñ@Çh‚A5 :AÇ&ø=õ}¾xv?«Ñ@Çh‚A5 :AAŸÚ@³Aü9A[GÝ@{-ƒAZÔ9Aàà„=·„s¾±x?«Ñ@Çh‚A5 :A[GÝ@{-ƒAZÔ9A<úÓ@l9„AË:A1†Ö=Ò‹¾Ît?<úÓ@l9„AË:A[GÝ@{-ƒAZÔ9AÞ;Þ@¶ƒAy:AŒy]=¯‚¾‹5w?<úÓ@l9„AË:AÞ;Þ@¶ƒAy:A Õ@zÍ„AØ;A¡Bº=6"•¾RÊs? Õ@zÍ„AØ;AÞ;Þ@¶ƒAy:Aûšá@¤d…AÎý:A¾ç=i×¾ Ïu? Õ@zÍ„AØ;Aûšá@¤d…AÎý:ADËØ@ýž†AAE½<ï½¾ ¹m?Üá@qŠAO:>AåÍé@ôžˆA-$=Aªî@5)ŠA6c>ADÜ'½û°¾týo?Üá@qŠAO:>Aªî@5)ŠA6c>AÇ3ç@伋A„?A2$U¼Ç‰Å¾ä'l?Ç3ç@伋A„?Aªî@5)ŠA6c>Aýï@‹ŠAF¹>A)¡]½Mµ¾o?Ç3ç@伋A„?Aýï@‹ŠAF¹>Az§è@µ%ŒAüÜ?A¸ßï¼Eʾrk?z§è@µ%ŒAüÜ?Aýï@‹ŠAF¹>A ™õ@JŒAP"@ANü›½N»¾tm?z§è@µ%ŒAüÜ?A ™õ@JŒAP"@ALËî@¹ºA„QAA”Yx½l-Ò¾\ëh?LËî@¹ºA„QAA ™õ@JŒAP"@Aç©û@£lA ¢AA­~Ö½E¬Á¾åtk?LËî@¹ºA„QAAç©û@£lA ¢AAšgõ@+4AëÜBA¸¼½¹HؾPÖf?šgõ@+4AëÜBAç©û@£lA ¢AAýAr·ŽA¦7CAuq¾Ÿiƾ„i?šgõ@+4AëÜBAýAr·ŽA¦7CA|ü@‘AR~DAêÍü½·Ü¾ðÑd?|ü@‘AR~DAýAr·ŽA¦7CAK’AéæAþáDA q%¾<£É¾ð¥g?|ü@‘AR~DAK’AéæAþáDA‰A¤Ï‘A4FAœ¾Ö"ß¾Kc?‰A¤Ï‘A4FAK’AéæAþáDA}ïATQA&‡EA¶œ5¾÷àʾ/žf?‰A¤Ï‘A4FA}ïATQA&‡EA }Aú>’A/ÞFAT*¾]Cà¾|)b? }Aú>’A/ÞFA}ïATQA&‡EA<À A‘Y‘AÚOGAÛòL¾Ç˾e1e? }Aú>’A/ÞFA<À A‘Y‘AÚOGAñšA`R“Aí²HA«ÙI¾8á¾;S`?ñšA`R“Aí²HA<À A‘Y‘AÚOGA€¶ A<’Ac"IAMìh¾ÀÄ˾̄c?ñšA`R“Aí²HA€¶ A<’Ac"IAƒÞ Al=”AJ‘JAïih¾“ྚ^?ƒÞ Al=”AJ‘JA€¶ A<’Ac"IAàÏAˆù’AbýJAÛ÷¾¦Ê¾Hôa?ƒÞ Al=”AJ‘JAàÏAˆù’AbýJA1EAxÿ”AçwLAüƒ¾™ÌÞ¾¾ü\?1EAxÿ”AçwLAàÏAˆù’AbýJA‘ AX“AbßLA¼þ޾CCȾœ~`?1EAxÿ”AçwLA‘ AX“AbßLAÌAx—•AOeNAQG¾Qgܾ ®[?ÌAx—•AOeNA‘ AX“AbßLA·£A#Ö“A—NAñ˜¾ëÿžü_?ÌAx—•AOeNA·£A#Ö“A—NA¢”A5Þ•AE‘OAú¯™¾F™Ù¾)žZ?¢”A5Þ•AE‘OA·£A#Ö“A—NAPAÅ)”AzëOAÝÑ¢¾Š‰Â¾ ^^?¢”A5Þ•AE‘OAPAÅ)”AzëOAq@Aˆ/–AƒQA²—§¾Á¾Ì|]?q@Aˆ/–AƒQAPAÅ)”AzëOAu}A÷–AÝCRA&Þ¬¾ëÖ«¾ù a?q@Aˆ/–AƒQAu}A÷–AÝCRAïnAÍE–ASiRA@£¾'Ø>bFY?u}AÒ3AÝCRAàAî{7A»ÌPA®žA'ý7AôáNA)>ž¾>Ãò>ø S?®žA'ý7AôáNAàAî{7A»ÌPA[AmÙ8AZPAa“¾îp?ÂGN?®žA'ý7AôáNA[AmÙ8AZPA;¹A/Â;AÌLA³”¾)’ ?ÿH?;¹A/Â;AÌLA[AmÙ8AZPAIàAL=;AаNAZæ¾|¼?.@?;¹A/Â;AÌLAIàAL=;AаNAŒ‚ Ai=Aø MAw»€¾ƒÓ#?ã9?Œ‚ Ai=Aø MAüAè*?AbIA’¾bk*?îTIA‡AAA,…FAøA]gBAr²DAɾ:‰!?òÊC?°¼Aµ=A>IAøA]gBAr²DA"ëA’?AØ?"ëA’?AØ>A¶$=¥6?³L?|AJlDAÆ]BA|òA…žIAŸ>>A(øA¹FAéÃ@AúÐ=Ñ ?zéF?(øA¹FAéÃ@A|òA…žIAŸ>>AÉAAA÷KA¶¹?Aº»> ¨?BI?ØAv6IA >?AÉAAA÷KA¶¹–?¿P?ØAv6IA >?AçAÁSNA1^;AUû@b¹KAÅá=AÝC>J?ˆ™K?Uû@b¹KAÅá=AçAÁSNA1^;APRý@·çPA` :AÛÐ,>ð3 ?XS?Uû@b¹KAÅá=APRý@·çPA` :AÓ"ö@ÝxNAT¤¦ ?3þM?Ó"ö@ÝxNAT½¬? ~U?Ó"ö@ÝxNATÁé?/YP?9Àñ@âPQAY;AíKù@/‘SA¡Ö8A6¶õ@*MVAî¼7A2¨~>ä%ô>kÓW?9Àñ@âPQAY;A6¶õ@*MVAî¼7AäÕí@M>TA?:Aë^¡>‚ ò>¤R?äÕí@M>TA?:A6¶õ@*MVAî¼7AÐŒò@iYAX¿6AO0’>ûÅà>’Z?äÕí@M>TA?:AÐŒò@iYAX¿6A›_ê@Á>WARA9A‰¿´>}`Û>¿ìT?›_ê@Á>WARA9AÐŒò@iYAX¿6AÌï@ù:\AÊ5A:Õ¤>¯É>ie\?›_ê@Á>WARA9AÌï@ù:\AÊ5Axç@–œZAæK8AzèÆ>º¼Á>¥W?xç@–œZAæK8AÌï@ù:\AÊ5A-Gí@_Aô 5Aãµ>8h±>ûk^?xç@–œZAæK8A-Gí@_Aô 5A”ä@!¯]AÛ7AhæÕ>îÙ§>uëX?”ä@!¯]AÛ7A-Gí@_Aô 5A[gë@àíaAÂl4AOÏÂ>Ù/˜>á.`?”ä@!¯]AÛ7A[gë@àíaAÂl4A‘‚â@ÍÁ`A¹î6AÃâ>zhŒ>Ì…Z?‘‚â@ÍÁ`A¹î6A[gë@àíaAÂl4Afçé@0ÆdApë3AšyÎ>:öz>ܳa?‘‚â@ÍÁ`A¹î6Afçé@0ÆdApë3AìÙà@$ÕcA€m6A“\í>Ÿ_>Ý[?ìÙà@$ÕcA€m6Afçé@0ÆdApë3AþÁè@9ŸgA[‡3A$í×>ßB>Nób?ìÙà@$ÕcA€m6AþÁè@9ŸgA[‡3AÍ”ß@VêfA… 6Axõ>2Ø#> å\?Í”ß@VêfA… 6AþÁè@9ŸgA[‡3Aíúç@,ZjAÈB3AtÜÞ>D >…Þc?Í”ß@VêfA… 6Aíúç@,ZjAÈB3Aâ·Þ@ÂßiAÅ5A’û>Ó¸Î=¦ž]?â·Þ@ÂßiAÅ5Aíúç@,ZjAÈB3A÷}ç@G:mAs3AÖzã>š =Md?â·Þ@ÂßiAÅ5A÷}ç@G:mAs3A-Þ@ þlA™5Aþ>,V=&^?-Þ@ þlA™5A÷}ç@G:mAs3AzVç@ÇpAµ 3A£“å>öžŽ(§½¼š^?+Þ@upA Œ5AzVç@ÇpAµ 3A&‚ç@HêrAç3AÌå>ÿ",½ˆ´d?+Þ@upA Œ5A&‚ç@HêrAç3A·1Þ@)sA6›5Aü>(£­½Â]?·1Þ@)sA6›5A&‚ç@HêrAç3ADè@TÁuAúD3Aãá>ôªÎ½Hd?·1Þ@)sA6›5ADè@TÁuAúD3Aí¾Þ@ >vA9Ç5A! ø>”i ¾Ž.]?í¾Þ@ >vA9Ç5ADè@TÁuAúD3A5uè@}rwAùl3Aè!Þ>Ug¾¸ºc?í¾Þ@ >vA9Ç5A5uè@}rwAùl3A ?ß@…xA+ï5A1Çò>u¥9¾T\? ?ß@…xA+ï5A5uè@}rwAùl3A!ƒé@[XzA]É3AT…×>k—E¾]æb? ?ß@…xA+ï5A!ƒé@[XzA]É3Aàjà@è6{AuK6A@‚é>‹Üu¾™`[?àjà@è6{AuK6A!ƒé@[XzA]É3A8ëê@"9}A%C4AxÑÍ>‚N~¾Xža?àjà@è6{AuK6A8ëê@"9}A%C4A^ùá@ÀS~A#Å6AšáÝ>]Œ—¾óéY?^ùá@ÀS~A#Å6A8ëê@"9}A%C4A|±ì@‰ €AÚ4A3èÁ>äš¾9`?^ùá@ÀS~A#Å6A|±ì@‰ €AÚ4Aÿîã@%¶€A{\7AÏÐ>˜Ž²¾»3X?ÿîã@%¶€A{\7A|±ì@‰ €AÚ4A‘Ûî@«yA:5Aò³>ÿ@³¾gG^?ÿîã@%¶€A{\7A‘Ûî@«yA:5AlQæ@Ò@‚A8A+?Ä>\$ƾ4±V?lQæ@Ò@‚A8A‘Ûî@«yA:5AŒ£ï@ôîA Ñ5AˆÈ«>56À¾/]?lQæ@Ò@‚A8AŒ£ï@ôîA Ñ5Aa-ç@¿‚AîR8AU—º>á³Ó¾›U?a-ç@¿‚AîR8AŒ£ï@ôîA Ñ5Afhò@ÐaƒAг6Alž>,Ò¾>–[?a-ç@¿‚AîR8Afhò@ÐaƒAг6A¯7ê@ÙM„AÉ59AU ¨>,Ä꾎jS?¯7ê@ÙM„AÉ59Afhò@ÐaƒAг6A,—õ@¤Ì„AL³7A7/Œ>4Sç¾\Y?¯7ê@ÙM„AÉ59A,—õ@¤Ì„AL³7Aò³í@(Ó…Au5:Aæ”>ÿ¾Q?ò³í@(Ó…Au5:A,—õ@¤Ì„AL³7A­4ù@$/†A‘Ï8A¿`q>«8ú¾ W?ò³í@(Ó…Au5:A­4ù@$/†A‘Ï8Aܦñ@·N‡A R;Aˆè}>Ñ÷¿ˆÀN?ܦñ@·N‡A R;A­4ù@$/†A‘Ï8A{Eý@/ˆ‡A:AU4H>ör¿»§T?ܦñ@·N‡A R;A{Eý@/ˆ‡A:AÜö@W¿ˆA‹6!¿ËèL?Üö@W¿ˆA‹‘5 ¿*kS?Üö@W¿ˆA‹uù¿K´K?hJ÷@q‰Aàcm¿G—Q?hJ÷@q‰AàA6`>k´¿q=I?Mmü@÷€ŠAC>AAŽA.‰AP¿;AËAjŠAü7=AΈÈ=™P¿î%O?Mmü@÷€ŠAC>AËAjŠAü7=AEÿA´Ð‹A¼?AüêÌ=ª7¿ÒF?EÿA´Ð‹A¼?AËAjŠAü7=AûåA ‘‹A6Æ>A¬Z={ ¿ÁL?EÿA´Ð‹A¼?AûåA ‘‹A6Æ>AOÿA AÜKAAóôW=@”#¿8uD?OÿA AÜKAAûåA ‘‹A6Æ>Aˆà Ak¡ŒAåh@Aý‹<¥³¿÷lJ?OÿA AÜKAAˆà Ak¡ŒAåh@AT6A…)ŽA»ïBA7}~?sßAªó‘A¡ñKAŒA"“AmAKA:öAëG’A.ÒMAižˆ¾Uô"¿µ>9?:öAëG’A.ÒMAŒA"“AmAKAŒ‚ A}K‘Aø MA(t‘¾KL¿±??:öAëG’A.ÒMAŒ‚ A}K‘Aø MAIàAZa’AаNAÌ;‘ã+?C2?Œ‚ Ai=Aø MA:ß Ap¦>AãLAüAè*?AbAãLAì!A/aAAciIAwÙU¾|??OG!?üAè*?AbõT?~4?ðãA¦DA/äCAê"Aø¦AA $IAÍQ#Au0DA’ÎEAO¡)¾hO\?º•ö>ðãA¦DA/äCAÍQ#Au0DA’ÎEA-“#AœŽDAì%EAƒ0¾ý²b?-|ä>-“#AœŽDAì%EA y!AlFA;@AðãA¦DA/äCAÿ~”½°Åg?œ9Ö>ðãA¦DA/äCA y!AlFA;@AŸNAýAGAK>AžXŒ½%Ïb?‚Óê>ðãA¦DA/äCAŸNAýAGAK>AjAê\EA€ýAA¯‘î»Oßg?gõØ>jAê\EA€ýAAŸNAýAGAK>Að9A"HA_jAê\EA€ýAAð9A"HA_¡OAQRFAV@Að9A"HA_¡OAQRFAV@A3=A˜;IA#x:Ab,A„GAÆ>>A…áô=6~d?ÓžÞ>b,A„GAÆ>>A3=A˜;IA#x:A¥èAÖFJAðô8A/=ë=W1_?øÅó>b,A„GAÆ>>A¥èAÖFJAðô8A׺A«¤HAZÄQ]a?Õfá>׺A«¤HAZÄл[?4÷>׺A«¤HAZÄÅ’\?”¥ä>%×AÖ8JAÒû:Aè%AؾKA!7AÓ‹AFcMAR^5A®Ds>ÄÐV?:ˆú>%×AÖ8JAÒû:AÓ‹AFcMAR^5A–AÓúKA¯D9A$ë›><|V?üç>–AÓúKA¯D9AÓ‹AFcMAR^5A”A1OA{­3AÃ>™>L›P?Ï&þ>–AÓúKA¯D9A”A1OA{­3AS” A0çMAߟ7A%»>O? ië>S” A0çMAߟ7A”A1OA{­3AgÒ A®%QA¬2Aª/¸>–I?=î?S” A0çMAߟ7AgÒ A®%QA¬2A‰5 AüúOAe6AÏéÙ>OF?÷Ôî>‰5 AüúOAe6AgÒ A®%QA¬2AŽÑ AESA œ0Ay6Õ>Ž@?%¾?‰5 AüúOAe6AŽÑ AESA œ0Al"A<RA¤¦4AM…ö>fàl"A<RA¤¦4AŽÑ AESA œ0AšçAOIUAß0/AÓuñ>$³6?ï—?l"A<RA¤¦4AšçAOIUAß0/Aª(AÆZTAãG3AZF ?Ä1?ϰõ>ª(AÆZTAãG3AšçAOIUAß0/A.A§‡WAöá-AU?S‚+?r?ª(AÆZTAãG3A.A§‡WAöá-A€bA¢¶VA<2ASw?{%?ù>€bA¢¶VA<2A.A§‡WAöá-A,£Aü×YA’¯,AÏ?û"?ÎA?€bA¢¶VA<2A,£Aü×YA’¯,AÖÍA=#YAÑÞ0A"Ç"?Œ?ìcü>ÖÍA=#YAÑÞ0A,£Aü×YA’¯,AYEA™8\Aš+Aÿ ?¬•?E ?ÖÍA=#YAÑÞ0AYEA™8\Aš+AÂhAªž[AÝÔ/A7}.?Íë?D¬ÿ>ÂhAªž[AÝÔ/AYEA™8\Aš+A:øA¸ä^Aâ‹*A`­*?©Û?Ë ?ÂhAªž[AÝÔ/A:øA¸ä^Aâ‹*AX,þ@Rf^A Ò.AÒT9?øeð>‹b?X,þ@Rf^A Ò.A:øA¸ä^Aâ‹*AòùA„VaAD¹)A÷°4?A5ã>zZ ?X,þ@Rf^A Ò.AòùA„VaAD¹)A¡)ü@ÿî`AÝ .Aì/B?óPÏ> ³?¡)ü@ÿî`AÝ .AòùA„VaAD¹)A”'AÂÉcAÚ)A8=? Â>šµ?¡)ü@ÿî`AÝ .A”'AÂÉcAÚ)Asú@ wcA)a-Añ·I?RĬ>¿Ø?sú@ wcA)a-A”'AÂÉcAÚ)Aýþ@Ë>fAw(AÇ'D?ÆyŸ>Óà?sú@ wcA)a-Aýþ@Ë>fAw(AÌ-ù@?ÿeA·×,AšáO?„àˆ>sÎ?Ì-ù@?ÿeA·×,Aýþ@Ë>fAw(A¿ùý@o¶hAj(A¥ØI?fw>Ö?Ì-ù@?ÿeA·×,A¿ùý@o¶hAj(A*ø@qˆhAm,AØT?ÿ´H>V‹?*ø@qˆhAm,A¿ùý@o¶hAj(AIIý@kA¹'AÜÿM?ô"/>^‹?*ø@qˆhAm,AIIý@kA¹'AÌy÷@/÷jAá#,AÆW?éyý=ò?Ìy÷@/÷jAá#,AIIý@kA¹'AIÚü@ò•mAý‡'AøÄP?ø/È= ?Ìy÷@/÷jAá#,AIÚü@ò•mAý‡'A ÷@I‡mAõ+AmY?”•M?}8¾Øq?j÷@R!uA:&,A½µý@¿zvA©è'Aæ÷@H£vAïP,AèS?!ëa¾‹V?æ÷@H£vAïP,A½µý@¿zvA©è'AФþ@þxA¸P(A¶I?ìßx¾òÕ?æ÷@H£vAïP,AФþ@þxA¸P(AÕø@ 8yAp³,AÄM?Ö2–¾/€?Õø@ 8yAp³,AФþ@þxA¸P(Aÿáÿ@{{APÙ(AYåC?œÐ ¾îÛ?Õø@ 8yAp³,Aÿáÿ@{{APÙ(A§ú@ÓÇ{Aø4-AÃG?Eú¹¾?v?§ú@ÓÇ{Aø4-Aÿáÿ@{{APÙ(Aj¸A\ó}AR‚)Aų?E4ܾ}>?S¥û@T~A“Õ-Aj¸A\ó}AR‚)A‘ªAæ3€AúK*AÜ14?¦æä¾ìM ?S¥û@T~A“Õ-A‘ªAæ3€AúK*AëŽý@µo€A¨•.A½Ó7?\ƒõ¾%!?ëŽý@µo€A¨•.A‘ªAæ3€AúK*A³AH˜€A¦“*A /?ETö¾äk ?ëŽý@µo€A¨•.A³AH˜€A¦“*AŽ?þ@ä×€A Ú.AB32?ƒ¿­d?Ž?þ@ä×€A Ú.A³AH˜€A¦“*A’5AÏÔAj+Abì&?29¿ì< ?Ž?þ@ä×€A Ú.A’5AÏÔAj+A°XA&!‚A¿È/AÇ'?Pſ¦ý>°XA&!‚A¿È/A’5AÏÔAj+AÊ•A+ ƒA¥,A¶ƒ?@Ì¿5… ?°XA&!‚A¿È/AÊ•A+ ƒA¥,A$ÀA cƒA»Ô0Aî?÷Ñ ¿f[ú>$ÀA cƒA»Ô0AÊ•A+ ƒA¥,A$A15„ALÚ-A8)?²'#¿«¹?$ÀA cƒA»Ô0A$A15„ALÚ-A@XAZ„AÜý1Aaß ?‚¬-¿"òö>@XAZ„AÜý1A$A15„ALÚ-AâAX…AÁ,/Aï?#AÏ…AêC3AâAX…AÁ,/AÁ[A˜ …A¼‡/ASö>‘ó4¿DÜ?#AÏ…AêC3AÁ[A˜ …A¼‡/Ah A”†A³›3A£eø>§(<¿y‹ò>h A”†A³›3AÁ[A˜ …A¼‡/Aÿ_ A º†A1A–à>nì<¿÷|?h A”†A³›3Aÿ_ A º†A1AǵAÍD‡AI 5AÝGÚ>ú\F¿Ï÷î>ǵAÍD‡AI 5Aÿ_ A º†A1AéŽ AöÁ‡AB–2A“ Â>íRF¿ÿ’?ǵAÍD‡AI 5AéŽ AöÁ‡AB–2A#ù A|\ˆAà6A©2»>å)O¿¦që>#ù A|\ˆAà6AéŽ AöÁ‡AB–2A¹èA‚·ˆAJ=4AL%£>JWN¿Ybÿ>#ù A|\ˆAà6A¹èA‚·ˆAJ=4AÛj A¦a‰A–+8A”>›>Y›V¿!ýç>Ûj A¦a‰A–+8A¹èA‚·ˆAJ=4A,mAX™‰Aø÷5A‹yƒ>hU¿J³û>Ûj A¦a‰A–+8A,mAX™‰Aø÷5A¹ A¼RŠADÚ9AÕŽ>·[¿±1å>¹ A¼RŠADÚ9A,mAX™‰Aø÷5AjA¶è‰A÷¢6As®a>QX¿^zù>¹ A¼RŠADÚ9AjA¶è‰A÷¢6AÃA±§ŠAÚ€:AÓë[>­¯^¿^ã>ÃA±§ŠAÚ€:AjA¶è‰A÷¢6A;.A?®ŠAˆz8AýR->ê\¿ÎÅö>ÃA±§ŠAÚ€:A;.A?®ŠAˆz8A•÷AÅ{‹AÔLXþb¿<à>•÷AÅ{‹AÔL•÷AÅ{‹AÔLAcª=Fðe¿cÝ>üA 3ŒAÊ!>A*A¨X‹A€Z:A$ APç‹A”AüA 3ŒAÊ!>A$ APç‹A”ApAxÎŒApþ?A$ APç‹A”AA’ºÀ¼Úb¿õì>pAxÎŒApþ?A2 ANYŒAb.>Aˆ\ACKA]áAA”!½Ôüg¿×>ˆ\ACKA]áAA2 ANYŒAb.>Aà A³ŒA„Y?Akµ½1Ïb¿Ç²ê>ˆ\ACKA]áAAà A³ŒA„Y?A%]Am‡AÌCA)³½‘g¿ ¨Õ>%]Am‡AÌCAà A³ŒA„Y?A:#A ÑŒAFIAA¾gßa¿êNè>%]Am‡AÌCA:#A ÑŒAFIAAñ¼!AûÐA‘íDAˆÆ¾(b¿Kiã>ñ¼!AûÐA‘íDA:#A ÑŒAFIAA-“#A±¸Aì%EA¨Þ4¾£ë[¿‹úõ>ñ¼!AûÐA‘íDA-“#A±¸Aì%EAÍQ#AÅçA’ÎEA[ô ¾_Zg?Ð>-“#AœŽDAì%EAª¹$A·6FA?.BA y!AlFA;@A!ƒì½GTm?¿œ¶> y!AlFA;@Aª¹$A·6FA?.BAUg%A3âFAAn@A)oœ½ëq?ÝÖ¢> y!AlFA;@AUg%A3âFAAn@A§#AÆHA7V§#AÆHA7VA-E€½lÿx?A e>§#AÆHA7VA§X'AÄVHAYk;AéoD½ëp{¿f:>§X'AžÔ‹AYk;AúÈ$AËŒAj=Ab&A¸«‹AGd9AñUϼiz¿ ÅZ>b&A¸«‹AGd9AúÈ$AËŒAj=AA¸!Aÿá‹Aho;AF‚<¢$|¿«T0>b&A¸«‹AGd9AA¸!Aÿá‹Aho;AÑh#A¹‹A\7AË=HÇy¿‚&]>Ñh#A¹‹A\7AA¸!Aÿá‹Aho;AåA ²‹A=:AKOŽ=íy{¿vô1>Ñh#A¹‹A\7AåA ²‹A=:A#¢!A‹Z‹A}!6A­Ý·=Äx¿ƒ_>#¢!A‹Z‹A}!6AåA ²‹A=:AØíA1M‹AÊC8A(z>–·y¿i;4>#¢!A‹Z‹A}!6AØíA1M‹AÊC8A®¼A@‹Aö4AN/%>­5v¿}­b>®¼A@‹Aö4AØíA1M‹AÊC8An A ÌŠA–O6A»2Q>ªev¿ëÔ6>®¼A@‹Aö4An A ÌŠA–O6A+éA»ŠAÈ2Ahãm> Dr¿þf>+éA»ŠAÈ2An A ÌŠA–O6AžBAå/ŠAÑa4As>s­q¿á9>+éA»ŠAÈ2AžBAå/ŠAÑa4AD)AoŠAJ0Aµôš>”èl¿÷~i>D)AoŠAJ0AžBAå/ŠAÑa4Aö‘A)y‰A¿{2A†±>½‡k¿um<>D)AoŠAJ0Aö‘A)y‰A¿{2Ak~Aƒ[‰A¶".A1·>Òªg¿î"l>k~Aƒ[‰A¶".Aö‘A)y‰A¿{2Ah›AU/‰A<Ë1AR½Å>iPg¿´í=>k~Aƒ[‰A¶".Ah›AU/‰A<Ë1AòˆA‰Aðk-AŽ%Ë>Lc¿™}n>òˆA‰Aðk-Ah›AU/‰A<Ë1A %A+\ˆA™0A‹Åà>ìë`¿¿|@>òˆA‰Aðk-A %A+\ˆA™0A¸A·QˆAN‘+A´ì>ÆZ¿w8r>¸A·QˆAN‘+A %A+\ˆA™0A™ÕAÿt‡AAK.AÕð?ö¯W¿ …C>¸A·QˆAN‘+A™ÕAÿt‡AAK.A¿Acw‡A—É)AG…?]ñP¿v>¿Acw‡A—É)A™ÕAÿt‡AAK.A}­ Aéz†A~©,ATÕ?+M¿-œF>¿Acw‡A—É)A}­ Aéz†A~©,A$A㈆A&(A. ?bÊE¿åy>$A㈆A&(A}­ Aéz†A~©,A²¬ An…AR+AY ?ÒXA¿?¾I>$A㈆A&(A²¬ An…AR+A¿„ A‰†…Ax&A75!?'”<¿¼Š|>¿„ A‰†…Ax&A²¬ An…AR+Al3 A)…Ac¾*AœS'?gú:¿[K>¿„ A‰†…Ax&Al3 A)…Ac¾*A^ AIC…A­&AnA(?Q!6¿~´~>^ AIC…A­&Al3 A)…Ac¾*AuAŠ„A \)AŒ™1?!1¿E–M>^ AIC…A­&AuAŠ„A \)An< AJ3„A˜¡$A6‹5?°ˆ(¿-7>n< AJ3„A˜¡$AuAŠ„A \)AäAzï‚Ax(A±e>?Îý"¿vP>n< AJ3„A˜¡$AäAzï‚Ax(Aö›A¡ƒA•L#A–ÏA?‚ã¿Sƒ>ö›A¡ƒA•L#AäAzï‚Ax(A0A–ÃAzò&A%J?½ê¿oS>ö›A¡ƒA•L#A0A–ÃAzò&Ai&AííAc"AüM?43 ¿û¾„>i&AííAc"A0A–ÃAzò&A=EAö€A!ë%A¦ÎT?¨×¿B*V>i&AííAc"A=EAö€A!ë%A4ÛA4¹€Aºÿ AÝàT?0åú¾ä…>4ÛA4¹€Aºÿ A=EAö€A!ë%AìAg+€AjŸ%AŸZ?š‹õ¾ [W>4ÛA4¹€Aºÿ AìAg+€AjŸ%A–|ArV€At¯ A¡äY?”è¾ÛІ>–|ArV€At¯ AìAg+€AjŸ%AóA¨ë}AÊ$AöÔ`?«dÛ¾S`Y>–|ArV€At¯ AóA¨ë}AÊ$AWsA°=~AÐÌAÅb?Èñž”/ˆ>WsA°=~AÐÌAóA¨ë}AÊ$AÓ$Aœy{A·$Algh?–‰¸¾U|[>WsA°=~AÐÌAÓ$Aœy{A·$A)–AˆÃ{Aê Aêh?¢¾}^‰>)–AˆÃ{Aê AÓ$Aœy{A·$A×A/yAz…#A «n?‹€”¾¸G]>)–AˆÃ{Aê A×A/yAz…#A"äAS>yAðrAÐjn?‡z¾kWŠ>"äAS>yAðrA×A/yAz…#A.A ~vA¡#A—s?©^¾ƒ¸^>"äAS>yAðrA.A ~vA¡#Aò\AR­vAqüAår?Û¨8¾æïŠ>ò\AR­vAqüA.A ~vA¡#AZÍA¨uAtæ"A¾Fv?ø(¾ƒl_>ò\AR­vAqüAZÍA¨uAtæ"A`"Aø*uAâÈA­3t?äM¾z`‹>`"Aø*uAâÈAZÍA¨uAtæ"A#’Aâ‹rA;±"AÜvx?]´Í½•'`>`"Aø*uAâÈA#’Aâ‹rA;±"AÏáACŸrAàA¬îu?%ÏS½¦¯‹>ÏáACŸrAàA#’Aâ‹rA;±"A½}AHpAÙž"A®y?ÒÖØ¼²€`>ÏáACŸrAàA½}AHpAÙž"A‰ËAÍpA,|AÞ5v?ªÇ¾< º‹>‰ËAÍpA,|A½}AHpAÙž"A/A”mAy¯"AÖyy?ˆ D=)j`>‰ËAÍpA,|A/A”mAy¯"A®ßA•mAþA(u?ÕÑÉ=«~‹>®ßA•mAþA/A”mAy¯"AhÊAGkAÏã"A;Õw?ë²ú=Ñâ_>®ßA•mAþAhÊAGkAÏã"A*AíjAÆA8hr?Qe0>YÿŠ>*AíjAÆAhÊAGkAÏã"A»&A<³hAW6#APát?×F>iõ^>*AíjAÆA»&A<³hAW6#AƒAó~hA]A<|n?e-y>GŠ>ƒAó~hA]A»&A<³hAW6#Aì­A€=fA7®#AÂŽp?œ‡>;¦]>ƒAó~hA]Aì­A€=fA7®#AöAgûeApžAi?›*¡>N‰>öAgûeApžAì­A€=fA7®#Aa]AÂÌcA!H$A×j?뛫>õ[>öAgûeApžAa]AÂÌcA!H$A÷ÒA €cA’BAWb?ѵÄ>nˆ>÷ÒA €cA’BAa]AÂÌcA!H$A6A—`aA7%AßÍc?õÎ>‹ðY>÷ÒA €cA’BA6A—`aA7%Aw»Aó aA® AèDZ?© ç>»À†>w»Aó aA® A6A—`aA7%AŒ;Aõø^Aíâ%Aav[?ð>¡W>w»Aó aA® AŒ;Aõø^Aíâ%AñÐA€¢^A÷ A~ŽP?z°?ô+…>ñÐA€¢^A÷ AŒ;Aõø^Aíâ%A9AÉ[\AÍÿ&A`%Q?õ² ?–æT>ñÐA€¢^A÷ A9AÉ[\AÍÿ&AB7AO\Ay$"A!)E? ~?¶`ƒ>B7AO\Ay$"A9AÉ[\AÍÿ&A–ñA ZA#(A#âE?Þ°?5 R>B7AO\Ay$"A–ñA ZA#(AªA ¾YA4X#A€[9?¢@$?iœ>ªA ¾YA4X#A–ñA ZA#(AAvÏWA¦d)Aç9?w5(?„&O>ªA ¾YA4X#AAvÏWA¦d)AÌF ADŒWAª$Aí‹,?:þ1?‘>ÌF ADŒWAª$AAvÏWA¦d)Aå8 A‘§UA°Â*A1é,?‚¿5?²,L>ÌF ADŒWAª$Aå8 A‘§UA°Â*Aý A?sUA,&A·Ã?³>?ZÔ{>ý A?sUA,&Aå8 A‘§UA°Â*AJ Ac–SA9=,AQï?ý A?sUA,&AJ Ac–SA9=,AiA¹tSA¥'A­H?€*J?Bx>iA¹tSA¥'AJ Ac–SA9=,A¶Aa¶QA’¿-A~?BoM? -F>iA¹tSA¥'A¶Aa¶QA’¿-A§A«©QA8)A§7?é`T?Ónt>§A«©QA8)A¶Aa¶QA’¿-AÇZA ÞOAµl/AAþ?ò¬W?«,C>§A«©QA8)AÇZA ÞOAµl/A GAêOA¤ö*AÁìá>„µ]?t¯p> GAêOA¤ö*AÇZA ÞOAµl/AN¿A8-NAƒ,1A<%á>GØ`?‡,@> GAêOA¤ö*AN¿A8-NAƒ,1AW­ATNAqÇ,AxKÀ>_½e?§m>W­ATNAqÇ,AN¿A8-NAƒ,1AóHA¦LAàý2AU ¿>þ»h?[?=>W­ATNAqÇ,AóHA¦LAàý2A?4A=éLA^©.Ad›> yl?çvi>?4A=éLA^©.AóHA¦LAàý2Ao÷AüJKAÓß4A©û›>Vo?Þf:>?4A=éLA^©.Ao÷AüJKAÓß4AîÛA‹«KAh›0Ašx>v•q?ø3f>îÛA‹«KAh›0Ao÷AüJKAÓß4Aí8A‡VJA n6Aÿ'y>Qt?Eü7>îÛA‹«KAh›0Aí8A‡VJA n6AïA÷ÎJA/62A±“9>8Cu?«Sc>ïA÷ÎJA/62Aí8A‡VJA n6AïAÔWIAb8AœÊ4>ÅÛw?ö„5>ïA÷ÎJA/62AïAÔWIAb8AÐèAqíIA94AI<á=L3x?œ#`>ÐèAqíIA94AïAÔWIAb8A« AºHAvZ:A¡þÕ=ª¢z?Éý2>ÐèAqíIA94A« AºHAvZ:A˜Í!A~BIA¯?6Aí=’Äy?]>˜Í!A~BIA¯?6A« AºHAvZ:A§#AÆHA7V˜Í!A~BIA¯?6A§#AÆHA7VôÁ$A:ÏHAéH8A§#AÆHA7VôÁ$A:ÏHAéH8A§X'AÄVHAYk;AéÄ'AA•HAT:A†=?>X={?·5=#š AÊßIAúù/AÐèAqíIA94A?ê"A oIAœ§1AhC>ÿK|?rb´=?ê"A oIAœ§1AÐèAqíIA94A˜Í!A~BIA¯?6AP5 >›N}?µ3=?ê"A oIAœ§1A˜Í!A~BIA¯?6A•y#AÁSIAŸ2AÈú=¹õ}?0²=•y#AÁSIAŸ2A˜Í!A~BIA¯?6AôÁ$A:ÏHAéH8AÙw«=‘Ü~? Ú0=•y#AÁSIAŸ2AôÁ$A:ÏHAéH8A^d&AÔþHA-'4A-‹<â? µ¯=^d&AÔþHA-'4AôÁ$A:ÏHAéH8AéÄ'AA•HAT:A¦ <ïÁ?‹.=^d&AÔþHA-'4AéÄ'AA•HAT:A¨Y)A(âHAý?6A]ë^½€¦|?íj>éÄ'AA•HAT:A§X'AÄVHAYk;A›Ø4A¶eHAÙ@Azܽ?¯r?eh™>Â7&A°GA•T>AUg%A3âFAAn@A¿B3A-ôFAEEA0^¾)ØD?Ôø?ê"Aø¦AA $IAì!A/aAAciIA¼m0AÒeAA±wNATƒ¾Û'?ùØ5?:ß Ap¦>AãLAŒ‚ Ai=Aø MAD/A7t=A±ÊÎí½Y[z?†A„T#AªaAuŽA„T#Ar}^AéŽAöâ(AJ÷^Aò =§“¾Ò u?€ÿoAAñAôqaA³Ö|AAñA¡+aAºë|A„T#AnœbAœ½¤ÿ’¾pu?4&_AAñAtÕ`A·ÍlAAñAtƒaA{ÈlA„T#AÒôbAvTн_÷’¾×s?¾ÿŸl?5-A„T#AáíXAûA²V#A*”SAá AÝ'"ApkSA~‰Ø=i “¾T·s?l€AAñA{Ì`A‡g†AAñAJ°_A†A„T#AªaAY&>J “¾ûr?†A„T#AªaA‡g†AAñAJ°_A"̈AAñAùå^A¡Ú>÷l¾Âîu?†A„T#AªaA"̈AAñAùå^AuŽA„T#Ar}^Aqùv>.s—¾ôžl?³–AAñA5XYA‹I–Ap|"Aœ”ZAý‘AAñA-Á[Ašôc>6vu¾êq?ý‘AAñA-Á[A‹I–Ap|"Aœ”ZAuŽA„T#Ar}^Aè J>‚“¾gôo?ý‘AAñA-Á[AuŽA„T#Ar}^AQŽAAñAZ]Aöo2>瓾¿q?QŽAAñAZ]AuŽA„T#Ar}^A"̈AAñAùå^A¯¥­¾ß«<…Äp?xÎA;á*AFTA™ÏAã(A[TAŒ-Aöâ(A¬dYAÚ ­¾Eq˼¿p?Œ-Aöâ(A¬dYA™ÏAã(A[TAõÐAÏ~&AÛTAÜŪ¾~f:>sÌl?uA:/A“~SAÔùAäo.Ah—SA55-Acq.AœíXA‰¬¾1 >ÏŠn?55-Acq.AœíXAÔùAäo.Ah—SAxÎA;á*AFTA½„¼û’¾®6u?·ÍlAAñAtƒaA€ÿoAAñAôqaA{ÈlA„T#AÒôbAÏÊf<Úfl¾ùy?{ÈlA„T#AÒôbA€ÿoAAñAôqaAºë|A„T#AnœbAʽ=ÉÎí½q ~?{ÈlA„T#AÒôbAºë|A„T#AnœbAÍò|Aöâ(A‡cAŒû¤=L›m½H¼~?Íò|Aöâ(A‡cAºë|A„T#AnœbA‡†Aöâ(Aò™aA!ÆÔ=Fjn= -~?Íò|Aöâ(A‡cA‡†Aöâ(Aò™aA†Acq.AcaAè©>¿5î=õW{?†Acq.AcaA‡†Aöâ(Aò™aA–uŽAcq.A,}^Aëœ->±Kl>ÃGu?†Acq.AcaA–uŽAcq.A,}^AQŽA“Ô3AÏ]AhÄu>¯Ù:¾xt?‹I–Ap|"Aœ”ZAEM–A4V#A~¯ZAuŽA„T#Ar}^A”Üw>‰ ¾ v?uŽA„T#Ar}^AEM–A4V#A~¯ZA^–AE+'A¢([A¾Óa>z›½Šðx?uŽA„T#Ar}^A^–AE+'A¢([AéŽAöâ(AJ÷^Aôóy>Å’¼ä6x?éŽAöâ(AJ÷^A^–AE+'A¢([AÞ\–A‹â(A [AŠØy>8¦="x?éŽAöâ(AJ÷^AÞ\–A‹â(A [AÊZ–A¨ã+A[ABv=Ï“¾™¼t?³Ö|AAñA¡+aAl€AAñA{Ì`Aºë|A„T#AnœbA9»¬=´tl¾Ð$x?ºë|A„T#AnœbAl€AAñA{Ì`A†A„T#AªaAä.Ô=ÉÎí½–á|?ºë|A„T#AnœbA†A„T#AªaA‡†Aöâ(Aò™aA¥²>L›m½. |?‡†Aöâ(Aò™aA†A„T#AªaAéŽAöâ(AJ÷^Aê_2>Fjn=3¥{?‡†Aöâ(Aò™aAéŽAöâ(AJ÷^A–uŽAcq.A,}^A5†a>]·=û¨x?–uŽAcq.A,}^AéŽAöâ(AJ÷^AÊZ–A¨ã+A[A6g ¾èÃ>ö°^?àAî{7A»ÌPAu}AÒ3AÝCRAý¡-A“Ô3AMŒWAw£¾Õ:­> b?ý¡-A“Ô3AMŒWAu}AÒ3AÝCRAïnAft3ASiRAX¦¾^•>ø\f?ý¡-A“Ô3AMŒWAïnAft3ASiRAuA:/A“~SA<é—¾¼¹ø>+zR?[AmÙ8AZPAàAî{7A»ÌPA–S.AŸâ8A}KUA•’¾ØKÞ>v¿Z?–S.AŸâ8A}KUAàAî{7A»ÌPAý¡-A“Ô3AMŒWAðy¾æòå>C\?–S.AŸâ8A}KUAý¡-A“Ô3AMŒWA¶¦=AŸâ8ABlYA°§¾Ñç’¾–Sr?èÜLAAñABÈ^AÌôx?|ÈlAcq.A‰ôbA¶ë|Acq.A&œbA«Ö|A“Ô3A+aAlV=ý’>ñnt?«Ö|A“Ô3A+aA¶ë|Acq.A&œbA~g†A“Ô3A¾¯_A̸Â=ËäÊ>"Çi?«Ö|A“Ô3A+aA~g†A“Ô3A¾¯_Aò@†AŸâ8A%Y]A4À >æòå>b?ò@†AŸâ8A%Y]A~g†A“Ô3A¾¯_AJŽAŸâ8A6ÃZAE>Ôº ?:™R?ò@†AŸâ8A%Y]AJŽAŸâ8A6ÃZA=ÄA7t=AY WAM\w>õÜ>ñ‰u?ÊZ–A¨ã+A[AL–A°m.Aâ¦ZA–uŽAcq.A,}^Aå u>4ˆH>ts?–uŽAcq.A,}^AL–A°m.Aâ¦ZAÐ?–AJ‹0AkNZA/[>K>ñq?–uŽAcq.A,}^AÐ?–AJ‹0AkNZAQŽA“Ô3AÏ]A„n>"ë>^"l?QŽA“Ô3AÏ]AÐ?–AJ‹0AkNZAa–AÏ3AtGYA8ži>ß±µ>Kh?QŽA“Ô3AÏ]Aa–AÏ3AtGYAº –A=5AëäXAˆj ½ò’¾¨ht?àÈ\AAñAR·`A4&_AAñAtÕ`Af©\A„T#Aa'bA)`f½kVl¾¬x?f©\A„T#Aa'bA4&_AAñAtÕ`A{ÈlA„T#AÒôbAò‘½ÉÎí½K~?f©\A„T#Aa'bA{ÈlA„T#AÒôbA¸ÆlAöâ(AqcA¹á¦¾w?¶ë|Acq.A&œbA†Acq.AcaA~g†A“Ô3A¾¯_AÓô>ý’>æjr?~g†A“Ô3A¾¯_A†Acq.AcaAQŽA“Ô3AÏ]Av’#>ËäÊ>÷tg?~g†A“Ô3A¾¯_AQŽA“Ô3AÏ]AJŽAŸâ8A6ÃZAùùN>_3Ñ>ŽÚc?JŽAŸâ8A6ÃZAQŽA“Ô3AÏ]Aº –A=5AëäXAxO^>;ì>?C\?JŽAŸâ8A6ÃZAº –A=5AëäXA'Ì•ASß8A² WAhiˆ¾°Ù??ÐA7t=APNVAYvU¾Ôº ?+O?~_>A7t=APNVA–S.AŸâ8A}KUA¶¦=AŸâ8ABlYAÒ'¾Åó? þH?~_>A7t=APNVA¶¦=AŸâ8ABlYA ºMA7t=A|JYAÔÀj¾í)=?!3"?ì!A/aAAciIA:ß Ap¦>AãLA¼m0AÒeAA±wNA¡h¾æÍ2?Z»-?¼m0AÒeAA±wNA:ß Ap¦>AãLAD/A7t=A±A7t=APNVAÄ.¾yF:?Lë+?IC?AÒeAA£vRA~_>A7t=APNVAîWNAÒeAAeUA€e¾’º/?67?îWNAÒeAAeUA~_>A7t=APNVA ºMA7t=A|JYAz廽yF:?D.?îWNAÒeAAeUA ºMA7t=A|JYA&˜]AÒeAAN?WA'}¾,ˆx¾é‡k?á AÝ'"ApkSAÓ¡-AAñAÕŒWA5-A„T#AáíXA‡¾Cl¾ÁÄo?5-A„T#AáíXAÓ¡-AAñAÕŒWAË;šw?f£LAcq.Aà4`Am©\Acq.A'bAëÈ\A“Ô3AŶ`A\ýr½ý’>ªÀt?ëÈ\A“Ô3AŶ`Am©\Acq.A'bA¹ÍlA“Ô3Aæ‚aA νËäÊ>Þj?ëÈ\A“Ô3AŶ`A¹ÍlA“Ô3Aæ‚aAGÖlAŸâ8Al'_A}ö<çòå>G¸d?GÖlAŸâ8Al'_A¹ÍlA“Ô3Aæ‚aAN´|AŸâ8A„Ð^AKÝ<Ôº ? ¼U?GÖlAŸâ8Al'_AN´|AŸâ8A„Ð^A¯…|A7t=AÈž[AŒ´‚=Åó?¢L?¯…|A7t=AÈž[AN´|AŸâ8A„Ð^A£ †A7t=AË,ZAJ-™=’º/?,9?¯…|A7t=AÈž[A£ †A7t=AË,ZA&Ì…AÒeAA[CVAøqÒ=yF:?ëŸ-?&Ì…AÒeAA[CVA£ †A7t=AË,ZAT`AÒeAAœÂSAß/Ó=ßaM?ñ…?&Ì…AÒeAA[CVAT`AÒeAAœÂSA—ìŒAĘDAHOAnÚW>G?ëeV?'Ì•ASß8A² WA›Å•A}A9ArÜVAJŽAŸâ8A6ÃZANP>û» ?;lO?JŽAŸâ8A6ÃZA›Å•A}A9ArÜVAi•A=AS@TA£{5>Ì?•èH?JŽAŸâ8A6ÃZAi•A=AS@TA=ÄA7t=AY WA²?@>h¼#?ÌÔ>?=ÄA7t=AY WAi•A=AS@TAó^•A$o=A•÷SAZ7>7-?E×6?=ÄA7t=AY WAó^•A$o=A•÷SAú”AºŒ@AQAgQ\¾QÜ’¾=ún?n=AAñAǸ[AoÑ=AAñA“Û[AË£èx?m©\Acq.A'bA|ÈlAcq.A‰ôbA¹ÍlA“Ô3Aæ‚aA¼<ý’>‰6u?¹ÍlA“Ô3Aæ‚aA|ÈlAcq.A‰ôbA«Ö|A“Ô3A+aALBõ<ËäÊ>¤êj?¹ÍlA“Ô3Aæ‚aA«Ö|A“Ô3A+aAN´|AŸâ8A„Ð^AG>’=çòå>Gÿc?N´|AŸâ8A„Ð^A«Ö|A“Ô3A+aAò@†AŸâ8A%Y]AÅ¡°=Ôº ?´T?N´|AŸâ8A„Ð^Aò@†AŸâ8A%Y]A£ †A7t=AË,ZA¸ö=Åó?XôJ?£ †A7t=AË,ZAò@†AŸâ8A%Y]A=ÄA7t=AY WAè>’º/?ãW7?£ †A7t=AË,ZA=ÄA7t=AY WAT`AÒeAAœÂSA×þ>ªå7?d·-?T`AÒeAAœÂSA=ÄA7t=AY WAú”AºŒ@AQAà|!¾ƒ\b?¡á>ª¹$A·6FA?.BA-“#AœŽDAì%EAïÅ1AĘDAÏJAûE0¾ª\?$ô>ïÅ1AĘDAÏJA-“#AœŽDAì%EAÍQ#Au0DA’ÎEAœ.A¾ XU?òþ?ÍQ#Au0DA’ÎEAê"Aø¦AA $IAïÅ1AĘDAÏJA;‹A¾3N?A?ïÅ1AĘDAÏJAê"Aø¦AA $IA¼m0AÒeAA±wNAÿÒ¾ïU? =?ïÅ1AĘDAÏJA¼m0AÒeAA±wNA*K@AĘDANAö¾ßaM?ó?*K@AĘDANA¼m0AÒeAA±wNAIC?AÒeAA£vRAûå½ïU?'¡ ?*K@AĘDANAIC?AÒeAA£vRA(OAĘDA·áPAÊQݽßaM?«K?(OAĘDA·áPAIC?AÒeAA£vRAîWNAÒeAAeUAG&—½ïU?S ?(OAĘDA·áPAîWNAÒeAAeUAÎû]AĘDAã±RA!O‡½ßaM?´á?Îû]AĘDAã±RAîWNAÒeAAeUA&˜]AÒeAAN?WA¹½ïU?¤P ?Îû]AĘDAã±RA&˜]AÒeAAN?WAÅmAĘDAHqSAíâû½”µn?ìì­>Ug%A3âFAAn@Aª¹$A·6FA?.BA¿B3A-ôFAEEAD¾åîh?0‚É>¿B3A-ôFAEEAª¹$A·6FA?.BAïÅ1AĘDAÏJA#•Þ½|k?5ßÂ>¿B3A-ôFAEEAïÅ1AĘDAÏJAoAA-ôFA_IAðêæ½Ëd?RÞ>oAA-ôFA_IAïÅ1AĘDAÏJA*K@AĘDANAUŸ¦½|k?uUÆ>oAA-ôFA_IA*K@AĘDANAÅ×OA-ôFAhãKA/"§½Ëd?jÜá>Å×OA-ôFAhãKA*K@AĘDANA(OAĘDA·áPA¡£[½|k?ñÊÈ>Å×OA-ôFAhãKA(OAĘDA·áPAj^A-ôFA|¨MAM½Ëd?gBä>j^A-ôFA|¨MA(OAĘDA·áPAÎû]AĘDAã±RAxØÑ¼|k?x<Ê>j^A-ôFA|¨MAÎû]AĘDAã±RAmA-ôFANcNAãl•¼Ëd?à€å>mA-ôFANcNAÎû]AĘDAã±RAÅmAĘDAHqSAö/%;|k?,¨Ê>mA-ôFANcNAÅmAĘDAHqSAô¿{A-ôFAîNAöÁ¡¾¢Å¡={ r?xÎA;á*AFTAŒ-Aöâ(A¬dYA55-Acq.AœíXAÁ#о¾5î=‰³t?55-Acq.AœíXAŒ-Aöâ(A¬dYA'Ë?q?55-Acq.AœíXA'Ë… p?Ž=A“Ô3A=¸[A'Ë*6g?Ž=A“Ô3A=¸[AþÜLA“Ô3A¶Ç^A;MAŸâ8AŒs\AÏVó½æòå>ƒ²b?;MAŸâ8AŒs\AþÜLA“Ô3A¶Ç^AWü\AŸâ8Am]^A©»»½Ôº ?’ŽT?;MAŸâ8AŒs\AWü\AŸâ8Am]^A B]A7t=AW-[AVnM½Åó?àáL? B]A7t=AW-[AWü\AŸâ8Am]^AâálA7t=Aqô[A|—é¼’º/?3:? B]A7t=AW-[AâálA7t=Aqô[A2ðlAÒeAAÖXA1;¶;yF:?²™/?2ðlAÒeAAÖXAâálA7t=Aqô[A4L|AÒeAA·®WAñM™<ßaM?Ò¾?2ðlAÒeAAÖXA4L|AÒeAA·®WAŸ |AĘDAðSAº¢0=ïU?l* ?Ÿ |AĘDAðSA4L|AÒeAA·®WAr…AĘDAD»QAåY:=Ëd?W‚ä>Ÿ |AĘDAðSAr…AĘDAD»QAË.…A-ôFA÷LA9p=|k?CmÈ>Ë.…A-ôFA÷LAr…AĘDAD»QAŠlŒA-ôFAŽSJA_§G= Au?Ì¥>Ë.…A-ôFA÷LAŠlŒA-ôFAŽSJAä‹A¶eHAœ EA0p#>"îA?¹ "?ú”AºŒ@AQAa×”AáWAA/%PAT`AÒeAAœÂSA>zêI?ð¦?T`AÒeAAœÂSAa×”AáWAA/%PAöz”AvCA5ŠMA'P>кR?;Æ ?T`AÒeAAœÂSAöz”AvCA5ŠMA—ìŒAĘDAHOAû3>åÑZ?¢Ñ?—ìŒAĘDAHOAöz”AvCA5ŠMA0;”A†…DAù½KAÜ í=@a?…“ì>—ìŒAĘDAHOA0;”A†…DAù½KA§î“AQËEAœ•IAñhÀ=SÌg?¨êÓ>§î“AQËEAœ•IAŠlŒA-ôFAŽSJA—ìŒAĘDAHOAJæ=Ëd? Fâ>—ìŒAĘDAHOAŠlŒA-ôFAŽSJAr…AĘDAD»QA2ɧ=ïU?Ö ?—ìŒAĘDAHOAr…AĘDAD»QA&Ì…AÒeAA[CVAH%z=ßaM?Ê?&Ì…AÒeAA[CVAr…AĘDAD»QA4L|AÒeAA·®WA e^=yF:? /?&Ì…AÒeAA[CVA4L|AÒeAA·®WA¯…|A7t=AÈž[AÝ ¾<’º/?™:?¯…|A7t=AÈž[A4L|AÒeAA·®WAâálA7t=Aqô[A\|à;Åó?ØFM?¯…|A7t=AÈž[AâálA7t=Aqô[AGÖlAŸâ8Al'_APѽԺ ?ë¯U?GÖlAŸâ8Al'_AâálA7t=Aqô[AWü\AŸâ8Am]^A_«c½æòå>+Id?GÖlAŸâ8Al'_AWü\AŸâ8Am]^AëÈ\A“Ô3AŶ`AäÀͽËäÊ>R¡i?ëÈ\A“Ô3AŶ`AWü\AŸâ8Am]^AþÜLA“Ô3A¶Ç^AÉ+¾ý’>í s?ëÈ\A“Ô3AŶ`AþÜLA“Ô3A¶Ç^Af£LAcq.Aà4`AWß2¾°Kl>C u?f£LAcq.Aà4`AþÜLA“Ô3A¶Ç^A'˧X'AÄVHAYk;AÂ7&A°GA•T>A›Ø4A¶eHAÙ@A1Úª½{w?l>›Ø4A¶eHAÙ@AÂ7&A°GA•T>A¿B3A-ôFAEEA–Å‚½My?L¹b>›Ø4A¶eHAÙ@A¿B3A-ôFAEEAE¦BA¶eHA´ÖCAT ”½ Au?Ž>E¦BA¶eHA´ÖCA¿B3A-ôFAEEAoAA-ôFA_IA#nD½My?#Ìf>E¦BA¶eHA´ÖCAoAA-ôFA_IA¥®PA¶eHA‘FA©ÃW½ Au?%I>¥®PA¶eHA‘FAoAA-ôFA_IAÅ×OA-ôFAhãKAÌR½My?/´i>¥®PA¶eHA‘FAÅ×OA-ôFAhãKA‘ß^A¶eHAGJHAR/½ Au?pÖ‘>‘ß^A¶eHAGJHAÅ×OA-ôFAhãKAj^A-ôFA|¨MAð:~¼My?«mk>‘ß^A¶eHAGJHAj^A-ôFA|¨MA©&mA¶eHA8IA?ºG¼ Au?í¦’>©&mA¶eHA8IAj^A-ôFA|¨MAmA-ôFANcNAça:My?[ök>©&mA¶eHA8IAmA-ôFANcNArq{A¶eHAñ±HAaK< Au?Œ¹’>rq{A¶eHAñ±HAmA-ôFANcNAô¿{A-ôFAîNAÆ2rq{A¶eHAñ±HAô¿{A-ôFAîNAµÖ„A¶eHAÖ_GAÑ2‡¼¥»?xa.=¨Y)A(âHAý?6AéÄ'AA•HAT:A.{6A(âHAcÏ:AÙ› ½Ýž~?ÔÜÈ=.{6A(âHAcÏ:AéÄ'AA•HAT:A›Ø4A¶eHAÙ@A·ÿ‹¼c‘?EXc=.{6A(âHAcÏ:A›Ø4A¶eHAÙ@A,çCA(âHAñl>AâT÷¼ûD~?õ‹å=,çCA(âHAñl>A›Ø4A¶eHAÙ@AE¦BA¶eHA´ÖCAB©V¼c‘?¦¾g=,çCA(âHAñl>AE¦BA¶eHA´ÖCAAŒQA(âHAöAAžsµ¼ûD~?V\é=AŒQA(âHAöAAE¦BA¶eHA´ÖCA¥®PA¶eHA‘FA.=¼c‘?ùj=AŒQA(âHAöAA¥®PA¶eHA‘FAÂX_A(âHAÁBAÜNe¼ûD~?—þë=ÂX_A(âHAÁBA¥®PA¶eHA‘FA‘ß^A¶eHAGJHA^"¢»c‘?&m=ÂX_A(âHAÁBA‘ß^A¶eHAGJHAÒ:mA(âHAíqCA?½»ûD~?Roí=Ò:mA(âHAíqCA‘ß^A¶eHAGJHA©&mA¶eHA8IAÁÃWºc‘?uÚm=Ò:mA(âHAíqCA©&mA¶eHA8IAx {A(âHAÏ%CA¸";ûD~?¨¬í=x {A(âHAÏ%CA©&mA¶eHA8IArq{A¶eHAñ±HA±¨X;c‘?Ó}m=x {A(âHAÏ%CArq{A¶eHAñ±HAÜ{„A(âHA ÝAAµ/<ûD~?J¶ì=Ü{„A(âHA ÝAArq{A¶eHAñ±HAµÖ„A¶eHAÖ_GAêó;c‘?ºík=Ü{„A(âHA ÝAAµÖ„A¶eHAÖ_GAQW‹A(âHAN™?AKåº=0¹m?l&¸>§î“AQËEAœ•IAÚŽ“AéàFA:âFAŠlŒA-ôFAŽSJA‹¬¡=•r?c¡>ŠlŒA-ôFAŽSJAÚŽ“AéàFA:âFA"X“AtGAYWEAv=¬‡v?4†>ŠlŒA-ôFAŽSJA"X“AtGAYWEAä‹A¶eHAœ EAÔ°X= z?GS>ä‹A¶eHAœ EA"X“AtGAYWEAJ×’AÂXHAyµAA$Þ#=|?×™#>ä‹A¶eHAœ EAJ×’AÂXHAyµAA±º’AÿˆHAç@A᩾l–t>wÂk?uA:/A“~SA55-Acq.AœíXAý¡-A“Ô3AMŒWA Y…¾ý’>=ük?ý¡-A“Ô3AMŒWA55-Acq.AœíXAŽ=A“Ô3A=¸[AUj¾ËäÊ>«Ÿc?ý¡-A“Ô3AMŒWAŽ=A“Ô3A=¸[A¶¦=AŸâ8ABlYAsÎ9¾æòå>]ö_?¶¦=AŸâ8ABlYAŽ=A“Ô3A=¸[A;MAŸâ8AŒs\AÏ ¾Ôº ?ZR?¶¦=AŸâ8ABlYA;MAŸâ8AŒs\A ºMA7t=A|JYA!ñÚ½Åó?§sK? ºMA7t=A|JYA;MAŸâ8AŒs\A B]A7t=AW-[A𤽒º/?ú9? ºMA7t=A|JYA B]A7t=AW-[A&˜]AÒeAAN?WATô0½yF:?íA/?&˜]AÒeAAN?WA B]A7t=AW-[A2ðlAÒeAAÖXA)u¼ßaM?³?&˜]AÒeAAN?WA2ðlAÒeAAÖXAÅmAĘDAHqSAs†;ïU?‹˜ ?ÅmAĘDAHqSA2ðlAÒeAAÖXAŸ |AĘDAðSAÌ×_<Ëd?9–å>ÅmAĘDAHqSAŸ |AĘDAðSAô¿{A-ôFAîNA¹ û<|k?‚ Ê>ô¿{A-ôFAîNAŸ |AĘDAðSAË.…A-ôFA÷LA’Ñé< Au?8’>ô¿{A-ôFAîNAË.…A-ôFA÷LAµÖ„A¶eHAÖ_GAÃO =My? ti>µÖ„A¶eHAÖ_GAË.…A-ôFA÷LAä‹A¶eHAœ EABìš<ûD~?xê=µÖ„A¶eHAÖ_GAä‹A¶eHAœ EAQW‹A(âHAN™?AHºÉ<‰†~?jžÕ=QW‹A(âHAN™?Aä‹A¶eHAœ EA±º’AÿˆHAç@AúW<¿°?EB=QW‹A(âHAN™?A±º’AÿˆHAç@A¾’A(âHAƒ] Contents

Previous / Next / Contents

Fabmetheus Utilities
    Interpret Plugins
      Gts
      Obj
      Slc
      Stl
      Svg
      Xml
        Artofillusion
        Fabmetheus
  Geometry
    Creation
      Gear
    Geometry Utilities
      Boolean Geometry
      Boolean Solid
    Solids
  Skeinforge
    Analyze
        Display Line
        View Move
        View Rotate
        Zoom In
        Zoom Out
      Clairvoyance
      Comment
        Postscript
        Scalable Vector Graphics
      Interpret
      Skeiniso
      Skeinlayer
      Statistic
      Synopsis
      Vectorwrite
    Craft
      Alteration
      Bottom
      Carve
      Chamber
      Chop
      Cleave
      Clip
      Coil
      Comb
      Cool
      Dimension
      Drill
      Export
        Binary 16 Byte
        Gcode Step
        Gcode Time Segment
          Gcode Small
      Feed
      Fill
      Fillet
      Flow
      Home
      Hop
      Inset
      Jitter
      Lash
      Lift
      Limit
      Mill
      Multiply
      Oozebane
      Outset
      Preface
      Raft
      Scale
      Skin
      Skirt
      Smooth
      Speed
      Splodge
      Stretch
      Temperature
      Tower
      Unpause
      Whittle
      Widen
      Wipe
    Help
    Meta
      Description
      Polyfile
    Profile
      Cutting
      Extrusion
      Milling
      Winding

Previous / Next / Contents

sfact-2011.12.18/documentation/fabmetheus_utilities.archive.html000066400000000000000000000376251167321211700246220ustar00rootroot00000000000000 Python: module fabmetheus_utilities.archive
 
 
fabmetheus_utilities.archive ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/archive.py

Boolean geometry utilities.

 
Modules
       
__init__
os
sys
traceback

 
Functions
       
addToNamePathDictionary(directoryPath, namePathDictionary)
Add to the name path dictionary.
getAbsoluteFolderPath(filePath, folderName='')
Get the absolute folder path.
getAbsoluteFrozenFolderPath(filePath, folderName='')
Get the absolute frozen folder path.
getAnalyzePluginsDirectoryPath(subName='')
Get the analyze plugins directory path.
getCraftPluginsDirectoryPath(subName='')
Get the craft plugins directory path.
getDocumentationPath(subName='')
Get the documentation file path.
getElementsPath(subName='')
Get the evaluate_elements directory path.
getEndsWithList(word, wordEndings)
Determine if the word ends with a list.
getFabmetheusPath(subName='')
Get the fabmetheus directory path.
getFabmetheusToolsPath(subName='')
Get the fabmetheus tools directory path.
getFabmetheusUtilitiesPath(subName='')
Get the fabmetheus utilities directory path.
getFileNamesByFilePaths(pluginFilePaths)
Get the file names of the plugins by the file paths.
getFilePathWithUnderscoredBasename(fileName, suffix)
Get the file path with all spaces in the basename replaced with underscores.
getFilePaths(fileInDirectory='')
Get the file paths in the directory of the file in directory.
getFilePathsByDirectory(directoryName)
Get the file paths in the directory of the file in directory.
getFilePathsRecursively(fileInDirectory='')
Get the file paths in the directory of the file in directory.
getFileText(fileName, printWarning=True, readMode='r')
Get the entire text of a file.
getFileTextInFileDirectory(fileInDirectory, fileName, readMode='r')
Get the entire text of a file in the directory of the file in directory.
getFilesWithFileTypeWithoutWords(fileType, words=[], fileInDirectory='')
Get files which have a given file type, but with do not contain a word in a list.
getFilesWithFileTypesWithoutWords(fileTypes, words=[], fileInDirectory='')
Get files which have a given file type, but with do not contain a word in a list.
getFilesWithFileTypesWithoutWordsRecursively(fileTypes, words=[], fileInDirectory='')
Get files recursively which have a given file type, but with do not contain a word in a list.
getFundamentalsPath(subName='')
Get the evaluate_fundamentals directory path.
getGeometryDictionary(folderName)
Get to the geometry name path dictionary.
getGeometryPath(subName='')
Get the geometry directory path.
getGeometryToolsPath(subName='')
Get the geometry tools directory path.
getGeometryUtilitiesPath(subName='')
Get the geometry_utilities directory path.
getInterpretPluginsPath(subName='')
Get the interpret plugins directory path.
getJoinedPath(path, subName='')
Get the joined file path.
getModuleWithDirectoryPath(directoryPath, fileName)
Get the module from the fileName and folder name.
getModuleWithPath(path)
Get the module from the path.
getPluginFileNamesFromDirectoryPath(directoryPath)
Get the file names of the python plugins in the directory path.
getProfilesPath(subName='')
Get the profiles directory path, which is the settings directory joined with profiles.
getPythonDirectoryNames(directoryName)
Get the python directories.
getPythonDirectoryNamesRecursively(directoryName='')
Get the python directories recursively.
getPythonFileNamesExceptInit(fileInDirectory='')
Get the python fileNames of the directory which the fileInDirectory is in, except for the __init__.py file.
getPythonFileNamesExceptInitRecursively(directoryName='')
Get the python fileNames of the directory recursively, except for the __init__.py files.
getSettingsPath(subName='')
Get the settings directory path, which is the home directory joined with .skeinforge.
getSkeinforgePath(subName='')
Get the skeinforge directory path.
getSkeinforgePluginsPath(subName='')
Get the skeinforge plugins directory path.
getSummarizedFileName(fileName)
Get the fileName basename if the file is in the current working directory, otherwise return the original full name.
getTemplatesPath(subName='')
Get the templates directory path.
getTextIfEmpty(fileName, text)
Get the text from a file if it the text is empty.
getTextLines(text)
Get the all the lines of text of a text.
getUntilDot(text)
Get the text until the last dot, if any.
getVersionFileName()
Get the file name of the version date.getFabmetheusUtilitiesPath(subName=)
isFileWithFileTypeWithoutWords(fileType, fileName, words)
Determine if file has a given file type, but with does not contain a word in a list.
makeDirectory(directoryPath)
Make a directory if it does not already exist.
removeBackupFilesByType(fileType)
Remove backup files by type.
removeBackupFilesByTypes(fileTypes)
Remove backup files by types.
writeFileMessageEnd(end, fileName, fileText, message)
Write to a fileName with a suffix and print a message.
writeFileText(fileName, fileText, writeMode='w+')
Write a text to a file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalTemporarySettingsPath = '/home/enrique/.skeinforge'

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.euclidean.html000066400000000000000000002063201167321211700251200ustar00rootroot00000000000000 Python: module fabmetheus_utilities.euclidean
 
 
fabmetheus_utilities.euclidean ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/euclidean.py

Euclidean is a collection of python utilities for complex numbers, paths, polygons & Vector3s.

To use euclidean, install python 2.x on your machine, which is avaliable from http://www.python.org/download/

Then in the folder which euclidean is in, type 'python' in a shell to run the python interpreter. Finally type 'import euclidean' to import these utilities and 'from vector3 import Vector3' to import the Vector3 class.


Below are examples of euclidean use.

>>> from euclidean import *
>>> origin=complex()
>>> right=complex(1.0,0.0)
>>> back=complex(0.0,1.0)
>>> getMaximum(right,back)
1.0, 1.0
>>> polygon=[origin, right, back]
>>> getLoopLength(polygon)
3.4142135623730949
>>> getAreaLoop(polygon)
0.5

 
Modules
       
__init__
cStringIO
math
random
fabmetheus_utilities.xml_simple_writer

 
Classes
       
DistanceIndex
Endpoint
LoopLayer
NestedRing
NestedBand
PathZ
ProjectiveSpace
XIntersectionIndex

 
class DistanceIndex
    A class to hold the distance and the index of the loop.
 
  Methods defined here:
__init__(self, distance, index)
Initialize.
__repr__(self)
Get the string representation of this distance index.

 
class Endpoint
    The endpoint of a segment.
 
  Methods defined here:
__repr__(self)
Get the string representation of this Endpoint.
getClosestEndpoint(self, endpoints)
Get closest endpoint.
getClosestMiss(self, endpoints, path, pixelDictionary, width)
Get the closest endpoint which the segment to that endpoint misses the other extrusions.
getClosestMissCheckEndpointPath(self, endpoints, path, pixelDictionary, width)
Get the closest endpoint which the segment to that endpoint misses the other extrusions, also checking the path of the endpoint.
getFromOtherPoint(self, otherEndpoint, point)
Initialize from other endpoint.

 
class LoopLayer
    Loops with a z.
 
  Methods defined here:
__init__(self, z)
Initialize.
__repr__(self)
Get the string representation of this loop layer.

 
class NestedBand(NestedRing)
    A loop that surrounds paths.
 
  Methods defined here:
__init__(self)
Initialize.
__repr__(self)
Get the string representation of this nested ring.
addPerimeterInner(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence)
Add to the perimeter and the inner island.
addToBoundary(self, vector3)
Add vector3 to boundary.
addToLoop(self, vector3)
Add vector3 to loop.
addToThreads(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence)
Add to paths from the last location. perimeter>inner >fill>paths or fill> perimeter>inner >paths
getFillLoops(self, penultimateFillLoops)
Get last fill loops from the outside loop and the loops inside the inside loops.
getLoopsToBeFilled(self)
Get last fill loops from the outside loop and the loops inside the inside loops.
getSurroundingBoundaries(self)
Get the boundary of the surronding loop plus any boundaries of the innerNestedRings.
transferClosestFillLoops(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence)
Transfer closest fill loops.
transferInfillPaths(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence)
Transfer the infill paths.
transferPaths(self, paths)
Transfer paths.

Methods inherited from NestedRing:
addFlattenedNestedRings(self, flattenedNestedRings)
Add flattened nested rings.
getFromInsideSurroundings(self, inputSurroundingInsides)
Initialize from inside nested rings.

 
class NestedRing
    A nested ring.
 
  Methods defined here:
__init__(self)
Initialize.
__repr__(self)
Get the string representation of this nested ring.
addFlattenedNestedRings(self, flattenedNestedRings)
Add flattened nested rings.
getFromInsideSurroundings(self, inputSurroundingInsides)
Initialize from inside nested rings.

 
class PathZ
    Complex path with a z.
 
  Methods defined here:
__init__(self, z)
__repr__(self)
Get the string representation of this path z.

 
class ProjectiveSpace
    Class to define a projective space.
 
  Methods defined here:
__init__(self, basisX=(1.0, 0.0, 0.0), basisY=(0.0, 1.0, 0.0), basisZ=(0.0, 0.0, 1.0))
Initialize the basis vectors.
__repr__(self)
Get the string representation of this ProjectivePlane.
getByBasisXZ(self, basisX, basisZ)
Get by x basis x and y basis.
getByBasisZFirst(self, basisZ, firstVector3)
Get by basisZ and first.
getByBasisZTop(self, basisZ, top)
Get by basisZ and top.
getByLatitudeLongitude(self, viewpointLatitude, viewpointLongitude)
Get by latitude and longitude.
getByTilt(self, tilt)
Get by latitude and longitude.
getComplexByComplex(self, pointComplex)
Get complex by complex point.
getCopy(self)
Get copy.
getDotComplex(self, point)
Get the dot complex.
getDotVector3(self, point)
Get the dot vector3.
getNextSpace(self, nextNormal)
Get next space by next normal.
getSpaceByXYScaleAngle(self, angle, scale)
Get space by angle and scale.
getVector3ByPoint(self, point)
Get vector3 by point.
normalize(self)
Normalize.
unbuckle(self, maximumUnbuckling, normal)
Unbuckle space.

 
class XIntersectionIndex
    A class to hold the x intersection position and the index of the loop which intersected.
 
  Methods defined here:
__cmp__(self, other)
Get comparison in order to sort x intersections in ascending order of x.
__eq__(self, other)
Determine whether this XIntersectionIndex is identical to other one.
__init__(self, index, x)
Initialize.
__ne__(self, other)
Determine whether this XIntersectionIndex is not identical to other one.
__repr__(self)
Get the string representation of this x intersection.

 
Functions
       
addElementToListDictionary(element, key, listDictionary)
Add an element to the list table.
addElementToListDictionaryIfNotThere(element, key, listDictionary)
Add the value to the lists.
addElementToPixelList(element, pixelDictionary, x, y)
Add an element to the pixel list.
addElementToPixelListFromPoint(element, pixelDictionary, point)
Add an element to the pixel list.
addHorizontallyBoundedPoint(begin, center, end, horizontalBegin, horizontalEnd, path)
Add point if it is within the horizontal bounds.
addListToListTable(elementList, key, listDictionary)
Add a list to the list table.
addLoopToPixelTable(loop, pixelDictionary, width)
Add loop to the pixel table.
addNestedRingBeginning(distanceFeedRate, loop, z)
Add nested ring beginning to gcode output.
addPathToPixelTable(path, pixelDictionary, value, width)
Add path to the pixel table.
addPixelTableToPixelTable(fromPixelTable, intoPixelTable)
Add from pixel table to the into pixel table.
addPixelToPixelTableWithSteepness(isSteep, pixelDictionary, value, x, y)
Add pixels to the pixel table with steepness.
addPointToPath(path, pixelDictionary, point, value, width)
Add a point to a path and the pixel table.
addSegmentToPixelTable(beginComplex, endComplex, pixelDictionary, shortenDistanceBegin, shortenDistanceEnd, width)
Add line segment to the pixel table.
addSquareTwoToPixelDictionary(pixelDictionary, point, value, width)
Add square with two pixels around the center to pixel dictionary.
addToThreadsFromLoop(extrusionHalfWidth, gcodeType, loop, oldOrderedLocation, skein)
Add to threads from the last location from loop.
addToThreadsRemove(extrusionHalfWidth, nestedRings, oldOrderedLocation, skein, threadSequence)
Add to threads from the last location from nested rings.
addValueSegmentToPixelTable(beginComplex, endComplex, pixelDictionary, value, width)
Add line segment to the pixel table.
addValueToOutput(depth, keyInput, output, value)
Add value to the output.
addXIntersectionIndexesFromLoopListsY(loopLists, xIntersectionIndexList, y)
Add the x intersection indexes for the loop lists.
addXIntersectionIndexesFromLoopY(loop, solidIndex, xIntersectionIndexList, y)
Add the x intersection indexes for a loop.
addXIntersectionIndexesFromLoopsY(loops, solidIndex, xIntersectionIndexList, y)
Add the x intersection indexes for the loops.
addXIntersectionIndexesFromSegment(index, segment, xIntersectionIndexList)
Add the x intersection indexes from the segment.
addXIntersectionIndexesFromSegments(index, segments, xIntersectionIndexList)
Add the x intersection indexes from the segments.
addXIntersectionIndexesFromXIntersections(index, xIntersectionIndexList, xIntersections)
Add the x intersection indexes from the XIntersections.
addXIntersections(loop, xIntersections, y)
Add the x intersections for a loop.
addXIntersectionsFromLoopForTable(loop, xIntersectionsTable, width)
Add the x intersections for a loop into a table.
addXIntersectionsFromLoops(loops, xIntersections, y)
Add the x intersections for the loops.
addXIntersectionsFromLoopsForTable(loops, xIntersectionsTable, width)
Add the x intersections for a loop into a table.
compareSegmentLength(endpoint, otherEndpoint)
Get comparison in order to sort endpoints in ascending order of segment length.
concatenateRemovePath(connectedPaths, pathIndex, paths, pixelDictionary, segments, width)
Get connected paths from paths.
getAngleAroundZAxisDifference(subtractFromVec3, subtractVec3)
Get the angle around the Z axis difference between a pair of Vector3s.
getAngleDifferenceByComplex(subtractFromComplex, subtractComplex)
Get the angle between a pair of normalized complexes.
getAreaLoop(loop)
Get the area of a complex polygon.
getAreaLoopAbsolute(loop)
Get the absolute area of a complex polygon.
getAreaLoops(loops)
Get the area of a list of complex polygons.
getAreaVector3LoopAbsolute(loop)
Get the absolute area of a vector3 polygon.
getAroundLoop(begin, end, loop)
Get an arc around a loop.
getAwayPath(path, radius)
Get a path with only the points that are far enough away from each other, except for the last point.
getAwayPoints(points, radius)
Get a path with only the points that are far enough away from each other.
getBooleanFromDictionary(defaultBoolean, dictionary, key)
Get boolean from the dictionary and key.
getBooleanFromValue(value)
Get boolean from the word.
getBottomByPath(path)
Get the bottom of the path.
getBottomByPaths(paths)
Get the bottom of the paths.
getClippedAtEndLoopPath(clip, loopPath)
Get a clipped loop path.
getClippedLoopPath(clip, loopPath)
Get a clipped loop path.
getClippedSimplifiedLoopPath(clip, loopPath, radius)
Get a clipped and simplified loop path.
getClosestDistanceIndexToLine(point, loop)
Get the distance squared to the closest segment of the loop and index of that segment.
getClosestPointOnSegment(segmentBegin, segmentEnd, point)
Get the closest point on the segment.
getComplexByCommaString(valueCommaString)
Get the commaString as a complex.
getComplexByWords(words, wordIndex=0)
Get the complex by the first two words.
getComplexDefaultByDictionary(defaultComplex, dictionary, key)
Get the value as a complex.
getComplexDefaultByDictionaryKeys(defaultComplex, dictionary, keyX, keyY)
Get the value as a complex.
getComplexPath(vector3Path)
Get the complex path from the vector3 path.
getComplexPathByMultiplier(multiplier, path)
Get the multiplied complex path.
getComplexPaths(vector3Paths)
Get the complex paths from the vector3 paths.
getComplexPolygon(center, radius, sides, startAngle=0.0)
Get the complex polygon.
getComplexPolygonByComplexRadius(radius, sides, startAngle=0.0)
Get the complex polygon.
getComplexPolygonByStartEnd(endAngle, radius, sides, startAngle=0.0)
Get the complex polygon by start and end angle.
getConcatenatedList(originalLists)
Get the lists as one concatenated list.
getConnectedPaths(paths, pixelDictionary, width)
Get connected paths from paths.
getCrossProduct(firstComplex, secondComplex)
Get z component cross product of a pair of complexes.
getDecimalPlacesCarried(extraDecimalPlaces, value)
Get decimal places carried by the decimal places of the value plus the extraDecimalPlaces.
getDiagonalFlippedLoop(loop)
Get loop flipped over the dialogonal, in other words with the x and y swapped.
getDiagonalFlippedLoops(loops)
Get loops flipped over the dialogonal, in other words with the x and y swapped.
getDictionaryString(dictionary)
Get the dictionary string.
getDistanceToLine(begin, end, point)
Get the distance from a vector3 point to an infinite line.
getDistanceToLineByPath(begin, end, path)
Get the maximum distance from a path to an infinite line.
getDistanceToLineByPaths(begin, end, paths)
Get the maximum distance from paths to an infinite line.
getDistanceToPlaneSegment(segmentBegin, segmentEnd, point)
Get the distance squared from a point to the x & y components of a segment.
getDotProduct(firstComplex, secondComplex)
Get the dot product of a pair of complexes.
getDotProductPlusOne(firstComplex, secondComplex)
Get the dot product plus one of the x and y components of a pair of Vector3s.
getDurationString(seconds)
Get the duration string.
getEndpointFromPath(path, pathIndex)
Get endpoint segment from a path.
getEndpointsFromSegmentTable(segmentTable)
Get the endpoints from the segment table.
getEndpointsFromSegments(segments)
Get endpoints from segments.
getEnumeratorKeys(enumerator, keys)
Get enumerator keys.
getEnumeratorKeysAlwaysList(enumerator, keys)
Get enumerator keys.
getEnumeratorKeysExceptForOneArgument(enumerator, keys)
Get enumerator keys, except when there is one argument.
getFillOfSurroundings(nestedRings, penultimateFillLoops)
Get extra fill loops of nested rings.
getFlattenedNestedRings(nestedRings)
Get flattened nested rings.
getFloatDefaultByDictionary(defaultFloat, dictionary, key)
Get the value as a float.
getFloatFromValue(value)
Get the value as a float.
getFourSignificantFigures(number)
Get number rounded to four significant figures as a string.
getHalfSimplifiedLoop(loop, radius, remainder)
Get the loop with half of the points inside the channel removed.
getHalfSimplifiedPath(path, radius, remainder)
Get the path with half of the points inside the channel removed.
getHorizontallyBoundedPath(horizontalBegin, horizontalEnd, path)
Get horizontally bounded path.
getIncrementFromRank(rank)
Get the increment from the rank which is 0 at 1 and increases by three every power of ten.
getInsidesAddToOutsides(loops, outsides)
Add loops to either the insides or outsides.
getIntFromValue(value)
Get the value as an int.
getIntermediateLocation(alongWay, begin, end)
Get the intermediate location between begin and end.
getIntersectionOfXIntersectionIndexes(totalSolidSurfaceThickness, xIntersectionIndexList)
Get x intersections from surrounding layers.
getIntersectionOfXIntersectionsTables(xIntersectionsTables)
Get the intersection of the XIntersections tables.
getIsInFilledRegion(loops, point)
Determine if the point is in the filled region of the loops.
getIsInFilledRegionByPaths(loops, paths)
Determine if the point of any path is in the filled region of the loops.
getIsRadianClose(firstRadian, secondRadian)
Determine if the firstRadian is close to the secondRadian.
getIsWiddershinsByVector3(polygon)
Determine if the polygon goes round in the widdershins direction.
getJoinOfXIntersectionIndexes(xIntersectionIndexList)
Get joined x intersections from surrounding layers.
getLargestLoop(loops)
Get largest loop from loops.
getLeftPoint(points)
Get the leftmost complex point in the points.
getLeftPointIndex(points)
Get the index of the leftmost complex point in the points.
getListTableElements(listDictionary)
Get all the element in a list table.
getLoopCentroid(polygonComplex)
Get the area of a complex polygon using http://en.wikipedia.org/wiki/Centroid.
getLoopConvex(points)
Get convex hull of points using gift wrap algorithm.
getLoopConvexCentroid(polygonComplex)
Get centroid of the convex hull of a complex polygon.
getLoopInsideContainingLoop(containingLoop, loops)
Get a loop that is inside the containing loop.
getLoopLength(polygon)
Get the length of a polygon perimeter.
getLoopStartingClosest(extrusionHalfWidth, location, loop)
Add to threads from the last location from loop.
getLoopWithoutCloseEnds(close, loop)
Get loop without close ends.
getLoopWithoutCloseSequentialPoints(close, loop)
Get loop without close sequential points.
getMaximum(firstComplex, secondComplex)
Get a complex with each component the maximum of the respective components of a pair of complexes.
getMaximumByComplexPath(path)
Get a complex with each component the maximum of the respective components of a complex path.
getMaximumByComplexPaths(paths)
Get a complex with each component the maximum of the respective components of complex paths.
getMaximumByVector3Path(path)
Get a vector3 with each component the maximum of the respective components of a vector3 path.
getMaximumByVector3Paths(paths)
Get a complex with each component the maximum of the respective components of a complex path.
getMaximumSpan(loop)
Get the maximum span of the loop.
getMinimum(firstComplex, secondComplex)
Get a complex with each component the minimum of the respective components of a pair of complexes.
getMinimumByComplexPath(path)
Get a complex with each component the minimum of the respective components of a complex path.
getMinimumByComplexPaths(paths)
Get a complex with each component the minimum of the respective components of complex paths.
getMinimumByVector3Path(path)
Get a vector3 with each component the minimum of the respective components of a vector3 path.
getMinimumByVector3Paths(paths)
Get a complex with each component the minimum of the respective components of a complex path.
getMirrorPath(path)
Get mirror path.
getNormal(begin, center, end)
Get normal.
getNormalByPath(path)
Get normal by path.
getNormalWeighted(begin, center, end)
Get weighted normal.
getNormalized(complexNumber)
Get the normalized complex.
getNumberOfIntersectionsToLeft(loop, point)
Get the number of intersections through the loop for the line going left.
getNumberOfIntersectionsToLeftOfLoops(loops, point)
Get the number of intersections through the loop for the line starting from the left point and going left.
getOrderedNestedRings(nestedRings)
Get ordered nestedRings from nestedRings.
getPathCopy(path)
Get path copy.
getPathLength(path)
Get the length of a path ( an open polyline ).
getPathsFromEndpoints(endpoints, maximumConnectionLength, pixelDictionary, width)
Get paths from endpoints.
getPlaneDot(vec3First, vec3Second)
Get the dot product of the x and y components of a pair of Vector3s.
getPluralString(number, suffix)
Get the plural string.
getPointPlusSegmentWithLength(length, point, segment)
Get point plus a segment scaled to a given length.
getPointsByHorizontalDictionary(width, xIntersectionsDictionary)
Get points from the horizontalXIntersectionsDictionary.
getPointsByVerticalDictionary(width, xIntersectionsDictionary)
Get points from the verticalXIntersectionsDictionary.
getRadiusArealizedMultiplier(sides)
Get the radius multiplier for a polygon of equal area.
getRandomComplex(begin, end)
Get random complex.
getRank(width)
Get the rank which is 0 at 1 and increases by three every power of ten.
getRotatedComplexLists(planeAngle, pointLists)
Get point lists rotated by the plane angle
getRotatedComplexes(planeAngle, points)
Get points rotated by the plane angle
getRotatedWiddershinsQuarterAroundZAxis(vector3)
Get Vector3 rotated a quarter widdershins turn around Z axis.
getRoundZAxisByPlaneAngle(planeAngle, vector3)
Get Vector3 rotated by a plane angle.
getRoundedPoint(point)
Get point with each component rounded.
getRoundedToPlaces(decimalPlaces, number)
Get number rounded to a number of decimal places.
getRoundedToPlacesString(decimalPlaces, number)
Get number rounded to a number of decimal places as a string, without exponential formatting.
getRoundedToThreePlaces(number)
Get number rounded to three places as a string.
getSegmentFromPath(path, pathIndex)
Get endpoint segment from a path.
getSegmentFromPoints(begin, end)
Get endpoint segment from a pair of points.
getSegmentsFromXIntersectionIndexes(xIntersectionIndexList, y)
Get endpoint segments from the x intersection indexes.
getSegmentsFromXIntersections(xIntersections, y)
Get endpoint segments from the x intersections.
getSimplifiedLoop(loop, radius)
Get loop with points inside the channel removed.
getSimplifiedLoops(loops, radius)
Get the simplified loops.
getSimplifiedPath(path, radius)
Get path with points inside the channel removed.
getSquareIsOccupied(pixelDictionary, x, y)
Determine if a square around the x and y pixel coordinates is occupied.
getSquareLoopWiddershins(beginComplex, endComplex)
Get a square loop from the beginning to the end and back.
getSquareValues(pixelDictionary, x, y)
Get a list of the values in a square around the x and y pixel coordinates.
getSquareValuesFromPoint(pixelDictionary, point)
Get a list of the values in a square around the point.
getStepKeyFromPoint(point)
Get step key for the point.
getThreeSignificantFigures(number)
Get number rounded to three significant figures as a string.
getTopPath(path)
Get the top of the path.
getTopPaths(paths)
Get the top of the paths.
getTransferClosestNestedRing(extrusionHalfWidth, nestedRings, oldOrderedLocation, skein, threadSequence)
Get and transfer the closest remaining nested ring.
getTransferredNestedRings(insides, loop)
Get transferred paths from inside nested rings.
getTransferredPaths(insides, loop)
Get transferred paths from inside paths.
getTranslatedComplexPath(path, translateComplex)
Get the translated complex path.
getVector3Path(complexPath, z=0.0)
Get the vector3 path from the complex path.
getVector3Paths(complexPaths, z=0.0)
Get the vector3 paths from the complex paths.
getWiddershinsUnitPolar(angle)
Get polar complex from counterclockwise angle from 1, 0.
getXIntersectionIfExists(beginComplex, endComplex, y)
Get the x intersection if it exists.
getXIntersectionsFromIntersections(xIntersectionIndexList)
Get x intersections from the x intersection index list, in other words subtract non negative intersections from negatives.
getXYComplexFromVector3(vector3)
Get an xy complex from a vector3 if it exists, otherwise return None.
getYIntersectionIfExists(beginComplex, endComplex, x)
Get the y intersection if it exists.
getZComponentCrossProduct(vec3First, vec3Second)
Get z component cross product of a pair of Vector3s.
isInsideOtherLoops(loopIndex, loops)
Determine if a loop in a list is inside another loop in that list.
isLineIntersectingInsideXSegment(beginComplex, endComplex, segmentFirstX, segmentSecondX, y)
Determine if the line is crossing inside the x segment.
isLineIntersectingLoop(loop, pointBegin, pointEnd)
Determine if the line is intersecting loops.
isLineIntersectingLoops(loops, pointBegin, pointEnd)
Determine if the line is intersecting loops.
isLoopIntersectingInsideXSegment(loop, segmentFirstX, segmentSecondX, segmentYMirror, y)
Determine if the loop is intersecting inside the x segment.
isLoopIntersectingLoop(loop, otherLoop)
Determine if the loop is intersecting the other loop.
isLoopIntersectingLoops(loop, otherLoops)
Determine if the loop is intersecting other loops.
isLoopListIntersecting(loops)
Determine if a loop in the list is intersecting the other loops.
isLoopListIntersectingInsideXSegment(loopList, segmentFirstX, segmentSecondX, segmentYMirror, y)
Determine if the loop list is crossing inside the x segment.
isPathEntirelyInsideLoop(loop, path)
Determine if a path is entirely inside another loop.
isPathEntirelyInsideLoops(loops, path)
Determine if a path is entirely inside another loop in a list.
isPathInsideLoop(loop, path)
Determine if a path is inside another loop.
isPathInsideLoops(loops, path)
Determine if a path is inside another loop in a list.
isPixelTableIntersecting(bigTable, littleTable, maskTable={})
Add path to the pixel table.
isPointInsideLoop(loop, point)
Determine if a point is inside another loop.
isSegmentCompletelyInX(segment, xFirst, xSecond)
Determine if the segment overlaps within x.
isWiddershins(polygonComplex)
Determine if the complex polygon goes round in the widdershins direction.
isWithinChannel(channelRadius, pointIndex, loop)
Determine if the the point is within the channel between two adjacent points.
isXSegmentIntersectingPath(path, segmentFirstX, segmentSecondX, segmentYMirror, y)
Determine if a path is crossing inside the x segment.
isXSegmentIntersectingPaths(paths, segmentFirstX, segmentSecondX, segmentYMirror, y)
Determine if a path list is crossing inside the x segment.
joinSegmentTables(fromTable, intoTable)
Join both segment tables and put the join into the intoTable.
joinXIntersectionsTables(fromTable, intoTable)
Join both XIntersections tables and put the join into the intoTable.
overwriteDictionary(fromDictionary, keys, toDictionary)
Overwrite the dictionary.
removeElementFromDictionary(dictionary, key)
Remove element from the dictionary.
removeElementFromListTable(element, key, listDictionary)
Remove an element from the list table.
removeElementFromPixelListFromPoint(element, pixelDictionary, point)
Remove an element from the pixel list.
removeElementsFromDictionary(dictionary, keys)
Remove list from the dictionary.
removePixelTableFromPixelTable(pixelDictionaryToBeRemoved, pixelDictionaryToBeRemovedFrom)
Remove pixel from the pixel table.
removePrefixFromDictionary(dictionary, prefix)
Remove the attributes starting with the prefix from the dictionary.
removeTrueFromDictionary(dictionary, key)
Remove key from the dictionary in the value is true.
removeTrueListFromDictionary(dictionary, keys)
Remove list from the dictionary in the value is true.
subtractXIntersectionsTable(subtractFromTable, subtractTable)
Subtract the subtractTable from the subtractFromTable.
swapList(elements, indexBegin, indexEnd)
Swap the list elements.
toggleHashtable(hashtable, key, value)
Toggle a hashtable between having and not having a key.
transferClosestFillLoop(extrusionHalfWidth, oldOrderedLocation, remainingFillLoops, skein)
Transfer the closest remaining fill loop.
transferClosestPath(oldOrderedLocation, remainingPaths, skein)
Transfer the closest remaining path.
transferClosestPaths(oldOrderedLocation, remainingPaths, skein)
Transfer the closest remaining paths.
transferPathsToNestedRings(nestedRings, paths)
Transfer paths to nested rings.
translateVector3Path(path, translateVector3)
Translate the vector3 path.
translateVector3Paths(paths, translateVector3)
Translate the vector3 paths.
unbuckleBasis(basis, maximumUnbuckling, normal)
Unbuckle space.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalGoldenAngle = 3.883222077450933
globalGoldenRatio = 1.618033988749895
globalTau = 6.283185307179586

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.alphabetize.html000066400000000000000000000232351167321211700310230ustar00rootroot00000000000000 Python: module fabmetheus_utilities.fabmetheus_tools.alphabetize
 
 
fabmetheus_utilities.fabmetheus_tools.alphabetize ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/alphabetize.py

Alphabetize is a script to alphabetize functions and signatures.

 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
os

 
Classes
       
EndCharacterMonad
ParameterMonad
Snippet

 
class EndCharacterMonad
    A monad to return the parent monad when it encounters the end character.
 
  Methods defined here:
__init__(self, endCharacter, parentMonad)
Initialize.
getNextMonad(self, character)
Get the next monad.
getSnippet(self)
Get the snippet.

 
class ParameterMonad
    A monad to handle parameters.
 
  Methods defined here:
__init__(self, snippet)
Initialize.
addParameter(self)
Add parameter to the snippet.
getNextMonad(self, character)
Get the next monad.
getSnippet(self)
Get the snippet.

 
class Snippet
    A class to get the variables for a function.
 
  Methods defined here:
__init__(self, characterIndex, fileText)
Initialize.
__repr__(self)
Get the string representation of this Snippet.

 
Functions
       
addTogetherList(functionList, togetherLists)
Add the togetherList to the togetherLists is the sorted is different.
compareFunctionName(first, second)
Compare the function names.
getConvertedName(name)
Get converted name with init at the beginning and main at the endCompare the function names.
getFunctionLists(fileName)
Get the function lists in the file.
getFunctionsWithStringByFileName(fileName, searchString)
Get the functions with the search string in the file.
getFunctionsWithStringByFileNames(fileNames, searchString)
Get the functions with the search string in the files.
getParameterSequence(functionName)
Get the parameter sequence.
getSnippetsByFileName(fileName, functionName)
Get the function signature snippets by the file name.
getTogetherLists(fileName)
Get the lists of the unsorted and sorted functions in the file.
getTokenEnd(characterIndex, fileText, token)
Get the token end index for the file text and token.
main()
Run main function.
printTogetherListsByFileNames(fileNames)
Print the together lists of the file names, if the file name has a together list.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret.html000066400000000000000000000160711167321211700327520ustar00rootroot00000000000000 Python: module fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
 
 
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/fabmetheus_interpret.py

Fabmetheus interpret is a fabmetheus utility to interpret a file, turning it into fabmetheus constructive solid geometry xml.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
time

 
Classes
       
InterpretRepository

 
class InterpretRepository
    A class to handle the interpret settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Write button has been clicked.

 
Functions
       
getCarving(fileName)
Get carving.
getGNUTranslatorFilesUnmodified()
Get the file types from the translators in the import plugins folder.
getGNUTranslatorGcodeFileTypeTuples()
Get the file type tuples from the translators in the import plugins folder plus gcode.
getImportPluginFileNames()
Get interpret plugin fileNames.
getInterpretPlugin(fileName)
Get the interpret plugin for the file.
getNewRepository()
Get new repository.
getPluginsDirectoryPath()
Get the plugins directory path.
getTranslatorFileTypeTuples()
Get the file types from the translators in the import plugins folder.
getWindowAnalyzeFile(fileName)
Get file interpretion.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.html000066400000000000000000000051431167321211700265320ustar00rootroot00000000000000 Python: package fabmetheus_utilities.fabmetheus_tools
 
 
fabmetheus_utilities.fabmetheus_tools
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
alphabetize
fabmetheus_interpret
interpret_plugins (package)
prepare
wikifier

 
Data
        level = 2
numberOfLevelsDeepInPackageHierarchy = 2
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.interpret_plugins.gts.html000066400000000000000000000160761167321211700331110ustar00rootroot00000000000000 Python: module fabmetheus_utilities.fabmetheus_tools.interpret_plugins.gts
 
 
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.gts ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/gts.py

Previous / Next / Contents


The gts.py script is an import translator plugin to get a carving from an gts file.

An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getCarving function takes the file name of an gts file and returns the carving.

The GNU Triangulated Surface (.gts) format is described at:
http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE

Quoted from http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE
"All the lines beginning with GTS_COMMENTS (#!) are ignored. The first line contains three unsigned integers separated by spaces. The first integer is the number of vertexes, nv, the second is the number of edges, ne and the third is the number of faces, nf.

Follows nv lines containing the x, y and z coordinates of the vertexes. Follows ne lines containing the two indices (starting from one) of the vertexes of each edge. Follows nf lines containing the three ordered indices (also starting from one) of the edges of each face.

The format described above is the least common denominator to all GTS files. Consistent with an object-oriented approach, the GTS file format is extensible. Each of the lines of the file can be extended with user-specific attributes accessible through the read() and write() virtual methods of each of the objects written (surface, vertexes, edges or faces). When read with different object classes, these extra attributes are just ignored."


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.geometry.geometry_tools.face
fabmetheus_utilities.gcodec
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Functions
       
getCarving(fileName)
Get the carving for the gts file.
getFromGNUTriangulatedSurfaceText(gnuTriangulatedSurfaceText, triangleMesh)
Initialize from a GNU Triangulated Surface Text.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.interpret_plugins.html000066400000000000000000000066261167321211700323150ustar00rootroot00000000000000 Python: package fabmetheus_utilities.fabmetheus_tools.interpret_plugins
 
 
fabmetheus_utilities.fabmetheus_tools.interpret_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/__init__.py

Previous / Next / Contents


This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.


Previous / Next / Contents


 
Package Contents
       
csv
gts
obj
slc
stl
svg
xml
xml_plugins (package)

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.interpret_plugins.obj.html000066400000000000000000000156471167321211700330710ustar00rootroot00000000000000 Python: module fabmetheus_utilities.fabmetheus_tools.interpret_plugins.obj
 
 
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.obj ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/obj.py

Previous / Next / Contents


The obj.py script is an import translator plugin to get a carving from an obj file.

An example obj file is box.obj in the models folder.

An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getCarving function takes the file name of an obj file and returns the carving.

From wikipedia, OBJ (or .OBJ) is a geometry definition file format first developed by Wavefront Technologies for its Advanced Visualizer animation package:
http://en.wikipedia.org/wiki/Obj

The Object File specification is at:
http://local.wasp.uwa.edu.au/~pbourke/dataformats/obj/

An excellent link page about obj files is at:
http://people.sc.fsu.edu/~burkardt/data/obj/obj.html


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.geometry.geometry_tools.face
fabmetheus_utilities.gcodec
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Functions
       
addFacesGivenText(objText, triangleMesh)
Add faces given obj text.
getCarving(fileName='')
Get the triangle mesh for the obj file.
getFaceGivenLine(line, triangleMesh)
Add face given line index and lines.
getVertexGivenLine(line)
Get vertex given obj vertex line.
unpack(...)
Unpack the string containing packed C structure data, according to fmt.
Requires len(string) == calcsize(fmt).

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.interpret_plugins.slc.html000066400000000000000000000271511167321211700330710ustar00rootroot00000000000000 Python: module fabmetheus_utilities.fabmetheus_tools.interpret_plugins.slc
 
 
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.slc ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/slc.py

Previous / Next / Contents


The slc.py script is an import translator plugin to get a carving from an slc file.

An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getCarving function takes the file name of an slc file and returns the carving.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
math
fabmetheus_utilities.svg_writer
sys

 
Classes
       
SLCCarving
SampleTableEntry

 
class SLCCarving
    An slc carving.
 
  Methods defined here:
__init__(self)
Add empty lists.
__repr__(self)
Get the string representation of this carving.
addXML(self, depth, output)
Add xml for this object.
getCarveBoundaryLayers(self)
Get the  boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getCarvedSVG(self)
Get the carved svg text.
getFabmetheusXML(self)
Return the fabmetheus XML.
getInterpretationSuffix(self)
Return the suffix for a carving.
processContourLayers(self, file)
Process a contour layer at a time until the top of the part.
readFile(self, fileName)
Read SLC and store the layers.
readTableEntry(self, file)
Read in the sampling table section. It contains a table length (byte) and the table entries.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.

 
class SampleTableEntry
    Sample table entry.
 
  Methods defined here:
__init__(self, file)
Read in the sampling table section. It contains a table length (byte) and the table entries.
__repr__(self)
Get the string representation of this sample table entry.

 
Functions
       
getCarving(fileName='')
Get the triangle mesh for the slc file.
getLittleEndianFloatGivenFile(file)
Get little endian float given a file.
getLittleEndianUnsignedLongGivenFile(file)
Get little endian float given a file.
getPointsFromFile(numPoints, file)
Process the vertice points for a given boundary.
main()
Display the inset dialog.
readHeader(file)
Read the slc header.
unpack(...)
Unpack the string containing packed C structure data, according to fmt.
Requires len(string) == calcsize(fmt).

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.interpret_plugins.stl.html000066400000000000000000000175371167321211700331210ustar00rootroot00000000000000 Python: module fabmetheus_utilities.fabmetheus_tools.interpret_plugins.stl
 
 
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.stl ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/stl.py

Previous / Next / Contents


The stl.py script is an import translator plugin to get a carving from an stl file.

An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getCarving function takes the file name of an stl file and returns the carving.

STL is an inferior triangle surface format, described at:
http://en.wikipedia.org/wiki/STL_(file_format)

A good triangle surface format is the GNU Triangulated Surface format which is described at:
http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.geometry.geometry_tools.face
fabmetheus_utilities.gcodec
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Functions
       
addFacesGivenBinary(stlData, triangleMesh, vertexIndexTable)
Add faces given stl binary.
addFacesGivenText(stlText, triangleMesh, vertexIndexTable)
Add faces given stl text.
addFacesGivenVertexes(triangleMesh, vertexIndexTable, vertexes)
Add faces given stl text.
getCarving(fileName='')
Get the triangle mesh for the stl file.
getFaceGivenLines(triangleMesh, vertexStartIndex, vertexIndexTable, vertexes)
Add face given line index and lines.
getFloat(floatString)
Get the float, replacing commas if necessary because an inferior program is using a comma instead of a point for the decimal point.
getFloatGivenBinary(byteIndex, stlData)
Get vertex given stl vertex line.
getVertexGivenBinary(byteIndex, stlData)
Get vertex given stl vertex line.
getVertexGivenLine(line)
Get vertex given stl vertex line.
unpack(...)
Unpack the string containing packed C structure data, according to fmt.
Requires len(string) == calcsize(fmt).

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.interpret_plugins.svg.html000066400000000000000000000221301167321211700330770ustar00rootroot00000000000000 Python: module fabmetheus_utilities.fabmetheus_tools.interpret_plugins.svg
 
 
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.svg ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/svg.py

Previous / Next / Contents


The svg.py script is an import translator plugin to get a carving from an svg file. This script will read an svg file made by skeinforge or by inkscape.

An example inkscape svg file is inkscape_star.svg in the models folder.

An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getCarving function takes the file name of an svg file and returns the carving.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
math
fabmetheus_utilities.svg_writer
fabmetheus_utilities.xml_simple_writer

 
Classes
       
SVGCarving

 
class SVGCarving
    An svg carving.
 
  Methods defined here:
__init__(self)
Add empty lists.
__repr__(self)
Get the string representation of this carving.
addXML(self, depth, output)
Add xml for this object.
getCarveBoundaryLayers(self)
Get the  boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getCarvedSVG(self)
Get the carved svg text.
getFabmetheusXML(self)
Return the fabmetheus XML.
getInterpretationSuffix(self)
Return the suffix for a carving.
parseSVG(self, fileName, svgText)
Parse SVG text and store the layers.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.

 
Functions
       
getCarving(fileName='')
Get the triangle mesh for the gts file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml.html000066400000000000000000000261371167321211700331130ustar00rootroot00000000000000 Python: module fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml
 
 
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/xml.py

Previous / Next / Contents


The xml.py script is an import translator plugin to get a carving from an xml file.

An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getCarving function takes the file name of an xml file and returns the carving.

An example of an xml boolean geometry format file follows below.

<?xml version='1.0' ?>
<fabmetheus version="2010-03-29">
<difference id="cube_cylinder_difference">
<matrix m14="-10.0" m24="20.0" m34="5.0" />
<cube id="Cube 5" halfx="5.0" halfy="5.0" halfz="5.0">
</cube>
<cylinder id="Cylinder 5" height="10.0" radiusx="5.0" radiusy="5.0" topOverBottom="1.0">
<matrix m14="5.0" m24="-5.0" />
</cylinder>
</difference>
</fabmetheus>

In the 'fabmetheus' format, all class names are lower case. The defined geometric objects are cube, cylinder, difference, group, sphere, trianglemesh and union. The id attribute is not necessary. The default matrix is a four by four identity matrix. The attributes of the cube, cylinder and sphere default to one. The attributes of the vertexes in the triangle mesh default to zero. The boolean solids are difference, intersection and union. The difference solid is the first solid minus the remaining solids. The combined_shape.xml example in the xml_models folder in the models folder is pasted below.

<?xml version='1.0' ?>
<fabmetheus version="2010-03-29">
<difference id="cube_cylinder_difference">
<matrix m14="-10.0" m24="20.0" m34="5.0" />
<cube id="Cube 5" halfx="5.0" halfy="5.0" halfz="5.0">
</cube>
<cylinder id="Cylinder 5" height="10.0" radiusx="5.0" radiusy="5.0" topOverBottom="1.0">
<matrix m14="5.0" m24="-5.0" />
</cylinder>
</difference>
<intersection id="cube_cylinder_intersection">
<matrix m14="-10.0" m34="5.0" />
<cube id="Cube 5" halfx="5.0" halfy="5.0" halfz="5.0">
</cube>
<cylinder id="Cylinder 5" height="10.0" radiusx="5.0" radiusy="5.0" topOverBottom="1.0">
<matrix m14="5.0" m24="-5.0" />
</cylinder>
</intersection>
<union id="cube_cylinder_union">
<matrix m14="-10.0" m24="-20.0" m34="5.0" />
<cube id="Cube 5" halfx="5.0" halfy="5.0" halfz="5.0">
</cube>
<cylinder id="Cylinder 5" height="10.0" radiusx="5.0" radiusy="5.0" topOverBottom="1.0">
<matrix m14="5.0" m24="-5.0" />
</cylinder>
</union>
<group id="sphere_tetrahedron_group">
<matrix m14="10.0" m24="-20.0" m34="5.0" />
<sphere id="Group Sphere 5" radiusx="5.0" radiusy="5.0" radiusz="5.0">
</sphere>
<trianglemesh id="Group Tetrahedron 5">
<matrix m14="15.0" />
<vertex x="-5.0" y="-5.0" z="-5.0" />
<vertex x="5.0" y="-5.0" z="-5.0" />
<vertex y="5.0" z="-5.0" />
<vertex z="5.0" />
<face vertex0="0" vertex1="2" vertex2="1" />
<face vertex0="3" vertex1="1" vertex2="2" />
<face vertex0="3" vertex1="2" vertex2="0" />
<face vertex0="3" vertex1="0" vertex2="1" />
</trianglemesh>
</group>
<sphere id="Sphere 5" radiusx="5.0" radiusy="5.0" radiusz="5.0">
<matrix m14="10.0" m34="5.0" />
</sphere>
<trianglemesh id="Tetrahedron 5">
<matrix m14="10.0" m24="20.0" m34="5.0" />
<vertex x="-5.0" y="-5.0" z="-5.0" />
<vertex x="5.0" y="-5.0" z="-5.0" />
<vertex y="5.0" z="-5.0" />
<vertex z="5.0" />
<face vertex0="0" vertex1="2" vertex2="1" />
<face vertex0="3" vertex1="1" vertex2="2" />
<face vertex0="3" vertex1="2" vertex2="0" />
<face vertex0="3" vertex1="0" vertex2="1" />
</trianglemesh>
</fabmetheus>

The 'fabmetheus' xml format is the preferred skeinforge format. When the Interpret button in the Interpret tool in Analyze is clicked, any xml format for which there is a plugin will be converted to the 'fabmetheus' format.

There is a plugin for the 'Art of Illusion' xml format. An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice. This will bring up the XML file chooser window, choose a place to save the file then click "OK". Leave the "compressFile" checkbox unchecked. All the objects from the scene will be exported, the artofillusion plugin will ignore the light and camera. If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.gcodec
os
sys

 
Functions
       
getCarving(fileName='')
Get the carving for the xml file.
getPluginsDirectoryPath()
Get the plugins directory path.
main()
Display the inset dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.artofillusion.html000066400000000000000000001644161167321211700374710ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.artofillusion
 
 
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.artofillusion ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/xml_plugins/artofillusion.py

Previous / Next / Contents


The xml.py script is an import translator plugin to get a carving from an Art of Illusion xml file.

An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getCarving function takes the file name of an xml file and returns the carving.

An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice. This will bring up the XML file chooser window, choose a place to save the file then click "OK". Leave the "compressFile" checkbox unchecked. All the objects from the scene will be exported, this plugin will ignore the light and camera. If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.boolean_geometry
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid
fabmetheus_utilities.geometry.solids.cube
fabmetheus_utilities.geometry.solids.cylinder
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_tools.face
fabmetheus_utilities.geometry.solids.group
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.solids.sphere
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid(fabmetheus_utilities.geometry.solids.group.Group)
BooleanSolid
fabmetheus_utilities.geometry.solids.cube.Cube(fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh)
Cube
fabmetheus_utilities.geometry.solids.cylinder.Cylinder(fabmetheus_utilities.geometry.solids.cube.Cube)
Cylinder
fabmetheus_utilities.geometry.solids.group.Group(fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary)
Group
fabmetheus_utilities.geometry.solids.sphere.Sphere(fabmetheus_utilities.geometry.solids.cube.Cube)
Sphere
fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh(fabmetheus_utilities.geometry.solids.group.Group)
TriangleMesh

 
class BooleanSolid(fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid)
    An Art of Illusion CSG object info.
 
 
Method resolution order:
BooleanSolid
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
setToArtOfIllusionDictionary(self)
Set the shape of this carvable object info.

Methods inherited from fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid:
getDifference(self, importRadius, visibleObjectLoopsList)
Get subtracted loops sliced through shape.
getIntersection(self, importRadius, visibleObjectLoopsList)
Get intersected loops sliced through shape.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList)
Get loops from visible object loops list.
getTransformedPaths(self)
Get all transformed paths.
getUnion(self, importRadius, visibleObjectLoopsList)
Get joined loops sliced through shape.
getXMLLocalName(self)
Get xml class name.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
__init__(self)
Add empty lists.
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
addXMLSection(self, depth, output)
Add the xml section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getGeometryOutput(self)
Get geometry output dictionary.
getMinimumZ(self)
Get the minimum z.
getPaths(self)
Get all paths.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getType(self)
Get type.
getVertexes(self)
Get all vertexes.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
class Cube(fabmetheus_utilities.geometry.solids.cube.Cube)
    An Art of Illusion Cube object.
 
 
Method resolution order:
Cube
fabmetheus_utilities.geometry.solids.cube.Cube
fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
setToArtOfIllusionDictionary(self)
Set the shape of this carvable object info.

Methods inherited from fabmetheus_utilities.geometry.solids.cube.Cube:
addXMLSection(self, depth, output)
Add the xml section for this object.
createShape(self)
Create the shape.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh:
__init__(self)
Add empty lists.
getCarveBoundaryLayers(self)
Get the boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getFabmetheusXML(self)
Return the fabmetheus XML.
getGeometryOutput(self)
Get geometry output dictionary.
getInterpretationSuffix(self)
Return the suffix for a triangle mesh.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getLoopsFromMesh(self, z)
Get loops from a carve of a mesh.
getMinimumZ(self)
Get the minimum z.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getVertexes(self)
Get all vertexes.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.
setEdgesForAllFaces(self)
Set the face edges of all the faces.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getType(self)
Get type.
getXMLLocalName(self)
Get xml local name.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
class Cylinder(fabmetheus_utilities.geometry.solids.cylinder.Cylinder)
    An Art of Illusion Cylinder object.
 
 
Method resolution order:
Cylinder
fabmetheus_utilities.geometry.solids.cylinder.Cylinder
fabmetheus_utilities.geometry.solids.cube.Cube
fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
setToArtOfIllusionDictionary(self)
Set the shape of this carvable object info.

Methods inherited from fabmetheus_utilities.geometry.solids.cylinder.Cylinder:
__init__(self)
Add empty lists.
createShape(self)
Create the shape.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.solids.cube.Cube:
addXMLSection(self, depth, output)
Add the xml section for this object.

Methods inherited from fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh:
getCarveBoundaryLayers(self)
Get the boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getFabmetheusXML(self)
Return the fabmetheus XML.
getGeometryOutput(self)
Get geometry output dictionary.
getInterpretationSuffix(self)
Return the suffix for a triangle mesh.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getLoopsFromMesh(self, z)
Get loops from a carve of a mesh.
getMinimumZ(self)
Get the minimum z.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getVertexes(self)
Get all vertexes.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.
setEdgesForAllFaces(self)
Set the face edges of all the faces.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getType(self)
Get type.
getXMLLocalName(self)
Get xml local name.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
class Group(fabmetheus_utilities.geometry.solids.group.Group)
    An Art of Illusion Group object.
 
 
Method resolution order:
Group
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
setToArtOfIllusionDictionary(self)
Set the shape of this group.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
__init__(self)
Add empty lists.
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
addXMLSection(self, depth, output)
Add the xml section for this object.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getGeometryOutput(self)
Get geometry output dictionary.
getMinimumZ(self)
Get the minimum z.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getType(self)
Get type.
getVertexes(self)
Get all vertexes.
getXMLLocalName(self)
Get xml local name.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
class Sphere(fabmetheus_utilities.geometry.solids.sphere.Sphere)
    An Art of Illusion Sphere object.
 
 
Method resolution order:
Sphere
fabmetheus_utilities.geometry.solids.sphere.Sphere
fabmetheus_utilities.geometry.solids.cube.Cube
fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
setToArtOfIllusionDictionary(self)
Set the shape of this carvable object.

Methods inherited from fabmetheus_utilities.geometry.solids.sphere.Sphere:
createShape(self)
Create the shape.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.solids.cube.Cube:
addXMLSection(self, depth, output)
Add the xml section for this object.

Methods inherited from fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh:
__init__(self)
Add empty lists.
getCarveBoundaryLayers(self)
Get the boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getFabmetheusXML(self)
Return the fabmetheus XML.
getGeometryOutput(self)
Get geometry output dictionary.
getInterpretationSuffix(self)
Return the suffix for a triangle mesh.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getLoopsFromMesh(self, z)
Get loops from a carve of a mesh.
getMinimumZ(self)
Get the minimum z.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getVertexes(self)
Get all vertexes.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.
setEdgesForAllFaces(self)
Set the face edges of all the faces.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getType(self)
Get type.
getXMLLocalName(self)
Get xml local name.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
class TriangleMesh(fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh)
    An Art of Illusion triangle mesh object.
 
 
Method resolution order:
TriangleMesh
fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
setToArtOfIllusionDictionary(self)
Set the shape of this carvable object info.

Methods inherited from fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh:
__init__(self)
Add empty lists.
addXMLSection(self, depth, output)
Add the xml section for this object.
getCarveBoundaryLayers(self)
Get the boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getFabmetheusXML(self)
Return the fabmetheus XML.
getGeometryOutput(self)
Get geometry output dictionary.
getInterpretationSuffix(self)
Return the suffix for a triangle mesh.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getLoopsFromMesh(self, z)
Get loops from a carve of a mesh.
getMinimumZ(self)
Get the minimum z.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getVertexes(self)
Get all vertexes.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.
setEdgesForAllFaces(self)
Set the face edges of all the faces.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getType(self)
Get type.
getXMLLocalName(self)
Get xml local name.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
Functions
       
getCarvableObject(elementNode, globalObject, object)
Get new carvable object info.
getCarvingFromParser(xmlParser)
Get the carving for the parser.
getTransformElementNode(coords, transformName)
Get the transform attributes.
processAppendElementNode(archivableObjects, elementNode, parentNode)
Add the object info if it is carvable.
processElementNode(elementNode)
Process the xml element.
removeListArtOfIllusionFromDictionary(dictionary, scrubKeys)
Remove the list and art of illusion keys from the dictionary.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalCarvableClassObjectTable = {'CSGObject': <class fabmetheus_utilities.fabmetheus_tools.int...t_plugins.xml_plugins.artofillusion.BooleanSolid>, 'Cube': <class fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.artofillusion.Cube>, 'Cylinder': <class fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.artofillusion.Cylinder>, 'Sphere': <class fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.artofillusion.Sphere>, 'TriangleMesh': <class fabmetheus_utilities.fabmetheus_tools.int...t_plugins.xml_plugins.artofillusion.TriangleMesh>, 'artofillusion.object.NullObject': <class fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.artofillusion.Group>}

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.fabmetheus.html000066400000000000000000000224361167321211700367150ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.fabmetheus
 
 
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.fabmetheus ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/xml_plugins/fabmetheus.py

Previous / Next / Contents


The xml.py script is an import translator plugin to get a carving from an Art of Illusion xml file.

An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getCarving function takes the file name of an xml file and returns the carving.

An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice. This will bring up the XML file chooser window, choose a place to save the file then click "OK". Leave the "compressFile" checkbox unchecked. All the objects from the scene will be exported, this plugin will ignore the light and camera. If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.geometry.geometry_utilities.boolean_geometry
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.gcodec
fabmetheus_utilities.geometry.solids.group
os
fabmetheus_utilities.settings
sys
traceback
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml
fabmetheus_utilities.xml_simple_reader

 
Classes
       
XMLBooleanGeometryProcessor

 
class XMLBooleanGeometryProcessor
    A class to process xml boolean geometry elements.
 
  Methods defined here:
__init__(self)
Initialize processor.
__repr__(self)
Get the string representation of this XMLBooleanGeometryProcessor.
convertElementNode(self, elementNode, geometryOutput)
Convert the xml element.
createChildNodes(self, geometryOutput, parentNode)
Create childNodes for the parentNode.
processChildNodes(self, elementNode)
Process the childNodes of the xml element.
processElementNode(self, elementNode)
Process the xml element.

 
Functions
       
getCarvingFromParser(xmlParser)
Get the carving for the parser.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins.html000066400000000000000000000052501167321211700345660ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: package fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins
 
 
fabmetheus_utilities.fabmetheus_tools.interpret_plugins.xml_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/xml_plugins/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
artofillusion
fabmetheus

 
Data
        level = 4
numberOfLevelsDeepInPackageHierarchy = 4
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.prepare.html000066400000000000000000000111501167321211700301620ustar00rootroot00000000000000 Python: module fabmetheus_utilities.fabmetheus_tools.prepare
 
 
fabmetheus_utilities.fabmetheus_tools.prepare ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/prepare.py

Prepare is a script to remove the generated files, run wikifier, and finally zip the package.

 
Modules
       
__init__
fabmetheus_utilities.archive
os
fabmetheus_utilities.fabmetheus_tools.wikifier

 
Functions
       
main()
Run main function.
prepareWikify()
Remove generated files, then wikify the file comments.
removeCSVFile(csvFilePath)
Remove csv file.
removeGcodeFile(gcodeFilePath)
Remove gcode file.
removeGeneratedFiles()
Remove generated files.
removeSVGFile(svgFilePath)
Remove svg file.
removeXMLFile(xmlFilePath)
Remove xml file.
removeZip()
Remove the zip file, then generate a new one.zip -r reprap_python_beanshell * -x \*.pyc \*~

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/fabmetheus_utilities.fabmetheus_tools.wikifier.html000066400000000000000000000175331167321211700303500ustar00rootroot00000000000000 Python: module fabmetheus_utilities.fabmetheus_tools.wikifier
 
 
fabmetheus_utilities.fabmetheus_tools.wikifier ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/fabmetheus_tools/wikifier.py

Wikifier is a script to add spaces to the pydoc files and move them to the documentation folder.

 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings

 
Classes
       
Heading

 
class Heading
    A class to hold the heading and subheadings.
 
  Methods defined here:
__init__(self, depth=0)
Initialize.
addToOutput(self, output)
Add to the output.
getFromLine(self, headingLineTable, line)
Get the heading from a line.

 
Functions
       
addToHeadings(headingLineTable, headings, line)
Add the line to the headings.
getLinkLine(line)
Get the link line with the wiki style link converted into a hypertext link.
getNavigationHypertext(fileText, transferredFileNameIndex, transferredFileNames)
Get the hypertext help with navigation lines.
getNavigationLine(contentsLinkText, previousLinkText, nextLinkText)
Get the wrapped pydoc hypertext help.
getNextLinkText(hypertextFiles, nextIndex)
Get the next link text.
getWrappedHypertext(fileText, hypertextFileIndex, hypertextFiles)
Get the wrapped pydoc hypertext help.
main()
Display the craft dialog.
readWriteDeleteHypertextHelp(documentDirectoryPath, hypertextFileIndex, hypertextFiles, transferredFileNames)
Read the pydoc hypertext help documents, write them in the documentation folder then delete the originals.
readWriteNavigationHelp(documentDirectoryPath, transferredFileNameIndex, transferredFileNames)
Read the hypertext help documents, and add the navigation lines to them.
removeFilesInDirectory(directoryPath)
Remove all the files in a directory.
writeContentsFile(documentDirectoryPath, hypertextFiles)
Write the contents file.
writeContentsLine(hypertextFile, output)
Write a line of the contents file.
writeHypertext()
Run pydoc, then read, write and delete each of the files.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalWikiLinkStart = '[<a href='

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/fabmetheus_utilities.gcodec.html000066400000000000000000000442761167321211700244250ustar00rootroot00000000000000 Python: module fabmetheus_utilities.gcodec
 
 
fabmetheus_utilities.gcodec ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/gcodec.py

Gcodec is a collection of utilities to decode and encode gcode.

To run gcodec, install python 2.x on your machine, which is avaliable from http://www.python.org/download/

Then in the folder which gcodec is in, type 'python' in a shell to run the python interpreter. Finally type 'from gcodec import *' to import this program.

Below is an example of gcodec use. This example is run in a terminal in the folder which contains gcodec and Screw Holder Bottom_export.gcode.

>>> from gcodec import *
>>> getFileText('Screw Holder Bottom_export.gcode')
'G90
G21
M103
M105
M106
M110 S60.0
M111 S30.0
M108 S210.0
M104 S235.0
G1 X0.37 Y-4.07 Z1.9 F60.0
M101

..
many lines of text
..

 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
math
os
sys
traceback

 
Classes
       
BoundingRectangle
DistanceFeedRate

 
class BoundingRectangle
    A class to get the corners of a gcode text.
 
  Methods defined here:
getFromGcodeLines(self, lines, radius)
Parse gcode text and get the minimum and maximum corners.
isPointInside(self, point)
Determine if the point is inside the bounding rectangle.
parseCorner(self, line)
Parse a gcode line and use the location to update the bounding corners.

 
class DistanceFeedRate
    A class to limit the z feed rate and round values.
 
  Methods defined here:
__init__(self)
Initialize.
addGcodeFromFeedRateThreadZ(self, feedRateMinute, thread, travelFeedRateMinute, z)
Add a thread to the output.
addGcodeFromLoop(self, loop, z)
Add the gcode loop.
addGcodeFromThreadZ(self, thread, z)
Add a thread to the output.
addGcodeMovementZ(self, point, z)
Add a movement to the output.
addGcodeMovementZWithFeedRate(self, feedRateMinute, point, z)
Add a movement to the output.
addLine(self, line)
Add a line of text and a newline to the output.
addLineCheckAlteration(self, line)
Add a line of text and a newline to the output and check to see if it is an alteration line.
addLines(self, lines)
Add lines of text to the output.
addLinesSetAbsoluteDistanceMode(self, lines)
Add lines of text to the output and ensure the absolute mode is set.
addParameter(self, firstWord, parameter)
Add the parameter.
addPerimeterBlock(self, loop, z)
Add the perimeter gcode block for the loop.
addTagBracketedLine(self, tagName, value)
Add a begin tag, value and end tag.
addTagBracketedProcedure(self, procedure)
Add a begin procedure tag, procedure and end procedure tag.
addTagRoundedLine(self, tagName, value)
Add a begin tag, rounded value and end tag.
getBoundaryLine(self, location)
Get boundary gcode line.
getFirstWordMovement(self, firstWord, location)
Get the start of the arc line.
getInfillBoundaryLine(self, location)
Get infill boundary gcode line.
getIsAlteration(self, line)
Determine if it is an alteration.
getLineWithFeedRate(self, feedRateMinute, line, splitLine)
Get the line with a feed rate.
getLineWithX(self, line, splitLine, x)
Get the line with an x.
getLineWithY(self, line, splitLine, y)
Get the line with a y.
getLineWithZ(self, line, splitLine, z)
Get the line with a z.
getLinearGcodeMovement(self, point, z)
Get a linear gcode movement.
getLinearGcodeMovementWithFeedRate(self, feedRateMinute, point, z)
Get a z limited gcode movement.
getRounded(self, number)
Get number rounded to the number of carried decimal places as a string.
parseSplitLine(self, firstWord, splitLine)
Parse gcode split line and store the parameters.

 
Functions
       
addLineAndNewlineIfNecessary(line, output)
Add the line and if the line does not end with a newline add a newline.
addLinesToCString(cString, lines)
Add lines which have something to cStringIO.
getArcDistance(relativeLocation, splitLine)
Get arc distance.
getDoubleAfterFirstLetter(word)
Get the double value of the word after the first letter.
getDoubleForLetter(letter, splitLine)
Get the double value of the word after the first occurence of the letter in the split line.
getDoubleFromCharacterSplitLine(character, splitLine)
Get the double value of the string after the first occurence of the character in the split line.
getDoubleFromCharacterSplitLineValue(character, splitLine, value)
Get the double value of the string after the first occurence of the character in the split line, if it does not exist return the value.
getFeedRateMinute(feedRateMinute, splitLine)
Get the feed rate per minute if the split line has a feed rate.
getFirstWord(splitLine)
Get the first word of a split line.
getFirstWordFromLine(line)
Get the first word of a line.
getFirstWordIndexReverse(firstWord, lines, startIndex)
Parse gcode in reverse order until the first word if there is one, otherwise return -1.
getGcodeFileText(fileName, gcodeText)
Get the gcode text from a file if it the gcode text is empty and if the file is a gcode file.
getGcodeWithoutDuplication(duplicateWord, gcodeText)
Get gcode text without duplicate first words.
getIndexOfStartingWithSecond(letter, splitLine)
Get index of the first occurence of the given letter in the split line, starting with the second word.  Return - 1 if letter is not found
getLineWithValueString(character, line, splitLine, valueString)
Get the line with a valueString.
getLocationFromSplitLine(oldLocation, splitLine)
Get the location from the split line.
getRotationBySplitLine(splitLine)
Get the complex rotation from the split gcode line.
getSplitLineBeforeBracketSemicolon(line)
Get the split line before a bracket or semicolon.
getStringFromCharacterSplitLine(character, splitLine)
Get the string after the first occurence of the character in the split line.
getTagBracketedLine(tagName, value)
Get line with a begin tag, value and end tag.
getTagBracketedProcedure(procedure)
Get line with a begin procedure tag, procedure and end procedure tag.
isProcedureDone(gcodeText, procedure)
Determine if the procedure has been done on the gcode text.
isProcedureDoneOrFileIsEmpty(gcodeText, procedure)
Determine if the procedure has been done on the gcode text or the file is empty.
isThereAFirstWord(firstWord, lines, startIndex)
Parse gcode until the first word if there is one.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation._drill.html000066400000000000000000000147271167321211700301010ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation._drill
 
 
fabmetheus_utilities.geometry.creation._drill ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/_drill.py

Drill negative solid.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.extrude
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.creation.teardrop
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
DrillDerivation

 
class DrillDerivation
    Class to hold drill variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation._svg.html000066400000000000000000000146121167321211700275630ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation._svg
 
 
fabmetheus_utilities.geometry.creation._svg ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/_svg.py

Svg reader.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.creation.lineation
fabmetheus_utilities.geometry.geometry_tools.path
fabmetheus_utilities.svg_reader

 
Classes
       
SVGDerivation

 
class SVGDerivation
    Class to hold svg variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getGeometryOutputBySVGReader(elementNode, svgReader)
Get vector3 vertexes from svgReader.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.circle.html000066400000000000000000000141661167321211700300720ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.circle
 
 
fabmetheus_utilities.geometry.creation.circle ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/circle.py

Polygon path.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path

 
Classes
       
CircleDerivation

 
class CircleDerivation
    Class to hold circle variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.concatenate.html000066400000000000000000000142621167321211700311120ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.concatenate
 
 
fabmetheus_utilities.geometry.creation.concatenate ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/concatenate.py

Boolean geometry concatenation.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path

 
Classes
       
ConcatenateDerivation

 
class ConcatenateDerivation
    Class to hold concatenate variables.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get triangle mesh from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get triangle mesh from attribute dictionary by arguments.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.extrude.html000066400000000000000000000346621167321211700303140ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.extrude
 
 
fabmetheus_utilities.geometry.creation.extrude ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/extrude.py

Boolean geometry extrusion.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
ExtrudeDerivation
Interpolation
PortionDirection

 
class ExtrudeDerivation
    Class to hold extrude variables.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.

 
class Interpolation
    Class to interpolate a path.
 
  Methods defined here:
__init__(self)
Set index.
__repr__(self)
Get the string representation of this Interpolation.
getByDistances(self)
Get by distances.
getByPrefixAlong(self, elementNode, path, prefix)
Get interpolation from prefix and xml element along the path.
getByPrefixX(self, elementNode, path, prefix)
Get interpolation from prefix and xml element in the z direction.
getByPrefixZ(self, elementNode, path, prefix)
Get interpolation from prefix and xml element in the z direction.
getComparison(self, first, second)
Compare the first with the second.
getComplexByPortion(self, portionDirection)
Get complex from z portion.
getInnerPortion(self)
Get inner x portion.
getVector3ByPortion(self, portionDirection)
Get vector3 from z portion.
getYByPortion(self, portionDirection)
Get y from x portion.
setInterpolationIndex(self, portionDirection)
Set the interpolation index.
setInterpolationIndexFromTo(self, portionDirection)
Set the interpolation index, the start vertex and the end vertex.

 
class PortionDirection
    Class to hold a portion and direction.
 
  Methods defined here:
__init__(self, portion)
Initialize.
__repr__(self)
Get the string representation of this PortionDirection.

 
Functions
       
addLoop(derivation, endMultiplier, loopLists, path, portionDirectionIndex, portionDirections, vertexes)
Add an indexed loop to the vertexes.
addNegatives(derivation, negatives, paths)
Add pillars output to negatives.
addNegativesPositives(derivation, negatives, paths, positives)
Add pillars output to negatives and positives.
addOffsetAddToLists(loop, offset, vector3Index, vertexes)
Add an indexed loop to the vertexes.
addPositives(derivation, paths, positives)
Add pillars output to positives.
addSpacedPortionDirection(portionDirection, spacedPortionDirections)
Add spaced portion directions.
addTwistPortions(interpolationTwist, remainderPortionDirection, twistPrecision)
Add twist portions.
comparePortionDirection(portionDirection, otherPortionDirection)
Comparison in order to sort portion directions in ascending order of portion then direction.
getGeometryOutput(derivation, elementNode)
Get triangle mesh from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get triangle mesh from attribute dictionary by arguments.
getGeometryOutputByLoops(derivation, loops)
Get geometry output by sorted, nested loops.
getGeometryOutputByNegativesPositives(elementNode, negatives, positives)
Get triangle mesh from elementNode, negatives and positives.
getGeometryOutputByNestedRing(derivation, nestedRing, portionDirections)
Get geometry output by sorted, nested loops.
getLoopListsByPath(derivation, endMultiplier, path, portionDirections)
Get loop lists from path.
getNewDerivation(elementNode)
Get new derivation.
getNormalAverage(normals)
Get normal.
getNormals(interpolationOffset, offset, portionDirection)
Get normals.
getSpacedPortionDirections(interpolationDictionary)
Get sorted portion directions.
insertTwistPortions(derivation, elementNode)
Insert twist portions and radian the twist.
processElementNode(elementNode)
Process the xml element.
setElementNodeToEndStart(elementNode, end, start)
Set elementNode attribute dictionary to a tilt following path from the start to end.
setOffsetByMultiplier(begin, end, multiplier, offset)
Set the offset by the multiplier.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.gear.html000066400000000000000000001200011167321211700275310ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.gear
 
 
fabmetheus_utilities.geometry.creation.gear ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/gear.py

Previous / Next / Contents


The gear script can generate a spur gear couple, a bevel gear couple, a ring gear couple and a rack & pinion couple.

A helix pattern can be added to each gear type. All the gear types have a clearance and all the teeth can be beveled. A keyway, shaft and lightening holes can be added to all the round gears, and rack holes can be added to the rack. The script can output solid gears or only the gear profiles. Both gears of the couple can be generated or just one.

The couple has a pinion gear and a complement.


Examples
  Bevel
  Collar
  Gear
  Keyway
  Rack
  Rack Hole
  Ring
  Shaft
  Shaft Top
  Spur Helix
  Spur Herringbone
  Spur Parabolic
  Spur Profile
Parameters
  Center Distance
  Clearance Couplet
    Clearance Over Wavelength
    Clearance
  Collar Addendum Couplet
    Collar Addendum Over Radius
    Collar Addendum
  Complement Collar Length Couplet
    Complement Collar Length Over Face Width
    Complement Collar Length
  Creation Type
    Both
    Complement
    Pinion
  Face Width
  Gear Hole Paths
  Helix Angle
  Helix Path
  Helix Type
    Basic
    Herringbone
    Parabolic
  Keyway Radius Couplet
    Keyway Radius Over Radius
    Keyway Radius
  Lightening Hole Margin Couplet
    Lightening Hole Margin Over Rim Dedendum
    Lightening Hole Margin
  Lightening Hole Minimum Radius
  Move Type
    None
    Mesh
    Separate
    Vertical
  Operating Angle
  Pinion Collar Length Couplet
    Pinion Collar Length Over Face Width
    Pinion Collar Length
  Pitch Radius
  Plate Clearance Couplet
    Plate Clearance Over Length
    Plate Clearance
  Plate Length Couplet
    Plate Length Over Face Width
    Plate Length
  Pressure Angle
  Profile Surfaces
  Rack Hole Below Over Width Couplet
    Rack Hole Below Over Width
    Rack Hole Below
  Rack Hole Radius Couplet
    Rack Hole Radius Over Width
    Rack Hole Radius
  Rack Hole Step Over Width Couplet
    Rack Hole Step Over Width
    Rack Hole Step
  Rack Length Over Radius Couplet
    Rack Length Over Radius
    Rack Length
  Rack Width Couplet
    Rack Width Over Face Width
    Rack Width
  Rim Dedendum Couplet
    Rim Dedendum Over Radius
    Rim Dedendum
  Root Bevel Couplet
    Root Bevel Over Clearance
    Root Bevel
  Shaft Depth Bottom Couplet
    Shaft Depth Bottom Over Radius
    Shaft Depth Bottom
  Shaft Depth Top Couplet
    Shaft Depth Top Over Radius
    Shaft Depth Top
  Shaft Path
  Shaft Radius Couplet
    Shaft Radius Over Pitch Radius
    Shaft Radius
  Shaft Sides
  Teeth Pinion
  Teeth Complement
  Tip Bevel Couplet
    Tip Bevel Over Clearance
    Tip Bevel
  Tooth Thickness Multiplier

Examples


The link text includes the distinguishing parameters. Each svg page was generated from an xml page of the same root name using carve. For example, gear.svg was generated by clicking 'Carve' on the carve tool panel and choosing gear.xml in the file chooser.

Each generated svg file has the xml fabmetheus element without comments towards the end of the file. To see it, open the svg file in a text editor and search for 'fabmetheus' If you copy that into a new text document, add the line '<?xml version='1.0' ?>' at the beginning and then give it a file name with the extension '.xml', you could then generate another svg file using carve.

Bevel

Bevel gear couple.

gear operatingAngle=90

Collar

Spur gear couple and each gear has a collar.

gear complementCollarLengthOverFaceWidth='1' pinionCollarLengthOverFaceWidth='1' shaftRadius='5'

Gear

Default spur gear with no parameters.

gear

Keyway

Spur gear couple and each gear has a collar and defined keyway.

gear complementCollarLengthOverFaceWidth='1' keywayRadius='2' pinionCollarLengthOverFaceWidth='1' shaftRadius='5'

Rack

Rack and pinion couple.

gear teethComplement='0'

Rack Hole

Rack and pinion couple, with holes in the rack.

gear rackHoleRadiusOverWidth='0.2' rackWidthOverFaceWidth='2' teethComplement='0'

Ring

Pinion and ring gear.

gear teethComplement='-23'

Shaft

Spur gear couple and each gear has a square shaft hole.

gear shaftRadius='5'

Shaft Top

Spur gear couple and each gear has a round shaft hole, truncated on top.

gear shaftRadius='5' shaftSides='13' shaftDepthTop='2'

Spur Helix

Spur gear couple with the gear teeth following a helix path.

gear helixAngle='45'

Spur Herringbone

Spur gear couple with the gear teeth following a herringbone path.

gear helixAngle='45' helixType='herringbone'

Spur Parabolic

Spur gear couple with the gear teeth following a parabolic path.

gear helixAngle='45' helixType='parabolic'

Spur Profile

Spur gear couple profile. Since this is just a horizontal path, it can not be sliced, so the path is then extruded to create a solid which can be sliced and viewed.

gear id='spurProfile' faceWidth='0' | extrude target='=document.getElementByID(spurProfile)

Parameters


Center Distance

Default is such that the pitch radius works out to twenty.

Defines the distance between the gear centers.

Clearance Couplet

Clearance Over Wavelength

Default is 0.1.

Defines the ratio of the clearance over the wavelength of the gear profile. The wavelength is the arc distance between the gear teeth.

Clearance

Default is the 'Clearance Over Wavelength' times the wavelength.

Defines the clearance between the gear tooth and the other gear of the couple. If the clearance is zero, the outside of the gear tooth will touch the other gear. If the clearance is too high, the gear teeth will be long and weak.

Collar Addendum Couplet

Collar Addendum Over Radius

Default is one.

Defines the ratio of the collar addendum over the shaft radius.

Collar Addendum

Default is the 'Collar Addendum Over Radius' times the shaft radius.

Defines the collar addendum.

Complement Collar Length Couplet

Complement Collar Length Over Face Width

Default is zero.

Defines the ratio of the complement collar length over the face width.

Complement Collar Length

Default is the 'Complement Collar Length Over Face Width' times the face width.

Defines the complement collar length. If the complement collar length is zero, there will not be a collar on the complement gear.

Creation Type

Default is 'both'.

Both

When selected, the pinion and complement will be generated.

Complement

When selected, only the complement gear or rack will be generated.

Pinion

When selected, only the pinion will be generated.

Face Width

Default is ten.

Defines the face width.

Gear Hole Paths

Default is empty.

Defines the centers of the gear holes. If the gear hole paths parameter is the default empty, then the centers of the gear holes will be generated from other parameters.

Helix Angle

Default is zero.

Helix Path

Default is empty.

Defines the helix path of the gear teeth. If the helix path is the default empty, then the helix will be generated from the helix angle and helix type.

Helix Type

Default is 'basic'.

Basic

When selected, the helix will be basic.

Herringbone

When selected, the helix will have a herringbone pattern.

Parabolic

When selected, the helix will have a parabolic pattern.

Keyway Radius Couplet

Keyway Radius Over Radius

Default is half.

Defines the ratio of the keyway radius over the shaft radius.

Keyway Radius

Default is the 'Keyway Radius Over Radius' times the shaft radius.

Defines the keyway radius. If the keyway radius is zero, there will not be a keyway on the collar.

Lightening Hole Margin Couplet

Lightening Hole Margin Over Rim Dedendum

Default is one.

Defines the ratio of the lightening hole margin over the rim dedendum.

Lightening Hole Margin

Default is the 'Lightening Hole Margin Over Rim Dedendum' times the rim dedendum.

Defines the minimum margin between lightening holes.

Lightening Hole Minimum Radius

Default is one.

Defines the minimum radius of the lightening holes.

Move Type

Default is 'separate'.

None

When selected, the gears will be not be moved and will therefore overlap. Afterwards the write plugin could be used to write each gear to a different file, so they can be fabricated in separate operations.

Mesh

When selected, the gears will be separated horizontally so that they just mesh. This is useful to test if the gears mesh properly.

Separate

When selected, the gears will be separated horizontally with a gap between them.

Vertical

When selected, the gears will be separated vertically.

Operating Angle

Default is 180 degrees.

Defines the operating angle between the gear axes. If the operating angle is not 180 degrees, a bevel gear couple will be generated.

Pinion Collar Length Couplet

Pinion Collar Length Over Face Width

Default is zero.

Defines the ratio of the pinion collar length over the face width.

Pinion Collar Length

Default is the 'Pinion Collar Length Over Face Width' times the face width.

Defines the pinion collar length. If the pinion collar length is zero, there will not be a collar on the pinion gear.

Pitch Radius

Default is twenty if the pitch radius has not been set. If the center distance is set, the default pitch radius is the center distance times the number of pinion teeth divided by the total number of gear teeth.

Defines the pinion pitch radius.

Plate Clearance Couplet

Plate Clearance Over Length

Default is 0.2.

Defines the ratio of the plate clearance over the plate length.

Plate Clearance

Default is the 'Plate Clearance Over Length' times the plate length.

Defines the clearance between the pinion and the plate of the ring gear. If the clearance is zero, they will touch.

Plate Length Couplet

Plate Length Over Face Width

Default is half.

Defines the ratio of the plate length over the face width.

Plate Length

Default is the 'Plate Length Over Face Width' times the face width.

Defines the length of the plate of the ring gear.

Pressure Angle

Default is twenty degrees.

Defines the pressure angle of the gear couple.

Profile Surfaces

Default is eleven.

Defines the number of profile surfaces.

Rack Hole Below Over Width Couplet

Rack Hole Below Over Width

Default is 0.6.

Defines the ratio of the distance below the pitch of the rack holes over the rack width.

Rack Hole Below

Default is the 'Rack Hole Below Over Width' times the rack width.

Defines the the distance below the pitch of the rack holes.

Rack Hole Radius Couplet

Rack Hole Radius Over Width

Default is zero.

Defines the ratio of the rack hole radius over the rack width.

Rack Hole Radius

Default is the 'Rack Hole Radius Over Width' times the rack width.

Defines the radius of the rack holes. If the rack hole radius is zero, there won't be any rack holes.

Rack Hole Step Over Width Couplet

Rack Hole Step Over Width

Default is one.

Defines the ratio of the rack hole step over the rack width.

Rack Hole Step

Default is the 'Rack Hole Step Over Width' times the rack width.

Defines the horizontal step distance between the rack holes.

Rack Length Over Radius Couplet

Rack Length Over Radius

Default is two times pi.

Defines the ratio of the rack length over the pitch radius.

Rack Length

Default is the 'Rack Length Over Radius' times the pitch radius.

Defines the rack length.

Rack Width Couplet

Rack Width Over Face Width

Default is one.

Defines the ratio of the rack width over the face width.

Rack Width

Default is the 'Rack Width Over Face Width' times the face width.

Defines the rack width.

Rim Dedendum Couplet

Rim Dedendum Over Radius

Default is 0.2.

Defines the ratio of the rim dedendum over the pitch radius.

Rim Dedendum

Default is the 'Rim Dedendum Over Radius' times the pitch radius.

Defines the rim dedendum of the gear.

Root Bevel Couplet

Root Bevel Over Clearance

Default is half.

Defines the ratio of the root bevel over the clearance.

Root Bevel

Default is the 'Root Bevel Over Clearance' times the clearance.

Defines the bevel at the root of the gear tooth.

Shaft Depth Bottom Couplet

Shaft Depth Bottom Over Radius

Default is zero.

Defines the ratio of the bottom shaft depth over the shaft radius.

Shaft Depth Bottom

Default is the 'Shaft Depth Bottom Over Radius' times the shaft radius.

Defines the bottom shaft depth.

Shaft Depth Top Couplet

Shaft Depth Top Over Radius

Default is zero.

Defines the ratio of the top shaft depth over the shaft radius.

Shaft Depth Top

Default is the 'Shaft Depth Top Over Radius' times the shaft radius.

Defines the top shaft depth.

Shaft Path

Default is empty.

Defines the path of the shaft hole. If the shaft path is the default empty, then the shaft path will be generated from the shaft depth bottom, shaft depth top, shaft radius and shaft sides.

Shaft Radius Couplet

Shaft Radius Over Pitch Radius

Default is zero.

Defines the ratio of the shaft radius over the pitch radius.

Shaft Radius

Default is the 'Shaft Radius Over Pitch Radius' times the pitch radius.

Defines the shaft radius. If the shaft radius is zero there will not be a shaft hole.

Shaft Sides

Default is four.

Defines the number of shaft sides.

Teeth Pinion

Default is seven.

Defines the number of teeth in the pinion.

Teeth Complement

Default is seventeen.

Defines the number of teeth in the complement of the gear couple. If the number of teeth is positive, the gear couple will be a spur or bevel type. If the number of teeth is zero, the gear couple will be a rack and pinion. If the number of teeth is negative, the gear couple will be a spur and ring.

Tip Bevel Couplet

Tip Bevel Over Clearance

Default is 0.1.

Defines the ratio of the tip bevel over the clearance.

Tip Bevel

Default is the 'Tip Bevel Over Clearance' times the clearance.

Defines the bevel at the tip of the gear tooth.

Tooth Thickness Multiplier

Default is 0.99999.

Defines the amount the thickness of the tooth will multiplied. If when the gears are produced, they mesh too tightly, you can reduce the tooth thickness multiplier so that they mesh with reasonable tightness.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.extrude
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.geometry_tools.path
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.geometry.creation.shaft
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.creation.teardrop
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
GearDerivation

 
class GearDerivation
    Class to hold gear variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
addBevelGear(derivation, extrudeDerivation, pitchRadius, positives, teeth, vector3GearProfile)
Get extrude output for a cylinder gear.
addBottomLoop(deltaZ, loops)
Add bottom loop to loops.
addCollarShaft(collarLength, derivation, elementNode, negatives, positives)
Add collar.
addCollarShaftSetDerivation(collarDerivation, collarLength, derivation, elementNode, negatives, positives)
Add collar and shaft.
addLighteningHoles(derivation, gearHolePaths, negatives, pitchRadius, positives)
Add lightening holes.
addRackHole(derivation, elementNode, vector3RackProfiles, x)
Add rack hole to vector3RackProfiles.
addRackHoles(derivation, elementNode, vector3RackProfiles)
Add rack holes to vector3RackProfiles.
addShaft(derivation, negatives, positives)
Add shaft.
getAxialMargin(circleRadius, numberOfSides, polygonRadius)
Get axial margin.
getBevelPath(begin, bevel, center, end)
Get bevel path.
getGearPaths(derivation, pitchRadius, teeth, toothProfile)
Get gear paths.
getGearProfileAnnulus(derivation, pitchRadius, teeth, toothProfile)
Get gear profile for an annulus gear.
getGearProfileCylinder(teeth, toothProfile)
Get gear profile for a cylinder gear.
getGearProfileRack(derivation, toothProfile)
Get gear profile for rack.
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getHalfwave(pitchRadius, teeth)
Get tooth halfwave.
getHelixComplexPath(derivation, elementNode)
Set gear helix path.
getLiftedOutput(derivation, geometryOutput)
Get extrude output for a rack.
getLighteningHoles(derivation, gearHolePaths, pitchRadius)
Get cutout circles.
getNewDerivation(elementNode)
Get new derivation.
getOutputCylinder(collarLength, derivation, elementNode, gearHolePaths, pitchRadius, teeth, twist, vector3GearProfile)
Get extrude output for a cylinder gear.
getOutputRack(derivation, elementNode, vector3GearProfile)
Get extrude output for a rack.
getPathOutput(creationFirst, derivation, elementNode, translation, vector3ComplementPaths, vector3PinionProfile)
Get gear path output.
getThicknessMultipliedPath(path, thicknessMultiplier)
Get thickness multiplied path.
getToothProfile(derivation, pitchRadius, teeth)
Get profile for one tooth.
getToothProfileAnnulus(derivation, pitchRadius, teeth)
Get profile for one tooth of an annulus.
getToothProfileCylinder(derivation, pitchRadius, teeth)
Get profile for one tooth of a cylindrical gear.
getToothProfileCylinderByProfile(derivation, pitchRadius, teeth, toothProfileHalf)
Get profile for one tooth of a cylindrical gear.
getToothProfileHalfCylinder(derivation, pitchRadius)
Get profile for half of a one tooth of a cylindrical gear.
getToothProfileRack(derivation)
Get profile for one rack tooth.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.grid.html000066400000000000000000000163631167321211700275570ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.grid
 
 
fabmetheus_utilities.geometry.creation.grid ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/grid.py

Grid path points.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path
random

 
Classes
       
GridDerivation

 
class GridDerivation
    Class to hold grid variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
addGridRow(diameter, gridPath, loopsComplex, maximumComplex, rowIndex, x, y, zigzag)
Add grid row.
getGeometryOutput(elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getHexagonalGrid(diameter, loopsComplex, maximumComplex, minimumComplex, zigzag)
Get hexagonal grid.
getIsPointInsideZoneAwayOthers(diameterReciprocal, loopsComplex, point, pixelDictionary)
Determine if the point is inside the loops zone and and away from the other points.
getNewDerivation(elementNode)
Get new derivation.
getRandomGrid(derivation, diameter, elementNode, loopsComplex, maximumComplex, minimumComplex)
Get rectangular grid.
getRectangularGrid(diameter, loopsComplex, maximumComplex, minimumComplex, zigzag)
Get rectangular grid.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.heightmap.html000066400000000000000000000206411167321211700305720ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.heightmap
 
 
fabmetheus_utilities.geometry.creation.heightmap ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/heightmap.py

Heightmap.
http://www.cs.otago.ac.nz/graphics/Mirage/node59.html
http://en.wikipedia.org/wiki/Heightmap
http://en.wikipedia.org/wiki/Netpbm_format

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path
random
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
HeightmapDerivation

 
class HeightmapDerivation
    Class to hold heightmap variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.
__repr__(self)
Get the string representation of this HeightmapDerivation.

 
Functions
       
addHeightsByBitmap(heights, textLines)
Add heights by bitmap.
addHeightsByGraymap(heights, textLines)
Add heights by graymap.
getAddIndexedHeightGrid(heightGrid, minimumXY, step, top, vertexes)
Get and add an indexed heightGrid.
getAddIndexedSegmentedPerimeter(heightGrid, maximumXY, minimumXY, step, vertexes, z=0.0)
Get and add an indexed segmented perimeter.
getGeometryOutput(elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getGeometryOutputByHeightGrid(derivation, elementNode, heightGrid)
Get vector3 vertexes from attribute dictionary.
getHeightGrid(fileName)
Get heightGrid by fileName.
getNewDerivation(elementNode)
Get new derivation.
getRaisedHeightGrid(heightGrid, start)
Get heightGrid raised above start.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.html000066400000000000000000000102721167321211700266240ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry.creation
 
 
fabmetheus_utilities.geometry.creation
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/__init__.py

Previous / Next / Contents


This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.


Previous / Next / Contents


 
Package Contents
       
_drill
_svg
circle
concatenate
extrude
gear
grid
heightmap
lathe
line
linear_bearing_cage
lineation
mechaslab
peg
polygon
shaft
solid
sponge_slice
square
teardrop
text

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.lathe.html000066400000000000000000000173311167321211700277230ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.lathe
 
 
fabmetheus_utilities.geometry.creation.lathe ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/lathe.py

Boolean geometry extrusion.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
LatheDerivation

 
class LatheDerivation
    Class to hold lathe variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
addLoopByComplex(derivation, endMultiplier, loopLists, path, pointComplex, vertexes)
Add an indexed loop to the vertexes.
addNegatives(derivation, negatives, paths)
Add pillars output to negatives.
addNegativesPositives(derivation, negatives, paths, positives)
Add pillars output to negatives and positives.
addOffsetAddToLists(loop, offset, vector3Index, vertexes)
Add an indexed loop to the vertexes.
addPositives(derivation, paths, positives)
Add pillars output to positives.
getGeometryOutput(derivation, elementNode)
Get triangle mesh from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get triangle mesh from attribute dictionary by arguments.
getGeometryOutputByNegativesPositives(derivation, elementNode, negatives, positives)
Get triangle mesh from derivation, elementNode, negatives and positives.
getLoopListsByPath(derivation, endMultiplier, path)
Get loop lists from path.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.line.html000066400000000000000000000145611167321211700275570ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.line
 
 
fabmetheus_utilities.geometry.creation.line ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/line.py

Square path.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path

 
Classes
       
LineDerivation

 
class LineDerivation
    Class to hold line variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getGeometryOutputByStep(elementNode, end, loop, steps, stepVector)
Get line geometry output by the end, loop, steps and stepVector.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.linear_bearing_cage.html000066400000000000000000000217051167321211700325460ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.linear_bearing_cage
 
 
fabmetheus_utilities.geometry.creation.linear_bearing_cage ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/linear_bearing_cage.py

Linear bearing cage.

 
Modules
       
__init__
fabmetheus_utilities.geometry.solids.cylinder
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.extrude
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.creation.peg
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.solids.sphere
fabmetheus_utilities.geometry.manipulation_matrix.translate

 
Classes
       
LinearBearingCageDerivation

 
class LinearBearingCageDerivation
    Class to hold linear bearing cage variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.
setAssemblyCage(self)
Set two piece assembly parameters.

 
Functions
       
addAssemblyCage(derivation, negatives, positives)
Add assembly linear bearing cage.
addCage(derivation, height, negatives, positives)
Add linear bearing cage.
addCageGroove(derivation, negatives, positives)
Add cage and groove.
addGroove(derivation, negatives)
Add groove on each side of cage.
addNegativePeg(derivation, negatives, x, y)
Add negative cylinder at x and y.
addNegativeSphere(derivation, negatives, x)
Add negative sphere at x.
addPositivePeg(derivation, positives, x, y)
Add positive cylinder at x and y.
getBearingCenterXs(bearingCenterX, numberOfSteps, stepX)
Get the bearing center x list.
getGeometryOutput(elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getNewDerivation(elementNode)
Get new derivation.
getPegCenterXs(numberOfSteps, pegCenterX, stepX)
Get the peg center x list.
getRoundedExtendedRectangle(radius, rectangleCenterX, sides)
Get the rounded extended rectangle.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.lineation.html000066400000000000000000000326701167321211700306130ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.lineation
 
 
fabmetheus_utilities.geometry.creation.lineation ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/lineation.py

Polygon path.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
math
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.geometry_tools.path

 
Classes
       
LineationDerivation
SideLoop
Spiral

 
class LineationDerivation
    Class to hold lineation variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
class SideLoop
    Class to handle loop, side angle and side length.
 
  Methods defined here:
__init__(self, loop, sideAngle=None, sideLength=None)
Initialize.
getManipulationPluginLoops(self, elementNode)
Get loop manipulated by the plugins in the manipulation paths folder.
rotate(self, elementNode)
Rotate.

 
class Spiral
    Class to add a spiral.
 
  Methods defined here:
__init__(self, spiral, stepRatio)
Initialize.
__repr__(self)
Get the string representation of this Spiral.
getSpiralPoint(self, unitPolar, vector3)
Add spiral to the vector.

 
Functions
       
getComplexByDictionary(dictionary, valueComplex)
Get complex by dictionary.
getComplexByDictionaryListValue(value, valueComplex)
Get complex by dictionary, list or value.
getComplexByFloatList(floatList, valueComplex)
Get complex by float list.
getComplexByMultiplierPrefix(elementNode, multiplier, prefix, valueComplex)
Get complex from multiplier, prefix and xml element.
getComplexByMultiplierPrefixes(elementNode, multiplier, prefixes, valueComplex)
Get complex from multiplier, prefixes and xml element.
getComplexByPrefix(elementNode, prefix, valueComplex)
Get complex from prefix and xml element.
getComplexByPrefixBeginEnd(elementNode, prefixBegin, prefixEnd, valueComplex)
Get complex from element node, prefixBegin and prefixEnd.
getComplexByPrefixes(elementNode, prefixes, valueComplex)
Get complex from prefixes and xml element.
getComplexIfNone(valueComplex)
Get new complex if the original complex is none.
getFloatByPrefixBeginEnd(elementNode, prefixBegin, prefixEnd, valueFloat)
Get float from prefixBegin, prefixEnd and xml element.
getFloatByPrefixSide(defaultValue, elementNode, prefix, side)
Get float by prefix and side.
getGeometryOutput(derivation, elementNode)
Get geometry output from paths.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getGeometryOutputByLoop(elementNode, sideLoop)
Get geometry output by side loop.
getGeometryOutputByManipulation(elementNode, sideLoop)
Get geometry output by manipulation.
getInradius(defaultInradius, elementNode)
Get inradius.
getMinimumRadius(beginComplexSegmentLength, endComplexSegmentLength, radius)
Get minimum radius.
getNewDerivation(elementNode)
Get new derivation.
getNumberOfBezierPoints(begin, elementNode, end)
Get the numberOfBezierPoints.
getPackedGeometryOutputByLoop(elementNode, sideLoop)
Get packed geometry output by side loop.
getRadiusAverage(radiusComplex)
Get average radius from radiusComplex.
getRadiusComplex(elementNode, radius)
Get radius complex for elementNode.
getStrokeRadiusByPrefix(elementNode, prefix)
Get strokeRadius by prefix.
processElementNode(elementNode)
Process the xml element.
processElementNodeByFunction(elementNode, manipulationFunction)
Process the xml element by the manipulationFunction.
processTargetByFunction(manipulationFunction, target)
Process the target by the manipulationFunction.
removeChildNodesFromElementObject(elementNode)
Process the xml element by manipulationFunction.
setClosedAttribute(elementNode, revolutions)
Set the closed attribute of the elementNode.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.mechaslab.html000066400000000000000000000251521167321211700305450ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.mechaslab
 
 
fabmetheus_utilities.geometry.creation.mechaslab ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/mechaslab.py

Mechaslab.

 
Modules
       
__init__
fabmetheus_utilities.geometry.solids.cylinder
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.extrude
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.creation.peg
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.manipulation_matrix.translate
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
CellExistence
HollowPegSocket
MechaslabDerivation

 
class CellExistence
    Class to determine if a cell exists.
 
  Methods defined here:
__init__(self, columns, rows, value)
Initialize.
__repr__(self)
Get the string representation of this CellExistence.
getIsInExistence(self, columnIndex, rowIndex)
Detremine if the cell at the column and row exists.

 
class HollowPegSocket
    Class to hold hollow peg socket variables.
 
  Methods defined here:
__init__(self, center)
Initialize.
__repr__(self)
Get the string representation of this HollowPegSocket.

 
class MechaslabDerivation
    Class to hold mechaslab variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.
__repr__(self)
Get the string representation of this MechaslabDerivation.

 
Functions
       
addAlongWay(begin, distance, end, loop)
Get the beveled rectangle.
addGroove(derivation, negatives)
Add groove on each side of cage.
addHollowPegSocket(derivation, hollowPegSocket, negatives, positives)
Add the socket and hollow peg.
addSlab(derivation, positives)
Add slab.
addXGroove(derivation, negatives, y)
Add x groove.
addYGroove(derivation, negatives, x)
Add y groove
getBeveledRectangle(bevel, bottomLeft)
Get the beveled rectangle.
getGeometryOutput(elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.peg.html000066400000000000000000000161161167321211700274010ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.peg
 
 
fabmetheus_utilities.geometry.creation.peg ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/peg.py

Peg.

 
Modules
       
__init__
fabmetheus_utilities.geometry.solids.cylinder
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.extrude
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.creation.solid

 
Classes
       
PegDerivation

 
class PegDerivation
    Class to hold peg variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
addPegOutput(bevel, endZ, outputs, radiusArealized, sides, start, topOverBottom)
Add beveled cylinder to outputs given bevel, endZ, radiusArealized and start.
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getNewDerivation(elementNode)
Get new derivation.
getTopAddBiconicOutput(bottomRadians, height, outputs, radius, sides, start, tipRadius, topRadians)
Get top and add biconic cylinder to outputs.
processElementNode(elementNode)
Process the xml element.
setTopOverBottomByRadius(derivation, endZ, radius, startZ)
Set the derivation topOverBottom by the angle of the elementNode, the endZ, float radius and startZ.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.polygon.html000066400000000000000000000142011167321211700303060ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.polygon
 
 
fabmetheus_utilities.geometry.creation.polygon ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/polygon.py

Polygon path.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path

 
Classes
       
PolygonDerivation

 
class PolygonDerivation
    Class to hold polygon variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.shaft.html000066400000000000000000000145471167321211700277410ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.shaft
 
 
fabmetheus_utilities.geometry.creation.shaft ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/shaft.py

Shaft path.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path

 
Classes
       
ShaftDerivation

 
class ShaftDerivation
    Class to hold shaft variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getNewDerivation(elementNode)
Get new derivation.
getShaftPath(depthBottom, depthTop, radius, sides)
Get shaft with the option of a flat on the top and/or bottom.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.solid.html000066400000000000000000000207511167321211700277400ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.solid
 
 
fabmetheus_utilities.geometry.creation.solid ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/solid.py

Solid.

Solid has some of the same functions as lineation, however you can not define geometry by dictionary string in the target because there is no getGeometryOutputByArguments function. You would have to define a shape by making the shape element. Also, you can not define geometry by 'get<Creation Name>, because the target only gets element. Instead you would have the shape element, and set the target in solid to that element.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.geometry_tools.path

 
Classes
       
SolidDerivation

 
class SolidDerivation
    Class to hold solid variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getGeometryOutputByFunction(elementNode, geometryFunction)
Get geometry output by manipulationFunction.
getGeometryOutputByManipulation(elementNode, geometryOutput)
Get geometryOutput manipulated by the plugins in the manipulation shapes & solids folders.
getNewDerivation(elementNode)
Get new derivation.
getSolidMatchingPlugins(elementNode)
Get solid plugins in the manipulation matrix, shapes & solids folders.
processArchiveRemoveSolid(elementNode, geometryOutput)
Process the target by the manipulationFunction.
processElementNode(elementNode)
Process the xml element.
processElementNodeByDerivation(derivation, elementNode)
Process the xml element by derivation.
processElementNodeByFunction(elementNode, manipulationFunction)
Process the xml element.
processElementNodeByFunctionPair(elementNode, geometryFunction, pathFunction)
Process the xml element by the appropriate manipulationFunction.
processElementNodeByGeometry(elementNode, geometryOutput)
Process the xml element by geometryOutput.
processTarget(target)
Process the target.
processTargetByFunctionPair(geometryFunction, pathFunction, target)
Process the target by the manipulationFunction.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.sponge.html000066400000000000000000000200531167321211700301140ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.sponge
 
 
fabmetheus_utilities.geometry.creation.sponge ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/sponge.py

Sponge cross section.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path
random
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
time

 
Classes
       
SpongeCircle
SpongeDerivation

 
class SpongeCircle
    Class to hold sponge circle.
 
  Methods defined here:
__init__(self, center, radius=0.0)
Initialize.
getRadius(self, arealOverlapRatio, center, derivation, otherCircles)
Set sponge bubble radius.
moveCircle(self, arealOverlapRatio, derivation, otherCircles)
Move circle into an open spot.

 
class SpongeDerivation
    Class to hold sponge variables.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.
__repr__(self)
Get the string representation of this SpongeDerivation.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getIsPointAway(minimumDistance, point, spongeCircles)
Determine if the point is at least the minimumDistance away from other points.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.sponge_slice.html000066400000000000000000000176111167321211700313010ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.sponge_slice
 
 
fabmetheus_utilities.geometry.creation.sponge_slice ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/sponge_slice.py

Sponge slice.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path
random
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
time

 
Classes
       
SpongeCircle
SpongeSliceDerivation

 
class SpongeCircle
    Class to hold sponge circle.
 
  Methods defined here:
__init__(self, center, radius=0.0)
Initialize.
getRadius(self, center, derivation, otherCircles, overlapArealRatio)
Get sponge bubble radius.
moveCircle(self, derivation, otherCircles, overlapArealRatio)
Move circle into an open spot.

 
class SpongeSliceDerivation
    Class to hold sponge slice variables.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getIsPointAway(minimumDistance, point, spongeCircles)
Determine if the point is at least the minimumDistance away from other points.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.square.html000066400000000000000000000141651167321211700301300ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.square
 
 
fabmetheus_utilities.geometry.creation.square ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/square.py

Square path.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path

 
Classes
       
SquareDerivation

 
class SquareDerivation
    Class to hold square variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.teardrop.html000066400000000000000000000163061167321211700304470ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.teardrop
 
 
fabmetheus_utilities.geometry.creation.teardrop ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/teardrop.py

Teardrop path.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.extrude
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_tools.path
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting

 
Classes
       
TeardropDerivation

 
class TeardropDerivation
    Class to hold teardrop variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
addNegativesByRadius(elementNode, end, negatives, radius, start)
Add teardrop drill hole to negatives.
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attribute dictionary.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getInclination(end, start)
Get inclination.
getNewDerivation(elementNode)
Get new derivation.
getTeardropPath(inclination, overhangRadians, overhangSpan, radiusArealized, sides)
Get vector3 teardrop path.
getTeardropPathByEndStart(elementNode, end, radius, start)
Get vector3 teardrop path by end and start.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.creation.text.html000066400000000000000000000142101167321211700276030ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.creation.text
 
 
fabmetheus_utilities.geometry.creation.text ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/creation/text.py

Text vertexes.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
fabmetheus_utilities.geometry.geometry_tools.path
fabmetheus_utilities.svg_reader

 
Classes
       
TextDerivation

 
class TextDerivation
    Class to hold text variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getGeometryOutput(derivation, elementNode)
Get vector3 vertexes from attributes.
getGeometryOutputByArguments(arguments, elementNode)
Get vector3 vertexes from attribute dictionary by arguments.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_tools.dictionary.html000066400000000000000000000241231167321211700322370ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.geometry_tools.dictionary
 
 
fabmetheus_utilities.geometry.geometry_tools.dictionary ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_tools/dictionary.py

Boolean geometry dictionary object.

 
Modules
       
__init__
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.xml_simple_writer

 
Classes
       
Dictionary

 
class Dictionary
    A dictionary object.
 
  Methods defined here:
__init__(self)
Add empty lists.
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
addXMLInnerSection(self, depth, output)
Add xml section for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getGeometryOutput(self)
Get geometry output dictionary.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getMinimumZ(self)
Get the minimum z.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getType(self)
Get type.
getVertexes(self)
Get all vertexes.
getVisible(self)
Get visible.
getXMLLocalName(self)
Get xml local name.
setToElementNode(self, elementNode)
Set the shape of this carvable object info.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
Functions
       
getAllPaths(paths, xmlObject)
Get all paths.
getAllTransformedPaths(transformedPaths, xmlObject)
Get all transformed paths.
getAllTransformedVertexes(transformedVertexes, xmlObject)
Get all transformed vertexes.
getAllVertexes(vertexes, xmlObject)
Get all vertexes.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_tools.face.html000066400000000000000000000216021167321211700307670ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.geometry_tools.face
 
 
fabmetheus_utilities.geometry.geometry_tools.face ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_tools/face.py

Face of a triangle mesh.

 
Modules
       
__init__
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.xml_simple_reader
fabmetheus_utilities.xml_simple_writer

 
Classes
       
Edge
Face

 
class Edge
    An edge of a triangle mesh.
 
  Methods defined here:
__init__(self)
Set the face indexes to None.
__repr__(self)
Get the string representation of this Edge.
addFaceIndex(self, faceIndex)
Add first None face index to input face index.
getFromVertexIndexes(self, edgeIndex, vertexIndexes)
Initialize from two vertex indices.

 
class Face
    A face of a triangle mesh.
 
  Methods defined here:
__init__(self)
Initialize.
__repr__(self)
Get the string representation of this object info.
addToAttributes(self, attributes)
Add to the attribute dictionary.
addXML(self, depth, output)
Add the xml for this object.
copy(self)
Get the copy of this face.
getFromEdgeIndexes(self, edgeIndexes, edges, faceIndex)
Initialize from edge indices.
setEdgeIndexesToVertexIndexes(self, edges, edgeTable)
Set the edge indexes to the vertex indexes.

 
Functions
       
addFaces(geometryOutput, faces)
Add the faces.
addGeometryList(elementNode, faces)
Add vertex elements to an xml element.
getCommonVertexIndex(edgeFirst, edgeSecond)
Get the vertex index that both edges have in common.
getFaces(geometryOutput)
Get the faces.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_tools.html000066400000000000000000000052741167321211700301010ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry.geometry_tools
 
 
fabmetheus_utilities.geometry.geometry_tools
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_tools/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
dictionary
face
path
path_elements (package)
vertex

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_tools.path.html000066400000000000000000000344221167321211700310310ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.geometry_tools.path
 
 
fabmetheus_utilities.geometry.geometry_tools.path ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_tools/path.py

Path.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_tools.dictionary
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.svg_writer
fabmetheus_utilities.geometry.geometry_tools.vertex
fabmetheus_utilities.xml_simple_reader
fabmetheus_utilities.xml_simple_writer

 
Classes
       
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary
Path
SVGFabricationCarving

 
class Path(fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary)
    A path.
 
  Methods defined here:
__init__(self)
Add empty lists.
addXMLInnerSection(self, depth, output)
Add the xml section for this object.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getGeometryOutput(self)
Get geometry output dictionary.
getMinimumZ(self)
Get the minimum z.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getType(self)
Get type.
getVertexes(self)
Get all vertexes.
getVisible(self)
Get visible.
getXMLLocalName(self)
Get xml local name.
setToElementNode(self, elementNode)
Set the shape of this carvable object info.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
class SVGFabricationCarving
    An svg carving.
 
  Methods defined here:
__init__(self, addLayerTemplate, elementNode)
Add empty lists.
__repr__(self)
Get the string representation of this carving.
addXML(self, depth, output)
Add xml for this object.
getCarveBoundaryLayers(self)
Get the  boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getCarvedSVG(self)
Get the carved svg text.
getFabmetheusXML(self)
Return the fabmetheus XML.
getInterpretationSuffix(self)
Return the suffix for a carving.
processSVGElement(self, fileName)
Parse SVG element and store the layers.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.

 
Functions
       
convertElementNode(elementNode, geometryOutput)
Convert the xml element by geometryOutput.
convertElementNodeByPath(elementNode, geometryOutput)
Convert the xml element to a path xml element.
convertElementNodeRenameByPaths(elementNode, geometryOutput)
Convert the xml element to a path xml element and add paths.
createLinkPath(elementNode)
Create and link a path object.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_tools.path_elements.arc.html000066400000000000000000000115731167321211700334730ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.geometry_tools.path_elements.arc
 
 
fabmetheus_utilities.geometry.geometry_tools.path_elements.arc ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_tools/path_elements/arc.py

Arc vertexes.

From:
http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.svg_reader

 
Functions
       
getArcPath(elementNode)
Get the arc path.rx ry x-axis-rotation large-arc-flag sweep-flag
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_tools.path_elements.cubic.html000066400000000000000000000116601167321211700340100ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.geometry_tools.path_elements.cubic
 
 
fabmetheus_utilities.geometry.geometry_tools.path_elements.cubic ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_tools/path_elements/cubic.py

Cubic vertexes.

From:
http://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
fabmetheus_utilities.svg_reader

 
Functions
       
getCubicPath(elementNode)
Get the cubic path.
getCubicPathByBeginEnd(begin, controlPoints, elementNode, end)
Get the cubic path by begin and end.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_tools.path_elements.html000066400000000000000000000052471167321211700327300ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry.geometry_tools.path_elements
 
 
fabmetheus_utilities.geometry.geometry_tools.path_elements
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_tools/path_elements/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
arc
cubic
quadratic

 
Data
        level = 4
numberOfLevelsDeepInPackageHierarchy = 4
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
fabmetheus_utilities.geometry.geometry_tools.path_elements.quadratic.html000066400000000000000000000113661167321211700346240ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_tools.path_elements.quadratic
 
 
fabmetheus_utilities.geometry.geometry_tools.path_elements.quadratic ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_tools/path_elements/quadratic.py

Quadratic vertexes.

From:
http://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
fabmetheus_utilities.svg_reader

 
Functions
       
getQuadraticPath(elementNode)
Get the quadratic path.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_tools.vertex.html000066400000000000000000000113301167321211700314030ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.geometry_tools.vertex
 
 
fabmetheus_utilities.geometry.geometry_tools.vertex ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_tools/vertex.py

Vertex of a triangle mesh.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.xml_simple_reader

 
Functions
       
addGeometryList(elementNode, vertexes)
Add vertex elements to an xml element.
addVertexToAttributes(attributes, vertex)
Add to the attribute dictionary.
getUnboundVertexElement(vertex)
Add vertex element to an xml element.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.boolean_geometry.html000066400000000000000000000260541167321211700342250ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.boolean_geometry
 
 
fabmetheus_utilities.geometry.geometry_utilities.boolean_geometry ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/boolean_geometry.py

Previous / Next / Contents


The xml.py script is an import translator plugin to get a carving from an Art of Illusion xml file.

An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getCarving function takes the file name of an xml file and returns the carving.

An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice. This will bring up the XML file chooser window, choose a place to save the file then click "OK". Leave the "compressFile" checkbox unchecked. All the objects from the scene will be exported, this plugin will ignore the light and camera. If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
math
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.settings
fabmetheus_utilities.geometry.solids.triangle_mesh
fabmetheus_utilities.xml_simple_writer

 
Classes
       
BooleanGeometry

 
class BooleanGeometry
    A boolean geometry scene.
 
  Methods defined here:
__init__(self)
Add empty lists.
__repr__(self)
Get the string representation of this carving.
addXML(self, depth, output)
Add xml for this object.
getCarveBoundaryLayers(self)
Get the boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getFabmetheusXML(self)
Return the fabmetheus XML.
getInterpretationSuffix(self)
Return the suffix for a boolean carving.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getMinimumZ(self)
Get the minimum z.
getNumberOfEmptyZLoops(self, z)
Get number of empty z loops.
setActualMinimumZ(self)
Get the actual minimum z at the lowest rotated boundary layer.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.

 
Functions
       
getEmptyZLoops(archivableObjects, importRadius, shouldPrintWarning, z, zoneArrangement)
Get loops at empty z level.
getLoopLayers(archivableObjects, importRadius, layerThickness, maximumZ, shouldPrintWarning, z, zoneArrangement)
Get loop layers.
getMinimumZ(geometryObject)
Get the minimum of the minimum z of the archivableObjects and the object.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.html000066400000000000000000000424351167321211700335640ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.geometry_utilities.boolean_solid
 
 
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/boolean_solid.py

Previous / Next / Contents


The xml.py script is an import translator plugin to get a carving from an Art of Illusion xml file.

An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getCarving function takes the file name of an xml file and returns the carving.

An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice. This will bring up the XML file chooser window, choose a place to save the file then click "OK". Leave the "compressFile" checkbox unchecked. All the objects from the scene will be exported, this plugin will ignore the light and camera. If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.gcodec
fabmetheus_utilities.geometry.solids.group
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
fabmetheus_utilities.geometry.solids.group.Group(fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary)
BooleanSolid

 
class BooleanSolid(fabmetheus_utilities.geometry.solids.group.Group)
    A boolean solid object.
 
 
Method resolution order:
BooleanSolid
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
getDifference(self, importRadius, visibleObjectLoopsList)
Get subtracted loops sliced through shape.
getIntersection(self, importRadius, visibleObjectLoopsList)
Get intersected loops sliced through shape.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList)
Get loops from visible object loops list.
getTransformedPaths(self)
Get all transformed paths.
getUnion(self, importRadius, visibleObjectLoopsList)
Get joined loops sliced through shape.
getXMLLocalName(self)
Get xml class name.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
__init__(self)
Add empty lists.
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
addXMLSection(self, depth, output)
Add the xml section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getGeometryOutput(self)
Get geometry output dictionary.
getMinimumZ(self)
Get the minimum z.
getPaths(self)
Get all paths.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getType(self)
Get type.
getVertexes(self)
Get all vertexes.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
Functions
       
addLineLoopsIntersections(loopLoopsIntersections, loops, pointBegin, pointEnd)
Add intersections of the line with the loops.
addLineXSegmentIntersection(lineLoopsIntersections, segmentFirstX, segmentSecondX, vector3First, vector3Second, y)
Add intersections of the line with the x segment.
addLoopLoopsIntersections(loop, loopsLoopsIntersections, otherLoops)
Add intersections of the loop with the other loops.
addLoopXSegmentIntersections(lineLoopsIntersections, loop, segmentFirstX, segmentSecondX, segmentYMirror, y)
Add intersections of the loop with the x segment.
addLoopsXSegmentIntersections(lineLoopsIntersections, loops, segmentFirstX, segmentSecondX, segmentYMirror, y)
Add intersections of the loops with the x segment.
getInBetweenLoopsFromLoops(loops, radius)
Get the in between loops from loops.
getInsetPointsByInsetLoop(insetLoop, inside, loops, radius)
Get the inset points of the inset loop inside the loops.
getInsetPointsByInsetLoops(insetLoops, inside, loops, radius)
Get the inset points of the inset loops inside the loops.
getIsInsetPointInsideLoops(inside, loops, pointBegin, pointCenter, pointEnd, radius)
Determine if the inset point is inside the loops.
getLoopsDifference(importRadius, loopLists)
Get difference loops.
getLoopsIntersection(importRadius, loopLists)
Get intersection loops.
getLoopsIntersectionByPair(importRadius, loopsFirst, loopsLast)
Get intersection loops for a pair of loop lists.
getLoopsListsIntersections(loopsList)
Get intersections betweens the loops lists.
getLoopsLoopsIntersections(loops, otherLoops)
Get all the intersections of the loops with the other loops.
getLoopsUnified(importRadius, loopLists)
Get joined loops sliced through shape.
getVisibleObjectLoopsList(importRadius, visibleObjects, z)
Get visible object loops list.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_utilities.evaluate.html000066400000000000000000005467551167321211700325770ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate.py

Evaluate expressions.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
math
os
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.settings
sys
traceback

 
Classes
       
BaseFunction
ClassFunction
Function
ClassObject
EmptyObject
Evaluator
EvaluatorAddition
EvaluatorAnd
EvaluatorOr
EvaluatorDivision
EvaluatorModulo
EvaluatorMultiplication
EvaluatorEqual
EvaluatorGreater
EvaluatorGreaterEqual
EvaluatorLess
EvaluatorLessEqual
EvaluatorNotEqual
EvaluatorPower
EvaluatorSubtraction
EvaluatorNot
EvaluatorAttribute
EvaluatorBracketCurly
EvaluatorBracketRound
EvaluatorBracketSquare
EvaluatorClass
EvaluatorComma
EvaluatorConcatenate
EvaluatorDictionary
EvaluatorElement
EvaluatorLocal
EvaluatorSelf
EvaluatorFalse
EvaluatorFunction
EvaluatorFundamental
EvaluatorNone
EvaluatorNumeric
EvaluatorTrue
EvaluatorValue
FunctionVariable
KeyValue
ModuleElementNode

 
class BaseFunction
    Class to get equation results.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.
__repr__(self)
Get the string representation of this Class.
getReturnValue(self)
Get return value.
processChildNodes(self, elementNode)
Process childNodes if shouldReturn is false.

 
class ClassFunction(BaseFunction)
    Class to get class results.
 
  Methods defined here:
getReturnValueByArguments(self, *arguments)
Get return value by arguments.
getReturnValueWithoutDeletion(self)
Get return value without deleting last function.

Methods inherited from BaseFunction:
__init__(self, elementNode)
Initialize.
__repr__(self)
Get the string representation of this Class.
getReturnValue(self)
Get return value.
processChildNodes(self, elementNode)
Process childNodes if shouldReturn is false.

 
class ClassObject
    Class to hold class attributes and functions.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.
__repr__(self)
Get the string representation of this Class.

 
class EmptyObject
    An empty object.
 
  Methods defined here:
__init__(self)
Do nothing.

 
class Evaluator
    Base evaluator class.
 
  Methods defined here:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorAddition(Evaluator)
    Class to add two evaluators.
 
  Methods defined here:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.
getValueFromValuePair(self, leftValue, rightValue)
Add two values.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorAnd(EvaluatorAddition)
    Class to compare two evaluators.
 
 
Method resolution order:
EvaluatorAnd
EvaluatorAddition
Evaluator

Methods defined here:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getBooleanFromValuePair(self, leftValue, rightValue)
And two values.
getValueFromValuePair(self, leftValue, rightValue)
Get value from comparison.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorAttribute(Evaluator)
    Class to handle an attribute.
 
  Methods defined here:
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorBracketCurly(Evaluator)
    Class to evaluate a string.
 
  Methods defined here:
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorBracketRound(Evaluator)
    Class to evaluate a string.
 
  Methods defined here:
__init__(self, elementNode, word)
Set value to none.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeRightOperation(self, evaluators, evaluatorIndex)
Evaluate the statement and delete the evaluators.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorBracketSquare(Evaluator)
    Class to evaluate a string.
 
  Methods defined here:
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeRightOperation(self, evaluators, evaluatorIndex)
Evaluate the statement and delete the evaluators.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorClass(Evaluator)
    Class evaluator class.
 
  Methods defined here:
__init__(self, elementNode, word)
Set value to none.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorComma(Evaluator)
    Class to join two evaluators.
 
  Methods defined here:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorConcatenate(Evaluator)
    Class to join two evaluators.
 
  Methods defined here:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorDictionary(Evaluator)
    Class to join two evaluators.
 
  Methods defined here:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorDivision(EvaluatorAddition)
    Class to divide two evaluators.
 
 
Method resolution order:
EvaluatorDivision
EvaluatorAddition
Evaluator

Methods defined here:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getValueFromValuePair(self, leftValue, rightValue)
Divide two values.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorElement(Evaluator)
    Element evaluator class.
 
  Methods defined here:
__init__(self, elementNode, word)
Set value to none.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorEqual(EvaluatorAddition)
    Class to compare two evaluators.
 
 
Method resolution order:
EvaluatorEqual
EvaluatorAddition
Evaluator

Methods defined here:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getBooleanFromValuePair(self, leftValue, rightValue)
Compare two values.
getValueFromValuePair(self, leftValue, rightValue)
Get value from comparison.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorFalse(Evaluator)
    Class to evaluate a string.
 
  Methods defined here:
__init__(self, elementNode, word)
Set value to zero.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorFunction(Evaluator)
    Function evaluator class.
 
  Methods defined here:
__init__(self, elementNode, word)
Set value to none.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorFundamental(Evaluator)
    Fundamental evaluator class.
 
  Methods defined here:
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorGreater(EvaluatorEqual)
    Class to compare two evaluators.
 
 
Method resolution order:
EvaluatorGreater
EvaluatorEqual
EvaluatorAddition
Evaluator

Methods defined here:
getBooleanFromValuePair(self, leftValue, rightValue)
Compare two values.

Methods inherited from EvaluatorEqual:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getValueFromValuePair(self, leftValue, rightValue)
Get value from comparison.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorGreaterEqual(EvaluatorEqual)
    Class to compare two evaluators.
 
 
Method resolution order:
EvaluatorGreaterEqual
EvaluatorEqual
EvaluatorAddition
Evaluator

Methods defined here:
getBooleanFromValuePair(self, leftValue, rightValue)
Compare two values.

Methods inherited from EvaluatorEqual:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getValueFromValuePair(self, leftValue, rightValue)
Get value from comparison.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorLess(EvaluatorEqual)
    Class to compare two evaluators.
 
 
Method resolution order:
EvaluatorLess
EvaluatorEqual
EvaluatorAddition
Evaluator

Methods defined here:
getBooleanFromValuePair(self, leftValue, rightValue)
Compare two values.

Methods inherited from EvaluatorEqual:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getValueFromValuePair(self, leftValue, rightValue)
Get value from comparison.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorLessEqual(EvaluatorEqual)
    Class to compare two evaluators.
 
 
Method resolution order:
EvaluatorLessEqual
EvaluatorEqual
EvaluatorAddition
Evaluator

Methods defined here:
getBooleanFromValuePair(self, leftValue, rightValue)
Compare two values.

Methods inherited from EvaluatorEqual:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getValueFromValuePair(self, leftValue, rightValue)
Get value from comparison.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorLocal(EvaluatorElement)
    Class to get a local variable.
 
 
Method resolution order:
EvaluatorLocal
EvaluatorElement
Evaluator

Methods defined here:
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.

Methods inherited from EvaluatorElement:
__init__(self, elementNode, word)
Set value to none.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorModulo(EvaluatorDivision)
    Class to modulo two evaluators.
 
 
Method resolution order:
EvaluatorModulo
EvaluatorDivision
EvaluatorAddition
Evaluator

Methods defined here:
getValueFromValuePair(self, leftValue, rightValue)
Modulo two values.

Methods inherited from EvaluatorDivision:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorMultiplication(EvaluatorDivision)
    Class to multiply two evaluators.
 
 
Method resolution order:
EvaluatorMultiplication
EvaluatorDivision
EvaluatorAddition
Evaluator

Methods defined here:
getValueFromValuePair(self, leftValue, rightValue)
Multiply two values.

Methods inherited from EvaluatorDivision:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorNone(Evaluator)
    Class to evaluate None.
 
  Methods defined here:
__init__(self, elementNode, word)
Set value to none.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorNot(EvaluatorSubtraction)
    Class to compare two evaluators.
 
 
Method resolution order:
EvaluatorNot
EvaluatorSubtraction
EvaluatorAddition
Evaluator

Methods defined here:
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Minus the value to the right.
getValueFromSingleValue(self, value)
Minus value.

Methods inherited from EvaluatorSubtraction:
executeLeft(self, evaluators, evaluatorIndex)
Minus the value to the right.
getNegativeValue(self, value)
Get the negative value.
getValueFromValuePair(self, leftValue, rightValue)
Subtract two values.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorNotEqual(EvaluatorEqual)
    Class to compare two evaluators.
 
 
Method resolution order:
EvaluatorNotEqual
EvaluatorEqual
EvaluatorAddition
Evaluator

Methods defined here:
getBooleanFromValuePair(self, leftValue, rightValue)
Compare two values.

Methods inherited from EvaluatorEqual:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getValueFromValuePair(self, leftValue, rightValue)
Get value from comparison.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorNumeric(Evaluator)
    Class to evaluate a string.
 
  Methods defined here:
__init__(self, elementNode, word)
Set value.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorOr(EvaluatorAnd)
    Class to compare two evaluators.
 
 
Method resolution order:
EvaluatorOr
EvaluatorAnd
EvaluatorAddition
Evaluator

Methods defined here:
getBooleanFromValuePair(self, leftValue, rightValue)
Or two values.

Methods inherited from EvaluatorAnd:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getValueFromValuePair(self, leftValue, rightValue)
Get value from comparison.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorPower(EvaluatorAddition)
    Class to power two evaluators.
 
 
Method resolution order:
EvaluatorPower
EvaluatorAddition
Evaluator

Methods defined here:
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getValueFromValuePair(self, leftValue, rightValue)
Power of two values.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorSelf(EvaluatorElement)
    Class to handle self.
 
 
Method resolution order:
EvaluatorSelf
EvaluatorElement
Evaluator

Methods defined here:
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.

Methods inherited from EvaluatorElement:
__init__(self, elementNode, word)
Set value to none.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorSubtraction(EvaluatorAddition)
    Class to subtract two evaluators.
 
 
Method resolution order:
EvaluatorSubtraction
EvaluatorAddition
Evaluator

Methods defined here:
executeLeft(self, evaluators, evaluatorIndex)
Minus the value to the right.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Minus the value to the right.
getNegativeValue(self, value)
Get the negative value.
getValueFromSingleValue(self, value)
Minus value.
getValueFromValuePair(self, leftValue, rightValue)
Subtract two values.

Methods inherited from EvaluatorAddition:
executePair(self, evaluators, evaluatorIndex)
Add two evaluators.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
getEvaluatedValues(self, enumerable, keys, value)
Get evaluatedValues.
getOperationValue(self, leftValue, rightValue)
Get operation value.

Methods inherited from Evaluator:
__init__(self, elementNode, word)
Set value to none.
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorTrue(Evaluator)
    Class to evaluate a string.
 
  Methods defined here:
__init__(self, elementNode, word)
Set value to true.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class EvaluatorValue(Evaluator)
    Class to evaluate a string.
 
  Methods defined here:
__init__(self, word)
Set value to none.

Methods inherited from Evaluator:
__repr__(self)
Get the string representation of this Class.
executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators)
Execute the bracket.
executeCenterOperation(self, evaluators, evaluatorIndex)
Execute operator which acts on the center.
executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the dictionary.
executeFunction(self, evaluators, evaluatorIndex, nextEvaluator)
Execute the function.
executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel)
Execute operator which acts from the left.
executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the key index.
executePairOperation(self, evaluators, evaluatorIndex, operationLevel)
Operate on two evaluators.
executeRightOperation(self, evaluators, evaluatorIndex)
Execute operator which acts from the right.
executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator)
Execute the string.
getIsInRange(self, keyIndex)
Determine if the keyIndex is in range.

 
class Function(BaseFunction)
    Class to get equation results.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.
getReturnValueWithoutDeletion(self)
Get return value without deleting last function.

Methods inherited from BaseFunction:
__repr__(self)
Get the string representation of this Class.
getReturnValue(self)
Get return value.
processChildNodes(self, elementNode)
Process childNodes if shouldReturn is false.

 
class FunctionVariable
    Class to hold class functions and variable set.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.
addToVariableSet(self, elementNode)
Add to variables.
processClass(self, elementNode)
Add class to FunctionVariable.
processFunction(self, elementNode)
Add function to function dictionary.
processStatement(self, elementNode)
Add self statement to variables.

 
class KeyValue
    Class to hold a key value.
 
  Methods defined here:
__init__(self, key=None, value=None)
Get key value.
__repr__(self)
Get the string representation of this KeyValue.
getByCharacter(self, character, line)
Get by character.
getByDot(self, line)
Get by dot.
getByEqual(self, line)
Get by dot.

 
class ModuleElementNode
    Class to get the in attribute, the index name and the value name.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.
processElse(self, elementNode)
Process the else statement.

 
Functions
       
addPrefixDictionary(dictionary, keys, value)
Add prefixed key values to dictionary.
addQuoteWord(evaluatorWords, word)
Add quote word and remainder if the word starts with a quote character or dollar sign, otherwise add the word.
addToPathsRecursively(paths, vector3Lists)
Add to vector3 paths recursively.
addValueToEvaluatedDictionary(elementNode, evaluatedDictionary, key)
Get the evaluated dictionary.
addVector3ToElementNode(elementNode, key, vector3)
Add vector3 to xml element.
compareExecutionOrderAscending(module, otherModule)
Get comparison in order to sort modules in ascending execution order.
convertToPaths(dictionary)
Recursively convert any ElementNodes to paths.
convertToTransformedPaths(dictionary)
Recursively convert any ElementNodes to paths.
executeLeftOperations(evaluators, operationLevel)
Evaluate the expression value from the numeric and operation evaluators.
executeNextEvaluatorArguments(evaluator, evaluators, evaluatorIndex, nextEvaluator)
Execute the nextEvaluator arguments.
executePairOperations(evaluators, operationLevel)
Evaluate the expression value from the numeric and operation evaluators.
getBracketEvaluators(bracketBeginIndex, bracketEndIndex, evaluators)
Get the bracket evaluators.
getBracketValuesDeleteEvaluator(bracketBeginIndex, bracketEndIndex, evaluators)
Get the bracket values and delete the evaluator.
getBracketsExist(evaluators)
Evaluate the expression value.
getCapitalizedSuffixKey(prefix, suffix)
Get key with capitalized suffix.
getDictionarySplitWords(dictionary, value)
Get split line for evaluators.
getElementNodeByKey(elementNode, key)
Get the xml element by key.
getElementNodeObject(evaluatedLinkValue)
Get ElementNodeObject.
getElementNodesByKey(elementNode, key)
Get the xml elements by key.
getEndIndexConvertEquationValue(bracketEndIndex, evaluatorIndex, evaluators)
Get the bracket end index and convert the equation value evaluators into a string.
getEvaluatedBoolean(defaultValue, elementNode, key)
Get the evaluated boolean.
getEvaluatedDictionaryByCopyKeys(copyKeys, elementNode)
Get the evaluated dictionary by copyKeys.
getEvaluatedDictionaryByEvaluationKeys(elementNode, evaluationKeys)
Get the evaluated dictionary.
getEvaluatedExpressionValue(elementNode, value)
Evaluate the expression value.
getEvaluatedExpressionValueBySplitLine(elementNode, words)
Evaluate the expression value.
getEvaluatedExpressionValueEvaluators(evaluators)
Evaluate the expression value from the numeric and operation evaluators.
getEvaluatedFloat(defaultValue, elementNode, key)
Get the evaluated float.
getEvaluatedInt(defaultValue, elementNode, key)
Get the evaluated int.
getEvaluatedIntByKeys(defaultValue, elementNode, keys)
Get the evaluated int by keys.
getEvaluatedLinkValue(elementNode, word)
Get the evaluated link value.
getEvaluatedString(defaultValue, elementNode, key)
Get the evaluated string.
getEvaluatedValue(defaultValue, elementNode, key)
Get the evaluated value.
getEvaluatedValueObliviously(elementNode, key)
Get the evaluated value.
getEvaluator(elementNode, evaluators, nextWord, word)
Get the evaluator.
getEvaluatorSplitWords(value)
Get split words for evaluators.
getFloatListFromBracketedString(bracketedString)
Get list from a bracketed string.
getFloatListListsByPaths(paths)
Get float lists by paths.
getIntFromFloatString(value)
Get the int from the string.
getIsBracketed(word)
Determine if the word is bracketed.
getIsQuoted(word)
Determine if the word is quoted.
getKeys(repository)
Get keys for repository.
getLocalAttributeValueString(key, valueString)
Get the local attribute value string with augmented assignment.
getMatchingPlugins(elementNode, namePathDictionary)
Get the plugins whose names are in the attribute dictionary.
getNextChildIndex(elementNode)
Get the next childNode index.
getPathByKey(defaultPath, elementNode, key)
Get path from prefix and xml element.
getPathByList(vertexList)
Get the paths by list.
getPathByPrefix(elementNode, path, prefix)
Get path from prefix and xml element.
getPathsByKey(defaultPaths, elementNode, key)
Get paths by key.
getPathsByLists(vertexLists)
Get paths by lists.
getRadiusArealizedBasedOnAreaRadius(elementNode, radius, sides)
Get the areal radius from the radius, number of sides and cascade radiusAreal.
getSidesBasedOnPrecision(elementNode, radius)
Get the number of polygon sides.
getSidesMinimumThreeBasedOnPrecision(elementNode, radius)
Get the number of polygon sides, with a minimum of three.
getSidesMinimumThreeBasedOnPrecisionSides(elementNode, radius)
Get the number of polygon sides, with a minimum of three.
getSplitDictionary()
Get split dictionary.
getStartsWithCurlyEqualRoundSquare(word)
Determine if the word starts with round or square brackets.
getTokenByNumber(number)
Get token by number.
getTransformedPathByKey(defaultTransformedPath, elementNode, key)
Get transformed path from prefix and xml element.
getTransformedPathByPrefix(elementNode, path, prefix)
Get path from prefix and xml element.
getTransformedPathsByKey(defaultTransformedPaths, elementNode, key)
Get transformed paths by key.
getUniqueQuoteIndex(uniqueQuoteIndex, word)
Get uniqueQuoteIndex.
getUniqueToken(word)
Get unique token.
getVector3ByDictionary(dictionary, vector3)
Get vector3 by dictionary.
getVector3ByDictionaryListValue(value, vector3)
Get vector3 by dictionary, list or value.
getVector3ByFloatList(floatList, vector3)
Get vector3 by float list.
getVector3ByMultiplierPrefix(elementNode, multiplier, prefix, vector3)
Get vector3 from multiplier, prefix and xml element.
getVector3ByMultiplierPrefixes(elementNode, multiplier, prefixes, vector3)
Get vector3 from multiplier, prefixes and xml element.
getVector3ByPrefix(defaultVector3, elementNode, prefix)
Get vector3 from prefix and xml element.
getVector3ByPrefixes(elementNode, prefixes, vector3)
Get vector3 from prefixes and xml element.
getVector3FromElementNode(elementNode)
Get vector3 from xml element.
getVector3IfNone(vector3)
Get new vector3 if the original vector3 is none.
getVector3ListsRecursively(floatLists)
Get vector3 lists recursively.
getVisibleObjects(archivableObjects)
Get the visible objects.
processArchivable(archivableClass, elementNode)
Get any new elements and process the archivable.
processCondition(elementNode)
Process the xml element condition.
removeIdentifiersFromDictionary(dictionary)
Remove the identifier elements from a dictionary.
setAttributesByArguments(argumentNames, arguments, elementNode)
Set the attribute dictionary to the arguments.
setFunctionLocalDictionary(arguments, function)
Evaluate the function statement and delete the evaluators.
setLocalAttribute(elementNode)
Set the local attribute if any.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalCreationDictionary = {'circle': '/home/enrique/Desktop/backup/babbleold/script/re...eus/fabmetheus_utilities/geometry/creation/circle', 'concatenate': '/home/enrique/Desktop/backup/babbleold/script/re...abmetheus_utilities/geometry/creation/concatenate', 'drill': '/home/enrique/Desktop/backup/babbleold/script/re...eus/fabmetheus_utilities/geometry/creation/_drill', 'extrude': '/home/enrique/Desktop/backup/babbleold/script/re...us/fabmetheus_utilities/geometry/creation/extrude', 'gear': '/home/enrique/Desktop/backup/babbleold/script/re...theus/fabmetheus_utilities/geometry/creation/gear', 'grid': '/home/enrique/Desktop/backup/babbleold/script/re...theus/fabmetheus_utilities/geometry/creation/grid', 'heightmap': '/home/enrique/Desktop/backup/babbleold/script/re.../fabmetheus_utilities/geometry/creation/heightmap', 'lathe': '/home/enrique/Desktop/backup/babbleold/script/re...heus/fabmetheus_utilities/geometry/creation/lathe', 'line': '/home/enrique/Desktop/backup/babbleold/script/re...theus/fabmetheus_utilities/geometry/creation/line', 'linearbearingcage': '/home/enrique/Desktop/backup/babbleold/script/re...s_utilities/geometry/creation/linear_bearing_cage', ...}
globalDictionaryOperatorBegin = {'!=': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorNotEqual>, '**': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorPower>, '<=': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorLessEqual>, '==': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorEqual>, '>=': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorGreaterEqual>, '||': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorConcatenate>}
globalElementNameSet = set(['creation', 'document', 'setting'])
globalFundamentalNameSet = set(['_math', 'euclid', 'measure', 'print'])
globalModuleEvaluatorDictionary = {'creation': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorElement>, 'document': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorElement>, 'euclid': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorFundamental>, 'math': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorFundamental>, 'measure': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorFundamental>, 'print': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorFundamental>, 'self': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorSelf>, 'setting': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorElement>}
globalModuleFunctionsDictionary = {}
globalSplitDictionary = {'!=': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorNotEqual>, '%': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorModulo>, '(': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorBracketRound>, ')': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.Evaluator>, '*': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorMultiplication>, '**': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorPower>, '+': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorAddition>, ',': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorComma>, '-': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorSubtraction>, '/': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorDivision>, ...}
globalSplitDictionaryOperator = {'%': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorModulo>, '(': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorBracketRound>, ')': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.Evaluator>, '*': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorMultiplication>, '+': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorAddition>, ',': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorComma>, '-': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorSubtraction>, '/': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorDivision>, ':': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorDictionary>, '<': <class fabmetheus_utilities.geometry.geometry_utilities.evaluate.EvaluatorLess>, ...}

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.creation.html000066400000000000000000000125751167321211700362030ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.creation
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.creation ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/creation.py

Boolean geometry utilities.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.gcodec

 
Classes
       
Creation

 
class Creation
    Class to handle a creation.
 
  Methods defined here:
__init__(self, elementNode, pluginModule)
Initialize.
__repr__(self)
Get the string representation of this creation.
getCreation(self, *arguments)
Get creation.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.document.html000066400000000000000000000161321167321211700362060ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.document
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.document ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/document.py

Boolean geometry utilities.

 
Modules
       
__init__

 
Classes
       
Document

 
class Document
    Class to handle elementNodes in a document.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.
__repr__(self)
Get the string representation of this Document.
getCascadeBoolean(self, defaultBoolean, key)
Get cascade boolean.
getCascadeFloat(self, defaultFloat, key)
Get cascade float.
getDocumentElement(self)
Get document element element.
getElementByID(self, idKey)
Get element by id.
getElementsByName(self, nameKey)
Get element by name.
getElementsByTag(self, tagKey)
Get element by tag.
getParentNode(self)
Get parentNode element.
getPrevious(self)
Get previous element.
getPreviousElement(self)
Get previous element.
getPreviousVertex(self)
Get previous element.
getSelfElement(self)
Get self element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalAccessibleAttributeDictionary = ['getCascadeBoolean', 'getCascadeFloat', 'getDocumentElement', 'getElementByID', 'getElementsByName', 'getElementsByTag', 'getParentNode', 'getPrevious', 'getPreviousElement', 'getPreviousVertex', 'getSelfElement']
globalGetAccessibleAttributeSet = set(['getCascadeBoolean', 'getCascadeFloat', 'getDocumentElement', 'getElementByID', 'getElementsByName', 'getElementsByTag', ...])

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.html000066400000000000000000000053571167321211700344000ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: package fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
creation
document
setting

 
Data
        level = 4
numberOfLevelsDeepInPackageHierarchy = 4
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting.html000066400000000000000000000245301167321211700360460ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/setting.py

Boolean geometry utilities.

 
Modules
       
__init__
math
skeinforge_application.skeinforge_utilities.skeinforge_craft

 
Classes
       
Setting

 
class Setting
    Class to get handle elementNodes in a setting.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.
__repr__(self)
Get the string representation of this Setting.
getImportRadius(self)
Get the importRadius.
getInteriorOverhangAngle(self)
Get the interior overhang support angle in degrees.
getInteriorOverhangRadians(self)
Get the interior overhang support angle in radians.
getLayerThickness(self)
Get the layer thickness.
getOverhangAngle(self)
Get the overhang support angle in degrees.
getOverhangRadians(self)
Get the overhang support angle in radians.
getOverhangSpan(self)
Get the overhang span.
getPerimeterWidth(self)
Get the perimeter width.
getPrecision(self)
Get the cascade precision.
getSheetThickness(self)
Get the sheet thickness.
getTwistPrecision(self)
Get the twist precision in degrees.
getTwistPrecisionRadians(self)
Get the twist precision in radians.

 
Functions
       
getCascadeFloatWithoutSelf(defaultFloat, elementNode, key)
Get the cascade float.
getImportRadius(elementNode)
Get the importRadius.
getInteriorOverhangAngle(elementNode)
Get the interior overhang support angle in degrees.
getInteriorOverhangRadians(elementNode)
Get the interior overhang support angle in radians.
getLayerThickness(elementNode)
Get the layer thickness.
getOverhangAngle(elementNode)
Get the overhang support angle in degrees.
getOverhangRadians(elementNode)
Get the overhang support angle in radians.
getOverhangSpan(elementNode)
Get the overhang span.
getPerimeterWidth(elementNode)
Get the perimeter width.
getPrecision(elementNode)
Get the cascade precision.
getSheetThickness(elementNode)
Get the sheet thickness.
getTwistPrecision(elementNode)
Get the twist precision in degrees.
getTwistPrecisionRadians(elementNode)
Get the twist precision in radians.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalAccessibleAttributeDictionary = ['getImportRadius', 'getInteriorOverhangAngle', 'getInteriorOverhangRadians', 'getLayerThickness', 'getOverhangSpan', 'getOverhangAngle', 'getOverhangRadians', 'getPerimeterWidth', 'getPrecision', 'getSheetThickness', 'getTwistPrecision', 'getTwistPrecisionRadians']
globalGetAccessibleAttributeSet = set(['getImportRadius', 'getInteriorOverhangAngle', 'getInteriorOverhangRadians', 'getLayerThickness', 'getOverhangAngle', 'getOverhangRadians', ...])

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables.dictionary_attribute.html000066400000000000000000000163111167321211700413050ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables.dictionary_attribute
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables.dictionary_attribute ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/dictionary_attribute.py

Dictionary object attributes.

 
Modules
       
__init__
fabmetheus_utilities.euclidean

 
Classes
       
DictionaryAttribute

 
class DictionaryAttribute
    Class to handle a dictionary.
 
  Methods defined here:
__init__(self, dictionaryObject)
Initialize.
__repr__(self)
Get the dictionary representation of this DictionaryAttribute.
count(self, value)
Get the count.
delete(self, arguments)
Get the delete dictionary.
getIsIn(self, value)
Determine if the value is in.
getIsNotIn(self, value)
Determine if the value is in.
getLength(self)
Get the length.
getMax(self)
Get the max.
getMin(self)
Get the min.
index(self, value)
Get the index element.
length(self)
Get the length.
set(self, itemIndex, value)
Set value.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalAccessibleAttributeDictionary = ['count', 'delete', 'getIsIn', 'getIsNotIn', 'getLength', 'getMax', 'getMin', 'index', 'length', 'set']
globalGetAccessibleAttributeSet = set(['count', 'delete', 'getIsIn', 'getIsNotIn', 'getLength', 'getMax', ...])
globalNativeFunctionSet = set(['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', ...])
globalNativeFunctions = ['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'remove', 'setdefault', 'update', 'values']

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables.html000066400000000000000000000054721167321211700350640ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: package fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
dictionary_attribute
list_attribute
string_attribute

 
Data
        level = 4
numberOfLevelsDeepInPackageHierarchy = 4
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables.list_attribute.html000066400000000000000000000176751167321211700401310ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables.list_attribute
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables.list_attribute ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/list_attribute.py

List object attributes.

 
Modules
       
__init__
fabmetheus_utilities.euclidean

 
Classes
       
ListAttribute

 
class ListAttribute
    Class to handle a list.
 
  Methods defined here:
__init__(self, listObject)
Initialize.
__repr__(self)
Get the list representation of this ListAttribute.
add(self, value)
Get the concatenation, same as append.
copy(self)
Get the copy.
delete(self, arguments)
Get the delete list.
get(self, itemIndex)
Get value by index
getExpansion(self, items)
Get the concatenated copies.
getIsIn(self, value)
Determine if the value is in.
getIsNotIn(self, value)
Determine if the value is in.
getLength(self)
Get the length.
getMax(self)
Get the max.
getMin(self)
Get the min.
insert(self, insertIndex, value)
Get the insert list.
keys(self)
Get the keys.
length(self)
Get the length.
rindex(self, value)
Get the rindex element.
set(self, itemIndex, value)
Set value.
values(self, arguments=None)
Get the values.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalAccessibleAttributeDictionary = ['add', 'copy', 'count', 'delete', 'get', 'getExpansion', 'getIsIn', 'getIsNotIn', 'getLength', 'getMax', 'getMin', 'insert', 'keys', 'length', 'rindex', 'set', 'values']
globalGetAccessibleAttributeSet = set(['add', 'copy', 'count', 'delete', 'get', 'getExpansion', ...])
globalNativeFunctionSet = set(['append', 'extend', 'index', 'pop', 'remove', 'reverse', ...])
globalNativeFunctions = ['append', 'extend', 'index', 'pop', 'remove', 'reverse', 'sort']

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables.string_attribute.html000066400000000000000000000206701167321211700404510ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables.string_attribute
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables.string_attribute ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/string_attribute.py

String object attributes.

 
Modules
       
__init__
fabmetheus_utilities.euclidean

 
Classes
       
StringAttribute

 
class StringAttribute
    Class to handle a string.
 
  Methods defined here:
__init__(self, stringObject)
Initialize.
__repr__(self)
Get the string representation of this StringAttribute.
add(self, nextString)
Get the add string, same as append.
append(self, nextString)
Get the append string.
copy(self)
Get the copy.
delete(self, arguments)
Get the delete string.
get(self, itemIndex)
Get value by characterIndex
getExpansion(self, items)
Get the concatenated copies.
getIsIn(self, value)
Determine if the value is in.
getIsNotIn(self, value)
Determine if the value is in.
getLength(self)
Get the length.
getMax(self)
Get the max.
getMin(self)
Get the min.
insert(self, insertIndex, value)
Get the insert string.
keys(self)
Get the keys.
length(self)
Get the length.
remove(self, value)
Get the remove string.
reverse(self)
Get the reverse string.
set(self, itemIndex, value)
Set value.
values(self)
Get the values.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalAccessibleAttributeDictionary = ['add', 'append', 'copy', 'delete', 'get', 'getExpansion', 'getIsIn', 'getIsNotIn', 'getLength', 'getMax', 'getMin', 'insert', 'keys', 'length', 'remove', 'reverse', 'set', 'values']
globalGetAccessibleAttributeSet = set(['add', 'append', 'copy', 'delete', 'get', 'getExpansion', ...])
globalNativeFunctionSet = set(['capitalize', 'center', 'count', 'decode', 'encode', 'endswith', ...])
globalNativeFunctions = ['capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'join', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'ljust', 'lower', ...]

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals._math.html000066400000000000000000000144261167321211700363310ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals._math
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals._math ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/_math.py

Boolean geometry utilities.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
math

 
Functions
       
getAbs(value)
Get the abs.
getBoolean(value)
Get the boolean.
getDivmod(x, y)
Get the divmod.
getFloat(value)
Get the float.
getHex(value)
Get the hex.
getInt(value)
Get the int.
getLong(value)
Get the long.
getMax(first, second)
Get the max.
getMin(first, second)
Get the min.
getRound(value)
Get the round.
getString(value)
Get the string.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalAccessibleAttributeDictionary = {'abs': <function getAbs>, 'boolean': <function getBoolean>, 'divmod': <function getDivmod>, 'float': <function getFloat>, 'hex': <function getHex>, 'int': <function getInt>, 'long': <function getLong>, 'max': <function getMax>, 'min': <function getMin>, 'round': <function getRound>, ...}
globalMathConstantDictionary = {'euler': 0.5772156649015329, 'golden': 1.618033988749895, 'goldenAngle': 3.883222077450933, 'goldenRatio': 1.618033988749895, 'tau': 6.283185307179586}
globalNativeFunctionSet = set(['acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', ...])
globalNativeFunctions = ['acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf', 'pi', ...]

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals.euclid.html000066400000000000000000000205151167321211700365020ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals.euclid
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals.euclid ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/euclid.py

Boolean geometry utilities.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
math

 
Classes
       
NestedVectorTestExample

 
class NestedVectorTestExample
    Class to test local attribute.
 
  Methods defined here:
__init__(self, vector3)
Get the accessible attribute.

 
Functions
       
getComplex(x=0.0, y=0.0)
Get the complex.
getCylindrical(azimuthDegrees, radius=1.0, z=0.0)
Get the cylindrical vector3 by degrees.
getCylindricalByRadians(azimuthRadians, radius=1.0, z=0.0)
Get the cylindrical vector3 by radians.
getNestedVectorTestExample(x=0.0, y=0.0, z=0.0)
Get the NestedVectorTestExample.
getPolar(angleDegrees, radius=1.0)
Get the complex polar by degrees.
getPolarByRadians(angleRadians, radius=1.0)
Get the complex polar by radians.
getSpherical(azimuthDegrees, elevationDegrees, radius=1.0)
Get the spherical vector3 unit by degrees.
getSphericalByRadians(azimuthRadians, elevationRadians, radius=1.0)
Get the spherical vector3 unit by radians.
getVector3(x=0.0, y=0.0, z=0.0)
Get the vector3.
getVector3Index(index=0, x=0.0, y=0.0, z=0.0)
Get the vector3.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalAccessibleAttributeDictionary = {'NestedVectorTestExample': <function getNestedVectorTestExample>, 'Vector3': <function getVector3>, 'Vector3Index': <function getVector3Index>, 'complex': <function getComplex>, 'getCylindrical': <function getCylindrical>, 'getCylindricalByRadians': <function getCylindricalByRadians>, 'getPolar': <function getPolar>, 'getPolarByRadians': <function getPolarByRadians>, 'getSpherical': <function getSpherical>, 'getSphericalByRadians': <function getSphericalByRadians>}

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals.html000066400000000000000000000055531167321211700352430ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: package fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
_math
euclid
measure
print

 
Data
        level = 4
numberOfLevelsDeepInPackageHierarchy = 4
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals.measure.html000066400000000000000000000137311167321211700367000ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals.measure
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals.measure ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/measure.py

Boolean geometry utilities.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
math

 
Functions
       
getBoundingBoxByPaths(elementNode)
Get bounding box of the transformed paths of the xmlObject of the elementNode.
getCenterByPaths(elementNode)
Get center of the transformed paths of the xmlObject of the elementNode.
getExtentByPaths(elementNode)
Get extent of the transformed paths of the xmlObject of the elementNode.
getInradiusByPaths(elementNode)
Get inradius of the transformed paths of the xmlObject of the elementNode.
getMaximumByPaths(elementNode)
Get maximum of the transformed paths of the xmlObject of the elementNode.
getMinimumByPaths(elementNode)
Get minimum of the transformed paths of the xmlObject of the elementNode.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalAccessibleAttributeDictionary = {'getBoundingBoxByPaths': <function getBoundingBoxByPaths>, 'getCenterByPaths': <function getCenterByPaths>, 'getExtentByPaths': <function getExtentByPaths>, 'getInradiusByPaths': <function getInradiusByPaths>, 'getMaximumByPaths': <function getMaximumByPaths>, 'getMinimumByPaths': <function getMinimumByPaths>}

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals.print.html000066400000000000000000000105771167321211700364000ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals.print
 
 
fabmetheus_utilities.geometry.geometry_utilities.evaluate_fundamentals.print ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/print.py

Boolean geometry utilities.

 
Modules
       
__init__
sys

 
Functions
       
continuous(valueString)
Print continuous.
line(valueString)
Print line.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalAccessibleAttributeDictionary = {'continuous': <function continuous>, 'line': <function line>}

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_utilities.html000066400000000000000000000067641167321211700307610ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry.geometry_utilities
 
 
fabmetheus_utilities.geometry.geometry_utilities
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/__init__.py

Previous / Next / Contents


This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.


Previous / Next / Contents


 
Package Contents
       
boolean_geometry
boolean_solid
evaluate
evaluate_elements (package)
evaluate_enumerables (package)
evaluate_fundamentals (package)
matrix

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.geometry_utilities.matrix.html000066400000000000000000000377251167321211700322650ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.geometry_utilities.matrix
 
 
fabmetheus_utilities.geometry.geometry_utilities.matrix ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/geometry_utilities/matrix.py

Boolean geometry four by four matrix.

 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
math
fabmetheus_utilities.xml_simple_writer

 
Classes
       
Matrix

 
class Matrix
    A four by four matrix.
 
  Methods defined here:
__eq__(self, other)
Determine whether this matrix is identical to other one.
__init__(self, tetragrid=None)
Add empty lists.
__ne__(self, other)
Determine whether this vector is not identical to other one.
__repr__(self)
Get the string representation of this four by four matrix.
addXML(self, depth, output)
Add xml for this object.
getAttributes(self, prefix='')
Get the attributes from row column attribute strings, counting from one.
getFromElementNode(self, elementNode, prefix)
Get the values from row column attribute strings, counting from one.
getOtherTimesSelf(self, otherTetragrid)
Get this matrix reverse multiplied by the other matrix.
getSelfTimesOther(self, otherTetragrid)
Get this matrix multiplied by the other matrix.

 
Functions
       
addVertexes(geometryOutput, vertexes)
Add the vertexes.
getBranchMatrix(elementNode)
Get matrix starting from the object if it exists, otherwise get a matrix starting from stratch.
getBranchMatrixSetElementNode(elementNode)
Get matrix starting from the object if it exists, otherwise get a matrix starting from stratch.
getCumulativeVector3Remove(defaultVector3, elementNode, prefix)
Get cumulative vector3 and delete the prefixed attributes.
getDiagonalSwitchedTetragrid(angleDegrees, diagonals)
Get the diagonals and switched matrix by degrees.
getDiagonalSwitchedTetragridByPolar(diagonals, unitPolar)
Get the diagonals and switched matrix by unitPolar.
getDiagonalSwitchedTetragridByRadians(angleRadians, diagonals)
Get the diagonals and switched matrix by radians.
getIdentityTetragrid(tetragrid=None)
Get four by four matrix with diagonal elements set to one.
getIsIdentityTetragrid(tetragrid)
Determine if the tetragrid is the identity tetragrid.
getIsIdentityTetragridOrNone(tetragrid)
Determine if the tetragrid is None or if it is the identity tetragrid.
getKeyA(row, column, prefix='')
Get the a format key string from row & column, counting from zero.
getKeyM(row, column, prefix='')
Get the m format key string from row & column, counting from one.
getKeysA(prefix='')
Get the matrix keys, counting from zero.
getKeysM(prefix='')
Get the matrix keys, counting from one.
getRemovedFloat(defaultFloat, elementNode, key, prefix)
Get the float by the key and the prefix.
getRemovedFloatByKeys(defaultFloat, elementNode, keys, prefix)
Get the float by the keys and the prefix.
getRotateAroundAxisTetragrid(elementNode, prefix)
Get rotate around axis tetragrid and delete the axis and angle attributes.
getRotateTetragrid(elementNode, prefix)
Get rotate tetragrid and delete the rotate attributes.
getScaleTetragrid(elementNode, prefix)
Get scale matrix and delete the scale attributes.
getTetragridA(elementNode, prefix, tetragrid)
Get the tetragrid from the elementNode letter a values.
getTetragridC(elementNode, prefix, tetragrid)
Get the matrix Tetragrid from the elementNode letter c values.
getTetragridCopy(tetragrid)
Get tetragrid copy.
getTetragridM(elementNode, prefix, tetragrid)
Get the tetragrid from the elementNode letter m values.
getTetragridMatrix(elementNode, prefix, tetragrid)
Get the tetragrid from the elementNode matrix value.
getTetragridR(elementNode, prefix, tetragrid)
Get the tetragrid from the elementNode letter r values.
getTetragridTimesOther(firstTetragrid, otherTetragrid)
Get this matrix multiplied by the other matrix.
getTransformTetragrid(elementNode, prefix)
Get the tetragrid from the elementNode.
getTransformedByList(floatList, point)
Get the point transformed by the array.
getTransformedVector3(tetragrid, vector3)
Get the vector3 multiplied by a matrix.
getTransformedVector3Blindly(tetragrid, vector3)
Get the vector3 multiplied by a tetragrid without checking if the tetragrid exists.
getTransformedVector3s(tetragrid, vector3s)
Get the vector3s multiplied by a matrix.
getTranslateTetragrid(elementNode, prefix)
Get translate matrix and delete the translate attributes.
getTranslateTetragridByTranslation(translation)
Get translate tetragrid by translation.
getVertexes(geometryOutput)
Get the vertexes.
setAttributesToMultipliedTetragrid(elementNode, tetragrid)
Set the element attribute dictionary and element matrix to the matrix times the tetragrid.
setElementNodeDictionaryMatrix(elementNode, matrix4X4)
Set the element attribute dictionary or element matrix to the matrix.
transformVector3Blindly(tetragrid, vector3)
Transform the vector3 by a tetragrid without checking to see if it exists.
transformVector3ByMatrix(tetragrid, vector3)
Transform the vector3 by a matrix.
transformVector3sByMatrix(tetragrid, vector3s)
Transform the vector3s by a matrix.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 300

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.html000066400000000000000000000071131167321211700250210ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry
 
 
fabmetheus_utilities.geometry
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/__init__.py

Previous / Next / Contents


This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.


Previous / Next / Contents


 
Package Contents
       
creation (package)
geometry_tools (package)
geometry_utilities (package)
manipulation_matrix (package)
manipulation_meta (package)
manipulation_paths (package)
manipulation_shapes (package)
solids (package)
statements (package)

 
Data
        level = 2
numberOfLevelsDeepInPackageHierarchy = 2
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_matrix._scale.html000066400000000000000000000145351167321211700323370ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_matrix._scale
 
 
fabmetheus_utilities.geometry.manipulation_matrix._scale ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_matrix/_scale.py

Boolean geometry scale.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.creation.solid

 
Classes
       
ScaleDerivation

 
class ScaleDerivation
    Class to hold scale variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
Get equated geometryOutput.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get equated paths.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
manipulateElementNode(elementNode, target)
Manipulate the xml element.
processElementNode(elementNode)
Process the xml element.
scalePoints(elementNode, points, prefix)
Scale the points.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 340

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_matrix.html000066400000000000000000000051601167321211700311040ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry.manipulation_matrix
 
 
fabmetheus_utilities.geometry.manipulation_matrix
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_matrix/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
_scale
rotate
transform
translate

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_matrix.rotate.html000066400000000000000000000147721167321211700324120ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_matrix.rotate
 
 
fabmetheus_utilities.geometry.manipulation_matrix.rotate ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_matrix/rotate.py

Boolean geometry rotate.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.creation.solid

 
Classes
       
RotateDerivation

 
class RotateDerivation
    Class to hold rotate variables.
 
  Methods defined here:
__init__(self, elementNode, prefix)
Set defaults.

 
Functions
       
getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
Get equated geometryOutput.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get equated paths.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
manipulateElementNode(elementNode, target)
Manipulate the xml element.
processElementNode(elementNode)
Process the xml element.
rotatePoints(elementNode, points, prefix)
Rotate the points.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 360

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_matrix.transform.html000066400000000000000000000150471167321211700331230ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_matrix.transform
 
 
fabmetheus_utilities.geometry.manipulation_matrix.transform ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_matrix/transform.py

Boolean geometry transform.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.creation.solid

 
Classes
       
TransformDerivation

 
class TransformDerivation
    Class to hold transform variables.
 
  Methods defined here:
__init__(self, elementNode, prefix)
Set defaults.

 
Functions
       
getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
Get equated geometryOutput.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get equated paths.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
manipulateElementNode(elementNode, target)
Manipulate the xml element.
processElementNode(elementNode)
Process the xml element.
transformPoints(elementNode, points, prefix)
Transform the points.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 320

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_matrix.translate.html000066400000000000000000000151571167321211700331070ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_matrix.translate
 
 
fabmetheus_utilities.geometry.manipulation_matrix.translate ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_matrix/translate.py

Boolean geometry translation.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.creation.solid

 
Classes
       
TranslateDerivation

 
class TranslateDerivation
    Class to hold translate variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
Get equated geometryOutput.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get equated paths.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
manipulateElementNode(elementNode, target)
Manipulate the xml element.
processElementNode(elementNode)
Process the xml element.
translateNegativesPositives(negatives, positives, translation)
Translate the negatives and postives.
translatePoints(elementNode, points, prefix)
Translate the points.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 380

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_meta._array.html000066400000000000000000000151161167321211700320040ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_meta._array
 
 
fabmetheus_utilities.geometry.manipulation_meta._array ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_meta/_array.py

Boolean geometry array.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
math
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.geometry_tools.vertex

 
Classes
       
ArrayDerivation

 
class ArrayDerivation
    Class to hold array variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
addPathToGroup(derivation, groupDictionaryCopy, path, targetMatrix, totalIndex)
Add path to the array group.
getNewDerivation(elementNode)
Get new derivation.
getRotationMatrix(arrayDictionary, derivation, path, point, pointIndex)
Get rotationMatrix.
getRotationMatrixByPolar(arrayDictionary, polar, polarLength)
Get rotationMatrix by polar and polarLength.
processElementNode(elementNode)
Process the xml element.
processElementNodeByDerivation(derivation, elementNode)
Process the xml element by derivation.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_meta._carve.html000066400000000000000000000152701167321211700317670ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_meta._carve
 
 
fabmetheus_utilities.geometry.manipulation_meta._carve ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_meta/_carve.py

Boolean geometry carve.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.boolean_geometry
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.geometry_tools.path
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.geometry.solids.triangle_mesh
fabmetheus_utilities.xml_simple_reader

 
Classes
       
CarveDerivation

 
class CarveDerivation
    Class to hold carve variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getLinkedElementNode(idSuffix, parentNode, target)
Get elementNode with identifiers and parentNode.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.
processElementNodeByDerivation(derivation, elementNode)
Process the xml element by derivation.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_meta._copy.html000066400000000000000000000140331167321211700316350ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_meta._copy
 
 
fabmetheus_utilities.geometry.manipulation_meta._copy ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_meta/_copy.py

Boolean geometry copy.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.creation.solid

 
Classes
       
CopyDerivation

 
class CopyDerivation
    Class to hold copy variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.
processElementNodeByDerivation(derivation, elementNode)
Process the xml element by derivation.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_meta.disjoin.html000066400000000000000000000155021167321211700321650ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_meta.disjoin
 
 
fabmetheus_utilities.geometry.manipulation_meta.disjoin ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_meta/disjoin.py

Boolean geometry disjoin.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.boolean_geometry
fabmetheus_utilities.geometry.solids.difference
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.geometry_tools.path
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.geometry.solids.triangle_mesh
fabmetheus_utilities.xml_simple_reader

 
Classes
       
DisjoinDerivation

 
class DisjoinDerivation
    Class to hold disjoin variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getLinkedElementNode(idSuffix, parentNode, target)
Get elementNode with identifiers and parentNode.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.
processElementNodeByDerivation(derivation, elementNode)
Process the xml element by derivation.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_meta.html000066400000000000000000000053741167321211700305350ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry.manipulation_meta
 
 
fabmetheus_utilities.geometry.manipulation_meta
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_meta/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
_array
_carve
_copy
disjoin
import
write

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_meta.import.html000066400000000000000000000156451167321211700320500ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_meta.import
 
 
fabmetheus_utilities.geometry.manipulation_meta.import ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_meta/import.py

Boolean geometry group of solids.

 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.geometry.solids.group
os
fabmetheus_utilities.settings
fabmetheus_utilities.xml_simple_reader
fabmetheus_utilities.xml_simple_writer

 
Classes
       
ImportDerivation

 
class ImportDerivation
    Class to hold import variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
appendAttributes(fromElementNode, toElementNode)
Append the attributes from the child nodes of fromElementNode to the attributes of toElementNode.
getNewDerivation(elementNode)
Get new derivation.
getXMLFromCarvingFileName(fileName)
Get xml text from xml text.
processElementNode(elementNode)
Process the xml element.
processElementNodeByDerivation(derivation, elementNode)
Process the xml element by derivation.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_meta.write.html000066400000000000000000000146261167321211700316660ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_meta.write
 
 
fabmetheus_utilities.geometry.manipulation_meta.write ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_meta/write.py

Boolean geometry write.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.gcodec
fabmetheus_utilities.geometry.geometry_utilities.matrix
os

 
Classes
       
WriteDerivation

 
class WriteDerivation
    Class to hold write variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.
processElementNodeByDerivation(derivation, elementNode)
Process the xml element by derivation.
writeElementNode(derivation, fileNames, target)
Write a quantity of the target.
writeXMLObject(absoluteFolderDirectory, derivation, fileNames, target, xmlObject)
Write one instance of the xmlObject.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_paths._inset.html000066400000000000000000000107661167321211700322070ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_paths._inset
 
 
fabmetheus_utilities.geometry.manipulation_paths._inset ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_paths/_inset.py

Create inset.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.intercircle
fabmetheus_utilities.geometry.creation.lineation

 
Functions
       
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get inset path.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 80

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_paths._outset.html000066400000000000000000000140141167321211700323760ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_paths._outset
 
 
fabmetheus_utilities.geometry.manipulation_paths._outset ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_paths/_outset.py

Create inset.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.intercircle
fabmetheus_utilities.geometry.creation.lineation
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting

 
Classes
       
OutsetDerivation

 
class OutsetDerivation
    Class to hold outset variables.
 
  Methods defined here:
__init__(self, elementNode, prefix)
Set defaults.

 
Functions
       
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get outset path.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 80

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_paths.bevel.html000066400000000000000000000140561167321211700320170ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_paths.bevel
 
 
fabmetheus_utilities.geometry.manipulation_paths.bevel ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_paths/bevel.py

Add material to support overhang or remove material at the overhang angle.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation

 
Classes
       
BevelDerivation

 
class BevelDerivation
    Class to hold bevel variables.
 
  Methods defined here:
__init__(self, elementNode, prefix, sideLength)
Set defaults.

 
Functions
       
getBevelPath(begin, center, close, end, radius)
Get bevel path.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get bevel loop.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 20

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_paths.convex.html000066400000000000000000000113201167321211700322130ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_paths.convex
 
 
fabmetheus_utilities.geometry.manipulation_paths.convex ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_paths/convex.py

Create outline.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation

 
Functions
       
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get path with overhangs removed or filled in.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 80

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_paths.html000066400000000000000000000056701167321211700307250ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry.manipulation_paths
 
 
fabmetheus_utilities.geometry.manipulation_paths
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_paths/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
_outset
bevel
convex
outline
overhang
round
segment
wedge

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_paths.outline.html000066400000000000000000000142001167321211700323700ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_paths.outline
 
 
fabmetheus_utilities.geometry.manipulation_paths.outline ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_paths/outline.py

Create outline.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.intercircle
fabmetheus_utilities.geometry.creation.lineation
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting

 
Classes
       
OutlineDerivation

 
class OutlineDerivation
    Class to hold outline variables.
 
  Methods defined here:
__init__(self, elementNode, prefix, sideLength)
Set defaults.

 
Functions
       
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get path with outline.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 80

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_paths.overhang.html000066400000000000000000000377431167321211700325430ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_paths.overhang
 
 
fabmetheus_utilities.geometry.manipulation_paths.overhang ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_paths/overhang.py

Add material to support overhang or remove material at the overhang angle.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting

 
Classes
       
AlongAway
OverhangClockwise
OverhangDerivation
OverhangWiddershinsLeft
OverhangWiddershinsRight

 
class AlongAway
    Class to derive the path along the point and away from the point.
 
  Methods defined here:
__init__(self, loop, overhangPlaneAngle)
Initialize.
__repr__(self)
Get the string representation of AlongAway.
addToBottomPoints(self, point)
Add point to bottom points and set y to minimumY.
getIsClockwisePointSupported(self, point)
Determine if the point on the clockwise loop is supported.
getIsPointSupportedBySegment(self, endIndex)
Determine if the point on the widdershins loop is supported.
getIsWiddershinsPointSupported(self, point)
Determine if the point on the widdershins loop is supported.

 
class OverhangClockwise
    Class to get the intersection up from the point.
 
  Methods defined here:
__init__(self, alongAway)
Initialize.
__repr__(self)
Get the string representation of OverhangClockwise.
alterLoop(self, unsupportedPointIndexes)
Alter alongAway loop.

 
class OverhangDerivation
    Class to hold overhang variables.
 
  Methods defined here:
__init__(self, elementNode, prefix)
Set defaults.

 
class OverhangWiddershinsLeft
    Class to get the intersection from the point down to the left.
 
  Methods defined here:
__init__(self, alongAway)
Initialize.
__repr__(self)
Get the string representation of OverhangWiddershins.
alterLoop(self)
Alter alongAway loop.
getBottomLoop(self, closestBottomIndex, insertedPoint)
Get loop around bottom.
getDistance(self)
Get distance between point and closest intersection or bottom point along line.
getDistanceToBottom(self)
Get distance between point and closest bottom point along line.
getIntersectLoop(self)
Get intersection loop.
getIsOnside(self, x)
Determine if x is on the side along the direction of the intersection line.
setRatios(self)
Set ratios.

 
class OverhangWiddershinsRight(OverhangWiddershinsLeft)
    Class to get the intersection from the point down to the right.
 
  Methods defined here:
__init__(self, alongAway)
Initialize.
getBottomLoop(self, closestBottomIndex, insertedPoint)
Get loop around bottom.
getIntersectLoop(self)
Get intersection loop.
getIsOnside(self, x)
Determine if x is on the side along the direction of the intersection line.

Methods inherited from OverhangWiddershinsLeft:
__repr__(self)
Get the string representation of OverhangWiddershins.
alterLoop(self)
Alter alongAway loop.
getDistance(self)
Get distance between point and closest intersection or bottom point along line.
getDistanceToBottom(self)
Get distance between point and closest bottom point along line.
setRatios(self)
Set ratios.

 
Functions
       
addUnsupportedPointIndexes(alongAway)
Add the indexes of the unsupported points.
alterClockwiseSupportedPath(alongAway, elementNode)
Get clockwise path with overhangs carved out.
alterWiddershinsSupportedPath(alongAway, close)
Get widdershins path with overhangs filled in.
alterWiddershinsSupportedPathByPoint(alongAway, overhangWiddershinsLeft, overhangWiddershinsRight, point)
Get widdershins path with overhangs filled in for point.
compareYAscending(point, pointOther)
Get comparison in order to sort points in ascending y.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get path with overhangs removed or filled in.
getMinimumYByPath(path)
Get path with overhangs removed or filled in.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 100

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_paths.round.html000066400000000000000000000141371167321211700320510ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_paths.round
 
 
fabmetheus_utilities.geometry.manipulation_paths.round ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_paths/round.py

Add material to support overhang or remove material at the overhang angle.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math

 
Classes
       
RoundDerivation

 
class RoundDerivation
    Class to hold round variables.
 
  Methods defined here:
__init__(self, elementNode, prefix, sideLength)
Set defaults.

 
Functions
       
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get round loop.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
getRoundPath(begin, center, close, end, radius, sidesPerRadian)
Get round path.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 40

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_paths.segment.html000066400000000000000000000177771167321211700324010ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_paths.segment
 
 
fabmetheus_utilities.geometry.manipulation_paths.segment ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_paths/segment.py

Add material to support overhang or remove material at the overhang angle.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation

 
Classes
       
SegmentDerivation
StartEnd

 
class SegmentDerivation
    Class to hold segment variables.
 
  Methods defined here:
__init__(self, elementNode, prefix)
Set defaults.

 
class StartEnd
    Class to get a start through end range.
 
  Methods defined here:
__init__(self, elementNode, modulo, prefix)
Initialize.
__repr__(self)
Get the string representation of this StartEnd.

 
Functions
       
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get segment loop.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
getRadialPath(begin, center, end, path)
Get radial path.
getSegmentPath(center, loop, path, pointIndex)
Get segment path.
getSegmentPathDefault()
Get segment path default.
getWedgePath(begin, centerBegin, centerEnd, centerEndMinusBegin, end, path)
Get segment path.
getWiddershinsAverageByVector3(centerMinusBeginComplex, endMinusCenterComplex)
Get the normalized average of the widdershins vectors.
getXNormalizedVector3Path(path)
Get path where the x ranges from 0 to 1.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 60

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_paths.wedge.html000066400000000000000000000134641167321211700320170ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_paths.wedge
 
 
fabmetheus_utilities.geometry.manipulation_paths.wedge ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_paths/wedge.py

Add material to support overhang or remove material at the overhang angle.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation

 
Classes
       
WedgeDerivation

 
class WedgeDerivation
    Class to hold wedge variables.
 
  Methods defined here:
__init__(self, elementNode, prefix)
Set defaults.

 
Functions
       
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get wedge loop.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = -200

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_shapes._bottom.html000066400000000000000000000160121167321211700325230ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_shapes._bottom
 
 
fabmetheus_utilities.geometry.manipulation_shapes._bottom ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_shapes/_bottom.py

Boolean geometry bottom.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.boolean_geometry
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.geometry.creation.solid

 
Classes
       
BottomDerivation

 
class BottomDerivation
    Class to hold bottom variables.
 
  Methods defined here:
__init__(self, elementNode, prefix)
Set defaults.
getAdditionalPathLift(self)
Get path lift.

 
Functions
       
bottomElementNode(derivation, target)
Bottom target.
getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
Get bottomed geometryOutput.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get flipped paths.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
processElementNode(elementNode)
Process the xml element.
processElementNodeByDerivation(derivation, elementNode)
Process the xml element by derivation.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 400

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_shapes._inset.html000066400000000000000000000163501167321211700323460ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_shapes._inset
 
 
fabmetheus_utilities.geometry.manipulation_shapes._inset ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_shapes/_inset.py

Create inset.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.boolean_geometry
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.intercircle
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements.setting
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
InsetDerivation

 
class InsetDerivation
    Class to hold inset variables.
 
  Methods defined here:
__init__(self, elementNode, prefix)
Set defaults.

 
Functions
       
getLoopOrEmpty(loopIndex, loops)
Get the loop, or if the loopIndex is out of range, get an empty list.
getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
Get inset geometryOutput.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get inset path.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 80

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_shapes.equation.html000066400000000000000000000176531167321211700327210ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_shapes.equation
 
 
fabmetheus_utilities.geometry.manipulation_shapes.equation ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_shapes/equation.py

Equation for vertexes.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
math
fabmetheus_utilities.geometry.geometry_utilities.matrix

 
Classes
       
EquationDerivation
EquationResult

 
class EquationDerivation
    Class to hold equation variables.
 
  Methods defined here:
__init__(self, elementNode, prefix)
Set defaults.
addEquationResult(self, elementNode, equationFunction, prefix)
Add equation result to equationResults.

 
class EquationResult
    Class to get equation results.
 
  Methods defined here:
__init__(self, elementNode, equationFunction, key)
Initialize.
getReturnValue(self, point, revolutions)
Get return value.

 
Functions
       
equate(point, returnValue)
Get equation for rectangular.
equatePoints(elementNode, points, prefix, revolutions)
Equate the points.
equateX(point, returnValue)
Get equation for rectangular x.
equateY(point, returnValue)
Get equation for rectangular y.
equateZ(point, returnValue)
Get equation for rectangular z.
getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
Get equated geometryOutput.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get equated paths.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = -100

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_shapes.flip.html000066400000000000000000000151471167321211700320220ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_shapes.flip
 
 
fabmetheus_utilities.geometry.manipulation_shapes.flip ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_shapes/flip.py

Add material to support overhang or remove material at the overhang angle.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.creation.solid

 
Classes
       
FlipDerivation

 
class FlipDerivation
    Class to hold flip variables.
 
  Methods defined here:
__init__(self, elementNode, prefix)
Set defaults.

 
Functions
       
flipPoints(elementNode, points, prefix)
Flip the points.
getFlippedLoop(elementNode, loop, prefix)
Get flipped loop.
getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
Get equated geometryOutput.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get flipped paths.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
getShouldReverse(elementNode, prefix)
Determine if the loop should be reversed.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 200

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_shapes.html000066400000000000000000000052751167321211700310720ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry.manipulation_shapes
 
 
fabmetheus_utilities.geometry.manipulation_shapes
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_shapes/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
_bottom
_inset
equation
flip
mirror

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.manipulation_shapes.mirror.html000066400000000000000000000126421167321211700323770ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.manipulation_shapes.mirror
 
 
fabmetheus_utilities.geometry.manipulation_shapes.mirror ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/manipulation_shapes/mirror.py

Add material to support overhang or remove material at the overhang angle.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_tools.face
fabmetheus_utilities.geometry.manipulation_shapes.flip
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Functions
       
getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
Get equated geometryOutput.
getManipulatedPaths(close, elementNode, loop, prefix, sideLength)
Get flipped paths.
getNewDerivation(elementNode, prefix, sideLength)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalExecutionOrder = 200

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.solids.cube.html000066400000000000000000000341261167321211700272360ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.solids.cube
 
 
fabmetheus_utilities.geometry.solids.cube ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/solids/cube.py

Boolean geometry cube.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
CubeDerivation
fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh(fabmetheus_utilities.geometry.solids.group.Group)
Cube

 
class Cube(fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh)
    A cube object.
 
 
Method resolution order:
Cube
fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
addXMLSection(self, depth, output)
Add the xml section for this object.
createShape(self)
Create the shape.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh:
__init__(self)
Add empty lists.
getCarveBoundaryLayers(self)
Get the boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getFabmetheusXML(self)
Return the fabmetheus XML.
getGeometryOutput(self)
Get geometry output dictionary.
getInterpretationSuffix(self)
Return the suffix for a triangle mesh.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getLoopsFromMesh(self, z)
Get loops from a carve of a mesh.
getMinimumZ(self)
Get the minimum z.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getVertexes(self)
Get all vertexes.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.
setEdgesForAllFaces(self)
Set the face edges of all the faces.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getType(self)
Get type.
getXMLLocalName(self)
Get xml local name.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
class CubeDerivation
    Class to hold cube variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
addCube(elementNode, faces, inradius, vertexes)
Add cube by inradius.
getGeometryOutput(elementNode, inradius)
Get cube triangle mesh by inradius.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.solids.cylinder.html000066400000000000000000000371331167321211700301320ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.solids.cylinder
 
 
fabmetheus_utilities.geometry.solids.cylinder ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/solids/cylinder.py

Boolean geometry cylinder.

 
Modules
       
__init__
fabmetheus_utilities.geometry.solids.cube
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.creation.lineation
math
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
fabmetheus_utilities.geometry.solids.cube.Cube(fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh)
Cylinder
CylinderDerivation

 
class Cylinder(fabmetheus_utilities.geometry.solids.cube.Cube)
    A cylinder object.
 
 
Method resolution order:
Cylinder
fabmetheus_utilities.geometry.solids.cube.Cube
fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
__init__(self)
Add empty lists.
createShape(self)
Create the shape.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.solids.cube.Cube:
addXMLSection(self, depth, output)
Add the xml section for this object.

Methods inherited from fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh:
getCarveBoundaryLayers(self)
Get the boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getFabmetheusXML(self)
Return the fabmetheus XML.
getGeometryOutput(self)
Get geometry output dictionary.
getInterpretationSuffix(self)
Return the suffix for a triangle mesh.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getLoopsFromMesh(self, z)
Get loops from a carve of a mesh.
getMinimumZ(self)
Get the minimum z.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getVertexes(self)
Get all vertexes.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.
setEdgesForAllFaces(self)
Set the face edges of all the faces.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getType(self)
Get type.
getXMLLocalName(self)
Get xml local name.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
class CylinderDerivation
    Class to hold cylinder variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
addCylinder(faces, inradius, sides, topOverBottom, vertexes)
Add cylinder by inradius.
addCylinderOutputByEndStart(endZ, inradiusComplex, outputs, sides, start, topOverBottom=1.0)
Add cylinder triangle mesh by endZ, inradius and start.
getGeometryOutput(inradius, sides, topOverBottom)
Get cylinder triangle mesh by inradius.
getNewDerivation(elementNode)
Get new derivation.
getTopOverBottom(angle, endZ, inradiusComplex, startZ)
Get topOverBottom by angle in radians, endZ, inradius and start.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.solids.difference.html000066400000000000000000000307631167321211700304150ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.solids.difference
 
 
fabmetheus_utilities.geometry.solids.difference ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/solids/difference.py

Boolean geometry difference of solids.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.solids.group

 
Classes
       
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid(fabmetheus_utilities.geometry.solids.group.Group)
Difference

 
class Difference(fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid)
    A difference object.
 
 
Method resolution order:
Difference
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList)
Get loops from visible object loops list.
getXMLLocalName(self)
Get xml class name.

Methods inherited from fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid:
getDifference(self, importRadius, visibleObjectLoopsList)
Get subtracted loops sliced through shape.
getIntersection(self, importRadius, visibleObjectLoopsList)
Get intersected loops sliced through shape.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getTransformedPaths(self)
Get all transformed paths.
getUnion(self, importRadius, visibleObjectLoopsList)
Get joined loops sliced through shape.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
__init__(self)
Add empty lists.
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
addXMLSection(self, depth, output)
Add the xml section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getGeometryOutput(self)
Get geometry output dictionary.
getMinimumZ(self)
Get the minimum z.
getPaths(self)
Get all paths.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getType(self)
Get type.
getVertexes(self)
Get all vertexes.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
Functions
       
convertElementNode(elementNode, geometryOutput)
Convert the xml element to a difference xml element.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.solids.group.html000066400000000000000000000247541167321211700274620ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.solids.group
 
 
fabmetheus_utilities.geometry.solids.group ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/solids/group.py

Boolean geometry group of solids.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_tools.dictionary
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_utilities.matrix

 
Classes
       
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary
Group

 
class Group(fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary)
    A group.
 
  Methods defined here:
__init__(self)
Add empty lists.
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
addXMLSection(self, depth, output)
Add the xml section for this object.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getGeometryOutput(self)
Get geometry output dictionary.
getMinimumZ(self)
Get the minimum z.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getType(self)
Get type.
getVertexes(self)
Get all vertexes.
getXMLLocalName(self)
Get xml local name.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
Functions
       
convertContainerElementNode(elementNode, geometryOutput, xmlObject)
Convert the xml element to a group xml element.
convertElementNode(elementNode, geometryOutput)
Convert the xml element to a group xml element.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.solids.html000066400000000000000000000063501167321211700263170ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry.solids
 
 
fabmetheus_utilities.geometry.solids
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/solids/__init__.py

Previous / Next / Contents


This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.


Previous / Next / Contents


 
Package Contents
       
cube
cylinder
difference
group
intersection
sphere
triangle_mesh
union

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.solids.intersection.html000066400000000000000000000315371167321211700310310ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.solids.intersection
 
 
fabmetheus_utilities.geometry.solids.intersection ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/solids/intersection.py

Boolean geometry intersection of solids.

 
Modules
       
__init__
fabmetheus_utilities.geometry.solids.difference
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.solids.group

 
Classes
       
fabmetheus_utilities.geometry.solids.difference.Difference(fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid)
Intersection

 
class Intersection(fabmetheus_utilities.geometry.solids.difference.Difference)
    An intersection object.
 
 
Method resolution order:
Intersection
fabmetheus_utilities.geometry.solids.difference.Difference
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList)
Get loops from visible object loops list.

Methods inherited from fabmetheus_utilities.geometry.solids.difference.Difference:
getXMLLocalName(self)
Get xml class name.

Methods inherited from fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid:
getDifference(self, importRadius, visibleObjectLoopsList)
Get subtracted loops sliced through shape.
getIntersection(self, importRadius, visibleObjectLoopsList)
Get intersected loops sliced through shape.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getTransformedPaths(self)
Get all transformed paths.
getUnion(self, importRadius, visibleObjectLoopsList)
Get joined loops sliced through shape.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
__init__(self)
Add empty lists.
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
addXMLSection(self, depth, output)
Add the xml section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getGeometryOutput(self)
Get geometry output dictionary.
getMinimumZ(self)
Get the minimum z.
getPaths(self)
Get all paths.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getType(self)
Get type.
getVertexes(self)
Get all vertexes.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
Functions
       
convertElementNode(elementNode, geometryOutput)
Convert the xml element to an intersection xml element.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.solids.sphere.html000066400000000000000000000352321167321211700276050ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.solids.sphere
 
 
fabmetheus_utilities.geometry.solids.sphere ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/solids/sphere.py

Boolean geometry sphere.

 
Modules
       
__init__
fabmetheus_utilities.geometry.solids.cube
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
math
fabmetheus_utilities.geometry.creation.solid
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
fabmetheus_utilities.geometry.solids.cube.Cube(fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh)
Sphere
SphereDerivation

 
class Sphere(fabmetheus_utilities.geometry.solids.cube.Cube)
    A sphere object.
 
 
Method resolution order:
Sphere
fabmetheus_utilities.geometry.solids.cube.Cube
fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
createShape(self)
Create the shape.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.solids.cube.Cube:
addXMLSection(self, depth, output)
Add the xml section for this object.

Methods inherited from fabmetheus_utilities.geometry.solids.triangle_mesh.TriangleMesh:
__init__(self)
Add empty lists.
getCarveBoundaryLayers(self)
Get the boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getFabmetheusXML(self)
Return the fabmetheus XML.
getGeometryOutput(self)
Get geometry output dictionary.
getInterpretationSuffix(self)
Return the suffix for a triangle mesh.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getLoopsFromMesh(self, z)
Get loops from a carve of a mesh.
getMinimumZ(self)
Get the minimum z.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getVertexes(self)
Get all vertexes.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.
setEdgesForAllFaces(self)
Set the face edges of all the faces.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getType(self)
Get type.
getXMLLocalName(self)
Get xml local name.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
class SphereDerivation
    Class to hold sphere variables.
 
  Methods defined here:
__init__(self, elementNode)
Set defaults.

 
Functions
       
addSphere(elementNode, faces, radius, vertexes)
Add sphere by radius.
getGeometryOutput(elementNode, radius)
Get triangle mesh from attribute dictionary.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.solids.triangle_mesh.html000066400000000000000000000735011167321211700311410ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.solids.triangle_mesh
 
 
fabmetheus_utilities.geometry.solids.triangle_mesh ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/solids/triangle_mesh.py

Triangle Mesh holds the faces and edges of a triangular mesh.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_tools.dictionary
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_tools.face
fabmetheus_utilities.geometry.solids.group
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.settings
fabmetheus_utilities.geometry.geometry_tools.vertex
fabmetheus_utilities.xml_simple_writer

 
Classes
       
fabmetheus_utilities.geometry.solids.group.Group(fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary)
TriangleMesh
EdgePair
FaceGenerator
ZoneArrangement

 
class EdgePair
     Methods defined here:
__init__(self)
Pair of edges on a face.
__repr__(self)
Get the string representation of this EdgePair.
getFromIndexesEdges(self, edgeIndexes, edges)
Initialize from edge indices.

 
class FaceGenerator
    A face generator.
 
  Methods defined here:
__init__(self, faces, indexedLoopBottom, indexedLoopTop)
Initialize.
addFacesByBottomIndex(self, bottomIndex, faces)
Add faces from the  bottom index to the next index.
getBetweenIndex(self, bottomPoint, bottomPointNext, topIndexPlusOne)
Get the index of the last point along the loop which is closer to the bottomPoint.

 
class TriangleMesh(fabmetheus_utilities.geometry.solids.group.Group)
    A triangle mesh.
 
 
Method resolution order:
TriangleMesh
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
__init__(self)
Add empty lists.
addXMLSection(self, depth, output)
Add the xml section for this object.
getCarveBoundaryLayers(self)
Get the boundary layers.
getCarveCornerMaximum(self)
Get the corner maximum of the vertexes.
getCarveCornerMinimum(self)
Get the corner minimum of the vertexes.
getCarveLayerThickness(self)
Get the layer thickness.
getFabmetheusXML(self)
Return the fabmetheus XML.
getGeometryOutput(self)
Get geometry output dictionary.
getInterpretationSuffix(self)
Return the suffix for a triangle mesh.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getLoopsFromMesh(self, z)
Get loops from a carve of a mesh.
getMinimumZ(self)
Get the minimum z.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getVertexes(self)
Get all vertexes.
setCarveImportRadius(self, importRadius)
Set the import radius.
setCarveIsCorrectMesh(self, isCorrectMesh)
Set the is correct mesh flag.
setCarveLayerThickness(self, layerThickness)
Set the layer thickness.
setEdgesForAllFaces(self)
Set the face edges of all the faces.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getPaths(self)
Get all paths.
getTransformedPaths(self)
Get all transformed paths.
getType(self)
Get type.
getXMLLocalName(self)
Get xml local name.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
class ZoneArrangement
    A zone arrangement.
 
  Methods defined here:
__init__(self, layerThickness, vertexes)
Initialize the zone interval and the zZone table.
getEmptyZ(self, z)
Get the first z which is not in the zone table.

 
Functions
       
addEdgePair(edgePairTable, edges, faceEdgeIndex, remainingEdgeIndex, remainingEdgeTable)
Add edge pair to the edge pair table.
addFacesByConcaveLoop(faces, indexedLoop)
Add faces from a polygon which is concave.
addFacesByConvex(faces, indexedLoop)
Add faces from a convex polygon.
addFacesByConvexBottomTopLoop(faces, indexedLoopBottom, indexedLoopTop)
Add faces from loops.
addFacesByConvexLoops(faces, indexedLoops)
Add faces from loops.
addFacesByConvexReversed(faces, indexedLoop)
Add faces from a reversed convex polygon.
addFacesByGrid(faces, grid)
Add faces from grid.
addFacesByLoop(faces, indexedLoop)
Add faces from a polygon which may be concave.
addFacesByLoopReversed(faces, indexedLoop)
Add faces from a reversed convex polygon.
addFacesByMeldedConvexLoops(faces, indexedLoops)
Add faces from melded loops.
addLoopToPointTable(loop, pointTable)
Add the points in the loop to the point table.
addMeldedPillarByLoops(faces, indexedLoops)
Add melded pillar by loops which may be concave.
addPillarByLoops(faces, indexedLoops)
Add pillar by loops which may be concave.
addPillarFromConvexLoopsGridTop(faces, indexedGridTop, indexedLoops)
Add pillar from convex loops and grid top.
addPillarFromConvexLoopsGrids(faces, indexedGrids, indexedLoops)
Add pillar from convex loops and grids.
addPointsAtZ(edgePair, points, radius, vertexes, z)
Add point complexes on the segment between the edge intersections with z.
addSymmetricXPath(outputs, path, x)
Add x path output to outputs.
addSymmetricXPaths(outputs, paths, x)
Add x paths outputs to outputs.
addSymmetricYPath(outputs, path, y)
Add y path output to outputs.
addSymmetricYPaths(outputs, paths, y)
Add y paths outputs to outputs.
addWithLeastLength(importRadius, loops, point)
Insert a point into a loop, at the index at which the loop would be shortest.
convertElementNode(elementNode, geometryOutput)
Convert the xml element to a TriangleMesh xml element.
getAddIndexedGrid(grid, vertexes, z)
Get and add an indexed grid.
getAddIndexedLoop(loop, vertexes, z)
Get and add an indexed loop.
getAddIndexedLoops(loop, vertexes, zList)
Get and add indexed loops.
getAdditionalLoopLength(loop, point, pointIndex)
Get the additional length added by inserting a point into a loop.
getCarveIntersectionFromEdge(edge, vertexes, z)
Get the complex where the carve intersects the edge.
getClosestDistanceIndexToPoint(point, loop)
Get the distance squared to the closest point of the loop and index of that point.
getDescendingAreaLoops(allPoints, corners, importRadius)
Get descending area loops which include most of the points.
getDescendingAreaOrientedLoops(allPoints, corners, importRadius)
Get descending area oriented loops which include most of the points.
getGeometryOutputByFacesVertexes(faces, vertexes)
Get geometry output dictionary by faces and vertexes.
getGeometryOutputCopy(object)
Get the geometry output copy.
getIndexedCellLoopsFromIndexedGrid(grid)
Get indexed cell loops from an indexed grid.
getIndexedLoopFromIndexedGrid(indexedGrid)
Get indexed loop from around the indexed grid.
getInfillDictionary(aroundInset, arounds, aroundWidth, infillInset, infillWidth, pixelTable, rotatedLoops, testLoops=None)
Get combined fill loops which include most of the points.
getInsetPoint(loop, tinyRadius)
Get the inset vertex.
getIsPathEntirelyOutsideTriangle(begin, center, end, vector3Path)
Determine if a path is entirely outside another loop.
getIsPointCloseInline(close, loop, point, pointIndex)
Insert a point into a loop, at the index at which the loop would be shortest.
getLoopLayerAppend(loopLayers, z)
Get next z and add extruder loops.
getLoopsFromCorrectMesh(edges, faces, vertexes, z)
Get loops from a carve of a correct mesh.
getLoopsFromUnprovenMesh(edges, faces, importRadius, vertexes, z)
Get loops from a carve of an unproven mesh.
getLoopsWithCorners(corners, importRadius, loops, pointTable)
Add corners to the loops.
getMeldedPillarOutput(loops)
Get melded pillar output.
getNewDerivation(elementNode)
Get new derivation.
getNextEdgeIndexAroundZ(edge, faces, remainingEdgeTable)
Get the next edge index in the mesh carve.
getOrientedLoops(loops)
Orient the loops which must be in descending order.
getOverlapRatio(loop, pointTable)
Get the overlap ratio between the loop and the point table.
getPath(edges, pathIndexes, loop, z)
Get the path from the edge intersections.
getPillarOutput(loops)
Get pillar output.
getPillarsOutput(loopLists)
Get pillars output.
getRemainingEdgeTable(edges, vertexes, z)
Get the remaining edge hashtable.
getRemainingLoopAddFace(faces, remainingLoop)
Get the remaining loop and add face.
getSharedFace(firstEdge, faces, secondEdge)
Get the face which is shared by two edges.
getSymmetricXLoop(path, vertexes, x)
Get symmetrix x loop.
getSymmetricYLoop(path, vertexes, y)
Get symmetrix y loop.
getUnifiedOutput(outputs)
Get unified output.
getUniqueVertexes(loops)
Get unique vertexes.
getWideAnglePointIndex(loop)
Get a point index which has a wide enough angle, most point indexes have a wide enough angle, this is just to make sure.
isInline(beginComplex, centerComplex, endComplex)
Determine if the three complex points form a line.
isPathAdded(edges, faces, loops, remainingEdgeTable, vertexes, z)
Get the path indexes around a triangle mesh carve and add the path to the flat loops.
processElementNode(elementNode)
Process the xml element.
setEdgeMaximumMinimum(edge, vertexes)
Set the edge maximum and minimum.
sortLoopsInOrderOfArea(isDescending, loops)
Sort the loops in the order of area according isDescending.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.solids.union.html000066400000000000000000000310471167321211700274470ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.solids.union
 
 
fabmetheus_utilities.geometry.solids.union ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/solids/union.py

Boolean geometry union of solids.

 
Modules
       
__init__
fabmetheus_utilities.geometry.solids.difference
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.solids.group

 
Classes
       
fabmetheus_utilities.geometry.solids.difference.Difference(fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid)
Union

 
class Union(fabmetheus_utilities.geometry.solids.difference.Difference)
    A difference object.
 
 
Method resolution order:
Union
fabmetheus_utilities.geometry.solids.difference.Difference
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid
fabmetheus_utilities.geometry.solids.group.Group
fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary

Methods defined here:
getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList)
Get loops from visible object loops list.

Methods inherited from fabmetheus_utilities.geometry.solids.difference.Difference:
getXMLLocalName(self)
Get xml class name.

Methods inherited from fabmetheus_utilities.geometry.geometry_utilities.boolean_solid.BooleanSolid:
getDifference(self, importRadius, visibleObjectLoopsList)
Get subtracted loops sliced through shape.
getIntersection(self, importRadius, visibleObjectLoopsList)
Get intersected loops sliced through shape.
getLoops(self, importRadius, z)
Get loops sliced through shape.
getTransformedPaths(self)
Get all transformed paths.
getUnion(self, importRadius, visibleObjectLoopsList)
Get joined loops sliced through shape.

Methods inherited from fabmetheus_utilities.geometry.solids.group.Group:
__init__(self)
Add empty lists.
addXMLInnerSection(self, depth, output)
Add xml inner section for this object.
addXMLSection(self, depth, output)
Add the xml section for this object.
getMatrix4X4(self)
Get the matrix4X4.
getMatrixChainTetragrid(self)
Get the matrix chain tetragrid.
getVisible(self)
Get visible.
setToElementNode(self, elementNode)
Set to elementNode.

Methods inherited from fabmetheus_utilities.geometry.geometry_tools.dictionary.Dictionary:
__repr__(self)
Get the string representation of this object info.
addXML(self, depth, output)
Add xml for this object.
addXMLArchivableObjects(self, depth, output)
Add xml for this object.
createShape(self)
Create the shape.
getAttributes(self)
Get attribute table.
getComplexTransformedPathLists(self)
Get complex transformed path lists.
getFabricationExtension(self)
Get fabrication extension.
getFabricationText(self, addLayerTemplate)
Get fabrication text.
getGeometryOutput(self)
Get geometry output dictionary.
getMinimumZ(self)
Get the minimum z.
getPaths(self)
Get all paths.
getTransformedVertexes(self)
Get all transformed vertexes.
getTriangleMeshes(self)
Get all triangleMeshes.
getType(self)
Get type.
getVertexes(self)
Get all vertexes.
transformGeometryOutput(self, geometryOutput)
Transform the geometry output by the local matrix4x4.

 
Functions
       
convertElementNode(elementNode, geometryOutput)
Convert the xml element to a union xml element.
getNewDerivation(elementNode)
Get new derivation.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements._print.html000066400000000000000000000110521167321211700304760ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.statements._print
 
 
fabmetheus_utilities.geometry.statements._print ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/_print.py

Print statement.

There is also the print attribute in geometry_utilities/evaluate_fundamentals/print.py

The model is xml_models/geometry_utilities/evaluate_fundamentals/print.xml

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate

 
Functions
       
getLocalDictionary(attributesKey, elementNode)
Get the local dictionary.
printAttributesKey(attributesKey, elementNode)
Print the attributesKey.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements.class.html000066400000000000000000000076031167321211700303170ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.statements.class
 
 
fabmetheus_utilities.geometry.statements.class ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/class.py

Class.

 
Modules
       
__init__

 
Functions
       
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements.elif.html000066400000000000000000000102451167321211700301250ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.statements.elif
 
 
fabmetheus_utilities.geometry.statements.elif ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/elif.py

Polygon path.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate

 
Functions
       
processElementNode(elementNode)
Process the xml element.
processElse(elementNode)
Process the else statement.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements.else.html000066400000000000000000000102451167321211700301360ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.statements.else
 
 
fabmetheus_utilities.geometry.statements.else ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/else.py

Polygon path.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate

 
Functions
       
processElementNode(elementNode)
Process the xml element.
processElse(elementNode)
Process the else statement.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements.for.html000066400000000000000000000127051167321211700277770ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.statements.for
 
 
fabmetheus_utilities.geometry.statements.for ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/for.py

Polygon path.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate

 
Classes
       
IndexValue

 
class IndexValue
    Class to get the in attribute, the index name and the value name.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.

 
Functions
       
processChildNodesByIndexValue(elementNode, function, index, indexValue, value)
Process childNodes by index value.
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements.function.html000066400000000000000000000076261167321211700310440ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.statements.function
 
 
fabmetheus_utilities.geometry.statements.function ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/function.py

Polygon path.

 
Modules
       
__init__

 
Functions
       
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements.html000066400000000000000000000057401167321211700272130ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry.statements
 
 
fabmetheus_utilities.geometry.statements
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
_print
class
elif
else
for
function
if
return
statement
while

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements.if.html000066400000000000000000000100111167321211700275730ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.statements.if
 
 
fabmetheus_utilities.geometry.statements.if ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/if.py

Polygon path.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate

 
Functions
       
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements.return.html000066400000000000000000000100311167321211700305160ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.statements.return
 
 
fabmetheus_utilities.geometry.statements.return ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/return.py

Polygon path.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate

 
Functions
       
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements.statement.html000066400000000000000000000100451167321211700312100ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.statements.statement
 
 
fabmetheus_utilities.geometry.statements.statement ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/statement.py

Polygon path.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate

 
Functions
       
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry.statements.while.html000066400000000000000000000100251167321211700303120ustar00rootroot00000000000000 Python: module fabmetheus_utilities.geometry.statements.while
 
 
fabmetheus_utilities.geometry.statements.while ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry/statements/while.py

Polygon path.

 
Modules
       
__init__
fabmetheus_utilities.geometry.geometry_utilities.evaluate

 
Functions
       
processElementNode(elementNode)
Process the xml element.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry_plugins.creation.html000066400000000000000000000044041167321211700303650ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry_plugins.creation
 
 
fabmetheus_utilities.geometry_plugins.creation
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry_plugins/creation/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry_plugins.html000066400000000000000000000054071167321211700265660ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry_plugins
 
 
fabmetheus_utilities.geometry_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry_plugins/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
creation (package)
manipulation_matrix (package)
manipulation_meta (package)
manipulation_paths (package)
manipulation_shapes (package)

 
Data
        level = 2
numberOfLevelsDeepInPackageHierarchy = 2
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry_plugins.manipulation_matrix.html000066400000000000000000000044601167321211700326470ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry_plugins.manipulation_matrix
 
 
fabmetheus_utilities.geometry_plugins.manipulation_matrix
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry_plugins/manipulation_matrix/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry_plugins.manipulation_meta.html000066400000000000000000000044501167321211700322700ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry_plugins.manipulation_meta
 
 
fabmetheus_utilities.geometry_plugins.manipulation_meta
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry_plugins/manipulation_meta/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry_plugins.manipulation_paths.html000066400000000000000000000044541167321211700324650ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry_plugins.manipulation_paths
 
 
fabmetheus_utilities.geometry_plugins.manipulation_paths
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry_plugins/manipulation_paths/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.geometry_plugins.manipulation_shapes.html000066400000000000000000000044601167321211700326260ustar00rootroot00000000000000 Python: package fabmetheus_utilities.geometry_plugins.manipulation_shapes
 
 
fabmetheus_utilities.geometry_plugins.manipulation_shapes
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/geometry_plugins/manipulation_shapes/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.hidden_scrollbar.html000066400000000000000000000053121167321211700264630ustar00rootroot00000000000000 Python: module fabmetheus_utilities.hidden_scrollbar
 
 
fabmetheus_utilities.hidden_scrollbar ($Date: 2008/23/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/hidden_scrollbar.py

Hidden scrollbar is in its own file so that even if Tkinter is not installed, settings can still be imported.

 
Modules
       
__init__

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/23/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/fabmetheus_utilities.html000066400000000000000000000067151167321211700231760ustar00rootroot00000000000000 Python: package fabmetheus_utilities
 
 
fabmetheus_utilities
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/__init__.py

Previous / Next / Contents


This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.


Previous / Next / Contents


 
Package Contents
       
archive
euclidean
fabmetheus_tools (package)
gcodec
geometry (package)
geometry_plugins (package)
hidden_scrollbar
intercircle
settings
svg_reader
svg_writer
vector3
vector3index
xml_simple_reader
xml_simple_writer

 
Data
        level = 1
numberOfLevelsDeepInPackageHierarchy = 1
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/fabmetheus_utilities.intercircle.html000066400000000000000000000532201167321211700254710ustar00rootroot00000000000000 Python: module fabmetheus_utilities.intercircle
 
 
fabmetheus_utilities.intercircle ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/intercircle.py

Intercircle is a collection of utilities for intersecting circles, used to get smooth loops around a collection of points and inset & outset loops.

 
Modules
       
__init__
fabmetheus_utilities.euclidean
math

 
Classes
       
BoundingLoop
CenterOutset
CircleIntersection
CircleNode

 
class BoundingLoop
    A class to hold a bounding loop composed of a minimum complex, a maximum complex and an outset loop.
 
  Methods defined here:
__eq__(self, other)
Determine whether this bounding loop is identical to other one.
__repr__(self)
Get the string representation of this bounding loop.
getFromLoop(self, loop)
Get the bounding loop from a path.
getOutsetBoundingLoop(self, outsetDistance)
Outset the bounding rectangle and loop by a distance.
isEntirelyInsideAnother(self, anotherBoundingLoop)
Determine if this bounding loop is entirely inside another bounding loop.
isOverlappingAnother(self, anotherBoundingLoop)
Determine if this bounding loop is intersecting another bounding loop.
isOverlappingAnotherInList(self, boundingLoops)
Determine if this bounding loop is intersecting another bounding loop in a list.
isRectangleMissingAnother(self, anotherBoundingLoop)
Determine if the rectangle of this bounding loop is missing the rectangle of another bounding loop.

 
class CenterOutset
    A class to hold a center and an outset.
 
  Methods defined here:
__init__(self, center, outset)
Set the center and outset.
__repr__(self)
Get the string representation of this CenterOutset.

 
class CircleIntersection
    An intersection of two complex circles.
 
  Methods defined here:
__init__(self, circleNodeAhead, index, circleNodeBehind)
__repr__(self)
Get the string representation of this CircleIntersection.
addToList(self, circleIntersectionPath)
Add this to the circle intersection path, setting stepped on to be true.
getAbsolutePosition(self)
Get the absolute position.
getCircleIntersectionAhead(self)
Get the first circle intersection on the circle node ahead.
isWithinCircles(self, pixelTable)
Determine if this circle intersection is within the circle node circles.

 
class CircleNode
    A complex node of complex circle intersections.
 
  Methods defined here:
__init__(self, oneOverRadius, point)
__repr__(self)
Get the string representation of this CircleNode.
getWithinNodes(self, pixelTable)
Get the nodes this circle node is within.

 
Functions
       
addCircleIntersectionLoop(circleIntersectionLoop, circleIntersections)
Add a circle intersection loop.
addEndCap(begin, end, points, radius)
Get circular end cap.
addHalfPath(path, points, radius, thresholdRatio=0.9)
Add the points from every point on a half path and between points.
addInsetPointFromClockwiseTriple(begin, center, end, loop, radius)
Get inset point with possible intersection from clockwise triple, out from widdershins loop.
addOrbits(distanceFeedRate, loop, orbitalFeedRatePerSecond, temperatureChangeTime, z)
Add orbits with the extruder off.
addOrbitsIfLarge(distanceFeedRate, loop, orbitalFeedRatePerSecond, temperatureChangeTime, z)
Add orbits with the extruder off if the orbits are large enough.
addPointsFromSegment(pointBegin, pointEnd, points, radius, thresholdRatio=0.9)
Add point complexes between the endpoints of a segment.
directLoop(isWiddershins, loop)
Direct the loop.
directLoopLists(isWiddershins, loopLists)
Direct the loop lists.
directLoops(isWiddershins, loops)
Direct the loops.
getAroundsFromLoop(loop, radius, thresholdRatio=0.9)
Get the arounds from the loop.
getAroundsFromLoops(loops, radius, thresholdRatio=0.9)
Get the arounds from the loops.
getAroundsFromPath(path, radius, thresholdRatio=0.9)
Get the arounds from the path.
getAroundsFromPathPoints(points, radius, thresholdRatio=0.9)
Get the arounds from the path.
getAroundsFromPaths(paths, radius, thresholdRatio=0.9)
Get the arounds from the path.
getAroundsFromPoints(points, radius)
Get the arounds from the points.
getCentersFromCircleNodes(circleNodes, radius)
Get the complex centers of the circle intersection loops from circle nodes.
getCentersFromIntersectionLoop(circleIntersectionLoop, radius)
Get the centers from the intersection loop.
getCentersFromIntersectionLoops(circleIntersectionLoops, radius)
Get the centers from the intersection loops.
getCentersFromLoop(loop, radius)
Get the centers of the loop.
getCentersFromLoopDirection(isWiddershins, loop, radius)
Get the centers of the loop which go around in the given direction.
getCentersFromPoints(points, radius)
Get the centers from the points.
getCircleIntersectionLoops(circleIntersections)
Get all the loops going through the circle intersections.
getCircleIntersectionsFromCircleNodes(circleNodes)
Get all the circle intersections which exist between all the circle nodes.
getCircleNodesFromLoop(loop, radius, thresholdRatio=0.9)
Get the circle nodes from every point on a loop and between points.
getCircleNodesFromPoints(points, radius)
Get the circle nodes from a path.
getInsetLoopsFromLoop(loop, radius, thresholdRatio=0.9)
Get the inset loops, which might overlap.
getInsetLoopsFromLoops(loops, radius)
Get the inset loops, which might overlap.
getInsetLoopsFromVector3Loop(loop, radius, thresholdRatio=0.9)
Get the inset loops from vector3 loop, which might overlap.
getInsetSeparateLoopsFromAroundLoops(loops, radius, radiusAround, thresholdRatio=0.9)
Get the separate inset loops.
getInsetSeparateLoopsFromLoops(loops, radius, thresholdRatio=0.9)
Get the separate inset loops.
getIsLarge(loop, radius)
Determine if the loop is large enough.
getLargestCenterOutsetLoopFromLoop(loop, radius, thresholdRatio=0.9)
Get the largest circle outset loop from the loop.
getLargestCenterOutsetLoopFromLoopRegardless(loop, radius)
Get the largest circle outset loop from the loop, even if the radius has to be shrunk and even if there is still no outset loop.
getLargestInsetLoopFromLoop(loop, radius)
Get the largest inset loop from the loop.
getLargestInsetLoopFromLoopRegardless(loop, radius)
Get the largest inset loop from the loop, even if the radius has to be shrunk and even if there is still no inset loop.
getLoopsFromLoopsDirection(isWiddershins, loops)
Get the loops going round in a given direction.
getPointsFromLoop(loop, radius, thresholdRatio=0.9)
Get the points from every point on a loop and between points.
getPointsFromLoops(loops, radius, thresholdRatio=0.9)
Get the points from every point on a loop and between points.
getPointsFromPath(path, radius, thresholdRatio=0.9)
Get the points from every point on a path and between points.
getSimplifiedInsetFromClockwiseLoop(loop, radius)
Get loop inset from clockwise loop, out from widdershins loop.
getWiddershinsByLength(begin, end, length)
Get the widdershins by length.
getWithoutIntersections(loop)
Get loop without intersections.
isLargeSameDirection(inset, loop, radius)
Determine if the inset is in the same direction as the loop and it is large enough.
isLoopIntersectingLoop(anotherLoop, loop)
Determine if the a loop is intersecting another loop.
orbitsAreLarge(loop, temperatureChangeTime)
Determine if the orbits are large enough.
removeIntersection(loop)
Get loop without the first intersection.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalDecreasingRadiusMultipliers = [1.0, 0.55, 0.35, 0.2]
globalIntercircleMultiplier = 1.04

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/fabmetheus_utilities.settings.html000066400000000000000000004554711167321211700250440ustar00rootroot00000000000000 Python: module fabmetheus_utilities.settings
 
 
fabmetheus_utilities.settings ($Date: 2008/23/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/settings.py

Settings is a collection of utilities to display, read & write the settings and position widgets.

 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
math
os
shutil
sys
traceback
webbrowser

 
Classes
       
CloseListener
DisplayToolButton
FileHelpMenuBar
FrameList
GridHorizontal
GridVertical
HelpPage
HelpPageRepository
LabelDisplay
LabelHelp
LabelSeparator
LatentStringVar
LayerCount
MenuButtonDisplay
PluginFrame
PluginGroupFrame
RepositoryDialog
StringSetting
BooleanSetting
MenuRadio
Radio
RadioCapitalized
RadioPlugin
RadioCapitalizedButton
FileNameInput
FloatSetting
FloatSpin
FloatSpinNotOnMenu
FloatSpinUpdate
IntSpin
IntSpinNotOnMenu
IntSpinUpdate
IntSetting
TextSetting
WindowPosition
TokenConversion
ToolDialog

 
class BooleanSetting(StringSetting)
    A class to display, read & write a boolean.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Add this to the repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
setStateToValue(self)
Set the checkbutton to the boolean.
setToDisplay(self)
Do nothing because toggleCheckbutton is handling the value.
setValueToString(self, valueString)
Set the boolean to the string.
toggleCheckbutton(self)
Workaround for Tkinter bug, toggle the value.
toggleMenuCheckbutton(self)
Workaround for Tkinter bug, toggle the value.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class CloseListener
    A class to listen to link a window to the global repository dialog list table.
 
  Methods defined here:
__init__(self, window, closeFunction=None)
Add the window to the global repository dialog list table.
listenToWidget(self, widget)
Listen to the destroy message of the widget.
wasClosed(self, event)
The dialog was closed.

 
class DisplayToolButton
    A class to display the tool dialog button, in a two column wide table.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
displayDialog(self)
Display function.
getFromPath(self, important, name, path, repository)
Initialize.

 
class FileHelpMenuBar
     Methods defined here:
__init__(self, root)
Create a menu bar with a file and help menu.
addMenuToMenuBar(self, labelText, menu)
Add a menu to the menu bar.
addPluginToMenuBar(self, modulePath, repository, window)
Add a menu to the menu bar from a tool.
completeMenu(self, closeFunction, repository, saveFunction, window)
Complete the menu.
saveClose(self)
Call the save function then the close function.

 
class FileNameInput(StringSetting)
    A class to display, read & write a fileName.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
execute(self)
Open the file picker.
getFileNameFirstTypes(self)
Get the file types with the file type of the fileName moved to the front of the list.
getFromFileName(self, fileTypes, name, repository, value)
Initialize.
setCancelledValue(self, fileName)
Set the value to the file name and wasCancelled true if a file was not picked.
setToDisplay(self)
Do nothing because the file dialog is handling the value.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setStateToValue(self)
Set the entry to the value.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
setValueToString(self, valueString)
Set the value to the value string.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class FloatSetting(StringSetting)
    A class to display, read & write a float.
 
  Methods defined here:
setValueToString(self, valueString)
Set the float to the string.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setStateToValue(self)
Set the entry to the value.
setToDisplay(self)
Set the string to the entry field.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class FloatSpin(FloatSetting)
    A class to display, read & write an float in a spin box.
 
 
Method resolution order:
FloatSpin
FloatSetting
StringSetting

Methods defined here:
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
decrease(self)
Decrease the value then set the state and color to the value.
entryUpdated(self, event=None)
Create the entry.
getFromValue(self, from_, name, repository, to, value)
Initialize.
increase(self)
Increase the value then set the state and color to the value.
setColor(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setColorToDisplay(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setStateToValue(self)
Set the entry to the value.
setStateUpdateColor(self)
Set the state to the value, call the update function, then set the color.

Methods inherited from FloatSetting:
setValueToString(self, valueString)
Set the float to the string.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setToDisplay(self)
Set the string to the entry field.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class FloatSpinNotOnMenu(FloatSpin)
    A class to display, read & write an float in a spin box, which is not to be added to a menu.
 
 
Method resolution order:
FloatSpinNotOnMenu
FloatSpin
FloatSetting
StringSetting

Methods defined here:
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.

Methods inherited from FloatSpin:
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
decrease(self)
Decrease the value then set the state and color to the value.
entryUpdated(self, event=None)
Create the entry.
getFromValue(self, from_, name, repository, to, value)
Initialize.
increase(self)
Increase the value then set the state and color to the value.
setColor(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setColorToDisplay(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setStateToValue(self)
Set the entry to the value.
setStateUpdateColor(self)
Set the state to the value, call the update function, then set the color.

Methods inherited from FloatSetting:
setValueToString(self, valueString)
Set the float to the string.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
getFromValueOnly(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setToDisplay(self)
Set the string to the entry field.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class FloatSpinUpdate(FloatSpin)
    A class to display, read, update & write an float in a spin box.
 
 
Method resolution order:
FloatSpinUpdate
FloatSpin
FloatSetting
StringSetting

Methods defined here:
createEntry(self, root)
Create the entry.

Methods inherited from FloatSpin:
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
bindEntry(self)
Bind the entry to the update function.
decrease(self)
Decrease the value then set the state and color to the value.
entryUpdated(self, event=None)
Create the entry.
getFromValue(self, from_, name, repository, to, value)
Initialize.
increase(self)
Increase the value then set the state and color to the value.
setColor(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setColorToDisplay(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setStateToValue(self)
Set the entry to the value.
setStateUpdateColor(self)
Set the state to the value, call the update function, then set the color.

Methods inherited from FloatSetting:
setValueToString(self, valueString)
Set the float to the string.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setToDisplay(self)
Set the string to the entry field.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class FrameList
    A class to list the frames.
 
  Methods defined here:
addToList(self, word)
Add the word to the sorted list.
getFromValue(self, name, repository, value)
Initialize.
removeFromList(self, word)
Remove the word from the sorted list.
setToDisplay(self)
Do nothing because frame list does not have a display.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second and later words of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and list to the repository writer.

 
class GridHorizontal
    A class to place elements horizontally on a grid.
 
  Methods defined here:
__init__(self, column, row)
Initialize the column and row.
getCopy(self)
Get a copy.
increment(self)
Increment the position horizontally.

 
class GridVertical
    A class to place elements vertically on a grid.
 
  Methods defined here:
__init__(self, column, row)
Initialize the column and row.
execute(self)
The execute button was clicked.
getCopy(self)
Get a copy.
increment(self)
Increment the position vertically.
incrementGivenNumberOfColumns(self, numberOfColumns)
Increment the position vertically and offset it horizontally by the given number of columns.
setExecutablesRepository(self, repository)
Set the executables to an empty list and set the repository.

 
class HelpPage
    A class to open a help page.
 
  Methods defined here:
__init__(self)
Initialize column.
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Add this to the repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
getFromNameAfterHTTP(self, afterHTTP, name, repository)
Initialize.
getFromNameAfterWWW(self, afterWWW, name, repository)
Initialize.
getFromNameSubName(self, name, repository, subName='')
Initialize.
getOpenFromAbsolute(self, hypertextAddress)
Get the open help page function from the hypertext address.
getOpenFromAfterHTTP(self, afterHTTP)
Get the open help page function from the part of the address after the HTTP.
getOpenFromAfterWWW(self, afterWWW)
Get the open help page function from the afterWWW of the address after the www.
getOpenFromDocumentationSubName(self, subName='')
Get the open help page function from the afterWWW of the address after the www.
openPage(self, event=None)
Open the browser to the hypertext address.
setToNameRepository(self, name, repository)
Set to the name and repository.

 
class HelpPageRepository
    A class to open a repository help page.
 
  Methods defined here:
__init__(self, repository)
Add this to the dialog.
openPage(self, event=None)
Open the browser to the repository help page.

 
class IntSetting(FloatSetting)
    A class to display, read & write an int.
 
 
Method resolution order:
IntSetting
FloatSetting
StringSetting

Methods defined here:
setValueToString(self, valueString)
Set the integer to the string.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setStateToValue(self)
Set the entry to the value.
setToDisplay(self)
Set the string to the entry field.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class IntSpin(FloatSpin)
    A class to display, read & write an int in a spin box.
 
 
Method resolution order:
IntSpin
FloatSpin
FloatSetting
StringSetting

Methods defined here:
getFromValue(self, from_, name, repository, to, value)
Initialize.
getSingleIncrementFromValue(self, from_, name, repository, to, value)
Initialize.
setValueToString(self, valueString)
Set the integer to the string.

Methods inherited from FloatSpin:
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
decrease(self)
Decrease the value then set the state and color to the value.
entryUpdated(self, event=None)
Create the entry.
increase(self)
Increase the value then set the state and color to the value.
setColor(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setColorToDisplay(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setStateToValue(self)
Set the entry to the value.
setStateUpdateColor(self)
Set the state to the value, call the update function, then set the color.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setToDisplay(self)
Set the string to the entry field.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class IntSpinNotOnMenu(IntSpin)
    A class to display, read & write an integer in a spin box, which is not to be added to a menu.
 
 
Method resolution order:
IntSpinNotOnMenu
IntSpin
FloatSpin
FloatSetting
StringSetting

Methods defined here:
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.

Methods inherited from IntSpin:
getFromValue(self, from_, name, repository, to, value)
Initialize.
getSingleIncrementFromValue(self, from_, name, repository, to, value)
Initialize.
setValueToString(self, valueString)
Set the integer to the string.

Methods inherited from FloatSpin:
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
decrease(self)
Decrease the value then set the state and color to the value.
entryUpdated(self, event=None)
Create the entry.
increase(self)
Increase the value then set the state and color to the value.
setColor(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setColorToDisplay(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setStateToValue(self)
Set the entry to the value.
setStateUpdateColor(self)
Set the state to the value, call the update function, then set the color.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
getFromValueOnly(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setToDisplay(self)
Set the string to the entry field.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class IntSpinUpdate(IntSpin)
    A class to display, read, update & write an int in a spin box.
 
 
Method resolution order:
IntSpinUpdate
IntSpin
FloatSpin
FloatSetting
StringSetting

Methods defined here:
createEntry(self, root)
Create the entry.

Methods inherited from IntSpin:
getFromValue(self, from_, name, repository, to, value)
Initialize.
getSingleIncrementFromValue(self, from_, name, repository, to, value)
Initialize.
setValueToString(self, valueString)
Set the integer to the string.

Methods inherited from FloatSpin:
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
bindEntry(self)
Bind the entry to the update function.
decrease(self)
Decrease the value then set the state and color to the value.
entryUpdated(self, event=None)
Create the entry.
increase(self)
Increase the value then set the state and color to the value.
setColor(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setColorToDisplay(self, event=None)
Set the color to the value, yellow if it is lower than the default and blue if it is higher.
setStateToValue(self)
Set the entry to the value.
setStateUpdateColor(self)
Set the state to the value, call the update function, then set the color.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setToDisplay(self)
Set the string to the entry field.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class LabelDisplay
    A class to add a label.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
getFromName(self, name, repository)
Initialize.

 
class LabelHelp
    A class to add help to a widget.
 
  Methods defined here:
__init__(self, fileNameHelp, master, name, widget)
Add menu to the widget.
displayPopupMenu(self, event=None)
Display the popup menu when the button is right clicked.
unpostPopupMenu(self, event=None)
Unpost the popup menu.

 
class LabelSeparator
    A class to add a label and menu separator.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Add this to the repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
getFromRepository(self, repository)
Initialize.

 
class LatentStringVar
    A class to provide a StringVar when needed.
 
  Methods defined here:
__init__(self)
Set the string var.
getString(self)
Get the string.
getVar(self)
Get the string var.
setString(self, word)
Set the string.

 
class LayerCount
    A class to handle the layerIndex.
 
  Methods defined here:
__init__(self)
Initialize.
__repr__(self)
Get the string representation of this LayerCount.
printProgressIncrement(self, procedureName)
Print progress then increment layerIndex.

 
class MenuButtonDisplay
    A class to add a menu button.
 
  Methods defined here:
addRadiosToDialog(self, gridPosition)
Add the menu radios to the dialog.
addToMenu(self, repositoryMenu)
Add this to the repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
getFromName(self, name, repository)
Initialize.
removeMenus(self)
Remove all menus.
setRadioVarToName(self, name)
Get the menu button.
setToNameAddToDialog(self, name, gridPosition)
Get the menu button.

 
class MenuRadio(BooleanSetting)
    A class to display, read & write a boolean with associated menu radio button.
 
 
Method resolution order:
MenuRadio
BooleanSetting
StringSetting

Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Add this to the submenu set by MenuButtonDisplay, the repository menu is ignored
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
addToSubmenu(self)
Add this to the submenu.
clickRadio(self)
Workaround for Tkinter bug, invoke and set the value when clicked.
getFromMenuButtonDisplay(self, menuButtonDisplay, name, repository, value)
Initialize.
invoke(self)
Workaround for Tkinter bug, invoke to set the value when changed.
setStateToValue(self)
Set the checkbutton to the boolean.
setToDisplay(self)
Set the boolean to the checkbutton.

Methods inherited from BooleanSetting:
setValueToString(self, valueString)
Set the boolean to the string.
toggleCheckbutton(self)
Workaround for Tkinter bug, toggle the value.
toggleMenuCheckbutton(self)
Workaround for Tkinter bug, toggle the value.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class PluginFrame
    A class to display the plugins in a frame.
 
  Methods defined here:
__init__(self)
Initialize.
addToDialog(self, gridPosition)
Add this to the dialog.
createFrame(self, gridPosition)
Create the frame.
focusSetMaster(self, gridPosition)
Set the focus to the plugin master.
getFromPath(self, defaultRadioButton, directoryPath, repository)
Initialize.
setStateToValue(self)
Set the state of all the plugins to the value.
setToDisplay(self)
Set the plugins to the display.
update(self)
Update the frame.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class PluginGroupFrame(PluginFrame)
    A class to display the plugin groups in a frame.
 
  Methods defined here:
createFrame(self, gridPosition)
Create the frame.
focusSetMaster(self, gridPosition)
Set the focus to the plugin master.

Methods inherited from PluginFrame:
__init__(self)
Initialize.
addToDialog(self, gridPosition)
Add this to the dialog.
getFromPath(self, defaultRadioButton, directoryPath, repository)
Initialize.
setStateToValue(self)
Set the state of all the plugins to the value.
setToDisplay(self)
Set the plugins to the display.
update(self)
Update the frame.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class Radio(BooleanSetting)
    A class to display, read & write a boolean with associated radio button.
 
 
Method resolution order:
Radio
BooleanSetting
StringSetting

Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
clickRadio(self)
Workaround for Tkinter bug, set the value.
createRadioButton(self, gridPosition)
Create the radio button.
getFromRadio(self, latentStringVar, name, repository, value)
Initialize.
setSelect(self)
Set the int var and select the radio button.
setStateToValue(self)
Set the checkbutton to the boolean.
setToDisplay(self)
Set the boolean to the checkbutton.

Methods inherited from BooleanSetting:
addToMenu(self, repositoryMenu)
Add this to the repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
setValueToString(self, valueString)
Set the boolean to the string.
toggleCheckbutton(self)
Workaround for Tkinter bug, toggle the value.
toggleMenuCheckbutton(self)
Workaround for Tkinter bug, toggle the value.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class RadioCapitalized(Radio)
    A class to display, read & write a boolean with associated radio button.
 
 
Method resolution order:
RadioCapitalized
Radio
BooleanSetting
StringSetting

Methods defined here:
createRadioButton(self, gridPosition)
Create the radio button.

Methods inherited from Radio:
addToDialog(self, gridPosition)
Add this to the dialog.
clickRadio(self)
Workaround for Tkinter bug, set the value.
getFromRadio(self, latentStringVar, name, repository, value)
Initialize.
setSelect(self)
Set the int var and select the radio button.
setStateToValue(self)
Set the checkbutton to the boolean.
setToDisplay(self)
Set the boolean to the checkbutton.

Methods inherited from BooleanSetting:
addToMenu(self, repositoryMenu)
Add this to the repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
setValueToString(self, valueString)
Set the boolean to the string.
toggleCheckbutton(self)
Workaround for Tkinter bug, toggle the value.
toggleMenuCheckbutton(self)
Workaround for Tkinter bug, toggle the value.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class RadioCapitalizedButton(Radio)
    A class to display, read & write a boolean with associated radio button.
 
 
Method resolution order:
RadioCapitalizedButton
Radio
BooleanSetting
StringSetting

Methods defined here:
createRadioButton(self, gridPosition)
Create the radio button.
displayDialog(self)
Display function.
getFromPath(self, latentStringVar, name, path, repository, value)
Initialize.

Methods inherited from Radio:
addToDialog(self, gridPosition)
Add this to the dialog.
clickRadio(self)
Workaround for Tkinter bug, set the value.
getFromRadio(self, latentStringVar, name, repository, value)
Initialize.
setSelect(self)
Set the int var and select the radio button.
setStateToValue(self)
Set the checkbutton to the boolean.
setToDisplay(self)
Set the boolean to the checkbutton.

Methods inherited from BooleanSetting:
addToMenu(self, repositoryMenu)
Add this to the repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
setValueToString(self, valueString)
Set the boolean to the string.
toggleCheckbutton(self)
Workaround for Tkinter bug, toggle the value.
toggleMenuCheckbutton(self)
Workaround for Tkinter bug, toggle the value.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class RadioPlugin(RadioCapitalized)
    A class to display, read & write a boolean with associated radio button.
 
 
Method resolution order:
RadioPlugin
RadioCapitalized
Radio
BooleanSetting
StringSetting

Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
getFromRadio(self, important, latentStringVar, name, repository, value)
Initialize.
incrementGridPosition(self, gridPosition)
Increment the grid position.

Methods inherited from RadioCapitalized:
createRadioButton(self, gridPosition)
Create the radio button.

Methods inherited from Radio:
clickRadio(self)
Workaround for Tkinter bug, set the value.
setSelect(self)
Set the int var and select the radio button.
setStateToValue(self)
Set the checkbutton to the boolean.
setToDisplay(self)
Set the boolean to the checkbutton.

Methods inherited from BooleanSetting:
addToMenu(self, repositoryMenu)
Add this to the repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
setValueToString(self, valueString)
Set the boolean to the string.
toggleCheckbutton(self)
Workaround for Tkinter bug, toggle the value.
toggleMenuCheckbutton(self)
Workaround for Tkinter bug, toggle the value.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class RepositoryDialog
     Methods defined here:
__init__(self, repository, root)
Add entities to the dialog.
__repr__(self)
Get the string representation of this RepositoryDialog.
addButtons(self, repository, root)
Add buttons to the dialog.
cancel(self, event=None)
Set all entities to their saved state.
close(self, event=None)
The dialog was closed.
save(self, event=None)
Set the entities to the dialog then write them.
setWindowPositionDeiconify(self)
Set the window position if that setting exists.

 
class StringSetting
    A class to display, read & write a string.
 
  Methods defined here:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToDialog(self, gridPosition)
Add this to the dialog.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setStateToValue(self)
Set the entry to the value.
setToDisplay(self)
Set the string to the entry field.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
setValueToString(self, valueString)
Set the value to the value string.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class TextSetting(StringSetting)
    A class to display, read & write a text.
 
  Methods defined here:
__init__(self)
Set the update function to none.
addToDialog(self, gridPosition)
Add this to the dialog.
getFromValue(self, name, repository, value)
Initialize.
setStateToValue(self)
Set the entry to the value.
setToDisplay(self)
Set the string to the entry field.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

Methods inherited from StringSetting:
__repr__(self)
Get the string representation of this StringSetting.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToString(self, valueString)
Set the value to the value string.
updateSaveListeners(self)
Update save listeners if any.

 
class TokenConversion
    A class to convert tokens in a string.
 
  Methods defined here:
__init__(self, name='replaceToken', token='___replaced___')
Set the name and token.
getNamedString(self, text)
Get a string with the tokens changed to names.
getTokenizedString(self, text)
Get a string with the names changed to tokens.

 
class ToolDialog
    A class to display the tool repository dialog.
 
  Methods defined here:
addPluginToMenu(self, menu, path)
Add the display command to the menu.
display(self)
Display the tool repository dialog.
getFromPath(self, path)
Initialize and return display function.

 
class WindowPosition(StringSetting)
    A class to display, read & write a window position.
 
  Methods defined here:
addToDialog(self, gridPosition)
Set the root to later get the geometry.
getFromValue(self, repository, value)
Initialize.
setToDisplay(self)
Set the string to the window position.
setWindowPosition(self)
Set the window position.

Methods inherited from StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setStateToValue(self)
Set the entry to the value.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
setValueToString(self, valueString)
Set the value to the value string.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
Functions
       
addAcceleratorCommand(acceleratorBinding, commandFunction, master, menu, text)
Add accelerator command.
addEmptyRow(gridPosition)
Add an empty row.
addListsToRepository(fileNameHelp, repository)
Add the value to the lists.
addListsToRepositoryByFunction(fileNameHelp, getProfileDirectory, repository)
Add the value to the lists.
addMenuEntitiesToMenu(menu, menuEntities)
Add the menu entities to the menu.
addMenuEntitiesToMenuFrameable(menu, menuEntities)
Add the menu entities to the menu.
addPluginsParentToMenu(directoryPath, menu, parentPath, pluginFileNames)
Add plugins and the parent to the menu.
addPluginsToMenu(directoryPath, menu, pluginFileNames)
Add plugins to the menu.
cancelRepository(repository)
Read the repository then set all the entities to the read repository values.
deleteDirectory(directory, subfolderName)
Delete the directory if it exists.
deleteMenuItems(menu)
Delete the menu items.
getAlongWayHexadecimalColor(beginBrightness, colorWidth, difference, endColorTuple, wayLength)
Get a color along the way from begin brightness to the end color.
getAlongWayHexadecimalPrimary(beginBrightness, beginRatio, colorWidth, endBrightness, endRatio)
Get a primary color along the way from grey to the end color.
getAlterationFile(fileName)
Get the file from the fileName or the lowercase fileName in the alterations directories.
getAlterationFileLine(fileName)
Get the alteration file line from the fileName.
getAlterationFileLineBlindly(fileName)
Get the alteration file line from the fileName.
getAlterationFileLines(fileName)
Get the alteration file line and the text lines from the fileName in the alterations directories.
getAlterationLines(fileName)
Get the text lines from the fileName in the alterations directories.
getDisplayToolButtonsRepository(directoryPath, importantFileNames, names, repository)
Get the display tool buttons.
getDisplayedDialogFromConstructor(repository)
Display the repository dialog.
getDisplayedDialogFromPath(path)
Display the repository dialog.
getEachWordCapitalized(name)
Get the capitalized name.
getFileInGivenDirectory(directory, fileName)
Get the file from the fileName or the lowercase fileName in the given directory.
getFileTextGivenDirectoryFileName(directory, fileName)
Get the entire text of a file with the given file name in the given directory.
getFolders(directory)
Get the folder list in a directory.
getGlobalRepositoryDialogValues()
Get the global repository dialog values.
getPathInFabmetheusFromFileNameHelp(fileNameHelp)
Get the directory path from file name help.
getProfileBaseName(repository)
Get the profile base file name.
getProfileBaseNameSynonym(repository)
Get the profile base file name synonym.
getProfilesDirectoryInAboveDirectory(subName='')
Get the profiles directory path in the above directory.
getRadioPluginsAddPluginFrame(directoryPath, importantFileNames, names, repository)
Get the radio plugins and add the plugin frame.
getReadRepository(repository)
Read and return settings from a file.
getRepositoryText(repository)
Get the text representation of the repository.
getRepositoryWriter(title)
Get the repository writer for the title.
getSelectedPluginModuleFromPath(filePath, plugins)
Get the selected plugin module.
getSelectedPluginName(plugins)
Get the selected plugin name.
getSelectedRadioPlugin(names, radioPlugins)
Get the selected radio button if it exists, None otherwise.
getShortestUniqueSettingName(settingName, settings)
Get the shortest unique name in the settings.
getSubfolderWithBasename(basename, directory)
Get the subfolder in the directory with the basename.
getTitleFromName(title)
Get the title of this setting.
getUntilFirstBracket(text)
Get the text until the first bracket, if any.
getWidthHex(number, width)
Get the first width hexadecimal digits.
liftRepositoryDialogs(repositoryDialogs)
Lift the repository dialogs.
openSVGPage(fileName, svgViewer)
Open svg page with an svg program.
openWebPage(webPagePath)
Open a web page in a browser.
printProgress(layerIndex, procedureName)
Print layerIndex followed by a carriage return.
printProgressByNumber(layerIndex, numberOfLayers, procedureName)
Print layerIndex and numberOfLayers followed by a carriage return.
printProgressByString(progressString)
Print progress string.
quitWindow(root)
Quit a window.
quitWindows(event=None)
Quit all windows.
readSettingsFromText(repository, text)
Read settings from a text.
saveAll()
Save all the dialogs.
saveRepository(repository)
Set the entities to the dialog then write them.
setButtonFontWeightString(button, isBold)
Set button font weight given isBold.
setEntryText(entry, value)
Set the entry text.
setIntegerValueToString(integerSetting, valueString)
Set the integer to the string.
setRepositoryToLine(lineIndex, lines, shortDictionary)
Set setting dictionary to a setting line.
setSpinColor(setting)
Set the spin box color to the value, yellow if it is lower than the default and blue if it is higher.
startMainLoopFromConstructor(repository)
Display the repository dialog and start the main loop.
startMainLoopFromWindow(window)
Display the tableau window and start the main loop.
temporaryAddPreferenceOverride(module, name, value)
temporaryApplyOverrides(repository)
Apply any overrides that have been set at the command line.
writeSettings(repository)
Write the settings to a file.
writeSettingsPrintMessage(repository)
Set the settings to the dialog then write them.
writeValueListToRepositoryWriter(repositoryWriter, setting)
Write tab separated name and list to the repository writer.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/23/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalCloseListTables = [{}, {}]
globalProfileSaveListenerListTable = {}
globalRepositoryDialogListTable = {}
globalSpreadsheetSeparator = '\t'
globalTemporaryOverrides = {}

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/fabmetheus_utilities.svg_reader.html000066400000000000000000000663561167321211700253250ustar00rootroot00000000000000 Python: module fabmetheus_utilities.svg_reader
 
 
fabmetheus_utilities.svg_reader ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/svg_reader.py

Svg reader.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
os
fabmetheus_utilities.settings
fabmetheus_utilities.svg_writer
sys
traceback
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
FontReader
Glyph
MatrixSVG
PathReader
SVGReader

 
class FontReader
    Class to read a font in the fonts folder.
 
  Methods defined here:
__init__(self, fontFamily)
Initialize.
getGlyph(self, character, yAxisPointingUpward)
Get the glyph for the character.

 
class Glyph
    Class to handle a glyph.
 
  Methods defined here:
__init__(self, elementNode, unitsPerEM, yAxisPointingUpward)
Initialize.
getSizedAdvancedLoops(self, fontSize, horizontalAdvanceX, yAxisPointingUpward=True)
Get loops for font size, advanced horizontally.

 
class MatrixSVG
    Two by three svg matrix.
 
  Methods defined here:
__init__(self, tricomplex=None)
Initialize.
__repr__(self)
Get the string representation of this two by three svg matrix.
getOtherTimesSelf(self, otherTricomplex)
Get the other matrix multiplied by this matrix.
getSelfTimesOther(self, otherTricomplex)
Get this matrix multiplied by the other matrix.
getTransformedPath(self, path)
Get transformed path.
getTransformedPaths(self, paths)
Get transformed paths.

 
class PathReader
    Class to read svg path.
 
  Methods defined here:
__init__(self, elementNode, loops, yAxisPointingUpward)
Add to path string to loops.
addPathArc(self, end)
Add an arc to the path.
addPathCubic(self, controlPoints, end)
Add a cubic curve to the path.
addPathCubicReflected(self, controlPoint, end)
Add a cubic curve to the path from a reflected control point.
addPathLine(self, lineFunction, point)
Add a line to the path.
addPathLineAxis(self, point)
Add an axis line to the path.
addPathLineByFunction(self, lineFunction)
Add a line to the path by line function.
addPathMove(self, lineFunction, point)
Add an axis line to the path.
addPathQuadratic(self, controlPoint, end)
Add a quadratic curve to the path.
addPathQuadraticReflected(self, end)
Add a quadratic curve to the path from a reflected control point.
getComplexByExtraIndex(self, extraIndex=0)
Get complex from the extraIndex.
getComplexRelative(self)
Get relative complex.
getFloatByExtraIndex(self, extraIndex=0)
Get float from the extraIndex.
getOldPoint(self)
Get the old point.
processPathWordA(self)
Process path word A.
processPathWordC(self)
Process path word C.
processPathWordH(self)
Process path word H.
processPathWordL(self)
Process path word L.
processPathWordM(self)
Process path word M.
processPathWordQ(self)
Process path word Q.
processPathWordS(self)
Process path word S.
processPathWordT(self)
Process path word T.
processPathWordV(self)
Process path word V.
processPathWordZ(self)
Process path word Z.
processPathWorda(self)
Process path word a.
processPathWordc(self)
Process path word C.
processPathWordh(self)
Process path word h.
processPathWordl(self)
Process path word l.
processPathWordm(self)
Process path word m.
processPathWordq(self)
Process path word q.
processPathWords(self)
Process path word s.
processPathWordt(self)
Process path word t.
processPathWordv(self)
Process path word v.
processPathWordz(self)
Process path word z.

 
class SVGReader
    An svg carving.
 
  Methods defined here:
__init__(self)
Add empty lists.
flipDirectLayer(self, loopLayer)
Flip the y coordinate of the layer and direct the loops.
getLoopLayer(self)
Return the rotated loop layer.
parseSVG(self, fileName, svgText)
Parse SVG text and store the layers.
parseSVGByElementNode(self, elementNode)
Parse SVG by elementNode.
processElementNode(self, elementNode)
Process the xml element.

 
Functions
       
addFunctionsToDictionary(dictionary, functions, prefix)
Add functions to dictionary.
getArcComplexes(begin, end, largeArcFlag, radius, sweepFlag, xAxisRotation)
Get the arc complexes, procedure at http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
getChainMatrixSVG(elementNode, matrixSVG)
Get chain matrixSVG by svgElement.
getChainMatrixSVGIfNecessary(elementNode, yAxisPointingUpward)
Get chain matrixSVG by svgElement and yAxisPointingUpward.
getCubicPoint(along, begin, controlPoints, end)
Get the cubic point.
getCubicPoints(begin, controlPoints, end, numberOfBezierPoints=22)
Get the cubic points.
getFontReader(fontFamily)
Get the font reader for the fontFamily.
getFontsDirectoryPath()
Get the fonts directory path.
getLabelString(dictionary)
Get the label string for the dictionary.
getMatrixSVG(elementNode)
Get matrixSVG by svgElement.
getQuadraticPoint(along, begin, controlPoint, end)
Get the quadratic point.
getQuadraticPoints(begin, controlPoint, end, numberOfBezierPoints=22)
Get the quadratic points.
getRightStripAlphabetPercent(word)
Get word with alphabet characters and the percent sign stripped from the right.
getRightStripMinusSplit(lineString)
Get string with spaces after the minus sign stripped.
getStrokeRadius(elementNode)
Get the stroke radius.
getStyleValue(defaultValue, elementNode, key)
Get the stroke value string.
getTextComplexLoops(fontFamily, fontSize, text, yAxisPointingUpward=True)
Get text as complex loops.
getTransformedFillOutline(elementNode, loop, yAxisPointingUpward)
Get the loops if fill is on, otherwise get the outlines.
getTransformedOutlineByPath(elementNode, path, yAxisPointingUpward)
Get the outline from the path.
getTransformedOutlineByPaths(elementNode, paths, yAxisPointingUpward)
Get the outline from the paths.
getTricomplexTimesColumn(firstTricomplex, otherColumn)
Get this matrix multiplied by the otherColumn.
getTricomplexTimesOther(firstTricomplex, otherTricomplex)
Get the first tricomplex multiplied by the other tricomplex.
getTricomplexmatrix(transformWords)
Get matrixSVG by transformWords.
getTricomplexrotate(transformWords)
Get matrixSVG by transformWords.
getTricomplexscale(transformWords)
Get matrixSVG by transformWords.
getTricomplexskewX(transformWords)
Get matrixSVG by transformWords.
getTricomplexskewY(transformWords)
Get matrixSVG by transformWords.
getTricomplextranslate(transformWords)
Get matrixSVG by transformWords.
processSVGElementcircle(elementNode, svgReader)
Process elementNode by svgReader.
processSVGElementellipse(elementNode, svgReader)
Process elementNode by svgReader.
processSVGElementg(elementNode, svgReader)
Process elementNode by svgReader.
processSVGElementline(elementNode, svgReader)
Process elementNode by svgReader.
processSVGElementpath(elementNode, svgReader)
Process elementNode by svgReader.
processSVGElementpolygon(elementNode, svgReader)
Process elementNode by svgReader.
processSVGElementpolyline(elementNode, svgReader)
Process elementNode by svgReader.
processSVGElementrect(elementNode, svgReader)
Process elementNode by svgReader.
processSVGElementtext(elementNode, svgReader)
Process elementNode by svgReader.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalFontFileNames = None
globalFontReaderDictionary = {}
globalGetTricomplexDictionary = {'matrix': <function getTricomplexmatrix>, 'rotate': <function getTricomplexrotate>, 'scale': <function getTricomplexscale>, 'skewX': <function getTricomplexskewX>, 'skewY': <function getTricomplexskewY>, 'translate': <function getTricomplextranslate>}
globalGetTricomplexFunctions = [<function getTricomplexmatrix>, <function getTricomplexrotate>, <function getTricomplexscale>, <function getTricomplexskewX>, <function getTricomplexskewY>, <function getTricomplextranslate>]
globalNumberOfBezierPoints = 22
globalNumberOfCirclePoints = 44
globalNumberOfCornerPoints = 11
globalProcessPathWordDictionary = {'A': <unbound method PathReader.processPathWordA>, 'C': <unbound method PathReader.processPathWordC>, 'H': <unbound method PathReader.processPathWordH>, 'L': <unbound method PathReader.processPathWordL>, 'M': <unbound method PathReader.processPathWordM>, 'Q': <unbound method PathReader.processPathWordQ>, 'S': <unbound method PathReader.processPathWordS>, 'T': <unbound method PathReader.processPathWordT>, 'V': <unbound method PathReader.processPathWordV>, 'Z': <unbound method PathReader.processPathWordZ>, ...}
globalProcessPathWordFunctions = [<unbound method PathReader.processPathWordA>, <unbound method PathReader.processPathWorda>, <unbound method PathReader.processPathWordC>, <unbound method PathReader.processPathWordc>, <unbound method PathReader.processPathWordH>, <unbound method PathReader.processPathWordh>, <unbound method PathReader.processPathWordL>, <unbound method PathReader.processPathWordl>, <unbound method PathReader.processPathWordM>, <unbound method PathReader.processPathWordm>, <unbound method PathReader.processPathWordQ>, <unbound method PathReader.processPathWordq>, <unbound method PathReader.processPathWordS>, <unbound method PathReader.processPathWords>, <unbound method PathReader.processPathWordT>, <unbound method PathReader.processPathWordt>, <unbound method PathReader.processPathWordV>, <unbound method PathReader.processPathWordv>, <unbound method PathReader.processPathWordZ>, <unbound method PathReader.processPathWordz>]
globalProcessSVGElementDictionary = {'circle': <function processSVGElementcircle>, 'ellipse': <function processSVGElementellipse>, 'g': <function processSVGElementg>, 'line': <function processSVGElementline>, 'path': <function processSVGElementpath>, 'polygon': <function processSVGElementpolygon>, 'polyline': <function processSVGElementpolyline>, 'rect': <function processSVGElementrect>, 'text': <function processSVGElementtext>}
globalProcessSVGElementFunctions = [<function processSVGElementcircle>, <function processSVGElementellipse>, <function processSVGElementg>, <function processSVGElementline>, <function processSVGElementpath>, <function processSVGElementpolygon>, <function processSVGElementpolyline>, <function processSVGElementrect>, <function processSVGElementtext>]
globalSideAngle = 0.14279966607226333

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.svg_writer.html000066400000000000000000000226621167321211700253670ustar00rootroot00000000000000 Python: module fabmetheus_utilities.svg_writer
 
 
fabmetheus_utilities.svg_writer ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/svg_writer.py

Svg_writer is a class and collection of utilities to read from and write to an svg file.

Svg_writer uses the layer_template.svg file in the templates folder in the same folder as svg_writer, to output an svg file.

 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
os
fabmetheus_utilities.xml_simple_reader
fabmetheus_utilities.xml_simple_writer

 
Classes
       
SVGWriter

 
class SVGWriter
    A base class to get an svg skein from a carving.
 
  Methods defined here:
__init__(self, addLayerTemplateToSVG, cornerMaximum, cornerMinimum, decimalPlacesCarried, layerThickness, perimeterWidth=None)
Initialize.
addLayerBegin(self, layerIndex, loopLayer)
Add the start lines for the layer.
addLoopLayerToOutput(self, layerIndex, loopLayer)
Add rotated boundary layer to the output.
addLoopLayersToOutput(self, loopLayers)
Add rotated boundary layers to the output.
addOriginalAsComment(self, elementNode)
Add original elementNode as a comment.
getReplacedSVGTemplate(self, fileName, loopLayers, procedureName, elementNode=None)
Get the lines of text from the layer_template.svg file.
getRounded(self, number)
Get number rounded to the number of carried decimal places as a string.
getRoundedComplexString(self, point)
Get the rounded complex string.
getSVGStringForLoop(self, loop)
Get the svg loop string.
getSVGStringForLoops(self, loops)
Get the svg loops string.
getSVGStringForPath(self, path)
Get the svg path string.
getTransformString(self)
Get the svg transform string.
setDimensionTexts(self, key, valueString)
Set the texts to the valueString followed by mm.
setMetadataNoscriptElement(self, key, prefix, value)
Set the metadata value and the text.
setTexts(self, key, valueString)
Set the texts to the valueString.

 
Functions
       
getCarving(fileName)
Get a carving for the file using an import plugin.
getCommentElement(elementNode)
Get a carving for the file using an import plugin.
getSVGByLoopLayers(addLayerTemplateToSVG, carving, loopLayers)
Get the svg text.
getSliceDictionary(elementNode)
Get the metadata slice attribute dictionary.
getSliceElementNodes(elementNode)
Get the slice elements.
getTruncatedRotatedBoundaryLayers(loopLayers, repository)
Get the truncated rotated boundary layers.
setSVGCarvingCorners(cornerMaximum, cornerMinimum, layerThickness, loopLayers)
Parse SVG text and store the layers.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalOriginalTextString = '<!-- Original XML Text:\n'

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/fabmetheus_utilities.vector3.html000066400000000000000000000336111167321211700245550ustar00rootroot00000000000000 Python: module fabmetheus_utilities.vector3
 
 
fabmetheus_utilities.vector3 ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/vector3.py

Vector3 is a three dimensional vector class.

Below are examples of Vector3 use.

>>> from vector3 import Vector3
>>> origin = Vector3()
>>> origin
0.0, 0.0, 0.0
>>> pythagoras = Vector3( 3, 4, 0 )
>>> pythagoras
3.0, 4.0, 0.0
>>> pythagoras.magnitude()
5.0
>>> pythagoras.magnitudeSquared()
25
>>> triplePythagoras = pythagoras * 3.0
>>> triplePythagoras
9.0, 12.0, 0.0
>>> plane = pythagoras.dropAxis()
>>> plane
(3+4j)

 
Modules
       
__init__
math
operator
fabmetheus_utilities.xml_simple_writer

 
Classes
       
Vector3

 
class Vector3
    A three dimensional vector class.
 
  Methods defined here:
__abs__(self)
Get the magnitude of the Vector3.
__add__(self, other)
Get the sum of this Vector3 and other one.
__copy__(self)
Get the copy of this Vector3.
__div__(self, other)
Get a new Vector3 by dividing each component of this one.
__eq__(self, other)
Determine whether this vector is identical to other one.
__floordiv__(self, other)
Get a new Vector3 by floor dividing each component of this one.
__hash__(self)
Determine whether this vector is identical to other one.
__iadd__(self, other)
Add other Vector3 to this one.
__idiv__(self, other)
Divide each component of this Vector3.
__ifloordiv__(self, other)
Floor divide each component of this Vector3.
__imul__(self, other)
Multiply each component of this Vector3.
__init__(self, x=0.0, y=0.0, z=0.0)
__isub__(self, other)
Subtract other Vector3 from this one.
__itruediv__(self, other)
True divide each component of this Vector3.
__mul__(self, other)
Get a new Vector3 by multiplying each component of this one.
__ne__(self, other)
Determine whether this vector is not identical to other one.
__neg__(self)
__nonzero__(self)
__pos__ = __copy__(self)
__rdiv__(self, other)
Get a new Vector3 by dividing each component of this one.
__repr__(self)
Get the string representation of this Vector3.
__rfloordiv__(self, other)
Get a new Vector3 by floor dividing each component of this one.
__rmul__(self, other)
Get a new Vector3 by multiplying each component of this one.
__rtruediv__(self, other)
Get a new Vector3 by true dividing each component of this one.
__sub__(self, other)
Get the difference between the Vector3 and other one.
__truediv__(self, other)
Get a new Vector3 by true dividing each component of this one.
copy = __copy__(self)
cross(self, other)
Calculate the cross product of this vector with other one.
distance(self, other)
Get the Euclidean distance between this vector and other one.
distanceSquared(self, other)
Get the square of the Euclidean distance between this vector and other one.
dot(self, other)
Calculate the dot product of this vector with other one.
dropAxis(self, which=2)
Get a complex by removing one axis of the vector3.
getFloatList(self)
Get the vector as a list of floats.
getIsDefault(self)
Determine if this is the zero vector.
getNormalized(self)
Get the normalized Vector3.
magnitude = __abs__(self)
magnitudeSquared(self)
Get the square of the magnitude of the Vector3.
maximize(self, other)
Maximize the Vector3.
minimize(self, other)
Minimize the Vector3.
normalize(self)
Scale each component of this Vector3 so that it has a magnitude of 1. If this Vector3 has a magnitude of 0, this method has no effect.
reflect(self, normal)
Reflect the Vector3 across the normal, which is assumed to be normalized.
setToVector3(self, other)
Set this Vector3 to be identical to other one.
setToXYZ(self, x, y, z)
Set the x, y, and z components of this Vector3.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://forums.reprap.org/profile.php?12,28>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalGetAccessibleAttributeSet = ['x', 'y', 'z']
globalSetAccessibleAttributeSet = ['x', 'y', 'z']

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://forums.reprap.org/profile.php?12,28>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.vector3index.html000066400000000000000000000327021167321211700256050ustar00rootroot00000000000000 Python: module fabmetheus_utilities.vector3index
 
 
fabmetheus_utilities.vector3index ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/vector3index.py

Vector3 is a three dimensional vector class.

Below are examples of Vector3 use.

>>> from vector3 import Vector3
>>> origin = Vector3()
>>> origin
0.0, 0.0, 0.0
>>> pythagoras = Vector3( 3, 4, 0 )
>>> pythagoras
3.0, 4.0, 0.0
>>> pythagoras.magnitude()
5.0
>>> pythagoras.magnitudeSquared()
25
>>> triplePythagoras = pythagoras * 3.0
>>> triplePythagoras
9.0, 12.0, 0.0
>>> plane = pythagoras.dropAxis()
>>> plane
(3+4j)

 
Modules
       
__init__
math
operator
fabmetheus_utilities.xml_simple_writer

 
Classes
       
Vector3Index

 
class Vector3Index
    A three dimensional vector index class.
 
  Methods defined here:
__abs__(self)
Get the magnitude of the Vector3.
__add__(self, other)
Get the sum of this Vector3 and other one.
__copy__(self)
Get the copy of this Vector3.
__div__(self, other)
Get a new Vector3 by dividing each component of this one.
__eq__(self, other)
Determine whether this vector is identical to other one.
__floordiv__(self, other)
Get a new Vector3 by floor dividing each component of this one.
__hash__(self)
Determine whether this vector is identical to other one.
__iadd__(self, other)
Add other Vector3 to this one.
__idiv__(self, other)
Divide each component of this Vector3.
__ifloordiv__(self, other)
Floor divide each component of this Vector3.
__imul__(self, other)
Multiply each component of this Vector3.
__init__(self, index, x=0.0, y=0.0, z=0.0)
__isub__(self, other)
Subtract other Vector3 from this one.
__itruediv__(self, other)
True divide each component of this Vector3.
__mul__(self, other)
Get a new Vector3 by multiplying each component of this one.
__ne__(self, other)
Determine whether this vector is not identical to other one.
__neg__(self)
__nonzero__(self)
__pos__ = __copy__(self)
__rdiv__(self, other)
Get a new Vector3 by dividing each component of this one.
__repr__(self)
Get the string representation of this Vector3 index.
__rfloordiv__(self, other)
Get a new Vector3 by floor dividing each component of this one.
__rmul__(self, other)
Get a new Vector3 by multiplying each component of this one.
__rtruediv__(self, other)
Get a new Vector3 by true dividing each component of this one.
__sub__(self, other)
Get the difference between the Vector3 and other one.
__truediv__(self, other)
Get a new Vector3 by true dividing each component of this one.
copy = __copy__(self)
cross(self, other)
Calculate the cross product of this vector with other one.
distance(self, other)
Get the Euclidean distance between this vector and other one.
distanceSquared(self, other)
Get the square of the Euclidean distance between this vector and other one.
dot(self, other)
Calculate the dot product of this vector with other one.
dropAxis(self, which=2)
Get a complex by removing one axis of the vector3.
getFloatList(self)
Get the vector as a list of floats.
getIsDefault(self)
Determine if this is the zero vector.
getNormalized(self)
Get the normalized Vector3.
magnitude = __abs__(self)
magnitudeSquared(self)
Get the square of the magnitude of the Vector3.
maximize(self, other)
Maximize the Vector3.
minimize(self, other)
Minimize the Vector3.
normalize(self)
Scale each component of this Vector3 so that it has a magnitude of 1. If this Vector3 has a magnitude of 0, this method has no effect.
reflect(self, normal)
Reflect the Vector3 across the normal, which is assumed to be normalized.
setToVector3(self, other)
Set this Vector3 to be identical to other one.
setToXYZ(self, x, y, z)
Set the x, y, and z components of this Vector3.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://forums.reprap.org/profile.php?12,28>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalGetAccessibleAttributeSet = ['x', 'y', 'z']
globalSetAccessibleAttributeSet = ['x', 'y', 'z']

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://forums.reprap.org/profile.php?12,28>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.xml_simple_reader.html000066400000000000000000001451741167321211700266730ustar00rootroot00000000000000 Python: module fabmetheus_utilities.xml_simple_reader
 
 
fabmetheus_utilities.xml_simple_reader ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/xml_simple_reader.py

The xml_simple_reader.py script is an xml parser that can parse a line separated xml text.

This xml parser will read a line seperated xml text and produce a tree of the xml with a document element. Each element can have an attribute table, childNodes, a class name, parentNode, text and a link to the document element.

This example gets an xml tree for the xml file boolean.xml. This example is run in a terminal in the folder which contains boolean.xml and xml_simple_reader.py.


> python
Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31)
[GCC 4.2.1 (SUSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> fileName = 'boolean.xml'
>>> file = open(fileName, 'r')
>>> xmlText = file.read()
>>> file.close()
>>> from xml_simple_reader import DocumentNode
>>> xmlParser = DocumentNode(fileName, xmlText)
>>> print( xmlParser )
?xml, {'version': '1.0'}
ArtOfIllusion, {'xmlns:bf': '//babelfiche/codec', 'version': '2.0', 'fileversion': '3'}
Scene, {'bf:id': 'theScene'}
materials, {'bf:elem-type': 'java.lang.Object', 'bf:list': 'collection', 'bf:id': '1', 'bf:type': 'java.util.Vector'}
..
many more lines of the xml tree
..

 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.geometry.geometry_utilities.evaluate
fabmetheus_utilities.geometry.geometry_utilities.matrix
fabmetheus_utilities.xml_simple_writer

 
Classes
       
CDATASectionMonad
CommentMonad
DocumentTypeMonad
CDATASectionNode
CommentNode
DocumentTypeNode
TextNode
DocumentNode
ElementEndMonad
OpenChooseMonad
OpenMonad
ElementLocalNameMonad
ElementNode
ElementReadMonad
KeyMonad
TextMonad
ValueMonad

 
class CDATASectionMonad
    A monad to handle a CDATASection node.
 
  Methods defined here:
__init__(self, input, parentNode)
Initialize.
getNextMonad(self, character)
Get the next monad.

 
class CDATASectionNode
    A CDATASection node.
 
  Methods defined here:
__init__(self, parentNode, textContent='')
Initialize.
__repr__(self)
Get the string representation of this CDATASection node.
addToIdentifierDictionaries(self)
Add the element to the owner document identifier dictionaries.
addXML(self, depth, output)
Add xml for this CDATASection node.
appendSelfToParent(self)
Append self to the parentNode.
copyXMLChildNodes(self, idSuffix, parentNode)
Copy the xml childNodes.
getAttributes(self)
Get the attributes.
getChildNodes(self)
Get the empty set.
getCopy(self, idSuffix, parentNode)
Copy the xml element, set its dictionary and add it to the parentNode.
getCopyShallow(self, attributes=None)
Copy the node and set its parentNode.
getNodeName(self)
Get the node name.
getNodeType(self)
Get the node type.
getOwnerDocument(self)
Get the owner document.
getTextContent(self)
Get the text content.
removeChildNodesFromIDNameParent(self)
Remove the childNodes from the id and name dictionaries and the childNodes.
removeFromIDNameParent(self)
Remove this from the id and name dictionaries and the childNodes of the parentNode.
setParentAddToChildNodes(self, parentNode)
Set the parentNode and add this to its childNodes.

Data descriptors defined here:
attributes
Get the attributes.
childNodes
Get the empty set.
nodeName
Get the node name.
nodeType
Get the node type.
ownerDocument
Get the owner document.

 
class CommentMonad(CDATASectionMonad)
    A monad to handle a comment node.
 
  Methods defined here:
getNextMonad(self, character)
Get the next monad.

Methods inherited from CDATASectionMonad:
__init__(self, input, parentNode)
Initialize.

 
class CommentNode(CDATASectionNode)
    A comment node.
 
  Methods defined here:
getCopyShallow(self, attributes=None)
Copy the node and set its parentNode.
getNodeName(self)
Get the node name.
getNodeType(self)
Get the node type.

Data descriptors defined here:
nodeName
Get the node name.
nodeType
Get the node type.

Methods inherited from CDATASectionNode:
__init__(self, parentNode, textContent='')
Initialize.
__repr__(self)
Get the string representation of this CDATASection node.
addToIdentifierDictionaries(self)
Add the element to the owner document identifier dictionaries.
addXML(self, depth, output)
Add xml for this CDATASection node.
appendSelfToParent(self)
Append self to the parentNode.
copyXMLChildNodes(self, idSuffix, parentNode)
Copy the xml childNodes.
getAttributes(self)
Get the attributes.
getChildNodes(self)
Get the empty set.
getCopy(self, idSuffix, parentNode)
Copy the xml element, set its dictionary and add it to the parentNode.
getOwnerDocument(self)
Get the owner document.
getTextContent(self)
Get the text content.
removeChildNodesFromIDNameParent(self)
Remove the childNodes from the id and name dictionaries and the childNodes.
removeFromIDNameParent(self)
Remove this from the id and name dictionaries and the childNodes of the parentNode.
setParentAddToChildNodes(self, parentNode)
Set the parentNode and add this to its childNodes.

Data descriptors inherited from CDATASectionNode:
attributes
Get the attributes.
childNodes
Get the empty set.
ownerDocument
Get the owner document.

 
class DocumentNode
    A class to parse an xml text and store the elements.
 
  Methods defined here:
__init__(self, fileName, xmlText)
Initialize.
__repr__(self)
Get the string representation of this xml document.
appendChild(self, elementNode)
Append child elementNode to the child nodes.
getAttributes(self)
Get the attributes.
getCascadeBoolean(self, defaultBoolean, key)
Get the cascade boolean.
getCascadeFloat(self, defaultFloat, key)
Get the cascade float.
getDocumentElement(self)
Get the document element.
getElementsByLocalName(self, localName)
Get the descendents which have the given local name.
getImportNameChain(self, suffix='')
Get the import name chain with the suffix at the end.
getNodeName(self)
Get the node name.
getNodeType(self)
Get the node type.
getOriginalRoot(self)
Get the original reparsed document element.
getOwnerDocument(self)
Get the owner document.

Data descriptors defined here:
attributes
Get the attributes.
documentElement
Get the document element.
nodeName
Get the node name.
nodeType
Get the node type.
ownerDocument
Get the owner document.

 
class DocumentTypeMonad(CDATASectionMonad)
    A monad to handle a document type node.
 
  Methods defined here:
getNextMonad(self, character)
Get the next monad.

Methods inherited from CDATASectionMonad:
__init__(self, input, parentNode)
Initialize.

 
class DocumentTypeNode(CDATASectionNode)
    A document type node.
 
  Methods defined here:
getCopyShallow(self, attributes=None)
Copy the node and set its parentNode.
getNodeName(self)
Get the node name.
getNodeType(self)
Get the node type.

Data descriptors defined here:
nodeName
Get the node name.
nodeType
Get the node type.

Methods inherited from CDATASectionNode:
__init__(self, parentNode, textContent='')
Initialize.
__repr__(self)
Get the string representation of this CDATASection node.
addToIdentifierDictionaries(self)
Add the element to the owner document identifier dictionaries.
addXML(self, depth, output)
Add xml for this CDATASection node.
appendSelfToParent(self)
Append self to the parentNode.
copyXMLChildNodes(self, idSuffix, parentNode)
Copy the xml childNodes.
getAttributes(self)
Get the attributes.
getChildNodes(self)
Get the empty set.
getCopy(self, idSuffix, parentNode)
Copy the xml element, set its dictionary and add it to the parentNode.
getOwnerDocument(self)
Get the owner document.
getTextContent(self)
Get the text content.
removeChildNodesFromIDNameParent(self)
Remove the childNodes from the id and name dictionaries and the childNodes.
removeFromIDNameParent(self)
Remove this from the id and name dictionaries and the childNodes of the parentNode.
setParentAddToChildNodes(self, parentNode)
Set the parentNode and add this to its childNodes.

Data descriptors inherited from CDATASectionNode:
attributes
Get the attributes.
childNodes
Get the empty set.
ownerDocument
Get the owner document.

 
class ElementEndMonad
    A monad to look for the end of an ElementNode tag.
 
  Methods defined here:
__init__(self, parentNode)
Initialize.
getNextMonad(self, character)
Get the next monad.

 
class ElementLocalNameMonad
    A monad to set the local name of an ElementNode.
 
  Methods defined here:
__init__(self, character, parentNode)
Initialize.
getNextMonad(self, character)
Get the next monad.
setLocalName(self)
Set the class name.

 
class ElementNode
    An xml element.
 
  Methods defined here:
__init__(self, parentNode=None)
Initialize.
__repr__(self)
Get the string representation of this xml document.
addSuffixToID(self, idSuffix)
Add the suffix to the id.
addToIdentifierDictionaries(self)
Add the element to the owner document identifier dictionaries.
addXML(self, depth, output)
Add xml for this elementNode.
appendChild(self, elementNode)
Append child elementNode to the child nodes.
appendSelfToParent(self)
Append self to the parentNode.
copyXMLChildNodes(self, idSuffix, parentNode)
Copy the xml childNodes.
getCascadeBoolean(self, defaultBoolean, key)
Get the cascade boolean.
getCascadeFloat(self, defaultFloat, key)
Get the cascade float.
getChildElementsByLocalName(self, localName)
Get the childNodes which have the given local name.
getCopy(self, idSuffix, parentNode)
Copy the xml element, set its dictionary and add it to the parentNode.
getCopyShallow(self, attributes=None)
Copy the xml element and set its dictionary and parentNode.
getDocumentElement(self)
Get the document element.
getElementNodeByID(self, idKey)
Get the xml element by id.
getElementNodesByName(self, nameKey)
Get the xml elements by name.
getElementNodesByTag(self, tagKey)
Get the xml elements by tag.
getElementsByLocalName(self, localName)
Get the descendents which have the given local name.
getFirstChildByLocalName(self, localName)
Get the first childNode which has the given class name.
getIDSuffix(self, elementIndex=None)
Get the id suffix from the dictionary.
getImportNameChain(self, suffix='')
Get the import name chain with the suffix at the end.
getNodeName(self)
Get the node name.
getNodeType(self)
Get the node type.
getOwnerDocument(self)
Get the owner document.
getParser(self)
Get the parser.
getPaths(self)
Get all paths.
getPreviousElementNode(self)
Get previous ElementNode if it exists.
getPreviousVertex(self, defaultVector3=None)
Get previous vertex if it exists.
getStrippedAttributesValue(self, keyString)
Get the stripped attribute value if the length is at least one, otherwise return None.
getSubChildWithID(self, idReference)
Get the childNode which has the idReference.
getTagKeys(self)
Get stripped tag keys.
getTextContent(self)
Get the text from the child nodes.
getValueByKey(self, key)
Get value by the key.
getVertexes(self)
Get the vertexes.
getXMLProcessor(self)
Get the xmlProcessor.
linkObject(self, xmlObject)
Link self to xmlObject and add xmlObject to archivableObjects.
printAllVariables(self)
Print all variables.
printAllVariablesRoot(self)
Print all variables and the document element variables.
removeChildNodesFromIDNameParent(self)
Remove the childNodes from the id and name dictionaries and the childNodes.
removeFromIDNameParent(self)
Remove this from the id and name dictionaries and the childNodes of the parentNode.
setParentAddToChildNodes(self, parentNode)
Set the parentNode and add this to its childNodes.
setTextContent(self, textContent='')
Get the text from the child nodes.

Data descriptors defined here:
nodeName
Get the node name.
nodeType
Get the node type.
ownerDocument
Get the owner document.
textContent
Get the text from the child nodes.

 
class ElementReadMonad
    A monad to read the attributes of the ElementNode tag.
 
  Methods defined here:
__init__(self, elementNode)
Initialize.
getNextMonad(self, character)
Get the next monad.

 
class KeyMonad
    A monad to set the key of an attribute of an ElementNode.
 
  Methods defined here:
__init__(self, character, elementNode)
Initialize.
getNextMonad(self, character)
Get the next monad.

 
class OpenChooseMonad(ElementEndMonad)
    A monad to choose the next monad.
 
  Methods defined here:
getNextMonad(self, character)
Get the next monad.

Methods inherited from ElementEndMonad:
__init__(self, parentNode)
Initialize.

 
class OpenMonad(ElementEndMonad)
    A monad to handle the open tag character.
 
  Methods defined here:
getNextMonad(self, character)
Get the next monad.

Methods inherited from ElementEndMonad:
__init__(self, parentNode)
Initialize.

 
class TextMonad
    A monad to handle the open tag character and set the text.
 
  Methods defined here:
__init__(self, parentNode)
Initialize.
getNextMonad(self, character)
Get the next monad.

 
class TextNode(CDATASectionNode)
    A text node.
 
  Methods defined here:
addXML(self, depth, output)
Add xml for this text node.
getCopyShallow(self, attributes=None)
Copy the node and set its parentNode.
getNodeName(self)
Get the node name.
getNodeType(self)
Get the node type.

Data descriptors defined here:
nodeName
Get the node name.
nodeType
Get the node type.

Methods inherited from CDATASectionNode:
__init__(self, parentNode, textContent='')
Initialize.
__repr__(self)
Get the string representation of this CDATASection node.
addToIdentifierDictionaries(self)
Add the element to the owner document identifier dictionaries.
appendSelfToParent(self)
Append self to the parentNode.
copyXMLChildNodes(self, idSuffix, parentNode)
Copy the xml childNodes.
getAttributes(self)
Get the attributes.
getChildNodes(self)
Get the empty set.
getCopy(self, idSuffix, parentNode)
Copy the xml element, set its dictionary and add it to the parentNode.
getOwnerDocument(self)
Get the owner document.
getTextContent(self)
Get the text content.
removeChildNodesFromIDNameParent(self)
Remove the childNodes from the id and name dictionaries and the childNodes.
removeFromIDNameParent(self)
Remove this from the id and name dictionaries and the childNodes of the parentNode.
setParentAddToChildNodes(self, parentNode)
Set the parentNode and add this to its childNodes.

Data descriptors inherited from CDATASectionNode:
attributes
Get the attributes.
childNodes
Get the empty set.
ownerDocument
Get the owner document.

 
class ValueMonad
    A monad to set the value of an attribute of an ElementNode.
 
  Methods defined here:
__init__(self, elementNode, key)
Initialize.
getNextMonad(self, character)
Get the next monad.

 
Functions
       
createAppendByText(parentNode, xmlText)
Create and append the child nodes from the xmlText.
createAppendByTextb(parentNode, xmlText)
Create and append the child nodes from the xmlText.
getChildElementsByLocalName(childNodes, localName)
Get the childNodes which have the given local name.
getDocumentNode(fileName)
Get the document from the file name.
getElementsByLocalName(childNodes, localName)
Get the descendents which have the given local name.
getFileText(fileName, printWarning=True, readMode='r')
Get the entire text of a file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalGetAccessibleAttributeSet = set(['getPaths', 'getPreviousElementNode', 'getPreviousVertex', 'getVertexes', 'parentNode'])

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/fabmetheus_utilities.xml_simple_writer.html000066400000000000000000000154501167321211700267360ustar00rootroot00000000000000 Python: module fabmetheus_utilities.xml_simple_writer
 
 
fabmetheus_utilities.xml_simple_writer ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/fabmetheus_utilities/xml_simple_writer.py

XML tag writer utilities.

 
Modules
       
__init__
cStringIO

 
Functions
       
addBeginEndInnerXMLTag(attributes, depth, innerText, localName, output, text='')
Add the begin and end xml tag and the inner text if any.
addBeginXMLTag(attributes, depth, localName, output, text='')
Add the begin xml tag.
addClosedXMLTag(attributes, depth, localName, output, text='')
Add the closed xml tag.
addEndXMLTag(depth, localName, output)
Add the end xml tag.
addXMLFromLoopComplexZ(attributes, depth, loop, output, z)
Add xml from loop.
addXMLFromObjects(depth, objects, output)
Add xml from objects.
addXMLFromVertexes(depth, output, vertexes)
Add xml from loop.
addXMLFromXYZ(depth, index, output, x, y, z)
Add xml from x, y & z.
compareAttributeKeyAscending(key, otherKey)
Get comparison in order to sort attribute keys in ascending order, with the id key first and name second.
getAttributesString(attributes)
Add the closed xml tag.
getBeginGeometryXMLOutput(elementNode=None)
Get the beginning of the string representation of this boolean geometry object info.
getBeginXMLOutput()
Get the beginning of the string representation of this object info.
getDictionaryWithoutList(dictionary, withoutList)
Get the dictionary without the keys in the list.
getEndGeometryXMLString(output)
Get the string representation of this object info.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/skeinforge_application.html000066400000000000000000000044711167321211700234740ustar00rootroot00000000000000 Python: package skeinforge_application
 
 
skeinforge_application
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
skeinforge
skeinforge_plugins (package)
skeinforge_utilities (package)

 
Data
        level = 1
numberOfLevelsDeepInPackageHierarchy = 1
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/skeinforge_application.skeinforge.html000066400000000000000000000625001167321211700256240ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge
 
 
skeinforge_application.skeinforge ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge.py

Previous / Next / Contents



Overview
  Introduction
  Command Line Interface
  Contribute
  Documentation
  Fabrication
  File Formats
  Getting Skeinforge
  Getting Started
  License
  Motto
  Troubleshooting
Examples

Overview


Introduction

Skeinforge is a GPL tool chain to forge a gcode skein for a model.

The tool chain starts with carve, which carves the model into layers, then the layers are modified by other tools in turn like fill, comb, tower, raft, stretch, hop, wipe, fillet & export. Each tool automatically gets the gcode from the previous tool. So if you want a carved & filled gcode, call the fill tool and it will call carve, then it will fill and output the gcode. If you want to use all the tools, call export and it will call in turn all the other tools down the chain to produce the gcode file.

If you do not want a tool after preface to modify the output, deselect the Activate checkbox for that tool. When the Activate checkbox is off, the tool will just hand off the gcode to the next tool without modifying it.

The skeinforge module provides a single place to call up all the setting dialogs. When the 'Skeinforge' button is clicked, skeinforge calls export, since that is the end of the chain.

The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight.

There are also tools which handle settings for the chain, like polyfile.

The analyze tool calls plugins in the analyze_plugins folder, which will analyze the gcode in some way when it is generated if their Activate checkbox is selected.

The interpret tool accesses and displays the import plugins.

The default settings are similar to those on Nophead's machine. A setting which is often different is the 'Layer Thickness' in carve.

Command Line Interface

To bring up the skeinforge dialog without a file name, type:
python skeinforge_application/skeinforge.py

Slicing a file from skeinforge_utilities/skeinforge_craft.py, for example:
python skeinforge_application/skeinforge_utilities/skeinforge_craft.py test.stl

will slice the file and exit. This is the correct option for programs which use skeinforge to only generate a gcode file.

Slicing a file from skeinforge.py, for example:
python skeinforge_application/skeinforge.py test.stl

will slice the file and bring up the skeinforge window and the analyze windows and then skeinforge will wait for user input.

Slicing a file from skeinforge_plugins/craft.py, for example:
python skeinforge_application/skeinforge_plugins/craft.py test.stl

will slice the file and bring up the analyze windows only and then skeinforge will wait for user input.

Contribute

You can contribute by helping develop the manual at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge

There is also a forum thread about how to contribute to skeinforge development at:
http://dev.forums.reprap.org/read.php?12,27562

I will only reply to emails from contributors or to complete bug reports.

Documentation

There is a manual at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge

There is also documentation is in the documentation folder, in the doc strings for each module and it can be called from the '?' button or the menu or by clicking F1 in each setting dialog.

A list of other tutorials is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge#Tutorials

Skeinforge tagged pages on thingiverse can be searched for at:
http://www.thingiverse.com/search?cx=015525747728168968820%3Arqnsgx1xxcw&cof=FORID%3A9&ie=UTF-8&q=skeinforge&sa=Search&siteurl=www.thingiverse.com%2F#944

Fabrication

To fabricate a model with gcode and the Arduino you can use the send.py in the fabricate folder. The documentation for it is in the folder as send.html and at:
http://reprap.org/bin/view/Main/ArduinoSend

Another way is to use an EMC2 or similar computer controlled milling machine, as described in the "ECM2 based repstrap" forum thread at:
http://forums.reprap.org/read.php?1,12143

using the M-Apps package, which is at:
http://forums.reprap.org/file.php?1,file=772

Another way is to use Zach's ReplicatorG at:
http://replicat.org/

There is also an older Processing script at:
http://reprap.svn.sourceforge.net/viewvc/reprap/trunk/users/hoeken/arduino/GCode_Host/

Yet another way is to use the reprap host, written in Java, to load and print gcode:
http://dev.www.reprap.org/bin/view/Main/DriverSoftware#Load_GCode

For jogging, the Metalab group wrote their own exerciser, also in Processing:
http://reprap.svn.sourceforge.net/viewvc/reprap/trunk/users/metalab/processing/GCode_Exerciser/

The Metalab group has descriptions of skeinforge in action and their adventures are described at:
http://reprap.soup.io/

There is a board about printing issues at:
http://www.bitsfrombytes.com/fora/user/index.php?board=5.0

You can buy the Rapman (an improved Darwin) from Bits from Bytes at:
http://www.bitsfrombytes.com/

You can buy the Makerbot from Makerbot Industries at:
http://www.makerbot.com/

File Formats

An explanation of the gcodes is at:
http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter

and at:
http://reprap.org/bin/view/Main/MCodeReference

A gode example is at:
http://forums.reprap.org/file.php?12,file=565

The settings are saved as tab separated .csv files in the .skeinforge folder in your home directory. The settings can be set in the tool dialogs. The .csv files can also be edited with a text editor or a spreadsheet program set to separate tabs.

The Scalable Vector Graphics file produced by vectorwrite can be opened by an SVG viewer or an SVG capable browser like Mozilla:
http://www.mozilla.com/firefox/

A good triangle surface format is the GNU Triangulated Surface format, which is supported by Mesh Viewer and described at:
http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE

You can export GTS files from Art of Illusion with the Export GNU Triangulated Surface.bsh script in the Art of Illusion Scripts folder.

STL is an inferior triangle surface format, described at:
http://en.wikipedia.org/wiki/STL_(file_format)

If you're using an STL file and you can't even carve it, try converting it to a GNU Triangulated Surface file in Art of Illusion. If it still doesn't carve, then follow the advice in the troubleshooting section.

Getting Skeinforge

The latest version is at:
http://members.axion.net/~enrique/reprap_python_beanshell.zip

a sometimes out of date version is in the last reprap_python_beanshell.zip attachment in the last post of the Fabmetheus blog at:
http://fabmetheus.blogspot.com/

another sometimes out of date version is at:
https://reprap.svn.sourceforge.net/svnroot/reprap/trunk/reprap/miscellaneous/python-beanshell-scripts/

Getting Started

For skeinforge to run, install python 2.x on your machine, which is available from:
http://www.python.org/download/

To use the settings dialog you'll also need Tkinter, which probably came with the python installation. If it did not, look for it at:
http://www.tcl.tk/software/tcltk/

If you want python and Tkinter together on MacOS, you can try:
http://www.astro.washington.edu/users/rowen/ROPackage/Overview.html

If you want python and Tkinter together on all platforms and don't mind filling out forms, you can try the ActivePython package from Active State at:
http://www.activestate.com/Products/activepython/feature_list.mhtml

The computation intensive python modules will use psyco if it is available and run about twice as fast. Psyco is described at:
http://psyco.sourceforge.net/index.html

The psyco download page is:
http://psyco.sourceforge.net/download.html

Skeinforge imports Stereolithography (.stl) files or GNU Triangulated Surface (.gts) files. If importing an STL file directly doesn't work, an indirect way to import an STL file is by turning it into a GTS file is by using the Export GNU Triangulated Surface script at:
http://members.axion.net/~enrique/Export%20GNU%20Triangulated%20Surface.bsh

The Export GNU Triangulated Surface script is also in the Art of Illusion folder, which is in the same folder as skeinforge.py. To bring the script into Art of Illusion, drop it into the folder ArtOfIllusion/Scripts/Tools/. Then import the STL file using the STL import plugin in the import submenu of the Art of Illusion file menu. Then from the Scripts submenu in the Tools menu, choose 'Export GNU Triangulated Surface' and select the imported STL shape. Click the 'Export Selected' checkbox and click OK. Once you've created the GTS file, you can turn it into gcode by typing in a shell in the same folder as skeinforge:
> python skeinforge.py

When the skeinforge dialog pops up, click 'Skeinforge', choose the file which you exported in 'Export GNU Triangulated Surface' and the gcode file will be saved with the suffix '_export.gcode'.

Or you can turn files into gcode by adding the file name, for example:
> python skeinforge.py Screw Holder Bottom.stl

License

GNU Affero General Public License
http://www.gnu.org/licenses/agpl.html

Motto

I may be slow, but I get there in the end.

Troubleshooting

If there's a bug, try downloading the very latest version because skeinforge is often updated without an announcement. The very latest version is at:
http://members.axion.net/~enrique/reprap_python_beanshell.zip

If there is still a bug, then first prepare the following files:

1. stl file
2. pictures explaining the problem
3. your settings (pack the whole .skeinforge directory with all your settings)
4. alterations folder, if you have any active alterations files

Then zip all the files.

Second, write a description of the error, send the description and the archive to the developer, enrique ( perez_enrique AT yahoo.com.removethispart ). After a bug fix is released, test the new version and report the results to enrique, whether the fix was successful or not.

If the dialog window is too big for the screen, on most Linux window managers you can move a window by holding down the Alt key and then drag the window with the left mouse button to get to the off screen widgets.

If you can't use the graphical interface, you can change the settings for skeinforge by using a text editor or spreadsheet to change the settings in the profiles folder in the .skeinforge folder in your home directory.

Comments and suggestions are welcome, however, I won't reply unless you are a contributor. Likewise, I will only answer your questions if you contribute to skeinforge in some way. Some ways of contributing to skeinforge are in the contributions thread at:
http://dev.forums.reprap.org/read.php?12,27562

You could also contribute articles to demozendium on any topic:
http://fabmetheus.crsndoo.com/wiki/index.php/Main_Page

If you contribute in a significant way to another open source project, I will consider that also.

When I answered everyone's questions, eventually I received more questions than I had time to answer, so now I only answer questions from contributors.

I reserve the right to make any correspondence public. Do not send me any correspondence marked confidential. If you do I will delete it.


Examples


The following examples forge the STL file Screw Holder.stl. The examples are run in a terminal in the folder which contains Screw Holder.gts and skeinforge.py.

> python skeinforge.py
This brings up the dialog, after clicking 'Skeinforge', the following is printed:
The exported file is saved as Screw Holder_export.gcode

> python skeinforge.py Screw Holder.stl
The exported file is saved as Screw Holder_export.gcode

To run only fill for example, type in the craft_plugins folder which fill is in:
> python fill.py


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
SkeinforgeRepository

 
class SkeinforgeRepository
    A class to handle the skeinforge settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Skeinforge button has been clicked.
save(self)
Profile has been saved and profile menu should be updated.

 
Functions
       
addToProfileMenu(profileSelection, profileType, repository)
Add a profile menu.
getNewRepository()
Get new repository.
getPluginFileNames()
Get skeinforge plugin fileNames.
getRadioPluginsAddPluginGroupFrame(directoryPath, importantFileNames, names, repository)
Get the radio plugins and add the plugin frame.
main()
Display the skeinforge dialog.
writeOutput(fileName)
Craft a file, display dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = '\nAdrian Bowyer <http://forums.reprap.org/profile...:\nArt of Illusion <http://www.artofillusion.org/>'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
       
Adrian Bowyer <http://forums.reprap.org/profile.php?12,13>
Brendan Erwin <http://forums.reprap.org/profile.php?12,217>
Greenarrow <http://forums.reprap.org/profile.php?12,81>
Ian England <http://forums.reprap.org/profile.php?12,192>
John Gilmore <http://forums.reprap.org/profile.php?12,364>
Jonwise <http://forums.reprap.org/profile.php?12,716>
Kyle Corbitt <http://forums.reprap.org/profile.php?12,90>
Michael Duffin <http://forums.reprap.org/profile.php?12,930>
Marius Kintel <http://reprap.soup.io/>
Nophead <http://www.blogger.com/profile/12801535866788103677>
PJR <http://forums.reprap.org/profile.php?12,757>
Reece.Arnott <http://forums.reprap.org/profile.php?12,152>
Wade <http://forums.reprap.org/profile.php?12,489>
Xsainnz <http://forums.reprap.org/profile.php?12,563>
Zach Hoeken <http://blog.zachhoeken.com/>
 
Organizations:
Art of Illusion <http://www.artofillusion.org/>
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.analyze.html000066400000000000000000000122611167321211700310260ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.analyze
 
 
skeinforge_application.skeinforge_plugins.analyze ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze.py

Previous / Next / Contents


Analyze is a script to access the plugins which analyze a gcode file.

The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight.


Gcodes

Gcodes


An explanation of the gcodes is at:
http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter

and at:
http://reprap.org/bin/view/Main/MCodeReference

A gode example is at:
http://forums.reprap.org/file.php?12,file=565


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_analyze
sys

 
Functions
       
addToMenu(master, menu, repository, window)
Add a tool plugin menu.
getNewRepository()
Get new repository.
main()
Display the analyze dialog.
writeOutput(fileName)
Analyze a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.display_line.html000066400000000000000000000250011167321211700407140ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.display_line
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.display_line ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities/display_line.py

Previous / Next / Contents


Display line is a mouse tool to select and display information about the line.

When a line is clicked, the line will be selected and information about the line will be displayed. If a gcode line is clicked, the information will be file line count of the line clicked, counting from one, and the line itself.

When the display line tool is chosen and the canvas has the focus, display line will listen to the arrow keys. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. When the right arrow key is pressed, display line will increase the line index of the layer by one, and change the selection accordingly. If the line index of the layer goes over the index of the last line, the layer index will be increased by one and the new line index will be zero. When the left arrow key is pressed, the index will be decreased. If the line index goes below the index of the first line, the layer index will be decreased by one and the new line index will be at the last line. The up arrow key increases the layer index by one and the down arow key decreases the line index.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.gcodec
fabmetheus_utilities.settings

 
Classes
       
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase
DisplayLine

 
class DisplayLine(skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase)
    Display the line when it is clicked.
 
  Methods defined here:
button1(self, event, shift=False)
Print line text and connection line.
destroyEverything(self)
Destroy items.
drawLineText(self, location, tags)
Draw the line text.
drawSelectedColoredLineText(self)
Draw the selected line and text.
getSelectedColoredLine(self)
Draw the selected line, add it to the items and return the colored line.
isSelectionTool(self)
Return if this mouse tool is a selection tool.
keyPressDown(self, event)
The down arrow was pressed.
keyPressLeft(self, event)
The left arrow was pressed.
keyPressRight(self, event)
The right arrow was pressed.
keyPressUp(self, event)
The up arrow was pressed.
update(self)
Update the mouse tool.

Methods inherited from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase:
buttonRelease1(self, event)
The left button was released, <ButtonRelease-1> function.
destroyEverythingGetFocus(self)
Destroy items and get the focus for the canvas.
getReset(self, window)
Reset the mouse tool to default.
getTagsGivenXY(self, x, y)
Get the tag for the x and y.
keyPressReturn(self, event)
The return key was pressed.
motion(self, event, shift=False)
The mouse moved, <Motion> function.
setWindowItems(self, window)
Set the canvas and items.

 
Functions
       
getNewMouseTool()
Get a new mouse tool.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.html000066400000000000000000000064651167321211700362560ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: package skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
display_line
mouse_tool_base
tableau
view_move
view_rotate
zoom_in
zoom_out

 
Data
        level = 4
numberOfLevelsDeepInPackageHierarchy = 4
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.html000066400000000000000000000157411167321211700414310ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities/mouse_tool_base.py

Display line is a mouse tool to display the line index of the line clicked, counting from one, and the line itself.

 
Modules
       
__init__

 
Classes
       
MouseToolBase

 
class MouseToolBase
    The mouse tool base class, which does nothing.
 
  Methods defined here:
button1(self, event)
The left button was clicked, <Button-1> function.
buttonRelease1(self, event)
The left button was released, <ButtonRelease-1> function.
destroyEverything(self)
Destroy items.
destroyEverythingGetFocus(self)
Destroy items and get the focus for the canvas.
getReset(self, window)
Reset the mouse tool to default.
getTagsGivenXY(self, x, y)
Get the tag for the x and y.
isSelectionTool(self)
Return if this mouse tool is a selection tool.
keyPressDown(self, event)
The down arrow was pressed.
keyPressLeft(self, event)
The left arrow was pressed.
keyPressReturn(self, event)
The return key was pressed.
keyPressRight(self, event)
The right arrow was pressed.
keyPressUp(self, event)
The up arrow was pressed.
motion(self, event, shift=False)
The mouse moved, <Motion> function.
setWindowItems(self, window)
Set the canvas and items.
update(self)
Update the mouse tool.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.html000066400000000000000000000603331167321211700376640ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities/tableau.py

Tableau has a couple of base classes for analyze viewers.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
math
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_in
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_out

 
Classes
       
ColoredLine
ExportCanvasDialog
TableauRepository
TableauWindow

 
class ColoredLine
    A colored index line.
 
  Methods defined here:
__init__(self, begin, colorName, displayString, end, tagString)
Set the color name and corners.
__repr__(self)
Get the string representation of this colored index line.

 
class ExportCanvasDialog
    A class to display the export canvas repository dialog.
 
  Methods defined here:
addPluginToMenu(self, canvas, fileName, menu, name, suffix)
Add the display command to the menu.
display(self)
Display the export canvas repository dialog.

 
class TableauRepository
    The viewer base repository class.
 
  Methods defined here:
addAnimation(self)
Add the animation settings.
addScaleScreenSlide(self)
Add the scale, screen and slide show settings.
setToDisplaySave(self, event=None)
Set the setting values to the display, save the new values.

 
class TableauWindow
     Methods defined here:
activateMouseModeTool(self)
Activate the mouse mode tool.
addCanvasMenuRootScrollSkein(self, repository, skein, suffix, title)
Add the canvas, menu bar, scroll bar, skein panes, tableau repository, root and skein.
addLayer(self, gridPosition)
Add the layer frame items.
addLine(self, gridPosition)
Add the line frame items.
addMouseInstantTool(self, fileName, gridPosition, mouseInstantTool)
Add the mouse instant tool and derived photo button.
addMouseToolsBind(self)
Add the mouse tool and bind button one clicked, button one released and motion.
addPhotoImage(self, fileName, gridPosition)
Get a PhotoImage button, grid the button and increment the grid position.
addScale(self, gridPosition)
Add the line frame items.
addSettingsMenuSetWindowGeometry(self, center)
Add the settings menu, center the scroll region, update, and set the window geometry.
button1(self, event)
The button was clicked.
buttonRelease1(self, event)
The button was released.
cancel(self, event=None)
Set all entities to their saved state.
cancelTimer(self, event=None)
Cancel the timer and set it to none.
cancelTimerResetButtons(self)
Cancel the timer and set it to none.
close(self, event=None)
The dialog was closed.
createMouseModeTool(self)
Create the mouse mode tool.
destroyAllDialogWindows(self)
Destroy all the dialog windows.
destroyMouseToolRaiseMouseButtons(self)
Destroy the mouse tool and raise the mouse buttons.
dive(self)
Dive, go down periodically.
diveCycle(self)
Start the dive cycle.
getAnimationLineDelay(self, coloredLine)
Get the animation line delay in milliseconds.
getDrawnLineText(self, location, tags, text)
Get the line text drawn on the canvas.
getEntityFromName(self, name)
Get the entity of the given name.
getPhotoButtonGridIncrement(self, commandFunction, fileName, gridPosition)
Get a PhotoImage button, grid the button and increment the grid position.
getRoundedRulingText(self, extraDecimalPlaces, number)
Get the rounded ruling text.
getRulingSeparationWidthPixels(self, rank)
Get the separation width in pixels.
getScrollPaneCenter(self)
Get the center of the scroll pane.
getScrollPaneFraction(self)
Get the scroll pane top left.
getSlideShowDelay(self)
Get the slide show delay in milliseconds.
getUpdateSkeinPanes(self)
Get the update skein panes.
isLineBelowZeroSetLayer(self)
Determine if the line index is below zero, and if so set the layer index.
isLineBeyondListSetLayer(self)
Determine if the line index is beyond the end of the list, and if so set the layer index.
keyPressDown(self, event)
The down arrow was pressed.
keyPressLeft(self, event)
The left arrow was pressed.
keyPressReturn(self, event)
The return key was pressed.
keyPressRight(self, event)
The right arrow was pressed.
keyPressUp(self, event)
The up arrow was pressed.
layerEntryReturnPressed(self, event=None)
The layer index entry return was pressed.
limitIndex(self)
Limit the index so it is not below zero or above the top.
limitIndexSetArrowMouseDeleteCanvas(self)
Limit the index, set the arrow type, and delete all the canvas items.
lineDive(self)
Line dive, go down periodically.
lineDiveCycle(self)
Start the line dive cycle.
lineEntryReturnPressed(self, event=None)
The line index entry return was pressed.
lineSoar(self)
Line soar, go up periodically.
lineSoarCycle(self)
Start the line soar cycle.
motion(self, event)
The mouse moved.
phoenixUpdate(self)
Update the skein, and deiconify a new window and destroy the old.
redisplayWindowUpdate(self, event=None)
Deiconify a new window and destroy the old.
relayXview(self, *args)
Relay xview changes.
relayYview(self, *args)
Relay yview changes.
resetPeriodicButtonsText(self)
Reset the text of the periodic buttons.
save(self)
Set the setting values to the display, save the new values.
scaleEntryReturnPressed(self, event=None)
The scale entry return was pressed.
setButtonImageText(self, button, text)
Set the text of the e periodic buttons.
setDisplayLayerIndex(self)
Set the display of the layer index entry field and buttons.
setInsetToCanvas(self, event=None)
Set the repository insets to the canvas.
setLayerIndex(self, layerIndex)
Set the layer index.
setLineButtonsState(self)
Set the state of the line buttons.
setWindowNewMouseTool(self, getNewMouseToolFunction, mouseTool)
Set the getNewMouseTool function and the update function.
setWindowToDisplaySavePhoenixUpdate(self, event=None)
Set the setting values to the display, save the new values, then call the update function.
setWindowToDisplaySaveUpdate(self, event=None)
Set the setting values to the display, save the new values, then call the update function.
shiftButtonRelease1(self, event)
The button was released while the shift key was pressed.
shiftMotion(self, event)
The mouse moved.
soar(self)
Soar, go up periodically.
soarCycle(self)
Start the soar cycle.
updateDeiconify(self, center=(0.5+0.5j))
Update and deiconify the window.
updateMouseToolIfSelection(self)
Update the mouse tool if it is a selection tool.
updateNewDestroyOld(self, scrollPaneCenter)
Update and deiconify a window and destroy the old.

 
Functions
       
getGeometricDifference(first, second)
Get the geometric difference of the two numbers.
getGridHorizontalFrame(gridPosition)
Get the grid horizontal object with a frame from the grid position.
getIsLayerStart(firstWord, skein, splitLine)
Determine if the line is the start of a layer.
getLengthMinusOneMinimumOne(elementList)
Get the length of the length minus one, minimum one.
getPluginsDirectoryPath()
Get the plugins directory path.
getScrollbarCanvasPortion(scrollbar)
Get the canvas portion of the scrollbar.
setStateNormalDisabled(active, widget)
Set the state of the widget to normal if active and disabled if inactive.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.view_move.html000066400000000000000000000240311167321211700402420ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.view_move
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.view_move ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities/view_move.py

Previous / Next / Contents


Viewpoint move is a mouse tool to move the viewpoint in the xy plane.

When the mouse is clicked and dragged on the canvas, viewpoint move will drag the scroll pane accordingly. If the shift key is also pressed, the scroll pane will be moved only in the x or y direction, whichever is largest.

When the viewpoint move tool is chosen and the canvas has the focus, viewpoint move will listen to the arrow keys. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. When the right arrow key is pressed, viewpoint move will move the scroll pane to the right by a pixel. When the left arrow key is pressed, the scroll pane will be moved a pixel to the left. The up arrow key moves the scroll pane a pixel up and the down arow key moves the scroll pane a pixel down.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.settings

 
Classes
       
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase
ViewpointMove

 
class ViewpointMove(skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase)
    Display the line when it is clicked.
 
  Methods defined here:
button1(self, event, shift=False)
Print line text and connection line.
buttonRelease1(self, event, shift=False)
The left button was released, <ButtonRelease-1> function.
destroyEverything(self)
Destroy items.
keyPressDown(self, event)
The down arrow was pressed.
keyPressLeft(self, event)
The left arrow was pressed.
keyPressRight(self, event)
The right arrow was pressed.
keyPressUp(self, event)
The up arrow was pressed.
motion(self, event, shift=False)
The mouse moved, <Motion> function.
relativeMove(self, relativeMotion)
Move the view given the relative motion.
setScrollPaneMove(self, relativeMotion)
The up arrow was pressed.

Methods inherited from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase:
destroyEverythingGetFocus(self)
Destroy items and get the focus for the canvas.
getReset(self, window)
Reset the mouse tool to default.
getTagsGivenXY(self, x, y)
Get the tag for the x and y.
isSelectionTool(self)
Return if this mouse tool is a selection tool.
keyPressReturn(self, event)
The return key was pressed.
setWindowItems(self, window)
Set the canvas and items.
update(self)
Update the mouse tool.

 
Functions
       
getNewMouseTool()
Get a new mouse tool.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.view_rotate.html000066400000000000000000000307001167321211700405720ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.view_rotate
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.view_rotate ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities/view_rotate.py

Previous / Next / Contents


Viewpoint rotate is a mouse tool to rotate the viewpoint around the origin.

When the mouse is clicked, dragged and released on the canvas, viewpoint rotate will rotate the longitude by the amount the mouse is dragged around the origin. If the mouse is moved towards the origin, the latitude will be increased, so the viewpoint will be closer to the top. If the mouse is moved away from the origin, the latitude will be decreased. If the shift key is also pressed, only the latitude or longitude will be changed, whichever is being changed the most.

When the viewpoint rotate tool is chosen and the canvas has the focus, viewpoint rotate will listen to the arrow keys. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. When the right arrow key is pressed, viewpoint rotate will increase the preview longitude by one degree. When the left arrow key is pressed, the preview longitude will be decreased. The up arrow key increase the preview latitude by one degree and the down arow decreases the preview latitude. Pressing the <Return> key implements the preview.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.euclidean
math
fabmetheus_utilities.settings

 
Classes
       
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase
ViewpointRotate
LatitudeLongitude

 
class LatitudeLongitude
    A latitude and longitude.
 
  Methods defined here:
__init__(self, buttonOnePressedCanvasCoordinate, newCoordinate, skeinWindow, shift)
Set the latitude and longitude.

 
class ViewpointRotate(skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase)
    Display the line when it is clicked.
 
  Methods defined here:
button1(self, event, shift=False)
Print line text and connection line.
buttonRelease1(self, event, shift=False)
The left button was released, <ButtonRelease-1> function.
destroyEverything(self)
Destroy items.
getMoveCoordinate(self)
Get the movement coordinate from the class relative latitude and longitude.
keyPressDown(self, event)
The down arrow was pressed.
keyPressLeft(self, event)
The left arrow was pressed.
keyPressMotion(self)
Move the motion viewpoint for the class key press coordinates.
keyPressReturn(self, event)
The return key was pressed.
keyPressRight(self, event)
The right arrow was pressed.
keyPressStart(self)
If necessary, destroy everything and calculate the keyStartCanvasCoordinate.
keyPressUp(self, event)
The up arrow was pressed.
motion(self, event, shift=False)
Move the motion viewpoint if the mouse was moved.
motionGivenCoordinates(self, motionCoordinate, shift, startCoordinate)
Move the motion viewpoint given the motion coordinates.
moveViewpointGivenCoordinates(self, moveCoordinate, shift, startCoordinate)
Move the viewpoint given the move coordinates.

Methods inherited from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase:
destroyEverythingGetFocus(self)
Destroy items and get the focus for the canvas.
getReset(self, window)
Reset the mouse tool to default.
getTagsGivenXY(self, x, y)
Get the tag for the x and y.
isSelectionTool(self)
Return if this mouse tool is a selection tool.
setWindowItems(self, window)
Set the canvas and items.
update(self)
Update the mouse tool.

 
Functions
       
getBoundedLatitude(latitude)
Get the bounded latitude.later get rounded
getNewMouseTool()
Get a new mouse tool.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_in.html000066400000000000000000000220741167321211700377210ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_in
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_in ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities/zoom_in.py

Previous / Next / Contents


Zoom in is a mouse tool to zoom in the display at the point where the mouse was clicked, increasing the scale by a factor of two.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.settings

 
Classes
       
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase
ZoomIn

 
class ZoomIn(skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase)
    The zoom in mouse tool.
 
  Methods defined here:
button1(self, event, shift=False)
Print line text and connection line.
click(self, event=None)
Set the window mouse tool to this.
getMultiplier(self)
Get the scale multiplier.
getReset(self, window)
Reset the mouse tool to default.

Methods inherited from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase:
buttonRelease1(self, event)
The left button was released, <ButtonRelease-1> function.
destroyEverything(self)
Destroy items.
destroyEverythingGetFocus(self)
Destroy items and get the focus for the canvas.
getTagsGivenXY(self, x, y)
Get the tag for the x and y.
isSelectionTool(self)
Return if this mouse tool is a selection tool.
keyPressDown(self, event)
The down arrow was pressed.
keyPressLeft(self, event)
The left arrow was pressed.
keyPressReturn(self, event)
The return key was pressed.
keyPressRight(self, event)
The right arrow was pressed.
keyPressUp(self, event)
The up arrow was pressed.
motion(self, event, shift=False)
The mouse moved, <Motion> function.
setWindowItems(self, window)
Set the canvas and items.
update(self)
Update the mouse tool.

 
Functions
       
getNewMouseTool()
Get a new mouse tool.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_out.html000066400000000000000000000243761167321211700401310ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_out
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_out ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities/zoom_out.py

Previous / Next / Contents


Zoom out is a mouse tool to zoom out the display at the point where the mouse was clicked, decreasing the scale by a factor of two.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.settings
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_in

 
Classes
       
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_in.ZoomIn(skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase)
ZoomOut

 
class ZoomOut(skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_in.ZoomIn)
    The zoom out mouse tool.
 
 
Method resolution order:
ZoomOut
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_in.ZoomIn
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase

Methods defined here:
getMultiplier(self)
Get the scale multiplier.

Methods inherited from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.zoom_in.ZoomIn:
button1(self, event, shift=False)
Print line text and connection line.
click(self, event=None)
Set the window mouse tool to this.
getReset(self, window)
Reset the mouse tool to default.

Methods inherited from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base.MouseToolBase:
buttonRelease1(self, event)
The left button was released, <ButtonRelease-1> function.
destroyEverything(self)
Destroy items.
destroyEverythingGetFocus(self)
Destroy items and get the focus for the canvas.
getTagsGivenXY(self, x, y)
Get the tag for the x and y.
isSelectionTool(self)
Return if this mouse tool is a selection tool.
keyPressDown(self, event)
The down arrow was pressed.
keyPressLeft(self, event)
The left arrow was pressed.
keyPressReturn(self, event)
The return key was pressed.
keyPressRight(self, event)
The right arrow was pressed.
keyPressUp(self, event)
The up arrow was pressed.
motion(self, event, shift=False)
The mouse moved, <Motion> function.
setWindowItems(self, window)
Set the canvas and items.
update(self)
Update the mouse tool.

 
Functions
       
getNewMouseTool()
Get a new mouse tool.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.clairvoyance.html000066400000000000000000000207631167321211700351740ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.clairvoyance
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.clairvoyance ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/clairvoyance.py

Previous / Next / Contents


Clairvoyance is an analyze plugin to open the gcode file with an outside program.

The clairvoyance manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Clairvoyance


Operation
Settings
  Gcode Program
Examples

Operation


The default 'Activate Clairvoyance' checkbox is off. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Clairvoyance' checkbox is on, when clairvoyance is run directly.

Settings


Gcode Program

Default is webbrowser.

If the 'Gcode Program' is set to webbrowser, the gcode file will be sent to the default browser to be opened. If the 'Gcode Program' is set to a program name, the gcode file will be sent to that program to be opened. A good gcode viewer is Pleasant3D, at:
http://www.pleasantsoftware.com/developer/pleasant3d/index.shtml

Examples


Below are examples of clairvoyance being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and clairvoyance.py.

> python clairvoyance.py
This brings up the clairvoyance dialog.

> python clairvoyance.py Screw Holder_penultimate.gcode
The file is opened by an outside program


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
subprocess
sys
traceback

 
Classes
       
ClairvoyanceRepository

 
class ClairvoyanceRepository
    A class to handle the clairvoyance settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Write button has been clicked.

 
Functions
       
getNewRepository()
Get new repository.
getWindowAnalyzeFile(fileName, repository=None)
Open penultimate file with outside program.
main()
Display the clairvoyance dialog.
writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText='')
Open penultimate file with outside program given text.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.comment.html000066400000000000000000000244401167321211700341530ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.comment
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.comment ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/comment.py

Previous / Next / Contents


Comment is an analyze plugin to comment a gcode file.

The comment manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Comment


Operation
Gcodes
Examples

Operation


The default 'Activate Comment' checkbox is off. When it is on, the file will be commented when called from the skeinforge toolchain, when it is off, the file will not be commented when called from the toolchain. The file will still be commented, whether or not the 'Activate Comment' checkbox is on, when comment is run directly.

Gcodes


An explanation of the gcodes is at:
http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter

and at:
http://reprap.org/bin/view/Main/MCodeReference

A gode example is at:
http://forums.reprap.org/file.php?12,file=565

Examples


Below are examples of comment being used. These examples are run in a terminal in the folder which contains Screw_Holder_penultimate.gcode and comment.py.

> python comment.py
This brings up the comment dialog.

> python comment.py Screw Holder_penultimate.gcode
The comment file is saved as Screw_Holder_penultimate_comment.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.gcodec
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
CommentRepository
CommentSkein

 
class CommentRepository
    A class to handle the comment settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Write button has been clicked.

 
class CommentSkein
    A class to comment a gcode skein.
 
  Methods defined here:
__init__(self)
addComment(self, comment)
Add a gcode comment and a newline to the output.
linearMove(self, splitLine)
Comment a linear move.
parseGcode(self, gcodeText)
Parse gcode text and store the commented gcode.
parseLine(self, line)
Parse a gcode line and add it to the commented gcode.
setHelicalMoveEndpoint(self, splitLine)
Get the endpoint of a helical move.

 
Functions
       
getNewRepository()
Get new repository.
getWindowAnalyzeFile(fileName)
Comment a gcode file.
getWindowAnalyzeFileGivenText(fileName, gcodeText)
Write a commented gcode file for a gcode file.
main()
Display the comment dialog.
writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText='')
Write a commented gcode file for a skeinforge gcode file, if 'Write Commented File for Skeinforge Chain' is selected.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins.html000066400000000000000000000054161167321211700371300ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: package skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/export_canvas_plugins/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
postscript
scalable_vector_graphics

 
Data
        level = 4
numberOfLevelsDeepInPackageHierarchy = 4
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins.postscript.html000066400000000000000000000204241167321211700413350ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins.postscript
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins.postscript ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/export_canvas_plugins/postscript.py

Previous / Next / Contents


Postscript is an export canvas plugin to export the canvas to a postscript file.

When the export menu item in the file menu in an analyze viewer tool, like skeinlayer or skeiniso is clicked, the postscript dialog will be displayed. When the 'Export to Postscript' button on that dialog is clicked, the canvas will be exported as a postscript file. If the 'Postscript Program' is set to a program name, the postscript file will be sent to that program to be opened. The default is gimp, the Gnu Image Manipulation Program (Gimp), which is open source, can open postscript and save in a variety of formats. It is available at:
http://www.gimp.org/

If furthermore the 'File Extension' is set to a file extension, the postscript file will be sent to the program, along with the file extension for the converted output. The default is blank because some systems do not have an image conversion program; if you have or will install an image conversion program, a common 'File Extension' is png. A good open source conversion program is Image Magick, which is available at:
http://www.imagemagick.org/script/index.php

An export canvas plugin is a script in the export_canvas_plugins folder which has the function getNewRepository, and which has a repository class with the functions setCanvasFileNameSuffix to set variables and execute to save the file. It is meant to be run from an analyze viewer tool, like skeinlayer or skeiniso. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
PostscriptRepository

 
class PostscriptRepository
    A class to handle the export settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Convert to postscript button has been clicked. Export the canvas as a postscript file.
setCanvasFileNameSuffix(self, canvas, fileName, suffix)
Set the canvas and initialize the execute title.

 
Functions
       
getNewRepository()
Get new repository.
main()
Display the file or directory dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
c76f6a7a5f9184921ad37865894b883c8b03bb3f.paxheader00006660000000000000000000000226116732121170020406xustar00rootroot00000000000000150 path=sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins.scalable_vector_graphics.html c76f6a7a5f9184921ad37865894b883c8b03bb3f.data000066400000000000000000000221611167321211700172460ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins.scalable_vector_graphics
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins.scalable_vector_graphics ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/export_canvas_plugins/scalable_vector_graphics.py

Previous / Next / Contents


Scalable vector graphics is an export canvas plugin to export the canvas to a scalable vector graphics (.svg) file.

When the export menu item in the file menu in an analyze viewer tool, like skeinlayer or skeiniso is clicked, the postscript dialog will be displayed. When the 'Export to Scalable Vector Graphics' button on that dialog is clicked, the canvas will be exported as a scalable vector graphics file. If the 'Scalable Vector Graphics Program' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'Scalable Vector Graphics Program' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.

If furthermore the 'File Extension' is set to a file extension, the scalable vector graphics file will be sent to the program, along with the file extension for the converted output. The default is blank because some systems do not have an image conversion program; if you have or will install an image conversion program, a common 'File Extension' is png. A good open source conversion program is Image Magick, which is available at:
http://www.imagemagick.org/script/index.php

An export canvas plugin is a script in the export_canvas_plugins folder which has the function getNewRepository, and which has a repository class with the functions setCanvasFileNameSuffix to set variables and execute to save the file. It is meant to be run from an analyze viewer tool, like skeinlayer or skeiniso. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
ScalableVectorGraphicsRepository

 
class ScalableVectorGraphicsRepository
    A class to handle the export settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
addCanvasLineToOutput(self, canvasLinesOutput, objectIDNumber)
Add the canvas line to the output.
execute(self)
Export the canvas as an svg file.
getCanvasLinesOutput(self)
Add the canvas line to the output.
setCanvasFileNameSuffix(self, canvas, fileName, suffix)
Set the canvas and initialize the execute title.

 
Functions
       
getNewRepository()
Get new repository.
main()
Display the file or directory dialog.
parseLineReplace(firstWordTable, line, output)
Parse the line and replace it if the first word of the line is in the first word table.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.analyze_plugins.html000066400000000000000000000066241167321211700325750ustar00rootroot00000000000000 Python: package skeinforge_application.skeinforge_plugins.analyze_plugins
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
analyze_utilities (package)
clairvoyance
comment
export_canvas_plugins (package)
interpret
skeiniso
skeinlayer
statistic
synopsis
vectorwrite

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
skeinforge_application.skeinforge_plugins.analyze_plugins.interpret.html000066400000000000000000000150771167321211700345330ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.interpret
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.interpret ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/interpret.py

Previous / Next / Contents


Interpret is an analyze plugin to interpret a file, turning a 2D file into svg and a 3D file into constructive solid geometry xml.

The comment manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Interpret


Operation
Settings
  Print Interpretion
  Text Program
Examples

Operation


The default 'Activate Interpret' checkbox is off. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the tool chain. The functions will still be called, whether or not the 'Activate Interpret' checkbox is on, when interpret is run directly.

Settings


Print Interpretion

Default is off.

When selected, the xml text will be printed to the console.

Text Program

Default is webbrowser.

If the 'Text Program' is set the default 'webbrowser', the XML file will be sent to the default browser to be opened. If the 'Text Program' is set to a program name, the XML file will be sent to that program to be opened.

Examples


Below are examples of interpret being used. These examples are run in a terminal in the folder which contains Screw_Holder.stl and interpret.py.

> python interpret.py
This brings up the interpret dialog.

> python interpret.py Screw_Holder.stl
The comment file is saved as Screw_Holder_interpret.xml


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.settings
sys

 
Functions
       
getNewRepository()
Get new repository.
main()
Display the interpret dialog.
writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText='')
Write file interpretation, if activate interpret is selected.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.skeiniso.html000066400000000000000000001473011167321211700343370ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.skeiniso
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.skeiniso ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/skeiniso.py

Previous / Next / Contents


Skeiniso is an analyze viewer to display a gcode file in an isometric view.

The skeiniso manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skeiniso


Operation
Settings
  Animation
    Animation Line Quickening
    Animation Slide Show Rate
  Axis Rulings
  Banding
    Band Height
    Bottom Band Brightness
    Bottom Layer Brightness
    Bright Band Start
      From the Bottom
      From the Top
  Draw Arrows
  Export Menu
  Go Around Extruder Off Travel
  Layers
    Layer
    Layer Extra Span
  Line
  Mouse Mode
    Display Line
    Viewpoint Move
    Viewpoint Rotate
  Number of Fill Layers
    Number of Fill Bottom Layers
  Number of Fill Top Layers
  Scale
  Screen Inset
    Screen Horizontal Inset
    Screen Vertical Inset
  Viewpoint
    Viewpoint Latitude
    Viewpoint Longitude
  Width
    Width of Axis Negative Side
    Width of Axis Positive Side
    Width of Infill Thread
    Width of Fill Bottom Thread
    Width of Fill Top Thread
    Width of Loop Thread
    Width of Perimeter Inside Thread
    Width of Perimeter Outside Thread
    Width of Raft Thread
    Width of Selection Thread
    Width of Travel Thread
Icons
Gcodes
Examples

Operation


The default 'Activate Skeiniso' checkbox is off. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Skeiniso' checkbox is on, when skeiniso is run directly.

Skeiniso requires skeinforge comments in the gcode file to distinguish the loops and perimeters. If the comments are deleted, all threads will be displayed as generic threads. To get the penultimate file of the tool chain, just before export deletes the comments, select 'Save Penultimate Gcode' in export, and open the gcode file with the suffix '_penultimate.gcode' with skeiniso.

The viewer is simple, the viewpoint can only be moved in a sphere around the center of the model by changing the viewpoint latitude and longitude. Different regions of the model can be hidden by setting the width of the thread to zero. The alternating bands act as contour bands and their brightness and width can be changed.

Settings


Animation

Animation Line Quickening

Default is one.

The quickness of the tool animation over the quickness of the actual tool.

Animation Slide Show Rate

Default is two layers per second.

The rate, in layers per second, at which the layer changes when the soar or dive button is pressed..

Axis Rulings

Default is on.

When selected, rulings will be drawn on the axis lines.

Banding

Band Height

Default is five layers.

Defines the height of the band in layers, a pair of bands is twice that height.

Bottom Band Brightness

Default is 0.7.

Defines the ratio of the brightness of the bottom band over the brightness of the top band. The higher it is the brighter the bottom band will be.

Bottom Layer Brightness

Default is one.

Defines the ratio of the brightness of the bottom layer over the brightness of the top layer. With a low bottom layer brightness ratio the bottom of the model will be darker than the top of the model, as if it was being illuminated by a light just above the top.

Bright Band Start

Default choice is 'From the Top'.

The button group that determines where the bright band starts from.

From the Bottom
When selected, the bright bands will start from the bottom.

From the Top
When selected, the bright bands will start from the top.

Draw Arrows

Default is on.

When selected, arrows will be drawn at the end of each line segment.

Export Menu

When the submenu in the export menu item in the file menu is clicked, an export canvas dialog will be displayed, which can export the canvas to a file.

Go Around Extruder Off Travel

Default is off.

When selected, the display will include the travel when the extruder is off, which means it will include the nozzle wipe path if any.

Layers

Layer

Default is zero.

On the display window, the Up button increases the 'Layer' by one, and the Down button decreases the layer by one. When the layer displayed in the layer spin box is changed then <Return> is hit, the layer shown will be set to the spin box, to a mimimum of zero and to a maximum of the highest index layer.The Soar button increases the layer at the 'Animation Slide Show Rate', and the Dive (double left arrow button beside the layer field) button decreases the layer at the slide show rate.

Layer Extra Span

Default is a huge number.

The viewer will draw the layers in the range including the 'Layer' index and the 'Layer' index plus the 'Layer Extra Span'. If the 'Layer Extra Span' is negative, the layers viewed will start at the 'Layer' index, plus the 'Layer Extra Span', and go up to and include the 'Layer' index. If the 'Layer Extra Span' is zero, only the 'Layer' index layer will be displayed. If the 'Layer Extra Span' is positive, the layers viewed will start at the 'Layer' index, and go up to and include the 'Layer' index plus the 'Layer Extra Span'.

Line

Default is zero.

The index of the selected line on the layer that is highlighted when the 'Display Line' mouse tool is chosen. The line spin box up button increases the 'Line' by one. If the line index of the layer goes over the index of the last line, the layer index will be increased by one and the new line index will be zero. The down button decreases the line index by one. If the line index goes below the index of the first line, the layer index will be decreased by one and the new line index will be at the last line. When the line displayed in the line field is changed then <Return> is hit, the line shown will be set to the line field, to a mimimum of zero and to a maximum of the highest index line. The Soar button increases the line at the speed at which the extruder would move, times the 'Animation Line Quickening' ratio, and the Dive (double left arrow button beside the line field) button decreases the line at the animation line quickening ratio.

Mouse Mode

Default is 'Display Line'.

The mouse tool can be changed from the 'Mouse Mode' menu button or picture button. The mouse tools listen to the arrow keys when the canvas has the focus. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas.

Display Line

The 'Display Line' tool will display the highlight the selected line, and display the file line count, counting from one, and the gcode line itself. When the 'Display Line' tool is active, clicking the canvas will select the closest line to the mouse click.

Viewpoint Move

The 'Viewpoint Move' tool will move the viewpoint in the xy plane when the mouse is clicked and dragged on the canvas.

Viewpoint Rotate

The 'Viewpoint Rotate' tool will rotate the viewpoint around the origin, when the mouse is clicked and dragged on the canvas, or the arrow keys have been used and <Return> is pressed. The viewpoint can also be moved by dragging the mouse. The viewpoint latitude will be increased when the mouse is dragged from the center towards the edge. The viewpoint longitude will be changed by the amount around the center the mouse is dragged. This is not very intuitive, but I don't know how to do this the intuitive way and I have other stuff to develop. If the shift key is pressed; if the latitude is changed more than the longitude, only the latitude will be changed, if the longitude is changed more only the longitude will be changed.

Number of Fill Layers

Number of Fill Bottom Layers

Default is one.

The "Number of Fill Bottom Layers" is the number of layers at the bottom which will be colored olive.

Number of Fill Top Layers

Default is one.

The "Number of Fill Top Layers" is the number of layers at the top which will be colored blue.

Scale

Default is ten.

The scale setting is the scale of the image in pixels per millimeter, the higher the number, the greater the size of the display.

The zoom in mouse tool will zoom in the display at the point where the mouse was clicked, increasing the scale by a factor of two. The zoom out tool will zoom out the display at the point where the mouse was clicked, decreasing the scale by a factor of two.

Screen Inset

Screen Horizontal Inset

Default is one hundred.

The "Screen Horizontal Inset" determines how much the canvas will be inset in the horizontal direction from the edge of screen, the higher the number the more it will be inset and the smaller it will be.

Screen Vertical Inset

Default is two hundred and twenty.

The "Screen Vertical Inset" determines how much the canvas will be inset in the vertical direction from the edge of screen, the higher the number the more it will be inset and the smaller it will be..

Viewpoint

Viewpoint Latitude

Default is fifteen degrees.

The "Viewpoint Latitude" is the latitude of the viewpoint, a latitude of zero is the top pole giving a top view, a latitude of ninety gives a side view and a latitude of 180 gives a bottom view.

Viewpoint Longitude

Default is 210 degrees.

The "Viewpoint Longitude" is the longitude of the viewpoint.

Width

The width of each type of thread and of each axis can be changed. If the width is set to zero, the thread will not be visible.

Width of Axis Negative Side

Default is two.

Defines the width of the negative side of the axis.

Width of Axis Positive Side

Default is six.

Defines the width of the positive side of the axis.

Width of Infill Thread

Default is one.

The "Width of Infill Thread" sets the width of the green extrusion threads, those threads which are not loops and not part of the raft.

Width of Fill Bottom Thread

Default is two.

The "Width of Fill Bottom Thread" sets the width of the olive extrusion threads at the bottom of the model.

Width of Fill Top Thread

Default is two.

The "Width of Fill Top Thread" sets the width of the blue extrusion threads at the top of the model.

Width of Loop Thread

Default is three.

The "Width of Loop Thread" sets the width of the yellow loop threads, which are not perimeters.

Width of Perimeter Inside Thread

Default is eight.

The "Width of Perimeter Inside Thread" sets the width of the orange inside perimeter threads.

Width of Perimeter Outside Thread

Default is eight.

The "Width of Perimeter Outside Thread" sets the width of the red outside perimeter threads.

Width of Raft Thread

Default is one.

The "Width of Raft Thread" sets the width of the brown raft threads.

Width of Selection Thread

Default is six.

The "Width of Selection Thread" sets the width of the selected line.

Width of Travel Thread

Default is zero.

The "Width of Travel Thread" sets the width of the grey extruder off travel threads.

Icons


The dive, soar and zoom icons are from Mark James' soarSilk icon set 1.3 at:
http://www.famfamfam.com/lab/icons/silk/

Gcodes


An explanation of the gcodes is at:
http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter

and at:
http://reprap.org/bin/view/Main/MCodeReference

A gode example is at:
http://forums.reprap.org/file.php?12,file=565

Examples


Below are examples of skeiniso being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and skeiniso.py.

> python skeiniso.py
This brings up the skeiniso dialog.

> python skeiniso.py Screw Holder_penultimate.gcode
This brings up the skeiniso viewer to view the gcode file.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.display_line
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.view_move
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.view_rotate

 
Classes
       
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauRepository
SkeinisoRepository
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauWindow
SkeinWindow
Ruling
SkeinPane
SkeinisoSkein

 
class Ruling
     Methods defined here:
__init__(self, modelDistance, roundedRulingText)
Initialize the ruling.

 
class SkeinPane
    A class to hold the colored lines for a layer.
 
  Methods defined here:
__init__(self, sequenceIndex)
Create empty line lists.

 
class SkeinWindow(skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauWindow)
     Methods defined here:
__init__(self, repository, skein)
Initialize the skein window.
drawRuling(self, projectiveSpace, relativeRulingEnd, ruling, tags, viewBegin, viewEnd)
Draw ruling.
drawRulings(self, axisLine, projectiveSpace, rulings)
Draw rulings for the axis line.
drawSkeinPane(self, projectiveSpace, skeinPane)
Draw colored lines.
drawXYAxisLines(self, projectiveSpace)
Draw the x and y axis lines.
drawZAxisLine(self, projectiveSpace)
Draw the z axis line.
getCanvasRadius(self)
Get half of the minimum of the canvas height and width.
getCentered(self, coordinate)
Get the centered coordinate.
getCenteredScreened(self, coordinate)
Get the normalized centered coordinate.
getColoredLines(self)
Get the colored lines from the skein pane.
getCopy(self)
Get a copy of this window.
getCopyWithNewSkein(self)
Get a copy of this window with a new skein.
getDrawnColoredLine(self, arrowType, coloredLine, projectiveSpace, tags, width)
Draw colored line.
getDrawnColoredLineMotion(self, coloredLine, projectiveSpace, width)
Draw colored line with motion stipple and tag.
getDrawnColoredLineWithoutArrow(self, coloredLine, projectiveSpace, tags, width)
Draw colored line without an arrow.
getDrawnColoredLines(self, coloredLines, projectiveSpace, width)
Draw colored lines.
getDrawnSelectedColoredLine(self, coloredLine)
Get the drawn selected colored line.
getScreenComplex(self, pointComplex)
Get the point in screen perspective.
getScreenView(self, point, projectiveSpace)
Get the point in screen view perspective.
printHexadecimalColorName(self, name)
Print the color name in hexadecimal.
update(self)
Update the screen.

Methods inherited from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauWindow:
activateMouseModeTool(self)
Activate the mouse mode tool.
addCanvasMenuRootScrollSkein(self, repository, skein, suffix, title)
Add the canvas, menu bar, scroll bar, skein panes, tableau repository, root and skein.
addLayer(self, gridPosition)
Add the layer frame items.
addLine(self, gridPosition)
Add the line frame items.
addMouseInstantTool(self, fileName, gridPosition, mouseInstantTool)
Add the mouse instant tool and derived photo button.
addMouseToolsBind(self)
Add the mouse tool and bind button one clicked, button one released and motion.
addPhotoImage(self, fileName, gridPosition)
Get a PhotoImage button, grid the button and increment the grid position.
addScale(self, gridPosition)
Add the line frame items.
addSettingsMenuSetWindowGeometry(self, center)
Add the settings menu, center the scroll region, update, and set the window geometry.
button1(self, event)
The button was clicked.
buttonRelease1(self, event)
The button was released.
cancel(self, event=None)
Set all entities to their saved state.
cancelTimer(self, event=None)
Cancel the timer and set it to none.
cancelTimerResetButtons(self)
Cancel the timer and set it to none.
close(self, event=None)
The dialog was closed.
createMouseModeTool(self)
Create the mouse mode tool.
destroyAllDialogWindows(self)
Destroy all the dialog windows.
destroyMouseToolRaiseMouseButtons(self)
Destroy the mouse tool and raise the mouse buttons.
dive(self)
Dive, go down periodically.
diveCycle(self)
Start the dive cycle.
getAnimationLineDelay(self, coloredLine)
Get the animation line delay in milliseconds.
getDrawnLineText(self, location, tags, text)
Get the line text drawn on the canvas.
getEntityFromName(self, name)
Get the entity of the given name.
getPhotoButtonGridIncrement(self, commandFunction, fileName, gridPosition)
Get a PhotoImage button, grid the button and increment the grid position.
getRoundedRulingText(self, extraDecimalPlaces, number)
Get the rounded ruling text.
getRulingSeparationWidthPixels(self, rank)
Get the separation width in pixels.
getScrollPaneCenter(self)
Get the center of the scroll pane.
getScrollPaneFraction(self)
Get the scroll pane top left.
getSlideShowDelay(self)
Get the slide show delay in milliseconds.
getUpdateSkeinPanes(self)
Get the update skein panes.
isLineBelowZeroSetLayer(self)
Determine if the line index is below zero, and if so set the layer index.
isLineBeyondListSetLayer(self)
Determine if the line index is beyond the end of the list, and if so set the layer index.
keyPressDown(self, event)
The down arrow was pressed.
keyPressLeft(self, event)
The left arrow was pressed.
keyPressReturn(self, event)
The return key was pressed.
keyPressRight(self, event)
The right arrow was pressed.
keyPressUp(self, event)
The up arrow was pressed.
layerEntryReturnPressed(self, event=None)
The layer index entry return was pressed.
limitIndex(self)
Limit the index so it is not below zero or above the top.
limitIndexSetArrowMouseDeleteCanvas(self)
Limit the index, set the arrow type, and delete all the canvas items.
lineDive(self)
Line dive, go down periodically.
lineDiveCycle(self)
Start the line dive cycle.
lineEntryReturnPressed(self, event=None)
The line index entry return was pressed.
lineSoar(self)
Line soar, go up periodically.
lineSoarCycle(self)
Start the line soar cycle.
motion(self, event)
The mouse moved.
phoenixUpdate(self)
Update the skein, and deiconify a new window and destroy the old.
redisplayWindowUpdate(self, event=None)
Deiconify a new window and destroy the old.
relayXview(self, *args)
Relay xview changes.
relayYview(self, *args)
Relay yview changes.
resetPeriodicButtonsText(self)
Reset the text of the periodic buttons.
save(self)
Set the setting values to the display, save the new values.
scaleEntryReturnPressed(self, event=None)
The scale entry return was pressed.
setButtonImageText(self, button, text)
Set the text of the e periodic buttons.
setDisplayLayerIndex(self)
Set the display of the layer index entry field and buttons.
setInsetToCanvas(self, event=None)
Set the repository insets to the canvas.
setLayerIndex(self, layerIndex)
Set the layer index.
setLineButtonsState(self)
Set the state of the line buttons.
setWindowNewMouseTool(self, getNewMouseToolFunction, mouseTool)
Set the getNewMouseTool function and the update function.
setWindowToDisplaySavePhoenixUpdate(self, event=None)
Set the setting values to the display, save the new values, then call the update function.
setWindowToDisplaySaveUpdate(self, event=None)
Set the setting values to the display, save the new values, then call the update function.
shiftButtonRelease1(self, event)
The button was released while the shift key was pressed.
shiftMotion(self, event)
The mouse moved.
soar(self)
Soar, go up periodically.
soarCycle(self)
Start the soar cycle.
updateDeiconify(self, center=(0.5+0.5j))
Update and deiconify the window.
updateMouseToolIfSelection(self)
Update the mouse tool if it is a selection tool.
updateNewDestroyOld(self, scrollPaneCenter)
Update and deiconify a window and destroy the old.

 
class SkeinisoRepository(skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauRepository)
    A class to handle the skeiniso settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Write button has been clicked.

Methods inherited from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauRepository:
addAnimation(self)
Add the animation settings.
addScaleScreenSlide(self)
Add the scale, screen and slide show settings.
setToDisplaySave(self, event=None)
Set the setting values to the display, save the new values.

 
class SkeinisoSkein
    A class to write a get a scalable vector graphics text for a gcode skein.
 
  Methods defined here:
__init__(self)
addToPath(self, line, location)
Add a point to travel and maybe extrusion.
getLayerTop(self)
Get the layer top.
getLayerZoneIndex(self, z)
Get the layer zone index.
initializeActiveLocation(self)
Set variables to default.
linearCorner(self, splitLine)
Update the bounding corners.
linearMove(self, line, location)
Get statistics for a linear move.
moveColoredThreadToSkeinPane(self)
Move a colored thread to the skein pane.
parseCorner(self, line)
Parse a gcode line and use the location to update the bounding corners.
parseGcode(self, fileName, gcodeText, repository)
Parse gcode text and store the vector output.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the vector output.
setColoredLineColor(self, coloredLine, colorTuple)
Set the color and stipple of the colored line.
setColoredThread(self, colorTuple, lineList)
Set the colored thread, then move it to the line list and stipple of the colored line.

 
Functions
       
compareLayerSequence(first, second)
Get comparison in order to sort skein panes in ascending order of layer zone index then sequence index.
getNewRepository()
Get new repository.
getWindowAnalyzeFile(fileName)
Skeiniso a gcode file.
getWindowAnalyzeFileGivenText(fileName, gcodeText, repository=None)
Display a skeiniso gcode file for a gcode file.
getWindowGivenTextRepository(fileName, gcodeText, repository)
Display the gcode text in a skeiniso viewer.
main()
Display the skeiniso dialog.
writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText='')
Write a skeinisoed gcode file for a skeinforge gcode file, if 'Activate Skeiniso' is selected.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.skeinlayer.html000066400000000000000000001215371167321211700346640ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.skeinlayer
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.skeinlayer ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/skeinlayer.py

Previous / Next / Contents


Skeinlayer is an analyze viewer to display each layer of a gcode file.

The skeinlayer manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skeinlayer

Skeinlayer is derived from Nophead's preview script. The extruded lines are in the resistor colors red, orange, yellow, green, blue, purple & brown. When the extruder is off, the travel line is grey. Skeinlayer is useful for a detailed view of the extrusion, skeiniso is better to see the orientation of the shape. To get an initial overview of the skein, when the skeinlayer display window appears, click the Soar button (double right arrow button beside the layer field).


Operation
Settings
  Animation
    Animation Line Quickening
    Animation Slide Show Rate
  Draw Arrows
  Export Menu
  Go Around Extruder Off Travel
  Layers
    Layer
    Layer Extra Span
  Line
  Mouse Mode
    Display Line
    Viewpoint Move
  Numeric Pointer
  Scale
  Screen Inset
    Screen Horizontal Inset
    Screen Vertical Inset
  Width
    Width of Extrusion Thread
    Width of Selection Thread
    Width of Travel Thread
Icons
Gcodes
Examples

Operation


The default 'Activate Skeinlayer' checkbox is on. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Skeinlayer' checkbox is on, when skeinlayer is run directly. Skeinlayer has trouble separating the layers when it reads gcode without comments.

Settings


Animation

Animation Line Quickening

Default is one.

The quickness of the tool animation over the quickness of the actual tool.

Animation Slide Show Rate

Default is two layers per second.

The rate, in layers per second, at which the layer changes when the soar or dive button is pressed..

Draw Arrows

Default is on.

When selected, arrows will be drawn at the end of each line segment.

Export Menu

When the submenu in the export menu item in the file menu is clicked, an export canvas dialog will be displayed, which can export the canvas to a file.

Go Around Extruder Off Travel

Default is off.

When selected, the display will include the travel when the extruder is off, which means it will include the nozzle wipe path if any.

Layers

Layer

Default is zero.

On the display window, the Up button increases the 'Layer' by one, and the Down button decreases the layer by one. When the layer displayed in the layer spin box is changed then <Return> is hit, the layer shown will be set to the spin box, to a mimimum of zero and to a maximum of the highest index layer.The Soar button increases the layer at the 'Animation Slide Show Rate', and the Dive (double left arrow button beside the layer field) button decreases the layer at the slide show rate.

Layer Extra Span

Default is zero.

The viewer will draw the layers in the range including the 'Layer' index and the 'Layer' index plus the 'Layer Extra Span'. If the 'Layer Extra Span' is negative, the layers viewed will start at the 'Layer' index, plus the 'Layer Extra Span', and go up to and include the 'Layer' index. If the 'Layer Extra Span' is zero, only the 'Layer' index layer will be displayed. If the 'Layer Extra Span' is positive, the layers viewed will start at the 'Layer' index, and go up to and include the 'Layer' index plus the 'Layer Extra Span'.

Line

Default is zero.

The index of the selected line on the layer that is highlighted when the 'Display Line' mouse tool is chosen. The line spin box up button increases the 'Line' by one. If the line index of the layer goes over the index of the last line, the layer index will be increased by one and the new line index will be zero. The down button decreases the line index by one. If the line index goes below the index of the first line, the layer index will be decreased by one and the new line index will be at the last line. When the line displayed in the line field is changed then <Return> is hit, the line shown will be set to the line field, to a mimimum of zero and to a maximum of the highest index line. The Soar button increases the line at the speed at which the extruder would move, times the 'Animation Line Quickening' ratio, and the Dive (double left arrow button beside the line field) button decreases the line at the animation line quickening ratio.

Mouse Mode

Default is 'Display Line'.

The mouse tool can be changed from the 'Mouse Mode' menu button or picture button. The mouse tools listen to the arrow keys when the canvas has the focus. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas.

Display Line

The 'Display Line' tool will display the highlight the selected line, and display the file line count, counting from one, and the gcode line itself. When the 'Display Line' tool is active, clicking the canvas will select the closest line to the mouse click.

Viewpoint Move

The 'Viewpoint Move' tool will move the viewpoint in the xy plane when the mouse is clicked and dragged on the canvas.

Numeric Pointer

Default is on.

When selected, the distance along the ruler of the arrow pointers will be drawn next to the pointers.

Scale

Default is ten.

The scale setting is the scale of the image in pixels per millimeter, the higher the number, the greater the size of the display.

The zoom in mouse tool will zoom in the display at the point where the mouse was clicked, increasing the scale by a factor of two. The zoom out tool will zoom out the display at the point where the mouse was clicked, decreasing the scale by a factor of two.

Screen Inset

Screen Horizontal Inset

Default is one hundred.

The "Screen Horizontal Inset" determines how much the canvas will be inset in the horizontal direction from the edge of screen, the higher the number the more it will be inset and the smaller it will be.

Screen Vertical Inset

Default is two hundred and twenty.

The "Screen Vertical Inset" determines how much the canvas will be inset in the vertical direction from the edge of screen, the higher the number the more it will be inset and the smaller it will be.

Width

The width of each type of thread and of each axis can be changed. If the width is set to zero, the thread will not be visible.

Width of Extrusion Thread

Default is three.

The "Width of Extrusion Thread" sets the width of the extrusion threads.

Width of Selection Thread

Default is six.

The "Width of Selection Thread" sets the width of the selected line.

Width of Travel Thread

Default is one.

The "Width of Travel Thread" sets the width of the grey extruder off travel threads.

Icons


The dive, soar and zoom icons are from Mark James' soarSilk icon set 1.3 at:
http://www.famfamfam.com/lab/icons/silk/

Gcodes


An explanation of the gcodes is at:
http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter

and at:
http://reprap.org/bin/view/Main/MCodeReference

A gode example is at:
http://forums.reprap.org/file.php?12,file=565

Examples


Below are examples of skeinlayer being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and skeinlayer.py.

> python skeinlayer.py
This brings up the skeinlayer dialog.

> python skeinlayer.py Screw Holder_penultimate.gcode
This brings up the skeinlayer viewer to view each layer of a gcode file.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.display_line
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.view_move

 
Classes
       
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauRepository
SkeinlayerRepository
skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauWindow
SkeinWindow
SkeinlayerSkein

 
class SkeinWindow(skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauWindow)
     Methods defined here:
__init__(self, repository, skein)
Initialize the skein window.setWindowNewMouseTool
addHorizontalRulerRuling(self, xMillimeters)
Add a ruling to the horizontal ruler.
addVerticalRulerRuling(self, yMillimeters)
Add a ruling to the vertical ruler.
createHorizontalLine(self, begin, yPixel)
Create a horizontal line for the horizontal ruler.
createRulers(self)
Create the rulers..
createVerticalLine(self, begin, xPixel)
Create a vertical line for the horizontal ruler.
getColoredLines(self)
Get the colored lines from the skein pane.
getCopy(self)
Get a copy of this window.
getCopyWithNewSkein(self)
Get a copy of this window with a new skein.
getDrawnColoredLine(self, coloredLine, tags, width)
Get the drawn colored line.
getDrawnColoredLineIfThick(self, coloredLine, width)
Get the drawn colored line if it has a positive thickness.
getDrawnSelectedColoredLine(self, coloredLine)
Get the drawn selected colored line.
motion(self, event)
The mouse moved.
qqqmotion(self, event)
The mouse moved.
relayXview(self, *args)
Relay xview changes.
relayYview(self, *args)
Relay yview changes.
update(self)
Update the window.

Methods inherited from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauWindow:
activateMouseModeTool(self)
Activate the mouse mode tool.
addCanvasMenuRootScrollSkein(self, repository, skein, suffix, title)
Add the canvas, menu bar, scroll bar, skein panes, tableau repository, root and skein.
addLayer(self, gridPosition)
Add the layer frame items.
addLine(self, gridPosition)
Add the line frame items.
addMouseInstantTool(self, fileName, gridPosition, mouseInstantTool)
Add the mouse instant tool and derived photo button.
addMouseToolsBind(self)
Add the mouse tool and bind button one clicked, button one released and motion.
addPhotoImage(self, fileName, gridPosition)
Get a PhotoImage button, grid the button and increment the grid position.
addScale(self, gridPosition)
Add the line frame items.
addSettingsMenuSetWindowGeometry(self, center)
Add the settings menu, center the scroll region, update, and set the window geometry.
button1(self, event)
The button was clicked.
buttonRelease1(self, event)
The button was released.
cancel(self, event=None)
Set all entities to their saved state.
cancelTimer(self, event=None)
Cancel the timer and set it to none.
cancelTimerResetButtons(self)
Cancel the timer and set it to none.
close(self, event=None)
The dialog was closed.
createMouseModeTool(self)
Create the mouse mode tool.
destroyAllDialogWindows(self)
Destroy all the dialog windows.
destroyMouseToolRaiseMouseButtons(self)
Destroy the mouse tool and raise the mouse buttons.
dive(self)
Dive, go down periodically.
diveCycle(self)
Start the dive cycle.
getAnimationLineDelay(self, coloredLine)
Get the animation line delay in milliseconds.
getDrawnLineText(self, location, tags, text)
Get the line text drawn on the canvas.
getEntityFromName(self, name)
Get the entity of the given name.
getPhotoButtonGridIncrement(self, commandFunction, fileName, gridPosition)
Get a PhotoImage button, grid the button and increment the grid position.
getRoundedRulingText(self, extraDecimalPlaces, number)
Get the rounded ruling text.
getRulingSeparationWidthPixels(self, rank)
Get the separation width in pixels.
getScrollPaneCenter(self)
Get the center of the scroll pane.
getScrollPaneFraction(self)
Get the scroll pane top left.
getSlideShowDelay(self)
Get the slide show delay in milliseconds.
getUpdateSkeinPanes(self)
Get the update skein panes.
isLineBelowZeroSetLayer(self)
Determine if the line index is below zero, and if so set the layer index.
isLineBeyondListSetLayer(self)
Determine if the line index is beyond the end of the list, and if so set the layer index.
keyPressDown(self, event)
The down arrow was pressed.
keyPressLeft(self, event)
The left arrow was pressed.
keyPressReturn(self, event)
The return key was pressed.
keyPressRight(self, event)
The right arrow was pressed.
keyPressUp(self, event)
The up arrow was pressed.
layerEntryReturnPressed(self, event=None)
The layer index entry return was pressed.
limitIndex(self)
Limit the index so it is not below zero or above the top.
limitIndexSetArrowMouseDeleteCanvas(self)
Limit the index, set the arrow type, and delete all the canvas items.
lineDive(self)
Line dive, go down periodically.
lineDiveCycle(self)
Start the line dive cycle.
lineEntryReturnPressed(self, event=None)
The line index entry return was pressed.
lineSoar(self)
Line soar, go up periodically.
lineSoarCycle(self)
Start the line soar cycle.
phoenixUpdate(self)
Update the skein, and deiconify a new window and destroy the old.
redisplayWindowUpdate(self, event=None)
Deiconify a new window and destroy the old.
resetPeriodicButtonsText(self)
Reset the text of the periodic buttons.
save(self)
Set the setting values to the display, save the new values.
scaleEntryReturnPressed(self, event=None)
The scale entry return was pressed.
setButtonImageText(self, button, text)
Set the text of the e periodic buttons.
setDisplayLayerIndex(self)
Set the display of the layer index entry field and buttons.
setInsetToCanvas(self, event=None)
Set the repository insets to the canvas.
setLayerIndex(self, layerIndex)
Set the layer index.
setLineButtonsState(self)
Set the state of the line buttons.
setWindowNewMouseTool(self, getNewMouseToolFunction, mouseTool)
Set the getNewMouseTool function and the update function.
setWindowToDisplaySavePhoenixUpdate(self, event=None)
Set the setting values to the display, save the new values, then call the update function.
setWindowToDisplaySaveUpdate(self, event=None)
Set the setting values to the display, save the new values, then call the update function.
shiftButtonRelease1(self, event)
The button was released while the shift key was pressed.
shiftMotion(self, event)
The mouse moved.
soar(self)
Soar, go up periodically.
soarCycle(self)
Start the soar cycle.
updateDeiconify(self, center=(0.5+0.5j))
Update and deiconify the window.
updateMouseToolIfSelection(self)
Update the mouse tool if it is a selection tool.
updateNewDestroyOld(self, scrollPaneCenter)
Update and deiconify a window and destroy the old.

 
class SkeinlayerRepository(skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauRepository)
    A class to handle the skeinlayer settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Write button has been clicked.

Methods inherited from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.tableau.TableauRepository:
addAnimation(self)
Add the animation settings.
addScaleScreenSlide(self)
Add the scale, screen and slide show settings.
setToDisplaySave(self, event=None)
Set the setting values to the display, save the new values.

 
class SkeinlayerSkein
    A class to write a get a scalable vector graphics text for a gcode skein.
 
  Methods defined here:
__init__(self)
Initialize.
addToPath(self, line, location)
Add a point to travel and maybe extrusion.
getModelCoordinates(self, screenCoordinates)
Get the model coordinates.
getScreenCoordinates(self, pointComplex)
Get the screen coordinates.
initializeActiveLocation(self)
Set variables to default.
linearCorner(self, splitLine)
Update the bounding corners.
linearMove(self, line, location)
Get statistics for a linear move.
parseCorner(self, line)
Parse a gcode line and use the location to update the bounding corners.
parseGcode(self, fileName, gcodeText, repository)
Parse gcode text and store the vector output.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the vector output.

 
Functions
       
getNewRepository()
Get new repository.
getRankIndex(rulingSeparationWidthMillimeters, screenOrdinate)
Get rank index.
getWindowAnalyzeFile(fileName)
Display a gcode file in a skeinlayer window.
getWindowAnalyzeFileGivenText(fileName, gcodeText, repository=None)
Display a gcode file in a skeinlayer window given the text.
getWindowGivenTextRepository(fileName, gcodeText, repository)
Display a gcode file in a skeinlayer window given the text and settings.
main()
Display the skeinlayer dialog.
writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText='')
Display a skeinlayered gcode file for a skeinforge gcode file, if 'Activate Skeinlayer' is selected.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.statistic.html000066400000000000000000000343721167321211700345250ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.statistic
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.statistic ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/statistic.py

Previous / Next / Contents


Statistic is an extremely valuable analyze plugin to print and/or save the statistics of the generated gcode.

The statistic manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Statistic


Operation
Settings
  Extrusion Diameter over Thickness
  Print Statistics
  Save Statistics
Gcodes
Examples

Operation


The default 'Activate Statistic' checkbox is on. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Statistic' checkbox is on, when statistic is run directly.

Settings


Extrusion Diameter over Thickness

Default is 1.25.

The 'Extrusion Diameter over Thickness is the ratio of the extrusion diameter over the layer thickness, the default is 1.25. The extrusion fill density ratio that is printed to the console, ( it is derived quantity not a parameter ) is the area of the extrusion diameter over the extrusion width over the layer thickness. Assuming the extrusion diameter is correct, a high value means the filament will be packed tightly, and the object will be almost as dense as the filament. If the fill density ratio is too high, there could be too little room for the filament, and the extruder will end up plowing through the extra filament. A low fill density ratio means the filaments will be far away from each other, the object will be leaky and light. The fill density ratio with the default extrusion settings is around 0.68.

Print Statistics

Default is on.

When the 'Print Statistics' checkbox is on, the statistics will be printed to the console.

Save Statistics

Default is off.

When the 'Save Statistics' checkbox is on, the statistics will be saved as a .txt file.

Gcodes


An explanation of the gcodes is at:
http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter

and at:
http://reprap.org/bin/view/Main/MCodeReference

A gode example is at:
http://forums.reprap.org/file.php?12,file=565

Examples


Below are examples of statistic being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and statistic.py. The 'Save Statistics' checkbox is selected.

> python statistic.py
This brings up the statistic dialog.

> python statistic.py Screw Holder_penultimate.gcode
Statistics are being generated for the file /home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/models/Screw Holder_penultimate.gcode

Cost
Machine time cost is 0.31$.
Material cost is 0.2$.
Total cost is 0.51$.

Extent
X axis extrusion starts at 61 mm and ends at 127 mm, for a width of 65 mm.
Y axis extrusion starts at 81 mm and ends at 127 mm, for a depth of 45 mm.
Z axis extrusion starts at 0 mm and ends at 15 mm, for a height of 15 mm.

Extruder
Build time is 18 minutes 47 seconds.
Distance extruded is 46558.4 mm.
Distance traveled is 58503.3 mm.
Extruder speed is 50.0
Extruder was extruding 79.6 percent of the time.
Extruder was toggled 1688 times.
Operating flow rate is 9.8 mm3/s.
Feed rate average is 51.9 mm/s, (3113.8 mm/min).

Filament
Cross section area is 0.2 mm2.
Extrusion diameter is 0.5 mm.
Extrusion fill density ratio is 0.68

Material
Mass extruded is 9.8 grams.
Volume extruded is 9.1 cc.

Meta
Text has 33738 lines and a size of 1239.0 KB.
Version is 11.09.28

Procedures
carve
bottom
preface
inset
fill
multiply
speed
temperature
raft
skirt
dimension
bookend

Profile
UM-PLA-HighQuality

Slice
Layer thickness is 0.4 mm.
Perimeter width is 0.72 mm.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
StatisticRepository
StatisticSkein

 
class StatisticRepository
    A class to handle the statistics settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Write button has been clicked.

 
class StatisticSkein
    A class to get statistics for a gcode skein.
 
  Methods defined here:
__init__(self)
addLine(self, line)
Add a line of text and a newline to the output.
addToPath(self, location)
Add a point to travel and maybe extrusion.
extruderSet(self, active)
Maybe increment the number of times the extruder was toggled.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the statistics.
getLocationSetFeedRateToSplitLine(self, splitLine)
Get location ans set feed rate to the plsit line.
helicalMove(self, isCounterclockwise, splitLine)
Get statistics for a helical move.
linearMove(self, splitLine)
Get statistics for a linear move.
parseLine(self, line)
Parse a gcode line and add it to the statistics.

 
Functions
       
getNewRepository()
Get new repository.
getWindowAnalyzeFile(fileName)
Write statistics for a gcode file.
getWindowAnalyzeFileGivenText(fileName, gcodeText, repository=None)
Write statistics for a gcode file.
main()
Display the statistics dialog.
writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText='')
Write statistics for a skeinforge gcode file, if 'Write Statistics File for Skeinforge Chain' is selected.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.analyze_plugins.synopsis.html000066400000000000000000000315231167321211700344000ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.synopsis
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.synopsis ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/synopsis.py

Previous / Next / Contents


Synopsis is an analyze plugin to export the profile from a skeinforge gcode file as a csv or zip file.

The synopsis manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Synopsis


Operation
Settings
  Export Profile As CSV File
  Export Profile As Zip File
Examples

Operation


The default 'Activate Synopsis' checkbox is off. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Synopsis' checkbox is on, when synopsis is run directly.

Settings


Export Profile As CSV File

Default is on.

If 'Export Profile As CSV File' is selected, the profile from a skeinforge gcode file with comments will be exported as a csv (comma separated values) file.

Export Profile As Zip File

Default is off.

If 'Export Profile As Zip File' is selected, the profile from a skeinforge gcode file with comments will be exported as a zip file.

Examples


Below are examples of synopsis being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and synopsis.py.

> python synopsis.py
This brings up the synopsis dialog.

> python synopsis.py Screw Holder_penultimate.gcode
The synopsis file is saved as Screw_Holder_penultimate_synopsis.csv


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
time
zipfile

 
Classes
       
AbridgedSetting
FileNamePath
SynopsisRepository

 
class AbridgedSetting
    A class to handle an abridged setting.
 
  Methods defined here:
__init__(self, splitLine)
Initialize.
__repr__(self)
Get the tab separated representation of this AbridgedSetting.

 
class FileNamePath
    A class to handle a file name and path.
 
  Methods defined here:
__init__(self, directoryName, fileName)
Initialize.
__repr__(self)
Get the tab separated representation of this FileNamePath.

 
class SynopsisRepository
    A class to handle the synopsis settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Write button has been clicked.

 
Functions
       
addAbridgedSettings(abridgedSettings, repositoryWriter)
Add the abridged settings to a repository writer.
exportProfileAsCSVFile(abridgedSettings, suffixFileNameWithoutExtension)
Export the profile from the gcode text as a csv file.
exportProfileAsZipFile(abridgedSettings, suffixDirectoryPath, suffixFileNameWithoutExtension)
Export the profile from the gcode text as a zip file.
getAbridgedSettings(gcodeText)
Get the abridged settings from the gcode text.
getNewRepository()
Get new repository.
getWindowAnalyzeFile(fileName)
Write scalable vector graphics for a gcode file.
getWindowAnalyzeFileGivenText(fileName, gcodeText, repository=None)
Write scalable vector graphics for a gcode file given the settings.
main()
Display the synopsis dialog.
writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText='')
Write scalable vector graphics for a skeinforge gcode file, if activate synopsis is selected.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Gary Hodgson <http://garyhodgson.com/reprap/2011/06/hacking-skeinforge-export-module/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Gary Hodgson <http://garyhodgson.com/reprap/2011/06/hacking-skeinforge-export-module/>
skeinforge_application.skeinforge_plugins.analyze_plugins.vectorwrite.html000066400000000000000000000502671167321211700350740ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.analyze_plugins.vectorwrite
 
 
skeinforge_application.skeinforge_plugins.analyze_plugins.vectorwrite ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/analyze_plugins/vectorwrite.py

Previous / Next / Contents


Vectorwrite is a very interesting analyze plugin that will create an SVG vector image for each layer that you can then use in some other printing system.

The Scalable Vector Graphics file can be opened by an SVG viewer or an SVG capable browser like Mozilla:
http://www.mozilla.com/firefox/

The vectorwrite manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Vectorwrite


Operation
Settings
  Add Loops
  Add Paths
  Add Perimeters
  Layers
    Layers From
    Layers To
  SVG Viewer
Examples

Operation


The default 'Activate Vectorwrite' checkbox is off. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Vectorwrite' checkbox is on, when vectorwrite is run directly.

Settings


Add Loops

Default is on.

If 'Add Loops' is selected, the loops will be added in yellow to the the scalable vector graphics output.

Add Paths

Default is on.

If 'Add Paths' is selected, the paths will be added in pink to the the scalable vector graphics output.

Add Perimeters

Default is on.

If 'Add Perimeters' is selected, the perimeters will be added to the the scalable vector graphics output. The outer perimeters will be red and the inner perimeters will be orange.

Layers

Layers From

Default is zero.

The "Layers From" is the index of the bottom layer that will be displayed. If the layer from is the default zero, the display will start from the lowest layer. If the the layer from index is negative, then the display will start from the layer from index below the top layer.

Layers To

Default is a huge number, which will be limited to the highest index layer.

The "Layers To" is the index of the top layer that will be displayed. If the layer to index is a huge number like the default, the display will go to the top of the model, at least until we model habitats:) If the layer to index is negative, then the display will go to the layer to index below the top layer. The layer from until layer to index is a python slice.

SVG Viewer

Default is webbrowser.

If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.

Examples


Below are examples of vectorwrite being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and vectorwrite.py.

> python vectorwrite.py
This brings up the vectorwrite dialog.

> python vectorwrite.py Screw Holder_penultimate.gcode
The vectorwrite file is saved as Screw_Holder_penultimate_vectorwrite.svg


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
fabmetheus_utilities.svg_writer
sys
time

 
Classes
       
fabmetheus_utilities.svg_writer.SVGWriter
SVGWriterVectorwrite
ThreadLayer
VectorwriteRepository
VectorwriteSkein

 
class SVGWriterVectorwrite(fabmetheus_utilities.svg_writer.SVGWriter)
    A class to vectorwrite a carving.
 
  Methods defined here:
addLoopLayerToOutput(self, layerIndex, threadLayer)
Add rotated boundary layer to the output.
addPaths(self, colorName, paths, transformString)
Add paths to the output.

Methods inherited from fabmetheus_utilities.svg_writer.SVGWriter:
__init__(self, addLayerTemplateToSVG, cornerMaximum, cornerMinimum, decimalPlacesCarried, layerThickness, perimeterWidth=None)
Initialize.
addLayerBegin(self, layerIndex, loopLayer)
Add the start lines for the layer.
addLoopLayersToOutput(self, loopLayers)
Add rotated boundary layers to the output.
addOriginalAsComment(self, elementNode)
Add original elementNode as a comment.
getReplacedSVGTemplate(self, fileName, loopLayers, procedureName, elementNode=None)
Get the lines of text from the layer_template.svg file.
getRounded(self, number)
Get number rounded to the number of carried decimal places as a string.
getRoundedComplexString(self, point)
Get the rounded complex string.
getSVGStringForLoop(self, loop)
Get the svg loop string.
getSVGStringForLoops(self, loops)
Get the svg loops string.
getSVGStringForPath(self, path)
Get the svg path string.
getTransformString(self)
Get the svg transform string.
setDimensionTexts(self, key, valueString)
Set the texts to the valueString followed by mm.
setMetadataNoscriptElement(self, key, prefix, value)
Set the metadata value and the text.
setTexts(self, key, valueString)
Set the texts to the valueString.

 
class ThreadLayer
    Threads with a z.
 
  Methods defined here:
__init__(self, z)
__repr__(self)
Get the string representation of this loop layer.
getTotalNumberOfThreads(self)
Get the total number of loops, paths and perimeters.
maximize(self, vector3)
Maximize the vector3 over the loops, paths and perimeters.
minimize(self, vector3)
Minimize the vector3 over the loops, paths and perimeters.

 
class VectorwriteRepository
    A class to handle the vectorwrite settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Write button has been clicked.

 
class VectorwriteSkein
    A class to vectorwrite a carving.
 
  Methods defined here:
__init__(self)
Initialize.
addLoopLayer(self, z)
Add loop layer.
addToLoops(self)
Add the thread to the loops.
addToPerimeters(self)
Add the thread to the perimeters.
getCarveLayerThickness(self)
Get the layer thickness.
getCarvedSVG(self, fileName, gcodeText, repository)
Parse gnu triangulated surface text and store the vectorwrite gcode.
linearMove(self, splitLine)
Get statistics for a linear move.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the outset skein.
removeEmptyLayers(self)
Remove empty layers.

 
Functions
       
getNewRepository()
Get new repository.
getWindowAnalyzeFile(fileName)
Write scalable vector graphics for a gcode file.
getWindowAnalyzeFileGivenText(fileName, gcodeText, repository=None)
Write scalable vector graphics for a gcode file given the settings.
main()
Display the vectorwrite dialog.
writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText='')
Write scalable vector graphics for a skeinforge gcode file, if activate vectorwrite is selected.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Nophead <http://hydraraptor.blogspot.com/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Nophead <http://hydraraptor.blogspot.com/>
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft.html000066400000000000000000000204321167321211700304610ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft
 
 
skeinforge_application.skeinforge_plugins.craft ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft.py

Previous / Next / Contents


Craft is a script to access the plugins which craft a gcode file.

The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
CraftMenuSaveListener
CraftRadioButtonsSaveListener

 
class CraftMenuSaveListener
    A class to update a craft menu.
 
  Methods defined here:
__init__(self, menu, window)
Set the menu.
save(self)
Profile has been saved and profile menu should be updated.

 
class CraftRadioButtonsSaveListener
    A class to update the craft radio buttons.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
getFromRadioPlugins(self, radioPlugins, repository)
Initialize.
save(self)
Profile has been saved and craft radio plugins should be updated.
setRadioButtons(self)
Profile has been saved and craft radio plugins should be updated.

 
Functions
       
addSubmenus(menu, pluginFileName, pluginFolderPath, pluginPath)
Add a tool plugin menu.
addToCraftMenu(menu)
Add a craft plugin menu.
addToMenu(master, menu, repository, window)
Add a tool plugin menu.
getNewRepository()
Get new repository.
main()
Display the craft dialog.
writeOutput(fileName)
Craft a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.craft_plugins.alteration.html000066400000000000000000000312441167321211700343070ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.craft_plugins.alteration
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.alteration ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/alteration.py

Previous / Next / Contents


The alteration plugin adds the start and end files to the gcode.

This plugin also removes the alteration prefix tokens from the alteration lines. Alteration lines have a prefix token so they can go through the craft plugins without being modified. However, the tokens are not recognized by the firmware so they have to be removed before export. The alteration token is:
(<alterationDeleteThisPrefix/>)

The alteration manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Alteration


Operation
Settings
  Name of End File
  Name of Start File
  Replace Variable with Setting
Examples

Operation


The default 'Activate Alteration' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Alteration looks for alteration files in the alterations folder in the .skeinforge folder in the home directory. Alteration does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.

Name of End File

Default is 'end.gcode'.

If there is a file with the name of the "Name of End File" setting, it will be added to the very end of the gcode.

Name of Start File

Default is 'start.gcode'.

If there is a file with the name of the "Name of Start File" setting, it will be added to the very beginning of the gcode.

Replace Variable with Setting

Default: True

If 'Replace Variable with Setting' is selected and there is an alteration line with a setting token, the token will be replaced by the value.

For example, if there is an alteration line like:

M140 S<setting.chamber.BedTemperature>

the token would be replaced with the value and assuming the bed chamber was 60.0, the output would be:

M140 S60.0

Examples


The following examples add the alteration information to the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and alteration.py.

> python alteration.py
This brings up the alteration dialog.

> python alteration.py Screw Holder Bottom.stl
The alteration tool is parsing the file:
Screw Holder Bottom.stl
..
The alteration tool has created the file:
.. Screw Holder Bottom_alteration.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
AlterationRepository
AlterationSkein

 
class AlterationRepository
    A class to handle the alteration settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Alteration button has been clicked.

 
class AlterationSkein
    A class to alteration a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize.
addFromUpperLowerFile(self, fileName)
Add lines of text from the fileName or the lowercase fileName, if there is no file by the original fileName in the directory.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the bevel gcode.
getReplacedAlterationLine(self, alterationFileLine, searchIndex=0)
Get the alteration file line with variables replaced with the settings.
getReplacedAlterationText(self)
Replace the alteration lines if there are settings.
parseInitialization(self)
Parse gcode initialization and store the parameters.
setSettingDictionary(self)
Set the setting dictionary from the gcode text.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Alteration a gcode linear move text.
getCraftedTextFromText(gcodeText, repository=None)
Alteration a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the alteration dialog.
writeOutput(fileName, shouldAnalyze=True)
Alteration a gcode linear move file.  Chain alteration the gcode if the alteration procedure has not been done.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.bookend.html000066400000000000000000000270641167321211700336520ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.bookend
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.bookend ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/bookend.py

Previous / Next / Contents


Bookend adds the start and end files to the gcode.

The bookend manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Bookend


Operation
Settings
  Name of End File
  Name of Start File
Examples

Operation


The default 'Activate Bookend' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Bookend looks for alteration files in the alterations folder in the .skeinforge folder in the home directory. Bookend does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.

Name of End File

Default is 'end.gcode'.

If there is a file with the name of the "Name of End File" setting, it will be added to the very end of the gcode.

Name of Start File

Default is 'start.gcode'.

If there is a file with the name of the "Name of Start File" setting, it will be added to the very beginning of the gcode.

Examples


The following examples add the bookend information to the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and bookend.py.

> python bookend.py
This brings up the bookend dialog.

> python bookend.py Screw Holder Bottom.stl
The bookend tool is parsing the file:
Screw Holder Bottom.stl
..
The bookend tool has created the file:
.. Screw Holder Bottom_bookend.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
BookendRepository
BookendSkein

 
class BookendRepository
    A class to handle the bookend settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Bookend button has been clicked.

 
class BookendSkein
    A class to bookend a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize.
addFromUpperLowerFile(self, fileName)
Add lines of text from the fileName or the lowercase fileName, if there is no file by the original fileName in the directory.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the bevel gcode.
getReplacedAlterationLine(self, alterationFileLine, searchIndex=0)
Get the alteration file line with variables replaced with the settings.
getReplacedAlterationText(self)
Replace the alteration lines if there are settings.
parseInitialization(self)
Parse gcode initialization and store the parameters.
setSettingDictionary(self)
Set the setting dictionary from the gcode text.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Bookend a gcode linear move text.
getCraftedTextFromText(gcodeText, repository=None)
Bookend a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the bookend dialog.
writeOutput(fileName, shouldAnalyze=True)
Bookend a gcode linear move file.  Chain bookend the gcode if the bookend procedure has not been done.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.bottom.html000066400000000000000000000255251167321211700335350ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.bottom
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.bottom ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/bottom.py

Previous / Next / Contents


Bottom sets the bottom of the carving to the defined altitude.

The bottom manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Bottom


Operation
Settings
  Additional Height over Layer Thickness
  Altitude
  SVG Viewer
Examples

Operation


The default 'Activate Bottom' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Additional Height over Layer Thickness

Default is half.

The layers will start at the altitude plus the 'Additional Height over Layer Thickness' times the layer thickness. The default value of half means that the bottom layer is at the height of the bottom slice, because each slice is made through the middle of each layer. Raft expects the layers to start at an additional half layer thickness. You should only change 'Additional Height over Layer Thickness' if you are manipulating the skeinforge output with your own program which does not use the raft tool.

Altitude

Default is zero.

Defines the altitude of the bottom of the model. The bottom slice has a z of the altitude plus the 'Additional Height over Layer Thickness' times the layer thickness.

SVG Viewer

Default is webbrowser.

If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.

Examples


The following examples bottom the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and bottom.py.

> python bottom.py
This brings up the bottom dialog.

> python bottom.py Screw Holder Bottom.stl
The bottom tool is parsing the file:
Screw Holder Bottom.stl
..
The bottom tool has created the file:
.. Screw Holder Bottom_bottom.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
fabmetheus_utilities.svg_writer
sys
time
fabmetheus_utilities.xml_simple_writer

 
Classes
       
BottomRepository
BottomSkein

 
class BottomRepository
    A class to handle the bottom settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Bottom button has been clicked.

 
class BottomSkein
    A class to bottom a skein of extrusions.
 
  Methods defined here:
getCraftedGcode(self, fileName, repository, svgText)
Parse svgText and store the bottom svgText.

 
Functions
       
getCraftedText(fileName, svgText='', repository=None)
Bottom and convert an svg file or svgText.
getCraftedTextFromText(fileName, svgText, repository=None)
Bottom and convert an svgText.
getNewRepository()
Get new repository.
main()
Display the bottom dialog.
writeOutput(fileName, shouldAnalyze=True)
Bottom the carving.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.carve.html000066400000000000000000000360471167321211700333320ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.carve
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.carve ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/carve.py

Previous / Next / Contents


Carve is the most important plugin to define for your printer.

It carves a shape into svg slice layers. It also sets the layer thickness and perimeter width for the rest of the tool chain.

The carve manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Carve

On the Arcol Blog a method of deriving the layer thickness is posted. That article "Machine Calibrating" is at:
http://blog.arcol.hu/?p=157


Settings
  Add Layer Template to SVG
  Extra Decimal Places
  Import Coarseness
  Layer Thickness
  Layers
    Layers From
    Layers To
  Mesh Type
    Correct Mesh
    Unproven Mesh
  Perimeter Width over Thickness
  SVG Viewer
Examples

Settings


Add Layer Template to SVG

Default is on.

When selected, the layer template will be added to the svg output, which adds javascript control boxes. So 'Add Layer Template to SVG' should be selected when the svg will be viewed in a browser.

When off, no controls will be added, the svg output will only include the fabrication paths. So 'Add Layer Template to SVG' should be deselected when the svg will be used by other software, like Inkscape.

Extra Decimal Places

Default is two.

Defines the number of extra decimal places export will output compared to the number of decimal places in the layer thickness. The higher the 'Extra Decimal Places', the more significant figures the output numbers will have.

Import Coarseness

Default is one.

When a triangle mesh has holes in it, the triangle mesh slicer switches over to a slow algorithm that spans gaps in the mesh. The higher the 'Import Coarseness' setting, the wider the gaps in the mesh it will span. An import coarseness of one means it will span gaps of the perimeter width.

Layer Thickness

Default is 0.4 mm.

Defines the the thickness of the layers skeinforge will cut your object into, in the z direction. This is the most important carve setting, many values in the toolchain are derived from the layer thickness.

For a 0.5 mm nozzle usable values are 0.3 mm to 0.5 mm. Note; if you are using thinner layers make sure to adjust the extrusion speed as well.

Layers

Carve slices from bottom to top. To get a single layer, set the "Layers From" to zero and the "Layers To" to one. The 'Layers From' until 'Layers To' range is a python slice.

Layers From

Default is zero.

Defines the index of the bottom layer that will be carved. If the 'Layers From' is the default zero, the carving will start from the lowest layer. If the 'Layers From' index is negative, then the carving will start from the 'Layers From' index below the top layer.

For example if your object is 5 mm tall and your layer thicknes is 1 mm if you set layers from to 3 you will ignore the first 3 mm and start from 3 mm.

Layers To

Default is a huge number, which will be limited to the highest index layer.

Defines the index of the top layer that will be carved. If the 'Layers To' index is a huge number like the default, the carving will go to the top of the model. If the 'Layers To' index is negative, then the carving will go to the 'Layers To' index below the top layer.

This is the same as layers from, only it defines when to end the generation of gcode.

Mesh Type

Default is 'Correct Mesh'.

Correct Mesh

When selected, the mesh will be accurately carved, and if a hole is found, carve will switch over to the algorithm that spans gaps.

Unproven Mesh

When selected, carve will use the gap spanning algorithm from the start. The problem with the gap spanning algothm is that it will span gaps, even if there is not actually a gap in the model.

Perimeter Width over Thickness

Default is 1.8.

Defines the ratio of the extrusion perimeter width to the layer thickness. This parameter tells skeinforge how wide the perimeter wall is expected to be in relation to the layer thickness. Default value of 1.8 for the default layer thickness of 0.4 states that a single filament perimeter wall should be 0.4 mm * 1.8 = 0.72 mm wide. The higher the value the more the perimeter will be inset. A ratio of one means the extrusion is a circle, the default ratio of 1.8 means the extrusion is a wide oval.

This is an important value because if you are calibrating your machine you need to ensure that the speed of the head and the extrusion rate in combination produce a wall that is 'Layer Thickness' * 'Perimeter Width over Thickness' wide. To start with 'Perimeter Width over Thickness' is probably best left at the default of 1.8 and the extrusion rate adjusted to give the correct calculated wall thickness.

Adjustment is in the 'Speed' section with 'Feed Rate' controlling speed of the head in X & Y and 'Flow Rate' controlling the extrusion rate. Initially it is probably easier to start adjusting the flow rate only a little at a time until you get a single filament of the correct width. If you change too many parameters at once you can get in a right mess.

SVG Viewer

Default is webbrowser.

If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.

Examples


The following examples carve the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and carve.py.

> python carve.py
This brings up the carve dialog.

> python carve.py Screw Holder Bottom.stl
The carve tool is parsing the file:
Screw Holder Bottom.stl
..
The carve tool has created the file:
.. Screw Holder Bottom_carve.svg


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
fabmetheus_utilities.svg_writer
sys
time

 
Classes
       
CarveRepository
CarveSkein

 
class CarveRepository
    A class to handle the carve settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Carve button has been clicked.

 
class CarveSkein
    A class to carve a carving.
 
  Methods defined here:
getCarvedSVG(self, carving, fileName, repository)
Parse gnu triangulated surface text and store the carved gcode.

 
Functions
       
getCraftedText(fileName, gcodeText='', repository=None)
Get carved text.
getNewRepository()
Get new repository.
main()
Display the carve dialog.
writeOutput(fileName, shouldAnalyze=True)
Carve a GNU Triangulated Surface file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.chamber.html000066400000000000000000000423201167321211700336220ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.chamber
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.chamber ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/chamber.py

Previous / Next / Contents


Some filaments contract too much and warp the extruded object. To prevent this you have to print the object in a temperature regulated chamber and/or on a temperature regulated bed. The chamber tool allows you to control the bed and chamber temperature and the holding pressure.

The chamber gcodes are also described at:

http://reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes

The chamber manual page is at:

http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Chamber


Operation
Settings
  Bed Temperature
  Chamber Temperature
  Holding Force
Heated Beds
  Bothacker
  Domingo
  Jmil
  Kulitorum
  Metalab
  Nophead
  Prusajr
  Pumpernickel2
  Zaggo
Examples

Operation


The default 'Activate Chamber' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Bed Temperature

Default is 60C.

Defines the print_bed temperature in Celcius by adding an M140 command.

Chamber Temperature

Default is 30C.

Defines the chamber temperature in Celcius by adding an M141 command.

Holding Force

Default is zero.

Defines the holding pressure of a mechanism, like a vacuum table or electromagnet, to hold the bed surface or object, by adding an M142 command. The holding pressure is in bars. For hardware which only has on/off holding, when the holding pressure is zero, turn off holding, when the holding pressure is greater than zero, turn on holding.

Heated Beds


Bothacker

A resistor heated aluminum plate by Bothacker:

http://bothacker.com

with an article at:

http://bothacker.com/2009/12/18/heated-build-platform/

Domingo

A heated copper build plate by Domingo:

http://casainho-emcrepstrap.blogspot.com/

with articles at:

http://casainho-emcrepstrap.blogspot.com/2010/01/first-time-with-pla-testing-it-also-on.html

http://casainho-emcrepstrap.blogspot.com/2010/01/call-for-helpideas-to-develop-heated.html

http://casainho-emcrepstrap.blogspot.com/2010/01/new-heated-build-platform.html

http://casainho-emcrepstrap.blogspot.com/2010/01/no-acrylic-and-instead-kapton-tape-on.html

http://casainho-emcrepstrap.blogspot.com/2010/01/problems-with-heated-build-platform-and.html

http://casainho-emcrepstrap.blogspot.com/2010/01/perfect-build-platform.html

http://casainho-emcrepstrap.blogspot.com/2009/12/almost-no-warp.html

http://casainho-emcrepstrap.blogspot.com/2009/12/heated-base-plate.html

Jmil

A heated build stage by jmil, over at:

http://www.hive76.org

with articles at:

http://www.hive76.org/handling-hot-build-surfaces

http://www.hive76.org/heated-build-stage-success

Kulitorum

Kulitorum has made a heated bed. It is a 5mm Alu sheet with a pattern laid out in kapton tape. The wire is a 0.6mm2 Konstantin wire and it's held in place by small pieces of kapton tape. The description and picture is at:

http://gallery.kulitorum.com/main.php?g2_itemId=283

Metalab

A heated base by the Metalab folks:

http://reprap.soup.io

with information at:

http://reprap.soup.io/?search=heated%20base

Nophead

A resistor heated aluminum bed by Nophead:

http://hydraraptor.blogspot.com

with articles at:

http://hydraraptor.blogspot.com/2010/01/will-it-stick.html

http://hydraraptor.blogspot.com/2010/01/hot-metal-and-serendipity.html

http://hydraraptor.blogspot.com/2010/01/new-year-new-plastic.html

http://hydraraptor.blogspot.com/2010/01/hot-bed.html

Prusajr

A resistive wire heated plexiglass plate by prusajr:

http://prusadjs.cz/

with articles at:

http://prusadjs.cz/2010/01/heated-reprap-print-bed-mk2/

http://prusadjs.cz/2009/11/look-ma-no-warping-heated-reprap-print-bed/

Pumpernickel2

A resistor heated aluminum plate by Pumpernickel2:

http://dev.forums.reprap.org/profile.php?14,844

with a picture at:

http://dev.forums.reprap.org/file.php?14,file=1228,filename=heatedplate.jpg

Zaggo

A resistor heated aluminum plate by Zaggo at Pleasant Software:

http://pleasantsoftware.com/developer/3d/

with articles at:

http://pleasantsoftware.com/developer/3d/2009/12/05/raftless/

http://pleasantsoftware.com/developer/3d/2009/11/15/living-in-times-of-warp-free-printing/

http://pleasantsoftware.com/developer/3d/2009/11/12/canned-heat/

Examples


The following examples chamber the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and chamber.py.

> python chamber.py
This brings up the chamber dialog.

> python chamber.py Screw Holder Bottom.stl
The chamber tool is parsing the file:
Screw Holder Bottom.stl
..
The chamber tool has created the file:
Screw Holder Bottom_chamber.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
ChamberRepository
ChamberSkein

 
class ChamberRepository
    A class to handle the chamber settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Chamber button has been clicked.

 
class ChamberSkein
    A class to chamber a skein of extrusions.
 
  Methods defined here:
__init__(self)
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the chamber gcode.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the chamber skein.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Chamber the file or text.
getCraftedTextFromText(gcodeText, repository=None)
Chamber a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the chamber dialog.
writeOutput(fileName, shouldAnalyze=True)
Chamber a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.chop.html000066400000000000000000000331111167321211700331500ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.chop
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.chop ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/chop.py

Previous / Next / Contents


Chop is a script to chop a shape into svg slice layers.


Settings
  Add Layer Template to SVG
  Add Extra Top Layer if Necessary
  Extra Decimal Places
  Import Coarseness
  Layer Thickness
  Layers
    Layers From
    Layers To
  Mesh Type
    Correct Mesh
    Unproven Mesh
  Perimeter Width
  SVG Viewer
Examples

Settings


Add Layer Template to SVG

Default is on.

When selected, the layer template will be added to the svg output, which adds javascript control boxes. So 'Add Layer Template to SVG' should be selected when the svg will be viewed in a browser.

When off, no controls will be added, the svg output will only include the fabrication paths. So 'Add Layer Template to SVG' should be deselected when the svg will be used by other software, like Inkscape.

Add Extra Top Layer if Necessary

Default is on.

When selected, chop will add an extra layer at the very top of the object if the top of the object is more than half the layer thickness above the first slice. This is so the cutting tool doesn't cut too deeply through the top of the object on its first pass.

Extra Decimal Places

Default is two.

Defines the number of extra decimal places export will output compared to the number of decimal places in the layer thickness. The higher the 'Extra Decimal Places', the more significant figures the output numbers will have.

Import Coarseness

Default is one.

When a triangle mesh has holes in it, the triangle mesh slicer switches over to a slow algorithm that spans gaps in the mesh. The higher the 'Import Coarseness' setting, the wider the gaps in the mesh it will span. An import coarseness of one means it will span gaps of the perimeter width.

Layer Thickness

Default is 0.4 mm.

Defines the thickness of the layer, this is the most important chop setting.

Layers

Chop slices from top to bottom. To get only the bottom layer, set the "Layers From" to minus one. The 'Layers From' until 'Layers To' range is a python slice.

Layers From

Default is zero.

Defines the index of the top layer that will be chopped. If the 'Layers From' is the default zero, the carving will start from the top layer. If the 'Layers From' index is negative, then the carving will start from the 'Layers From' index above the bottom layer.

Layers To

Default is a huge number, which will be limited to the highest index number.

Defines the index of the bottom layer that will be chopped. If the 'Layers To' index is a huge number like the default, the carving will go to the bottom of the model. If the 'Layers To' index is negative, then the carving will go to the 'Layers To' index above the bottom layer.

Mesh Type

Default is 'Correct Mesh'.

Correct Mesh

When selected, the mesh will be accurately chopped, and if a hole is found, chop will switch over to the algorithm that spans gaps.

Unproven Mesh

When selected, chop will use the gap spanning algorithm from the start. The problem with the gap spanning algothm is that it will span gaps, even if there is not actually a gap in the model.

Perimeter Width

Default is 2 mm.

Defines the width of the perimeter.

SVG Viewer

Default is webbrowser.

If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.

Examples


The following examples chop the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and chop.py.

> python chop.py
This brings up the chop dialog.

> python chop.py Screw Holder Bottom.stl
The chop tool is parsing the file:
Screw Holder Bottom.stl
..
The chop tool has created the file:
.. Screw Holder Bottom_chop.svg


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
fabmetheus_utilities.svg_writer
sys
time

 
Classes
       
ChopRepository
ChopSkein

 
class ChopRepository
    A class to handle the chop settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Chop button has been clicked.

 
class ChopSkein
    A class to chop a carving.
 
  Methods defined here:
addExtraTopLayerIfNecessary(self, carving, layerThickness, loopLayers)
Add extra top layer if necessary.
getCarvedSVG(self, carving, fileName, repository)
Parse gnu triangulated surface text and store the chopped gcode.

 
Functions
       
getCraftedText(fileName, gcodeText='', repository=None)
Get chopped text.
getNewRepository()
Get new repository.
main()
Display the chop dialog.
writeOutput(fileName, shouldAnalyze=True)
Chop a GNU Triangulated Surface file.  If no fileName is specified, chop the first GNU Triangulated Surface file in this folder.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.cleave.html000066400000000000000000000313601167321211700334620ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.cleave
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.cleave ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/cleave.py

Previous / Next / Contents


Cleave is a script to cleave a shape into svg slice layers.


Settings
  Add Layer Template to SVG
  Extra Decimal Places
  Import Coarseness
  Layer Thickness
  Layers
    Layers From
    Layers To
  Mesh Type
    Correct Mesh
    Unproven Mesh
  Perimeter Width
  SVG Viewer
Examples

Settings


Add Layer Template to SVG

Default is on.

When selected, the layer template will be added to the svg output, which adds javascript control boxes. So 'Add Layer Template to SVG' should be selected when the svg will be viewed in a browser.

When off, no controls will be added, the svg output will only include the fabrication paths. So 'Add Layer Template to SVG' should be deselected when the svg will be used by other software, like Inkscape.

Extra Decimal Places

Default is two.

Defines the number of extra decimal places export will output compared to the number of decimal places in the layer thickness. The higher the 'Extra Decimal Places', the more significant figures the output numbers will have.

Import Coarseness

Default is one.

When a triangle mesh has holes in it, the triangle mesh slicer switches over to a slow algorithm that spans gaps in the mesh. The higher the 'Import Coarseness' setting, the wider the gaps in the mesh it will span. An import coarseness of one means it will span gaps of the perimeter width.

Layer Thickness

Default is 0.4 mm.

Defines the thickness of the layer, this is the most important cleave setting.

Layers

Cleave slices from bottom to top. To get a single layer, set the "Layers From" to zero and the "Layers To" to one. The layer from until layer to range is a python slice.

Layers From

Default is zero.

Defines the index of the bottom layer that will be cleaved. If the layer from is the default zero, the carving will start from the lowest layer. If the 'Layers From' index is negative, then the carving will start from the 'Layers From' index below the top layer.

Layers To

Default is a huge number, which will be limited to the highest index layer.

Defines the index of the top layer that will be cleaved. If the 'Layers To' index is a huge number like the default, the carving will go to the top of the model. If the 'Layers To' index is negative, then the carving will go to the 'Layers To' index below the top layer.

Mesh Type

Default is 'Correct Mesh'.

Correct Mesh

When selected, the mesh will be accurately cleaved, and if a hole is found, cleave will switch over to the algorithm that spans gaps.

Unproven Mesh

When selected, cleave will use the gap spanning algorithm from the start. The problem with the gap spanning algothm is that it will span gaps, even if there is not actually a gap in the model.

Perimeter Width

Default is two millimeters.

Defines the width of the perimeter.

SVG Viewer

Default is webbrowser.

If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.

Examples


The following examples cleave the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and cleave.py.

> python cleave.py
This brings up the cleave dialog.

> python cleave.py Screw Holder Bottom.stl
The cleave tool is parsing the file:
Screw Holder Bottom.stl
..
The cleave tool has created the file:
.. Screw Holder Bottom_cleave.svg


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
fabmetheus_utilities.svg_writer
sys
time

 
Classes
       
CleaveRepository
CleaveSkein

 
class CleaveRepository
    A class to handle the cleave settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Cleave button has been clicked.

 
class CleaveSkein
    A class to cleave a carving.
 
  Methods defined here:
getCarvedSVG(self, carving, fileName, repository)
Parse gnu triangulated surface text and store the cleaved gcode.

 
Functions
       
getCraftedText(fileName, gcodeText='', repository=None)
Get cleaved text.
getNewRepository()
Get new repository.
main()
Display the cleave dialog.
writeOutput(fileName, shouldAnalyze=True)
Cleave a GNU Triangulated Surface file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.clip.html000066400000000000000000000315571167321211700331620ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.clip
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.clip ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/clip.py

Previous / Next / Contents


The clip plugin clips the loop ends to prevent bumps from forming, and connects loops.

The clip manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Clip


Operation
Settings
  Clip Over Perimeter Width
  Maximum Connection Distance Over Perimeter Width
Examples

Operation


The default 'Activate Clip' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Clip Over Perimeter Width

Default is 0.2.

Defines the ratio of the amount each end of the loop is clipped over the perimeter width. The total gap will therefore be twice the clip. If the ratio is too high loops will have a gap, if the ratio is too low there will be a bulge at the loop ends.

This setting will affect the output of clip, and the output of the skin. In skin the half width perimeters will be clipped by according to this setting.

Maximum Connection Distance Over Perimeter Width

Default is ten.

Defines the ratio of the maximum connection distance between loops over the perimeter width.

Clip will attempt to connect loops that end close to each other, combining them into a spiral, so that the extruder does not stop and restart. This setting sets the maximum gap size to connect. This feature can reduce the amount of extra material or gaps formed at the loop end.

Setting this to zero disables this feature, preventing the loops from being connected.

Examples


The following examples clip the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and clip.py.

> python clip.py
This brings up the clip dialog.

> python clip.py Screw Holder Bottom.stl
The clip tool is parsing the file:
Screw Holder Bottom.stl
..
The clip tool has created the file:
.. Screw Holder Bottom_clip.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
ClipRepository
ClipSkein

 
class ClipRepository
    A class to handle the clip settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Clip button has been clicked.

 
class ClipSkein
    A class to clip a skein of extrusions.
 
  Methods defined here:
__init__(self)
addGcodeFromThreadZ(self, thread, z)
Add a gcode thread to the output.
addSegmentToPixelTables(self, location, oldLocation)
Add the segment to the layer and mask table.
addTailoredLoopPath(self, line)
Add a clipped loop path.
getConnectionIsCloseWithoutOverlap(self, location, path)
Determine if the connection is close enough and does not overlap another thread.
getCraftedGcode(self, clipRepository, gcodeText)
Parse gcode text and store the clip gcode.
getNextThreadIsACloseLoop(self, path)
Determine if the next thread is a loop.
isNextExtruderOn(self)
Determine if there is an extruder on command before a move command.
linearMove(self, splitLine)
Add to loop path if this is a loop or path.
parseInitialization(self, clipRepository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the clip skein.
setLayerPixelTable(self)
Set the layer pixel table.

 
Functions
       
getCraftedText(fileName, text, clipRepository=None)
Clip a gcode linear move file or text.
getCraftedTextFromText(gcodeText, clipRepository=None)
Clip a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the clip dialog.
writeOutput(fileName, shouldAnalyze=True)
Clip a gcode linear move file.  Chain clip the gcode if it is not already clipped.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.coil.html000066400000000000000000000255431167321211700331570ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.coil
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.coil ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/coil.py

Previous / Next / Contents


Coil is a script to coil wire or filament around an object.


Operation
Settings
  Minimum Tool Distance
Examples

Operation


The default 'Activate Coil' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Minimum Tool Distance

Default is twenty millimeters.

Defines the minimum distance between the wire dispenser and the object. The 'Minimum Tool Distance' should be set to the maximum radius of the wire dispenser, times at least 1.3 to get a reasonable safety margin.

Examples


The following examples coil the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and coil.py.

> python coil.py
This brings up the coil dialog.

> python coil.py Screw Holder Bottom.stl
The coil tool is parsing the file:
Screw Holder Bottom.stl
..
The coil tool has created the file:
Screw Holder Bottom_coil.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
CoilRepository
CoilSkein

 
class CoilRepository
    A class to handle the coil settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Coil button has been clicked.

 
class CoilSkein
    A class to coil a skein of extrusions.
 
  Methods defined here:
__init__(self)
addCoilLayer(self, boundaryLayers, radius, z)
Add a coil layer.
addCoilLayers(self)
Add the coil layers.
addCoilToThread(self, beginLocation, endZ, loop, thread)
Add a coil to the thread.
addGcodeFromThread(self, thread)
Add a thread to the output.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the coil gcode.
parseBoundaries(self)
Parse the boundaries and add them to the boundary layers.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseUntilLayer(self)
Parse until the layer line and add it to the coil skein.

 
Functions
       
getCraftedText(fileName, gcodeText='', repository=None)
Coil the file or gcodeText.
getCraftedTextFromText(gcodeText, repository=None)
Coil a gcode linear move gcodeText.
getNewRepository()
Get new repository.
main()
Display the coil dialog.
writeOutput(fileName, shouldAnalyze=True)
Coil a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.comb.html000066400000000000000000000327521167321211700331510ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.comb
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.comb ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/comb.py

Previous / Next / Contents


Comb is a craft tool to comb the extrusion hair of a gcode file.

The comb manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Comb

Comb bends the extruder travel paths around holes in the slices, to avoid stringers. It moves the extruder to the inside of perimeters before turning the extruder on so any start up ooze will be inside the shape.


Operation
Settings
  Running Jump Space
Examples

Operation


The default 'Activate Comb' checkbox is off. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Running Jump Space

Placeholder.

Examples


The following examples comb the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and comb.py.

> python comb.py
This brings up the comb dialog.

> python comb.py Screw Holder Bottom.stl
The comb tool is parsing the file:
Screw Holder Bottom.stl
..
The comb tool has created the file:
.. Screw Holder Bottom_comb.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
CombRepository
CombSkein

 
class CombRepository
    A class to handle the comb settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Comb button has been clicked.

 
class CombSkein
    A class to comb a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize
addGcodePathZ(self, feedRateMinute, path, z)
Add a gcode path, without modifying the extruder, to the output.
addIfTravel(self, splitLine)
Add travel move around loops if the extruder is off.
addToLoop(self, location)
Add a location to loop.
getBetweens(self)
Set betweens for the layer.
getBoundaries(self)
Get boundaries for the layer.
getCraftedGcode(self, combRepository, gcodeText)
Parse gcode text and store the comb gcode.
getIsAsFarAndNotIntersecting(self, begin, end)
Determine if the point on the line is at least as far from the loop as the center point.
getIsRunningJumpPathAdded(self, betweens, end, lastPoint, closestEndMinusLastSegment, pathAround, penultimatePoint, runningJumpSpace)
Add a running jump path if possible, and return if it was added.
getPathBetween(self, loop, points)
Add a path between the perimeter and the fill.
getPathsBetween(self, begin, end)
Insert paths between the perimeter and the fill.
getSimplifiedAroundPath(self, begin, end, loop, pathAround)
Get the simplified path between the perimeter and the fill.
getSimplifiedBeginPath(self, begin, loop, pathAround)
Get the simplified begin path between the perimeter and the fill.
getSimplifiedEndPath(self, end, loop, pathAround)
Get the simplified end path between the perimeter and the fill.
parseBoundariesLayers(self, combRepository, line)
Parse a gcode line.
parseInitialization(self, combRepository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the comb skein.

 
Functions
       
getCraftedText(fileName, text, combRepository=None)
Comb a gcode linear move text.
getCraftedTextFromText(gcodeText, combRepository=None)
Comb a gcode linear move text.
getInsideness(path, loop)
Get portion of the path which is inside the loop.
getNewRepository()
Get new repository.
getPathsByIntersectedLoop(begin, end, loop)
Get both paths along the loop from the point closest to the begin to the point closest to the end.
main()
Display the comb dialog.
writeOutput(fileName, shouldAnalyze=True)
Comb a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.cool.html000066400000000000000000000425021167321211700331570ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.cool
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.cool ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py

Previous / Next / Contents


Cool is a craft tool to cool the shape.

Cool works well with a stepper extruder, it does not work well with a DC motor extruder.

If enabled, before each layer that takes less then "Minimum Layer Time" to print the tool head will orbit around the printed area for 'Minimum Layer Time' minus 'the time it takes to print the layer' before it starts printing the layer. This is great way to let layers with smaller area cool before you start printing on top of them (so you do not overheat the area).

The cool manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Cool

Allan Ecker aka The Masked Retriever's has written the "Skeinforge Quicktip: Cool" at:
http://blog.thingiverse.com/2009/07/28/skeinforge-quicktip-cool/


Operation
Settings
  Bridge Cool
  Cool Type
    Orbit
    Slow Down
  Maximum Cool
  Minimum Layer Time
  Minimum Orbital Radius
  Name of Alteration Files
    Name of Cool End File
    Name of Cool Start File
  Orbital Outset
  Turn Fan On at Beginning
  Turn Fan Off at Ending
Examples

Operation


The default 'Activate Cool' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Bridge Cool

Default is one degree Celcius.

If the layer is a bridge layer, then cool will lower the temperature by 'Bridge Cool' degrees Celcius.

Cool Type

Default is 'Slow Down'.

Orbit

When selected, cool will add orbits with the extruder off to give the layer time to cool, so that the next layer is not extruded on a molten base. The orbits will be around the largest island on that layer. Orbit should only be chosen if you can not upgrade to a stepper extruder.

Slow Down

When selected, cool will slow down the extruder so that it will take the minimum layer time to extrude the layer. DC motors do not operate properly at slow flow rates, so if you have a DC motor extruder, you should upgrade to a stepper extruder, but if you can't do that, you can try using the 'Orbit' option.

Maximum Cool

Default is 2 degrees Celcius.

If it takes less time to extrude the layer than the minimum layer time, then cool will lower the temperature by the 'Maximum Cool' setting times the layer time over the minimum layer time.

Minimum Layer Time

Default is 60 seconds.

Defines the minimum amount of time the extruder will spend on a layer, this is an important setting.

Minimum Orbital Radius

Default is 10 millimeters.

When the orbit cool type is selected, if the area of the largest island is as large as the square of the "Minimum Orbital Radius" then the orbits will be just within the island. If the island is smaller, then the orbits will be in a square of the "Minimum Orbital Radius" around the center of the island. This is so that the hot extruder does not stay too close to small islands.

Name of Alteration Files

Cool looks for alteration files in the alterations folder in the .skeinforge folder in the home directory. Cool does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder. The cool start and end text idea is from:
http://makerhahn.blogspot.com/2008/10/yay-minimug.html

Name of Cool End File

Default is cool_end.gcode.

If there is a file with the name of the "Name of Cool End File" setting, it will be added to the end of the orbits.

Name of Cool Start File

Default is cool_start.gcode.

If there is a file with the name of the "Name of Cool Start File" setting, it will be added to the start of the orbits.

Orbital Outset

Default is 2 millimeters.

When the orbit cool type is selected, the orbits will be outset around the largest island by 'Orbital Outset' millimeters. If 'Orbital Outset' is negative, the orbits will be inset instead.

Turn Fan On at Beginning

Default is on.

When selected, cool will turn the fan on at the beginning of the fabrication by adding the M106 command.

Turn Fan Off at Ending

Default is on.

When selected, cool will turn the fan off at the ending of the fabrication by adding the M107 command.

Examples


The following examples cool the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and cool.py.

> python cool.py
This brings up the cool dialog.

> python cool.py Screw Holder Bottom.stl
The cool tool is parsing the file:
Screw Holder Bottom.stl
..
The cool tool has created the file:
.. Screw Holder Bottom_cool.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
CoolRepository
CoolSkein

 
class CoolRepository
    A class to handle the cool settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Cool button has been clicked.

 
class CoolSkein
    A class to cool a skein of extrusions.
 
  Methods defined here:
__init__(self)
addCoolOrbits(self, remainingOrbitTime)
Add the minimum radius cool orbits.
addCoolTemperature(self, remainingOrbitTime)
Parse a gcode line and add it to the cool skein.
addFlowRate(self, flowRate)
Add a multipled line of flow rate if different.
addGcodeFromFeedRateMovementZ(self, feedRateMinute, point, z)
Add a movement to the output.
addOrbitsIfNecessary(self, remainingOrbitTime)
Parse a gcode line and add it to the cool skein.
addTemperature(self, temperature)
Add a line of temperature.
getCoolMove(self, line, location, splitLine)
Get cool line according to time spent on layer.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the cool gcode.
getLayerTime(self)
Get the time the extruder spends on the layer.
getLayerTimeActive(self)
Get the time the extruder spends on the layer while active.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the cool skein.
setMultiplier(self, remainingOrbitTime)
Set the feed and flow rate multiplier.

 
Functions
       
getCraftedText(fileName, text, repository=None)
Cool a gcode linear move text.
getCraftedTextFromText(gcodeText, repository=None)
Cool a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the cool dialog.
writeOutput(fileName, shouldAnalyze=True)
Cool a gcode linear move file.  Chain cool the gcode if it is not already cooled.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.craft_plugins.dimension.html000066400000000000000000000450111167321211700341270ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.craft_plugins.dimension
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.dimension ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/dimension.py

Previous / Next / Contents


Dimension adds Adrian's extruder distance E value so firmware does not have to calculate it on it's own and can set the extruder speed in relation to the distance that needs to be extruded. Some printers don't support this. Extruder distance is described at:

http://blog.reprap.org/2009/05/4d-printing.html

and in Erik de Bruijn's conversion script page at:

http://objects.reprap.org/wiki/3D-to-5D-Gcode.php

The dimension manual page is at:

http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Dimension

Nophead wrote an excellent article on how to set the filament parameters:

http://hydraraptor.blogspot.com/2011/03/spot-on-flow-rate.html


Operation
Settings
  Extrusion Distance Format Choice
    Absolute Extrusion Distance
    Relative Extrusion Distance
  Extruder Retraction Speed
  Filament
    Filament Diameter
    Filament Packing Density
  Maximum E Value before Reset
  Minimum Travel for Retraction
  Retract Within Island
  Retraction Distance
  Restart Extra Distance
Examples

Operation


The default 'Activate Dimension' checkbox is off. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Extrusion Distance Format Choice

Default is 'Absolute Extrusion Distance' because in Adrian's description the distance is absolute. In future, because the relative distances are smaller than the cumulative absolute distances, hopefully the firmware will be able to use relative distance.

Absolute Extrusion Distance

When selected, the extrusion distance output will be the total extrusion distance to that gcode line.

Relative Extrusion Distance

When selected, the extrusion distance output will be the extrusion distance from the last gcode line.

Extruder Retraction Speed

Default is 13.3 mm/s.

Defines the extruder retraction feed rate. A high value will allow the retraction operation to complete before much material oozes out. If your extruder can handle it, this value should be much larger than your feed rate.

As an example, I have a feed rate of 48 mm/s and a 'Extruder Retraction Speed' of 150 mm/s.

Filament

Filament Diameter

Default is 2.8 millimeters.

Defines the filament diameter.

Filament Packing Density

Default is 0.85. This is for ABS.

Defines the effective filament packing density.

The default value is so low for ABS because ABS is relatively soft and with a pinch wheel extruder the teeth of the pinch dig in farther, so it sees a smaller effective diameter. With a hard plastic like PLA the teeth of the pinch wheel don't dig in as far, so it sees a larger effective diameter, so feeds faster, so for PLA the value should be around 0.97. This is with Wade's hobbed bolt. The effect is less significant with larger pinch wheels.

Overall, you'll have to find the optimal filament packing density by experiment.

Maximum E Value before Reset

Default: 91234.0

Defines the maximum E value before it is reset with the 'G92 E0' command line. The reason it is reset only after the maximum E value is reached is because at least one firmware takes time to reset. The problem with waiting until the E value is high before resetting is that more characters are sent. So if your firmware takes a lot of time to reset, set this parameter to a high value, if it doesn't set this parameter to a low value or even zero.

Minimum Travel for Retraction

Default: 1.0 millimeter

Defines the minimum distance that the extruder head has to travel from the end of one thread to the beginning of another, in order to trigger the extruder retraction. Setting this to a high value means the extruder will retract only occasionally, setting it to a low value means the extruder will retract most of the time.

Retract Within Island

Default is off.

When selected, retraction will work even when the next thread is within the same island. If it is not selected, retraction will only work when crossing a boundary.

Retraction Distance

Default is zero.

Defines the amount the extruder retracts (sucks back) the extruded filament whenever an extruder stop is commanded. Using this seems to help prevent stringing. e.g. If set to 10 the extruder reverses the distance required to pull back 10mm of filament. In fact this does not actually happen but if you set this distance by trial and error you can get to a point where there is very little ooze from the extruder when it stops which is not normally the case.

Restart Extra Distance

Default is zero.

Defines the restart extra distance when the thread restarts. The restart distance will be the retraction distance plus the restart extra distance.

If this is greater than zero when the extruder starts this distance is added to the retract value giving extra filament. It can be a negative value in which case it is subtracted from the retraction distance. On some Repstrap machines a negative value can stop the build up of plastic that can occur at the start of perimeters.

Examples


The following examples dimension the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and dimension.py.

> python dimension.py
This brings up the dimension dialog.

> python dimension.py Screw Holder Bottom.stl
The dimension tool is parsing the file:
Screw Holder Bottom.stl
..
The dimension tool has created the file:
.. Screw Holder Bottom_dimension.gcode


Previous / Next / Contents


 
Modules
       
skeinforge_application.skeinforge_plugins.craft_plugins.__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
DimensionRepository
DimensionSkein

 
class DimensionRepository
    A class to handle the dimension settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Dimension button has been clicked.

 
class DimensionSkein
    A class to dimension a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize.
addLinearMoveExtrusionDistanceLine(self, extrusionDistance)
Get the extrusion distance string from the extrusion distance.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the dimension gcode.
getDimensionedArcMovement(self, line, splitLine)
Get a dimensioned arc movement.
getDimensionedLinearMovement(self, line, splitLine)
Get a dimensioned linear movement.
getDistanceToNextThread(self, lineIndex)
Get the travel distance to the next thread.
getExtrusionDistanceString(self, distance, splitLine)
Get the extrusion distance string.
getExtrusionDistanceStringFromExtrusionDistance(self, extrusionDistance)
Get the extrusion distance string from the extrusion distance.
getRetractionRatio(self, lineIndex)
Get the retraction ratio.
getSmallestEnclosureIndex(self, point)
Get the index of the smallest boundary loop which encloses the point.
parseBoundaries(self)
Parse the boundaries and add them to the boundary layers.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, lineIndex)
Parse a gcode line and add it to the dimension skein.

 
Functions
       
getCraftedText(fileName, gcodeText='', repository=None)
Dimension a gcode file or text.
getCraftedTextFromText(gcodeText, repository=None)
Dimension a gcode text.
getNewRepository()
Get new repository.
main()
Display the dimension dialog.
writeOutput(fileName, shouldAnalyze=True)
Dimension a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.drill.html000066400000000000000000000307741167321211700333410ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.drill
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.drill ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/drill.py

Previous / Next / Contents


Drill is a script to drill down small holes.


Operation
Settings
  Drilling Margin
  Drilling Margin on Top
  Drilling Margin on Bottom
Examples

Operation


The default 'Activate Drill' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Drilling Margin

The drill script will move the tool from the top of the hole plus the 'Drilling Margin on Top', to the bottom of the hole minus the 'Drilling Margin on Bottom'.

Drilling Margin on Top

Default is three millimeters.

Drilling Margin on Bottom

Default is one millimeter.

Examples


The following examples drill the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and drill.py.

> python drill.py
This brings up the drill dialog.

> python drill.py Screw Holder Bottom.stl
The drill tool is parsing the file:
Screw Holder Bottom.stl
..
The drill tool has created the file:
.. Screw Holder Bottom_drill.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
DrillRepository
DrillSkein
ThreadLayer

 
class DrillRepository
    A class to handle the drill settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Drill button has been clicked.

 
class DrillSkein
    A class to drill a skein of extrusions.
 
  Methods defined here:
__init__(self)
addDrillHoles(self)
Parse a gcode line.
addGcodeFromVerticalThread(self, point, zBegin, zEnd)
Add a thread to the output.
addThreadLayerIfNone(self)
Add a thread layer if it is none.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the drill gcode.
getDrillingCenterDepth(self, drillingCenterDepth, drillPoint)
Get the drilling center depth.
isPointClose(self, drillPoint, points)
Determine if a point on the thread layer is close.
linearMove(self, splitLine)
Add a linear move to the loop.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line.
parseNestedRing(self, line)
Parse a nested ring.

 
class ThreadLayer
    A layer of loops and paths.
 
  Methods defined here:
__init__(self, z)
Thread layer constructor.
__repr__(self)
Get the string representation of this thread layer.

 
Functions
       
getCraftedText(fileName, text, repository=None)
Drill a gcode linear move file or text.
getCraftedTextFromText(gcodeText, repository=None)
Drill a gcode linear move text.
getNewRepository()
Get new repository.
getPolygonCenter(polygon)
Get the centroid of a polygon.
main()
Display the drill dialog.
writeOutput(fileName, shouldAnalyze=True)
Drill a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.export.html000066400000000000000000000466201167321211700335510ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.export
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.export ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/export.py

Previous / Next / Contents


Export is a craft tool to pick an export plugin, add information to the file name, and delete comments.

The export manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Export


Operation
Settings
  Add Descriptive Extension
  Add Profile Extension
  Add Timestamp Extension
  Also Send Output To
  Analyze Gcode
  Comment Choice
    Do Not Delete Comments
    Delete Crafting Comments
    Delete All Comments
  Export Operations
  File Extension
  Name of Replace File
  Save Penultimate Gcode
Examples

Operation


The default 'Activate Export' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Add Descriptive Extension

Default is off.

When selected, key profile values will be added as an extension to the gcode file. For example:
test.04hx06w_03fill_2cx2r_33EL.gcode

would mean:

* . (Carve section.)
* 04h = 'Layer Thickness (mm):' 0.4
* x
* 06w = 0.6 width i.e. 0.4 times 'Perimeter Width over Thickness (ratio):' 1.5
* _ (Fill section.)
* 03fill = 'Infill Solidity (ratio):' 0.3
* _ (Multiply section; if there is one column and one row then this section is not shown.)
* 2c = 'Number of Columns (integer):' 2
* x
* 2r = 'Number of Rows (integer):' 2.
* _ (Speed section.)
* 33EL = 'Feed Rate (mm/s):' 33.0 and 'Flow Rate Setting (float):' 33.0. If either value has a positive value after the decimal place then this is also shown, but if it is zero it is hidden. Also, if the values differ (which they shouldn't with 5D volumetrics) then each should be displayed separately. For example, 35.2E30L = 'Feed Rate (mm/s):' 35.2 and 'Flow Rate Setting (float):' 30.0.

Add Profile Extension

Default is off.

When selected, the current profile will be added to the file extension. For example:
test.my_profile_name.gcode

Add Timestamp Extension

Default is off.

When selected, the current date and time is added as an extension in format YYYYmmdd_HHMMSS (so it is sortable if one has many files). For example:
test.my_profile_name.20110613_220113.gcode

Also Send Output To

Default is empty.

Defines the output name for sending to a file or pipe. A common choice is stdout to print the output in the shell screen. Another common choice is stderr. With the empty default, nothing will be done. If the value is anything else, the output will be written to that file name.

Analyze Gcode

Default is on.

When selected, the penultimate gcode will be sent to the analyze plugins to be analyzed and viewed.

Comment Choice

Default is 'Delete All Comments'.

Do Not Delete Comments

When selected, export will not delete comments. Crafting comments slow down the processing in many firmware types, which leads to pauses and therefore a lower quality print.

Delete Crafting Comments

When selected, export will delete the time consuming crafting comments, but leave the initialization comments. Since the crafting comments are deleted, there are no pauses during extrusion. The remaining initialization comments provide some useful information for the analyze tools.

Delete All Comments

When selected, export will delete all comments. The comments are not necessary to run a fabricator. Some printers do not support comments at all so the safest way is choose this option.

Export Operations

Export presents the user with a choice of the export plugins in the export_plugins folder. The chosen plugin will then modify the gcode or translate it into another format. There is also the "Do Not Change Output" choice, which will not change the output. An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function.

File Extension

Default is gcode.

Defines the file extension added to the name of the output file. The output file will be named as originalname_export.extension so if you are processing XYZ.stl the output will by default be XYZ_export.gcode

Name of Replace File

Default is replace.csv.

When export is exporting the code, if there is a tab separated file with the name of the "Name of Replace File" setting, it will replace the string in the first column by its replacement in the second column. If there is nothing in the second column, the first column string will be deleted, if this leads to an empty line, the line will be deleted. If there are replacement columns after the second, they will be added as extra lines of text. There is an example file replace_example.csv to demonstrate the tab separated format, which can be edited in a text editor or a spreadsheet.

Export looks for the alteration file in the alterations folder in the .skeinforge folder in the home directory. Export does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.

Save Penultimate Gcode

Default is off.

When selected, export will save the gcode file with the suffix '_penultimate.gcode' just before it is exported. This is useful because the code after it is exported could be in a form which the viewers can not display well.

Examples


The following examples export the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and export.py.

> python export.py
This brings up the export dialog.

> python export.py Screw Holder Bottom.stl
The export tool is parsing the file:
Screw Holder Bottom.stl
..
The export tool has created the file:
.. Screw Holder Bottom_export.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_analyze
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
time

 
Classes
       
ExportRepository
ExportSkein

 
class ExportRepository
    A class to handle the export settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Export button has been clicked.

 
class ExportSkein
    A class to export a skein of extrusions.
 
  Methods defined here:
__init__(self)
addLine(self, line)
Add a line of text and a newline to the output.
getCraftedGcode(self, repository, gcodeText)
Parse gcode text and store the export gcode.
getLineWithTruncatedNumber(self, character, line, splitLine)
Get a line with the number after the character truncated.
parseLine(self, line)
Parse a gcode line.

 
Functions
       
getCraftedTextFromText(gcodeText, repository=None)
Export a gcode linear move text.
getDescriptionCarve(lines)
Get the description for carve.
getDescriptionFill(lines)
Get the description for fill.
getDescriptionMultiply(lines)
Get the description for multiply.
getDescriptionSpeed(lines)
Get the description for speed.
getDescriptiveExtension(gcodeText)
Get the descriptive extension.
getDistanceGcode(exportText)
Get gcode lines with distance variable added.
getFirstValue(gcodeText, word)
Get the value from the first line which starts with the given word.
getNewRepository()
Get new repository.
getReplaceableExportGcode(nameOfReplaceFile, replaceableExportGcode)
Get text with strings replaced according to replace.csv file.
getSelectedPluginModule(plugins)
Get the selected plugin module.
getSettingString(lines, procedureName, settingNameStart)
Get the setting value from the lines, return None if there is no setting starting with that name.
main()
Display the export dialog.
sendOutputTo(outputTo, text)
Send output to a file or a standard output.
writeOutput(fileName, shouldAnalyze=True)
Export a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__credits__ = 'Gary Hodgson <http://garyhodgson.com/reprap/2011/06/hacking-skeinforge-export-module/>'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)

 
Credits
        Gary Hodgson <http://garyhodgson.com/reprap/2011/06/hacking-skeinforge-export-module/>
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.binary_16_byte.html000066400000000000000000000321201167321211700400350ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.binary_16_byte
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.binary_16_byte ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/binary_16_byte.py

Previous / Next / Contents


Binary 16 byte is an export plugin to convert gcode into 16 byte binary segments.

An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getOutput function of this script takes a gcode text and returns that text converted into 16 byte segments. The writeOutput function of this script takes a gcode text and writes that in a binary format converted into 16 byte segments.

This plugin is just a starter to make a real binary converter.


Settings
  Feed Rate Step Length
  File Extension
  Offset
    X Offset
    Y Offset
    Z Offset
  Step Length
    X Step Length
    Y Step Length
    Z Step Length
Record structure

Settings


Feed Rate Step Length

Default is 0.1 millimeters/second.

Defines the feed rate step length.

File Extension

Default is bin.

Defines the file extension suffix.

Offset

X Offset

Default is zero.

Defines the X Offset.

Y Offset

Default is zero.

Defines the Y Offset.

Z Offset

Default is zero.

Defines the Z Offset.

Step Length

X Step Length

Default is 0.1 millimeters.

Defines the X axis step length.

Y Step Length

Default is 0.1 millimeters.

Defines the Y axis step length.

Z Step Length

Default is 0.01 millimeters.

Defines the Z axis step length.

Record structure


BinArray(0) = AscW(Inst_Code_Letter)
BinArray(1) = cInst_Code

X Data
sInt32_to_Hbytes(iXdim_1)
BinArray(2) = lsb 'short lsb
BinArray(3) = msb 'short msb

Y Data
sInt32_to_Hbytes(iYdim_2)
BinArray(4) = lsb 'short lsb
BinArray(5) = msb 'short msb

Z Data
sInt32_to_Hbytes(iZdim_3)
BinArray(6) = lsb 'short lsb
BinArray(7) = msb 'short msb

I Data
sInt32_to_Hbytes(iIdim_4)
BinArray(8) = lsb 'short lsb
BinArray(9) = msb 'short msb

J Data
sInt32_to_Hbytes(iJdim_5)
BinArray(10) = lsb 'short lsb
BinArray(11) = msb 'short msb

BinArray(12) = FP_Char
sInt32_to_Hbytes(iFP_Num)
BinArray(13) = lsb 'short lsb

BinArray(14) = bActiveFlags

BinArray(15) = AscW("#")End of record filler

Byte 14 is worth a few extra notes, this byte is used to define which of the axes are active, its used to get round the problem of say a line of code with no mention of z. This would be put into the file as z = 0 as the space for this data is reserved, if we did nothing, this would instruct the machine to go to z = 0. If we use the active flag to define the z axis as inactive the z = 0 is ignored and the value set to the last saved value of z, i.e it does not move. If the z data is actually set to z = 0 then the axis would be set to active and the move takes place.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
Binary16ByteRepository
Binary16ByteSkein

 
class Binary16ByteRepository
    A class to handle the export settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Convert to binary 16 byte button has been clicked.

 
class Binary16ByteSkein
    A class to convert gcode into 16 byte binary segments.
 
  Methods defined here:
__init__(self)
getCraftedGcode(self, gcodeText, binary16ByteRepository)
Parse gcode text and store the gcode.
parseLine(self, line)
Parse a gcode line.

 
Functions
       
getIntegerFlagFromCharacterSplitLine(character, splitLine)
Get the integer flag after the first occurence of the character in the split line.
getIntegerFromCharacterLengthLineOffset(character, offset, splitLine, stepLength)
Get the integer after the first occurence of the character in the split line.
getNewRepository()
Get new repository.
getOutput(gcodeText, binary16ByteRepository=None)
Get the exported version of a gcode file.
main()
Display the export dialog.
writeOutput(fileName, gcodeText='')
Write the exported version of a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalIsReplaceable = False

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_step.html000066400000000000000000000323601167321211700373420ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_step
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_step ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/gcode_step.py

Previous / Next / Contents


Gcode step is an export plugin to convert gcode from float position to number of steps.

An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getOutput function of this script takes a gcode text and returns it with the positions converted into number of steps. The writeOutput function of this script takes a gcode text and writes that with the positions converted into number of steps.


Settings
  Add Feed Rate Even When Unchanging
  Add Space Between Words
  Add Z Even When Unchanging
  Feed Rate Step Length
  Offset
    X Offset
    Y Offset
    Z Offset
  Step Length
    E Step Length
  Radius Rate Step Length
    X Step Length
    Y Step Length
    Z Step Length

Settings


Add Feed Rate Even When Unchanging

Default is on.

When selected, the feed rate will be added even when it did not change from the previous line.

Add Space Between Words

Default is on.

When selected, a space will be added between each gcode word.

Add Z Even When Unchanging

Default is on.

When selected, the z word will be added even when it did not change.

Feed Rate Step Length

Default is 0.1 millimeters/second.

Defines the feed rate step length.

Offset

X Offset

Default is zero.

Defines the X Offset.

Y Offset

Default is zero.

Defines the Y Offset.

Z Offset

Default is zero.

Defines the Z Offset.

Step Length

E Step Length

Default is 0.1 millimeters.

Defines the E extrusion distance step length.

Radius Rate Step Length

Default is 0.1 millimeters/second.

Defines the radius step length.

X Step Length

Default is 0.1 millimeters.

Defines the X axis step length.

Y Step Length

Default is 0.1 millimeters.

Defines the Y axis step length.

Z Step Length

Default is 0.01 millimeters.

Defines the Z axis step length.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
GcodeStepRepository
GcodeStepSkein

 
class GcodeStepRepository
    A class to handle the export settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Convert to gcode step button has been clicked.

 
class GcodeStepSkein
    A class to convert gcode into 16 byte binary segments.
 
  Methods defined here:
__init__(self)
addCharacterInteger(self, character, lineStringIO, offset, splitLine, stepLength)
Add a character and integer to line string.
addLine(self, line)
Add a line of text and a newline to the output.
addStringToLine(self, lineStringIO, wordString)
Add a character and integer to line string.
getCraftedGcode(self, repository, gcodeText)
Parse gcode text and store the gcode.
parseLine(self, line)
Parse a gcode line.

 
Functions
       
getCharacterIntegerString(character, offset, splitLine, stepLength)
Get a character and integer string.
getFloatFromCharacterSplitLine(character, splitLine)
Get the float after the first occurence of the character in the split line.
getNewRepository()
Get new repository.
getOutput(gcodeText, repository=None)
Get the exported version of a gcode file.
main()
Display the export dialog.
writeOutput(fileName, gcodeText='')
Write the exported version of a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalIsReplaceable = True

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_time_segment.html000066400000000000000000000303771167321211700410550ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_time_segment
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_time_segment ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/gcode_time_segment.py

Previous / Next / Contents


Gcode time segment is an export plugin to convert gcode from float position to number of steps.

An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getOutput function of this script takes a gcode text and returns it with the positions converted into number of steps and time. The writeOutput function of this script takes a gcode text and writes that with the positions converted into number of steps and time.


Settings
  Add Space Between Words
  Offset
    X Offset
    Y Offset
    Z Offset
  Step
  Extrusion Step
  Time Step
    X Step
    Y Step
    Z Step

Settings


Add Space Between Words

Default is on.

When selected, a space will be added between each gcode word.

Offset

X Offset

Default is zero.

Defines the X Offset.

Y Offset

Default is zero.

Defines the Y Offset.

Z Offset

Default is zero.

Defines the Z Offset.

Step

Extrusion Step

Default is 0.01 mm.

Defines the radius step length.

Time Step

Default is 1 microsecond(mcs).

Defines the time step duration.

X Step

Default is 0.1 mm.

Defines the X axis step length.

Y Step

Default is 0.1 mm.

Defines the Y axis step length.

Z Step

Default is 0.01 mm.

Defines the Z axis step length.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
GcodeTimeSegmentRepository
GcodeTimeSegmentSkein

 
class GcodeTimeSegmentRepository
    A class to handle the export settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Convert to gcode step button has been clicked.

 
class GcodeTimeSegmentSkein
    A class to convert gcode into time segments.
 
  Methods defined here:
__init__(self)
Initialize.
addCharacterInteger(self, character, lineStringIO, offset, splitLine, step)
Add a character and integer to line string.
addLine(self, line)
Add a line of text and a newline to the output.
addStringToLine(self, lineStringIO, wordString)
Add a character and integer to line string.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the gcode.
parseLine(self, line)
Parse a gcode line.

 
Functions
       
getCharacterIntegerString(character, offset, splitLine, step)
Get a character and integer string.
getFloatFromCharacterSplitLine(character, splitLine)
Get the float after the first occurence of the character in the split line.
getNewRepository()
Get new repository.
getOutput(gcodeText, repository=None)
Get the exported version of a gcode file.
main()
Display the export dialog.
writeOutput(fileName, gcodeText='')
Write the exported version of a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalIsReplaceable = True

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.html000066400000000000000000000057421167321211700352330ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: package skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
binary_16_byte
gcode_step
gcode_time_segment
static_plugins (package)

 
Data
        level = 4
numberOfLevelsDeepInPackageHierarchy = 4
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
956d9eda103fdfeeededfc4555f8a61799308cac.paxheader00006660000000000000000000000217116732121170021123xustar00rootroot00000000000000143 path=sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.static_plugins.gcode_small.html 956d9eda103fdfeeededfc4555f8a61799308cac.data000066400000000000000000000207031167321211700177630ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.static_plugins.gcode_small
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.static_plugins.gcode_small ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/gcode_small.py

Previous / Next / Contents


Gcode_small is an export plugin to remove the comments and the redundant z and feed rate parameters from a gcode file.

An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.

The getOutput function of this script takes a gcode text and returns that text without comments and redundant z and feed rate parameters. The writeOutput function of this script takes a gcode text and writes that text without comments and redundant z and feed rate parameters to a file.

Many of the functions in this script are copied from gcodec in skeinforge_utilities. They are copied rather than imported so developers making new plugins do not have to learn about gcodec, the code here is all they need to learn.


Previous / Next / Contents


 
Modules
       
cStringIO
os

 
Classes
       
GcodeSmallSkein

 
class GcodeSmallSkein
    A class to remove redundant z and feed rate parameters from a skein of extrusions.
 
  Methods defined here:
__init__(self)
getCraftedGcode(self, gcodeText)
Parse gcode text and store the gcode.
parseLine(self, line)
Parse a gcode line.

 
Functions
       
getIndexOfStartingWithSecond(letter, splitLine)
Get index of the first occurence of the given letter in the split line, starting with the second word.  Return - 1 if letter is not found
getOutput(gcodeText)
Get the exported version of a gcode file.
getSplitLineBeforeBracketSemicolon(line)
Get the split line before a bracket or semicolon.
getStringFromCharacterSplitLine(character, splitLine)
Get the string after the first occurence of the character in the split line.
getSummarizedFileName(fileName)
Get the fileName basename if the file is in the current working directory, otherwise return the original full name.
getTextLines(text)
Get the all the lines of text of a text.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)
globalIsReplaceable = True

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.static_plugins.html000066400000000000000000000054121167321211700402540ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: package skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.static_plugins
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.static_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
gcode_small

 
Data
        level = 5
numberOfLevelsDeepInPackageHierarchy = 5
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.feed.html000066400000000000000000000256731167321211700331400ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.feed
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.feed ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/feed.py

Previous / Next / Contents


The feed script sets the maximum feed rate, operating feed rate & travel feed rate.


Operation
Settings
  Feed Rate
  Maximum Z Drill Feed Rate
  Maximum Z Feed Rate
  Travel Feed Rate
Examples

Operation


The default 'Activate Feed' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Feed Rate

Default is 16 millimeters/second.

Defines the feed rate for the shape.

Maximum Z Drill Feed Rate

Default is 0.1 millimeters/second.

If your firmware limits the z feed rate, you do not need to set this setting.

Defines the maximum feed that the tool head will move in the z direction while the tool is on.

Maximum Z Feed Rate

Default is one millimeter per second.

Defines the maximum speed that the tool head will move in the z direction.

Travel Feed Rate

Default is 16 millimeters/second.

Defines the feed rate when the cutter is off. The travel feed rate could be set as high as the cutter can be moved, it does not have to be limited by the maximum cutter rate.

Examples


The following examples feed the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and feed.py.

> python feed.py
This brings up the feed dialog.

> python feed.py Screw Holder Bottom.stl
The feed tool is parsing the file:
Screw Holder Bottom.stl
..
The feed tool has created the file:
.. Screw Holder Bottom_feed.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
FeedRepository
FeedSkein

 
class FeedRepository
    A class to handle the feed settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Feed button has been clicked.

 
class FeedSkein
    A class to feed a skein of cuttings.
 
  Methods defined here:
__init__(self)
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the feed gcode.
getFeededLine(self, line, splitLine)
Get gcode line with feed rate.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the feed skein.

 
Functions
       
getCraftedText(fileName, gcodeText='', repository=None)
Feed the file or text.
getCraftedTextFromText(gcodeText, repository=None)
Feed a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the feed dialog.
writeOutput(fileName, shouldAnalyze=True)
Feed a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.fill.html000066400000000000000000001250231167321211700331510ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.fill
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.fill ($Date: 2008/28/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/fill.py

Previous / Next / Contents


Fill is a script to fill the perimeters of a gcode file.

The fill manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fill

Allan Ecker aka The Masked Retriever has written the "Skeinforge Quicktip: Fill" at:
http://blog.thingiverse.com/2009/07/21/mysteries-of-skeinforge-fill/


Operation
Settings
  Diaphragm
    Diaphragm Period
    Diaphragm Thickness
  Extra Shells
    Extra Shells on Alternating Solid Layers
    Extra Shells on Base
    Extra Shells on Sparse Layer
  Grid
    Grid Circle Separation over Perimeter Width
    Grid Extra Overlap
    Grid Junction Separation over Octogon Radius At End
    Grid Junction Separation over Octogon Radius At Middle
    Grid Junction Separation Band Height
  Infill
    Infill Pattern
      Grid Circular
      Grid Hexagonal
      Grid Rectangular
      Line
    Infill Begin Rotation
    Infill Odd Layer Extra Rotation
    Infill Begin Rotation Repeat
    Infill Perimeter Overlap
    Infill Solidity
    Infill Width over Thickness
  Solid Surface Thickness
  Start From Choice
    Lower Left
    Nearest
  Surrounding Angle
  Thread Sequence Choice
    Infill > Loops > Perimeter
    Infill > Perimeter > Loops
    Loops > Infill > Perimeter
    Loops > Perimeter > Infill
    Perimeter > Infill > Loops
    Perimeter > Loops > Infill
Examples

Operation


The default 'Activate Fill' checkbox is off. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Diaphragm

The diaphragm is a solid group of layers, at regular intervals. It can be used with a sparse infill to give the object watertight, horizontal compartments and/or a higher shear strength.

Diaphragm Period

Default is one hundred.

Defines the number of layers between diaphrams.

Diaphragm Thickness

Default is zero, because the diaphragm feature is rarely used.

Defines the number of layers the diaphram is composed of.

Extra Shells

The shells interior perimeter loops. Adding extra shells makes the object stronger & heavier.

Extra Shells on Alternating Solid Layers

Default is two.

Defines the number of extra shells, on the alternating solid layers.

Extra Shells on Base

Default is one.

Defines the number of extra shells on the bottom, base layer and every even solid layer after that. Setting this to a different value than the "Extra Shells on Alternating Solid Layers" means the infill pattern will alternate, creating a strong interleaved bond even if the perimeter loop shrinks.

Extra Shells on Sparse Layer

Default is one.

Defines the number of extra shells on the sparse layers. The solid layers are those at the top & bottom, and wherever the object has a plateau or overhang, the sparse layers are the layers in between.

Grid

Grid Circle Separation over Perimeter Width

Default is 0.2.

Defines the ratio of the amount the grid circle is inset over the perimeter width, the default is zero. With a value of zero the circles will touch, with a value of one two threads could be fitted between the circles.

Grid Extra Overlap

Default is 0.1.

Defines the amount of extra overlap added when extruding the grid to compensate for the fact that when the first thread going through a grid point is extruded, since there is nothing there yet for it to connect to it will shrink extra.

Grid Junction Separation over Octogon Radius At End

Default is zero.

Defines the ratio of the amount the grid square is increased in each direction over the extrusion width at the end. With a value of one or so the grid pattern will have large squares to go with the octogons.

Grid Junction Separation over Octogon Radius At Middle

Default is zero.

Defines the increase at the middle. If this value is different than the value at the end, the grid would have an accordion pattern, which would give it a higher shear strength.

Grid Junction Separation Band Height

Default is ten.

Defines the height of the bands of the accordion pattern.

Infill

Infill Pattern

Default is 'Line', since it is quicker to generate and does not add extra movements for the extruder. The grid pattern has extra diagonal lines, so when choosing a grid option, set the infill solidity to 0.2 or less so that there is not too much plastic and the grid generation time, which increases with the third power of solidity, will be reasonable.

Grid Circular
When selected, the infill will be a grid of separated circles. Because the circles are separated, the pattern is weak, it only provides support for the top layer threads and some strength in the z direction. The flip side is that this infill does not warp the object, the object will get warped only by the walls.

Because this pattern turns the extruder on and off often, it is best to use a stepper motor extruder.

Grid Hexagonal
When selected, the infill will be a hexagonal grid. Because the grid is made with threads rather than with molding or milling, only a partial hexagon is possible, so the rectangular grid pattern is stronger.

Grid Rectangular
When selected, the infill will be a funky octogon square honeycomb like pattern which gives the object extra strength.

Line
When selected, the infill will be made up of lines.

Infill Begin Rotation

Default is forty five degrees, giving a diagonal infill.

Defines the amount the infill direction of the base and every second layer thereafter is rotated.

Infill Odd Layer Extra Rotation

Default is ninety degrees, making the odd layer infill perpendicular to the base layer.

Defines the extra amount the infill direction of the odd layers is rotated compared to the base layer.

Infill Begin Rotation Repeat

Default is one, giving alternating cross hatching.

Defines the number of layers that the infill begin rotation will repeat. With a value higher than one, the infill will go in one direction more often, giving the object more strength in one direction and less in the other, this is useful for beams and cantilevers.

Infill Perimeter Overlap

Default is 0.15.

Defines the amount the infill overlaps the perimeter over the average of the perimeter and infill width. The higher the value the more the infill will overlap the perimeter, and the thicker join between the infill and the perimeter. If the value is too high, the join will be so thick that the nozzle will run plow through the join below making a mess, also when it is above 0.45 fill may not be able to create infill correctly. If you want to stretch the infill a lot, set 'Path Stretch over Perimeter Width' in stretch to a high value.

Infill Solidity

Default is 0.2.

Defines the solidity of the infill, this is the most important setting in fill. A value of one means the infill lines will be right beside each other, resulting in a solid, strong, heavy shape which takes a long time to extrude. A low value means the infill will be sparse, the interior will be mosty empty space, the object will be weak, light and quick to build.

Infill Width over Thickness

Default is 1.5.

Defines the ratio of the infill width over the layer thickness. The higher the value the wider apart the infill will be and therefore the sparser the infill will be.

Solid Surface Thickness

Default is three.

Defines the number of solid layers that are at the bottom, top, plateaus and overhang. With a value of zero, the entire object will be composed of a sparse infill, and water could flow right through it. With a value of one, water will leak slowly through the surface and with a value of three, the object could be watertight. The higher the solid surface thickness, the stronger and heavier the object will be.

Start From Choice

Default is 'Lower Left'.

Defines where each layer starts from.

Lower Left

When selected the layer will start from the lower left corner. This is to extrude in round robin fashion so that the first extrusion will be deposited on the coolest part of the last layer. The reason for this is described at:
http://hydraraptor.blogspot.com/2010/12/round-robin.html

Nearest

When selected the layer will start from the closest point to the end of the last layer. This leads to less stringing, but the first extrusion will be deposited on the hottest part of the last layer which leads to melting problems. So this option is deprecated, eventually this option will be removed and the layers will always start from the lower left.

Surrounding Angle

Default: 60 degrees

Defines the angle that the surrounding layers around the infill are expanded.

To decide whether or not the infill should be sparse or solid, fill looks at the 'Solid Surface Thickness' surrounding layers above and below the infill. If any of the expanded layers above or below the infill do not cover the infill, then the infill will be solid in that region. The layers are expanded by the height difference times the tangent of the surrounding angle, which is from the vertical. For example, if the model is a wedge with a wall angle less than the surrounding angle, the interior layers (those which are not on the bottom or top) will be sparse. If the wall angle is greater than the surrounding angle, the interior layers will be solid.

The time required to examine the surrounding layers increases with the surrounding angle, so the surrounding angle is limited to eighty degrees, regardless of the input value.

If you have an organic shape with gently sloping surfaces; if the surrounding angle is set too high, then too many layers will be sparse. If the surrounding angle is too low, then too many layers will be solid and the extruder may end up plowing through previous layers:
http://hydraraptor.blogspot.com/2008/08/bearing-fruit.html

Thread Sequence Choice

The 'Thread Sequence Choice' is the sequence in which the threads will be extruded on the second and higher layers. There are three kinds of thread, the perimeter threads on the outside of the object, the loop threads aka inner shell threads, and the interior infill threads. The first layer thread sequence is 'Perimeter > Loops > Infill'.

The default choice is 'Perimeter > Loops > Infill', which the default stretch parameters are based on. If you change from the default sequence choice setting of perimeter, then loops, then infill, the optimal stretch thread parameters would also be different. In general, if the infill is extruded first, the infill would have to be stretched more so that even after the filament shrinkage, it would still be long enough to connect to the loop or perimeter. The six sequence combinations follow below.

Infill > Loops > Perimeter

Infill > Perimeter > Loops

Loops > Infill > Perimeter

Loops > Perimeter > Infill

Perimeter > Infill > Loops

Perimeter > Loops > Infill


Examples


The following examples fill the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and fill.py.

> python fill.py
This brings up the fill dialog.

> python fill.py Screw Holder Bottom.stl
The fill tool is parsing the file:
Screw Holder Bottom.stl
..
The fill tool has created the file:
.. Screw Holder Bottom_fill.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
FillRepository
FillSkein
RotatedLayer
YIntersectionPath

 
class FillRepository
    A class to handle the fill settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Fill button has been clicked.

 
class FillSkein
    A class to fill a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize.
addFill(self, layerIndex)
Add fill to the carve layer.
addGcodeFromThreadZ(self, thread, z)
Add a gcode thread to the output.
addGrid(self, arounds, fillLoops, gridPointInsetX, layerIndex, paths, pixelTable, reverseRotation, surroundingCarves, width)
Add the grid to the infill layer.
addGridCircle(self, center, infillPaths, layerRotation, pixelTable, rotatedLoops, startRotation, width)
Add circle to the grid.
addGridLinePoints(self, begin, end, gridPoints, gridRotationAngle, offset, y)
Add the segments of one line of a grid to the infill.
addRemainingGridPoints(self, arounds, gridPointInsetX, gridPointInsetY, gridPoints, isBothOrNone, paths, pixelTable, width)
Add the remaining grid points to the grid point list.
addRotatedCarve(self, currentLayer, layerDelta, reverseRotation, surroundingCarves)
Add a rotated carve to the surrounding carves.rotatedCarveDictionary
addThreadsBridgeLayer(self, layerIndex, nestedRings, rotatedLayer, testLoops=None)
Add the threads, add the bridge end & the layer end tag.
addToThread(self, location)
Add a location to thread.
getCraftedGcode(self, repository, gcodeText)
Parse gcode text and store the bevel gcode.
getGridPoints(self, fillLoops, reverseRotation)
Get the grid points.
getGridPointsByLoops(self, gridRotationAngle, loops)
Get the grid points by loops.
getLayerRotation(self, layerIndex)
Get the layer rotation.
getNextGripXStep(self, gridXStep)
Get the next grid x step, increment by an extra one every three if hexagonal grid is chosen.
isGridToBeExtruded(self)
Determine if the grid is to be extruded.
isPointInsideLineSegments(self, gridPoint)
Is the point inside the line segments of the loops.
linearMove(self, splitLine)
Add a linear move to the thread.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, lineIndex)
Parse a gcode line and add it to the fill skein.
setGridVariables(self, repository)
Set the grid variables.

 
class RotatedLayer
    A rotated layer.
 
  Methods defined here:
__init__(self, z)
Initialize.
__repr__(self)
Get the string representation of this RotatedLayer.

 
class YIntersectionPath
    A class to hold the y intersection position, the loop which it intersected and the point index of the loop which it intersected.
 
  Methods defined here:
__init__(self, pathIndex, pointIndex, y)
Initialize from the path, point index, and y.
__repr__(self)
Get the string representation of this y intersection.
getPath(self, paths)
Get the path from the paths and path index.
getPointIndexPlusOne(self)
Get the point index plus one.

 
Functions
       
addAroundGridPoint(arounds, gridPoint, gridPointInsetX, gridPointInsetY, gridPoints, gridSearchRadius, isBothOrNone, isDoubleJunction, isJunctionWide, paths, pixelTable, width)
Add the path around the grid point.
addInfillBoundary(infillBoundary, nestedRings)
Add infill boundary to the nested ring that contains it.
addLoop(infillWidth, infillPaths, loop, rotationPlaneAngle)
Add simplified path to fill.
addPath(infillWidth, infillPaths, path, rotationPlaneAngle)
Add simplified path to fill.
addPathIndexFirstSegment(gridPixel, pathIndexTable, pixelTable, segmentFirstPixel)
Add the path index of the closest segment found toward the second segment.
addPathIndexSecondSegment(gridPixel, pathIndexTable, pixelTable, segmentSecondPixel)
Add the path index of the closest segment found toward the second segment.
addPointOnPath(path, pathIndex, pixelTable, point, pointIndex, width)
Add a point to a path and the pixel table.
addPointOnPathIfFree(path, pathIndex, pixelTable, point, pointIndex, width)
Add the closest point to a path, if the point added to a path is free.
addSparseEndpoints(doubleInfillWidth, endpoints, horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey, infillSolidity, removedEndpoints, solidSurfaceThickness, surroundingXIntersections)
Add sparse endpoints.
addSparseEndpointsFromSegment(doubleInfillWidth, endpoints, horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey, infillSolidity, removedEndpoints, segment, solidSurfaceThickness, surroundingXIntersections)
Add sparse endpoints from a segment.
addYIntersectionPathToList(pathIndex, pointIndex, y, yIntersection, yIntersectionPaths)
Add the y intersection path to the y intersection paths.
compareDistanceFromCenter(self, other)
Get comparison in order to sort y intersections in ascending order of distance from the center.
comparePointIndexDescending(self, other)
Get comparison in order to sort y intersections in descending order of point index.
createExtraFillLoops(nestedRing, radius, radiusAround, shouldExtraLoopsBeAdded)
Create extra fill loops.
createFillForSurroundings(nestedRings, radius, radiusAround, shouldExtraLoopsBeAdded)
Create extra fill loops for nested rings.
getAdditionalLength(path, point, pointIndex)
Get the additional length added by inserting a point into a path.
getClosestOppositeIntersectionPaths(yIntersectionPaths)
Get the close to center paths, starting with the first and an additional opposite if it exists.
getCraftedText(fileName, gcodeText='', repository=None)
Fill the inset file or gcode text.
getCraftedTextFromText(gcodeText, repository=None)
Fill the inset gcode text.
getKeyIsInPixelTableAddValue(key, pathIndexTable, pixelTable)
Determine if the key is in the pixel table, and if it is and if the value is not None add it to the path index table.
getLowerLeftCorner(nestedRings)
Get the lower left corner from the nestedRings.
getNewRepository()
Get new repository.
getNonIntersectingGridPointLine(gridPointInsetX, isJunctionWide, paths, pixelTable, yIntersectionPath, width)
Get the points around the grid point that is junction wide that do not intersect.
getPlusMinusSign(number)
Get one if the number is zero or positive else negative one.
getWithLeastLength(path, point)
Insert a point into a path, at the index at which the path would be shortest.
getYIntersectionInsideYSegment(segmentFirstY, segmentSecondY, beginComplex, endComplex, x)
Get the y intersection inside the y segment if it does, else none.
insertGridPointPair(gridPoint, gridPointInsetX, gridPoints, isJunctionWide, paths, pixelTable, yIntersectionPath, width)
Insert a pair of points around the grid point is is junction wide, otherwise inset one point.
insertGridPointPairWithLinePath(gridPoint, gridPointInsetX, gridPoints, isJunctionWide, linePath, paths, pixelTable, yIntersectionPath, width)
Insert a pair of points around the grid point is is junction wide, otherwise inset one point.
insertGridPointPairs(gridPoint, gridPointInsetX, gridPoints, intersectionPathFirst, intersectionPathSecond, isBothOrNone, isJunctionWide, paths, pixelTable, width)
Insert a pair of points around a pair of grid points.
isAddedPointOnPathFree(path, pixelTable, point, pointIndex, width)
Determine if the point added to a path is intersecting the pixel table or the path.
isAddedPointOnPathIntersectingPath(begin, path, point, pointIndex)
Determine if the point added to a path is intersecting the path by checking line intersection.
isIntersectingLoopsPaths(loops, paths, pointBegin, pointEnd)
Determine if the segment between the first and second point is intersecting the loop list.
isPointAddedAroundClosest(layerInfillWidth, paths, pixelTable, removedEndpointPoint, width)
Add the closest removed endpoint to the path, with minimal twisting.
isSegmentAround(aroundSegmentsDictionary, aroundSegmentsDictionaryKey, segment)
Determine if there is another segment around.
isSegmentCompletelyInAnIntersection(segment, xIntersections)
Add sparse endpoints from a segment.
isSegmentInX(segment, xFirst, xSecond)
Determine if the segment overlaps within x.
isSharpCorner(beginComplex, centerComplex, endComplex)
Determine if the three complex points form a sharp corner.
isSidePointAdded(pixelTable, closestPath, closestPathIndex, closestPointIndex, layerInfillWidth, removedEndpointPoint, width)
Add side point along with the closest removed endpoint to the path, with minimal twisting.
main()
Display the fill dialog.
removeEndpoints(layerInfillWidth, paths, pixelTable, removedEndpoints, aroundWidth)
Remove endpoints which are added to the path.
setIsOutside(yCloseToCenterPath, yIntersectionPaths)
Determine if the yCloseToCenterPath is outside.
writeOutput(fileName, shouldAnalyze=True)
Fill an inset gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/28/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.fillet.html000066400000000000000000000643621167321211700335120ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.fillet
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.fillet ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/fillet.py

Previous / Next / Contents


Fillet rounds the corners slightly in a variety of ways. This is to reduce corner blobbing and sudden extruder acceleration.

The fillet manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fillet


Operation
Settings
  Fillet Procedure Choice
    Arc Point
    Arc Radius
    Arc Segment
    Bevel
  Corner Feed Rate Multiplier
  Fillet Radius over Perimeter Width
  Reversal Slowdown over Perimeter Width
  Use Intermediate Feed Rate in Corners
Examples

Operation


The default 'Activate Fillet' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Fillet Procedure Choice

Default is 'Bevel''.

Arc Point

When selected, the corners will be filleted with an arc using the gcode point form.

Arc Radius

When selected, the corners will be filleted with an arc using the gcode radius form.

Arc Segment

When selected, the corners will be filleted with an arc composed of several segments.

Bevel

When selected, the corners will be beveled.

Corner Feed Rate Multiplier

Default: 1.0

Defines the ratio of the feed rate in corners over the original feed rate. With a high value the extruder will move quickly in corners, accelerating quickly and leaving a thin extrusion. With a low value, the extruder will move slowly in corners, accelerating gently and leaving a thick extrusion.

Fillet Radius over Perimeter Width

Default is 0.35.

Defines the width of the fillet.

Reversal Slowdown over Perimeter Width

Default is 0.5.

Defines how far before a path reversal the extruder will slow down. Some tools, like nozzle wipe, double back the path of the extruder and this option will add a slowdown point in that path so there won't be a sudden jerk at the end of the path. If the value is less than 0.1 a slowdown will not be added.

Use Intermediate Feed Rate in Corners

Default is on.

When selected, the feed rate entering the corner will be the average of the old feed rate and the new feed rate.

Examples


The following examples fillet the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and fillet.py.

> python fillet.py
This brings up the fillet dialog.

> python fillet.py Screw Holder Bottom.stl
The fillet tool is parsing the file:
Screw Holder Bottom.stl
..
The fillet tool has created the file:
.. Screw Holder Bottom_fillet.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
BevelSkein
ArcSegmentSkein
ArcPointSkein
ArcRadiusSkein
FilletRepository

 
class ArcPointSkein(ArcSegmentSkein)
    A class to arc point a skein of extrusions.
 
 
Method resolution order:
ArcPointSkein
ArcSegmentSkein
BevelSkein

Methods defined here:
addArc(self, afterCenterDifferenceAngle, afterPoint, beforeCenterSegment, beforePoint, center)
Add an arc point to the filleted skein.
getRelativeCenter(self, centerMinusBeforeComplex)
Get the relative center.

Methods inherited from ArcSegmentSkein:
splitPointGetAfter(self, location, nextLocation)
Fillet a point into arc segments and return the end of the last segment.

Methods inherited from BevelSkein:
__init__(self)
addLinearMovePoint(self, feedRateMinute, point)
Add a gcode linear move, feedRate and newline to the output.
getCornerFeedRate(self)
Get the corner feed rate, which may be based on the intermediate feed rate.
getCraftedGcode(self, repository, gcodeText)
Parse gcode text and store the bevel gcode.
getExtruderOffReversalPoint(self, afterSegment, afterSegmentComplex, beforeSegment, beforeSegmentComplex, location)
If the extruder is off and the path is reversing, add intermediate slow points.
getNextLocation(self)
Get the next linear move.  Return none is none is found.
linearMove(self, splitLine)
Bevel a linear move.
parseInitialization(self, repository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the bevel gcode.

 
class ArcRadiusSkein(ArcPointSkein)
    A class to arc radius a skein of extrusions.
 
 
Method resolution order:
ArcRadiusSkein
ArcPointSkein
ArcSegmentSkein
BevelSkein

Methods defined here:
getRelativeCenter(self, centerMinusBeforeComplex)
Get the relative center.

Methods inherited from ArcPointSkein:
addArc(self, afterCenterDifferenceAngle, afterPoint, beforeCenterSegment, beforePoint, center)
Add an arc point to the filleted skein.

Methods inherited from ArcSegmentSkein:
splitPointGetAfter(self, location, nextLocation)
Fillet a point into arc segments and return the end of the last segment.

Methods inherited from BevelSkein:
__init__(self)
addLinearMovePoint(self, feedRateMinute, point)
Add a gcode linear move, feedRate and newline to the output.
getCornerFeedRate(self)
Get the corner feed rate, which may be based on the intermediate feed rate.
getCraftedGcode(self, repository, gcodeText)
Parse gcode text and store the bevel gcode.
getExtruderOffReversalPoint(self, afterSegment, afterSegmentComplex, beforeSegment, beforeSegmentComplex, location)
If the extruder is off and the path is reversing, add intermediate slow points.
getNextLocation(self)
Get the next linear move.  Return none is none is found.
linearMove(self, splitLine)
Bevel a linear move.
parseInitialization(self, repository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the bevel gcode.

 
class ArcSegmentSkein(BevelSkein)
    A class to arc segment a skein of extrusions.
 
  Methods defined here:
addArc(self, afterCenterDifferenceAngle, afterPoint, beforeCenterSegment, beforePoint, center)
Add arc segments to the filleted skein.
splitPointGetAfter(self, location, nextLocation)
Fillet a point into arc segments and return the end of the last segment.

Methods inherited from BevelSkein:
__init__(self)
addLinearMovePoint(self, feedRateMinute, point)
Add a gcode linear move, feedRate and newline to the output.
getCornerFeedRate(self)
Get the corner feed rate, which may be based on the intermediate feed rate.
getCraftedGcode(self, repository, gcodeText)
Parse gcode text and store the bevel gcode.
getExtruderOffReversalPoint(self, afterSegment, afterSegmentComplex, beforeSegment, beforeSegmentComplex, location)
If the extruder is off and the path is reversing, add intermediate slow points.
getNextLocation(self)
Get the next linear move.  Return none is none is found.
linearMove(self, splitLine)
Bevel a linear move.
parseInitialization(self, repository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the bevel gcode.

 
class BevelSkein
    A class to bevel a skein of extrusions.
 
  Methods defined here:
__init__(self)
addLinearMovePoint(self, feedRateMinute, point)
Add a gcode linear move, feedRate and newline to the output.
getCornerFeedRate(self)
Get the corner feed rate, which may be based on the intermediate feed rate.
getCraftedGcode(self, repository, gcodeText)
Parse gcode text and store the bevel gcode.
getExtruderOffReversalPoint(self, afterSegment, afterSegmentComplex, beforeSegment, beforeSegmentComplex, location)
If the extruder is off and the path is reversing, add intermediate slow points.
getNextLocation(self)
Get the next linear move.  Return none is none is found.
linearMove(self, splitLine)
Bevel a linear move.
parseInitialization(self, repository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the bevel gcode.
splitPointGetAfter(self, location, nextLocation)
Bevel a point and return the end of the bevel.   should get complex for radius

 
class FilletRepository
    A class to handle the fillet settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Fillet button has been clicked.

 
Functions
       
getCraftedText(fileName, gcodeText, repository=None)
Fillet a gcode linear move file or text.
getCraftedTextFromText(gcodeText, repository=None)
Fillet a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the fillet dialog.
writeOutput(fileName, shouldAnalyze=True)
Fillet a gcode linear move file. Depending on the settings, either arcPoint, arcRadius, arcSegment, bevel or do nothing.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.flow.html000066400000000000000000000234031167321211700331710ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.flow
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.flow ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/flow.py

Previous / Next / Contents


The flow script sets the flow rate by writing the M108 gcode.


Operation
Settings
  Flow Rate
Examples

Operation


The default 'Activate Flow' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Flow Rate

Default is 210.

Defines the flow rate which will be written following the M108 command. The flow rate is usually a PWM setting, but could be anything, like the rpm of the tool or the duty cycle of the tool.

Examples


The following examples flow the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and flow.py.

> python flow.py
This brings up the flow dialog.

> python flow.py Screw Holder Bottom.stl
The flow tool is parsing the file:
Screw Holder Bottom.stl
..
The flow tool has created the file:
.. Screw Holder Bottom_flow.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
FlowRepository
FlowSkein

 
class FlowRepository
    A class to handle the flow settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Flow button has been clicked.

 
class FlowSkein
    A class to flow a skein of extrusions.
 
  Methods defined here:
__init__(self)
addFlowRateLine(self)
Add flow rate line.
getCraftedGcode(self, gcodeText, flowRepository)
Parse gcode text and store the flow gcode.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the flow skein.

 
Functions
       
getCraftedText(fileName, text='', flowRepository=None)
Flow the file or text.
getCraftedTextFromText(gcodeText, flowRepository=None)
Flow a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the flow dialog.
writeOutput(fileName, shouldAnalyze=True)
Flow a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.home.html000066400000000000000000000254371167321211700331630ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.home
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.home ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/home.py

Previous / Next / Contents


Plugin to home the tool at beginning of each layer.

The home manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Home


Operation
Settings
  Name of Home File
Examples

Operation


The default 'Activate Home' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Name of Home File

Default: home.gcode

At the beginning of a each layer, home will add the commands of a gcode script with the name of the "Name of Home File" setting, if one exists. Home does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. Home looks for those files in the alterations folder in the .skeinforge folder in the home directory. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.

Examples


The following examples home the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and home.py.

> python home.py
This brings up the home dialog.

> python home.py Screw Holder Bottom.stl
The home tool is parsing the file:
Screw Holder Bottom.stl
..
The home tool has created the file:
.. Screw Holder Bottom_home.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
HomeRepository
HomeSkein

 
class HomeRepository
    A class to handle the home settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Home button has been clicked.

 
class HomeSkein
    A class to home a skein of extrusions.
 
  Methods defined here:
__init__(self)
addFloat(self, begin, end)
Add dive to the original height.
addHomeTravel(self, splitLine)
Add the home travel gcode.
addHopUp(self, location)
Add hop to highest point.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the home gcode.
parseInitialization(self, repository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the bevel gcode.

 
Functions
       
getCraftedText(fileName, text, repository=None)
Home a gcode linear move file or text.
getCraftedTextFromText(gcodeText, repository=None)
Home a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the home dialog.
writeOutput(fileName, shouldAnalyze=True)
Home a gcode linear move file.  Chain home the gcode if it is not already homed.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.hop.html000066400000000000000000000257661167321211700330260ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.hop
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.hop ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/hop.py

Previous / Next / Contents


Hop is a script to raise the extruder when it is not extruding.

Note:

Note: In some cases where you have thin overhang this plugin can help solve the problem object being knocked off by the head

The hop manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Hop


Operation
Settings
  Hop Over Layer Thickness
  Minimum Hop Angle
Examples

Operation


The default 'Activate Hop' checkbox is off.

It is off because Vik and Nophead found better results without hopping. Numerous users reported better output without this plugin hence it is off by default.

When activated the extruder will hop when traveling. When it is off, nothing will be done.

Settings


Hop Over Layer Thickness

Default is one.

Defines the ratio of the hop height over the layer thickness, this is the most important hop setting.

Minimum Hop Angle

Default is 20 degrees.

Defines the minimum angle that the path of the extruder will be raised. An angle of ninety means that the extruder will go straight up as soon as it is not extruding and a low angle means the extruder path will gradually rise to the hop height.

Examples


The following examples hop the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and hop.py.

> python hop.py
This brings up the hop dialog.

> python hop.py Screw Holder Bottom.stl
The hop tool is parsing the file:
Screw Holder Bottom.stl
..
The hop tool has created the file:
.. Screw Holder Bottom_hop.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
HopRepository
HopSkein

 
class HopRepository
    A class to handle the hop settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Hop button has been clicked.

 
class HopSkein
    A class to hop a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize
getCraftedGcode(self, gcodeText, hopRepository)
Parse gcode text and store the hop gcode.
getHopLine(self, line)
Get hopped gcode line.
isNextTravel(self)
Determine if there is another linear travel before the thread ends.
parseInitialization(self, hopRepository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the bevel gcode.

 
Functions
       
getCraftedText(fileName, text, hopRepository=None)
Hop a gcode linear move text.
getCraftedTextFromText(gcodeText, hopRepository=None)
Hop a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the hop dialog.
writeOutput(fileName, shouldAnalyze=True)
Hop a gcode linear move file.  Chain hop the gcode if it is not already hopped.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.html000066400000000000000000000144621167321211700322300ustar00rootroot00000000000000 Python: package skeinforge_application.skeinforge_plugins.craft_plugins
 
 
skeinforge_application.skeinforge_plugins.craft_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
alteration
bottom
carve
chamber
chop
cleave
clip
coil
comb
cool
dimension
drill
export
export_plugins (package)
feed
fill
fillet
flow
home
hop
inset
jitter
lash
lift
limit
mill
multiply
oozebane
outset
preface
raft
scale
skin
skirt
smooth
speed
splodge
stretch
temperature
tower
unpause
whittle
widen
wipe

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.inset.html000066400000000000000000000412421167321211700333450ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.inset
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.inset ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/inset.py

Previous / Next / Contents


Inset will inset the outside outlines by half the perimeter width, and outset the inside outlines by the same amount.

The inset manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Inset


Settings
  Add Custom Code for Temperature Reading
  Infill in Direction of Bridge
  Loop Order Choice
    Ascending Area
    Descending Area
  Overlap Removal Width over Perimeter Width
  Turn Extruder Heater Off at Shut Down
Examples

Settings


Add Custom Code for Temperature Reading

Default is on.

When selected, the M105 custom code for temperature reading will be added at the beginning of the file.

Infill in Direction of Bridge

Default is on.

When selected, the infill will be in the direction of any bridge across a gap, so that the fill will be able to span a bridge easier.

Loop Order Choice

Default loop order choice is 'Ascending Area'.

When overlap is to be removed, for each loop, the overlap is checked against the list of loops already extruded. If the latest loop overlaps an already extruded loop, the overlap is removed from the latest loop. The loops are ordered according to their areas.

Ascending Area

When selected, the loops will be ordered in ascending area. With thin walled parts, if overlap is being removed the outside of the container will not be extruded. Holes will be the correct size.

Descending Area

When selected, the loops will be ordered in descending area. With thin walled parts, if overlap is being removed the inside of the container will not be extruded. Holes will be missing the interior wall so they will be slightly wider than model size.

Overlap Removal Width over Perimeter Width

Default is 0.6.

Defines the ratio of the overlap removal width over the perimeter width. Any part of the extrusion that comes within the overlap removal width of another is removed. This is to prevent the extruder from depositing two extrusions right beside each other. If the 'Overlap Removal Width over Perimeter Width' is less than 0.2, the overlap will not be removed.

Turn Extruder Heater Off at Shut Down

Default is on.

When selected, the M104 S0 gcode line will be added to the end of the file to turn the extruder heater off by setting the extruder heater temperature to 0.

Examples


The following examples inset the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and inset.py.

> python inset.py
This brings up the inset dialog.

> python inset.py Screw Holder Bottom.stl
The inset tool is parsing the file:
Screw Holder Bottom.stl
..
The inset tool has created the file:
.. Screw Holder Bottom_inset.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cmath
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
InsetRepository
InsetSkein

 
class InsetRepository
    A class to handle the inset settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Inset button has been clicked.

 
class InsetSkein
    A class to inset a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize.
addGcodeFromPerimeterPaths(self, isIntersectingSelf, loop, loopLayer, loopLists, radius)
Add the perimeter paths to the output.
addGcodeFromRemainingLoop(self, loop, loopLayer, loopLists, radius)
Add the remainder of the loop which does not overlap the alreadyFilledArounds loops.
addGcodePerimeterBlockFromRemainingLoop(self, loop, loopLayer, loopLists, radius)
Add the perimter block remainder of the loop which does not overlap the alreadyFilledArounds loops.
addInitializationToOutput(self)
Add initialization gcode to the output.
addInset(self, loopLayer)
Add inset to the layer.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the bevel gcode.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the inset skein.

 
Functions
       
addAlreadyFilledArounds(alreadyFilledArounds, loop, radius)
Add already filled loops around loop to alreadyFilledArounds.
addSegmentOutline(isThick, outlines, pointBegin, pointEnd, width)
Add a diamond or hexagonal outline for a line segment.
getBridgeDirection(belowLoops, layerLoops, radius)
Get span direction for the majority of the overhanging extrusion perimeter, if any.
getCraftedText(fileName, text='', repository=None)
Inset the preface file or text.
getCraftedTextFromText(gcodeText, repository=None)
Inset the preface gcode text.
getDoubledRoundZ(overhangingSegment, segmentRoundZ)
Get doubled plane angle around z of the overhanging segment.
getInteriorSegments(loops, segments)
Get segments inside the loops.
getIsIntersectingWithinList(loop, loopList)
Determine if the loop is intersecting or is within the loop list.
getNewRepository()
Get new repository.
getOverhangDirection(belowOutsetLoops, segmentBegin, segmentEnd)
Add to span direction from the endpoint segments which overhang the layer below.
getSegmentsFromLoopListsPoints(loopLists, pointBegin, pointEnd)
Get endpoint segments from the beginning and end of a line segment.
isCloseToLast(paths, point, radius)
Determine if the point is close to the last point of the last path.
isIntersectingItself(loop, width)
Determine if the loop is intersecting itself.
isIntersectingWithinLists(loop, loopLists)
Determine if the loop is intersecting or is within the loop lists.
main()
Display the inset dialog.
writeOutput(fileName, shouldAnalyze=True)
Inset the carving of a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.jitter.html000066400000000000000000000276721167321211700335370ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.jitter
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.jitter ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/jitter.py

Previous / Next / Contents


This craft tool jitters the loop end position to a different place on each layer to prevent a ridge from being created on the side of the object.

The jitter manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Jitter


Operation
Settings
  Jitter Over Perimeter Width
Examples

Operation


The default 'Activate Jitter' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Jitter Over Perimeter Width

Default: 2

Defines the amount the loop ends will be jittered over the perimeter width. A high value means the loops will start all over the place and a low value means loops will start at roughly the same place on each layer.

For example if you turn jitter off and print a cube every outside shell on the cube will start from exactly the same point so you will have a visible "mark/line/seam" on the side of the cube. Using the jitter tool you move that start point around hence you avoid that visible seam.


Examples


The following examples jitter the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and jitter.py.

> python jitter.py
This brings up the jitter dialog.

> python jitter.py Screw Holder Bottom.stl
The jitter tool is parsing the file:
Screw Holder Bottom.stl
..
The jitter tool has created the file:
.. Screw Holder Bottom_jitter.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
JitterRepository
JitterSkein

 
class JitterRepository
    A class to handle the jitter settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Jitter button has been clicked.

 
class JitterSkein
    A class to jitter a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize.
addGcodeFromThreadZ(self, thread, z)
Add a gcode thread to the output.
addGcodeMovementZ(self, feedRateMinute, point, z)
Add a movement to the output.
addGcodePathZ(self, feedRateMinute, path, z)
Add a gcode path, without modifying the extruder, to the output.
addTailoredLoopPath(self)
Add a clipped and jittered loop path.
getCraftedGcode(self, jitterRepository, gcodeText)
Parse gcode text and store the jitter gcode.
parseInitialization(self, jitterRepository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line, jitter it and add it to the jitter skein.
setFeedRateLocationLoopPath(self, line, splitLine)
Set the feedRateMinute, oldLocation and loopPath.

 
Functions
       
getCraftedText(fileName, text, jitterRepository=None)
Jitter a gcode linear move text.
getCraftedTextFromText(gcodeText, jitterRepository=None)
Jitter a gcode linear move text.
getJitteredLoop(jitterDistance, jitterLoop)
Get a jittered loop path.
getNewRepository()
Get new repository.
isLoopNumberEqual(betweenX, betweenXIndex, loopNumber)
Determine if the loop number is equal.
main()
Display the jitter dialog.
writeOutput(fileName, shouldAnalyze=True)
Jitter a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.lash.html000066400000000000000000000245531167321211700331600ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.lash
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.lash ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/lash.py

Previous / Next / Contents


Lash is a script to partially compensate for the backlash of the tool head.

The lash manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Lash

The lash tool is ported from Erik de Bruijn's 3D-to-5D-Gcode php GPL'd script at:
http://objects.reprap.org/wiki/3D-to-5D-Gcode.php

The default values are from the settings in Erik's 3D-to-5D-Gcode, I believe the settings are used on his Darwin reprap.


Operation
Settings
  X Backlash
  Y Backlash
Examples

Operation


The default 'Activate Lash' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


X Backlash

Default is 0.2 millimeters.

Defines the distance the tool head will be lashed in the X direction.

Y Backlash

Default is 0.2 millimeters.

Defines the distance the tool head will be lashed in the Y direction.

Examples


The following examples lash the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and lash.py.

> python lash.py
This brings up the lash dialog.

> python lash.py Screw Holder Bottom.stl
The lash tool is parsing the file:
Screw Holder Bottom.stl
..
The lash tool has created the file:
.. Screw Holder Bottom_lash.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
LashRepository
LashSkein

 
class LashRepository
    A class to handle the lash settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Lash button has been clicked.

 
class LashSkein
    A class to lash a skein of extrusions.
 
  Methods defined here:
__init__(self)
getCraftedGcode(self, gcodeText, lashRepository)
Parse gcode text and store the lash gcode.
getLashedLine(self, line, location, splitLine)
Get lashed gcode line.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLash(self, line)
Parse a gcode line and add it to the lash skein.

 
Functions
       
getCraftedText(fileName, text, lashRepository=None)
Get a lashed gcode linear move text.
getCraftedTextFromText(gcodeText, lashRepository=None)
Get a lashed gcode linear move text from text.
getNewRepository()
Get new repository.
main()
Display the lash dialog.
writeOutput(fileName, shouldAnalyze=True)
Lash a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.lift.html000066400000000000000000000262771167321211700331740ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.lift
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.lift ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/lift.py

Previous / Next / Contents


Lift will change the altitude of the cutting tool when it is on so that it will cut through the slab at the correct altitude. It will also lift the gcode when the tool is off so that the cutting tool will clear the top of the slab.


Operation
Settings
  Cutting Lift over Layer Step
  Clearance above Top
Examples

Operation


The default 'Activate Lift' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Cutting Lift over Layer Step

Default is minus 0.5, because the end mill is the more common tool.

Defines the ratio of the amount the cutting tool will be lifted over the layer step. If whittle is off the layer step will be the layer thickness, if it is on, it will be the layer step from the whittle gcode. If the cutting tool is like an end mill, where the cutting happens until the end of the tool, then the 'Cutting Lift over Layer Step' should be minus 0.5, so that the end mill cuts to the bottom of the slab. If the cutting tool is like a laser, where the cutting happens around the focal point. the 'Cutting Lift over Layer Step' should be zero, so that the cutting action will be focused in the middle of the slab.

Clearance above Top

Default is 5 millimeters.

Defines the distance above the top of the slab the cutting tool will be lifted when will tool is off so that the cutting tool will clear the top of the slab.

Examples


The following examples lift the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and lift.py.

> python lift.py
This brings up the lift dialog.

> python lift.py Screw Holder Bottom.stl
The lift tool is parsing the file:
Screw Holder Bottom.stl
..
The lift tool has created the file:
.. Screw Holder Bottom_lift.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
LiftRepository
LiftSkein

 
class LiftRepository
    A class to handle the lift settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Lift button has been clicked.

 
class LiftSkein
    A class to lift a skein of extrusions.
 
  Methods defined here:
__init__(self)
addPreviousInactiveMovementLineIfNecessary(self)
Add the previous inactive movement line if necessary.
getCraftedGcode(self, liftRepository, gcodeText)
Parse gcode text and store the lift gcode.
getLinearMove(self, line, location, splitLine)
Get the linear move.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the lift skein.
setMaximumZ(self)
Set maximum  z.

 
Functions
       
getCraftedText(fileName, text='', liftRepository=None)
Lift the preface file or text.
getCraftedTextFromText(gcodeText, liftRepository=None)
Lift the preface gcode text.
getNewRepository()
Get new repository.
main()
Display the lift dialog.
writeOutput(fileName, shouldAnalyze=True)
Lift the carving of a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.limit.html000066400000000000000000000256231167321211700333460ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.limit
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.limit ($Date: 2008/28/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/limit.py

Previous / Next / Contents


This plugin limits the feed rate of the tool head, so that the stepper motors are not driven too fast and skip steps.

The limit manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Limit

The maximum z feed rate is defined in speed.


Operation
Settings
  Maximum Initial Feed Rate
Examples

Operation


The default 'Activate Limit' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Maximum Initial Feed Rate

Default is one millimeter per second.

Defines the maximum speed of the inital tool head move.

Examples


The following examples limit the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and limit.py.

> python limit.py
This brings up the limit dialog.

> python limit.py Screw Holder Bottom.stl
The limit tool is parsing the file:
Screw Holder Bottom.stl
..
The limit tool has created the file:
.. Screw Holder Bottom_limit.gcode


Previous / Next / Contents


 
Modules
       
skeinforge_application.skeinforge_plugins.craft_plugins.__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
LimitRepository
LimitSkein

 
class LimitRepository
    A class to handle the limit settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Limit button has been clicked.

 
class LimitSkein
    A class to limit a skein of extrusions.
 
  Methods defined here:
__init__(self)
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the limit gcode.
getLimitedInitialMovement(self, line, splitLine)
Get a limited linear movement.
getZLimitedLine(self, deltaZ, distance, line, splitLine)
Get a replaced z limited gcode movement line.
getZLimitedLineArc(self, line, splitLine)
Get a replaced z limited gcode arc movement line.
getZLimitedLineLinear(self, line, location, splitLine)
Get a replaced z limited gcode linear movement line.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, lineIndex)
Parse a gcode line and add it to the limit skein.

 
Functions
       
getCraftedText(fileName, gcodeText='', repository=None)
Limit a gcode file or text.
getCraftedTextFromText(gcodeText, repository=None)
Limit a gcode text.
getNewRepository()
Get new repository.
main()
Display the limit dialog.
writeOutput(fileName, shouldAnalyze=True)
Limit a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/28/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.mill.html000066400000000000000000000371251167321211700331650ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.mill
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.mill ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/mill.py

Previous / Next / Contents


Mill is a script to mill the outlines.


Operation
Settings
  Add Loops
    Add Inner Loops
    Add Outer Loops
  Cross Hatch
  Loop Outset
    Loop Inner Outset over Perimeter Width
    Loop Outer Outset over Perimeter Width
  Mill Width over Perimeter Width
Examples

Operation


The default 'Activate Mill' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Add Loops

Add Inner Loops

Default is on.

When selected, the inner milling loops will be added.

Add Outer Loops

Default is on.

When selected, the outer milling loops will be added.

Cross Hatch

Default is on.

When selected, there will be alternating horizontal and vertical milling paths, if it is off there will only be horizontal milling paths.

Loop Outset

Loop Inner Outset over Perimeter Width

Default is 0.5.

Defines the ratio of the amount the inner milling loop will be outset over the perimeter width.

Loop Outer Outset over Perimeter Width

Default is one.

Defines the ratio of the amount the outer milling loop will be outset over the perimeter width. The 'Loop Outer Outset over Perimeter Width' ratio should be greater than the 'Loop Inner Outset over Perimeter Width' ratio.

Mill Width over Perimeter Width

Default is one.

Defines the ratio of the mill line width over the perimeter width. If the ratio is one, all the material will be milled. The greater the 'Mill Width over Perimeter Width' the farther apart the mill lines will be and so less of the material will be directly milled, the remaining material might still be removed in chips if the ratio is not much greater than one.

Examples


The following examples mill the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and mill.py.

> python mill.py
This brings up the mill dialog.

> python mill.py Screw Holder Bottom.stl
The mill tool is parsing the file:
Screw Holder Bottom.stl
..
The mill tool has created the file:
Screw Holder Bottom_mill.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
Average
MillRepository
MillSkein

 
class Average
    A class to hold values and get the average.
 
  Methods defined here:
__init__(self)
addValue(self, value)
Add a value to the total and the number of values.
getAverage(self)
Get the average.
reset(self)
Set the number of values and the total to the default.

 
class MillRepository
    A class to handle the mill settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Mill button has been clicked.

 
class MillSkein
    A class to mill a skein of extrusions.
 
  Methods defined here:
__init__(self)
addGcodeFromLoops(self, loops, z)
Add gcode from loops.
addGcodeFromThreadZ(self, thread, z)
Add a thread to the output.
addMillThreads(self)
Add the mill threads to the skein.
addSegmentTableLoops(self, boundaryLayerIndex)
Add the segment tables and loops to the boundary.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the mill gcode.
getHorizontalSegmentTableForXIntersectionsTable(self, xIntersectionsTable)
Get the horizontal segment table from the xIntersectionsTable.
getHorizontalXIntersectionsTable(self, loops)
Get the horizontal x intersections table from the loops.
getVerticalSegmentTableForXIntersectionsTable(self, xIntersectionsTable)
Get the vertical segment table from the xIntersectionsTable which has the x and y swapped.
parseBoundaries(self)
Parse the boundaries and add them to the boundary layers.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the mill skein.

 
Functions
       
getCraftedText(fileName, gcodeText='', repository=None)
Mill the file or gcodeText.
getCraftedTextFromText(gcodeText, repository=None)
Mill a gcode linear move gcodeText.
getNewRepository()
Get new repository.
getPointsFromSegmentTable(segmentTable)
Get the points from the segment table.
isPointOfTableInLoop(loop, pointTable)
Determine if a point in the point table is in the loop.
main()
Display the mill dialog.
writeOutput(fileName, shouldAnalyze=True)
Mill a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.multiply.html000066400000000000000000000325041167321211700341030ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.multiply
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.multiply ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/multiply.py

Previous / Next / Contents


The multiply plugin will take a single object and create an array of objects. It is used when you want to print single object multiple times in a single pass.

You can also position any object using this plugin by setting the center X and center Y to the desired coordinates (0,0 for the center of the print_bed) and setting the number of rows and columns to 1 (effectively setting a 1x1 matrix - printing only a single object).

The multiply manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Multiply

Besides using the multiply tool, another way of printing many copies of the model is to duplicate the model in Art of Illusion, however many times you want, with the appropriate offsets. Then you can either use the Join Objects script in the scripts submenu to create a combined shape or you can export the whole scene as an xml file, which skeinforge can then slice.


Operation
Settings
  Center
    Center X
    Center Y
  Number of Cells
    Number of Columns
    Number of Rows
  Reverse Sequence every Odd Layer
  Separation over Perimeter Width
Examples

Operation


The default 'Activate Multiply' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Center

Default is the origin.

The center of the shape will be moved to the "Center X" and "Center Y" coordinates.

Center X

Center Y


Number of Cells

Number of Columns

Default is one.

Defines the number of columns in the array table.

Number of Rows

Default is one.

Defines the number of rows in the table.

Reverse Sequence every Odd Layer

Default is off.

When selected the build sequence will be reversed on every odd layer so that the tool will travel less. The problem is that the builds would be made with different amount of time to cool, so some would be too hot and some too cold, which is why the default is off.

Separation over Perimeter Width

Default is fifteen.

Defines the ratio of separation between the shape copies over the perimeter width.

Examples


The following examples multiply the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and multiply.py.

> python multiply.py
This brings up the multiply dialog.

> python multiply.py Screw Holder Bottom.stl
The multiply tool is parsing the file:
Screw Holder Bottom.stl
..
The multiply tool has created the file:
.. Screw Holder Bottom_multiply.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
MultiplyRepository
MultiplySkein

 
class MultiplyRepository
    A class to handle the multiply settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Multiply button has been clicked.

 
class MultiplySkein
    A class to multiply a skein of extrusions.
 
  Methods defined here:
__init__(self)
addElement(self, offset)
Add moved element to the output.
addLayer(self)
Add multiplied layer to the output.
addRemoveThroughLayer(self)
Parse gcode initialization and store the parameters.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the multiply gcode.
getMovedLocationSetOldLocation(self, offset, splitLine)
Get the moved location and set the old location.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the multiply skein.
setCorners(self)
Set maximum and minimum corners and z.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Multiply the fill file or text.
getCraftedTextFromText(gcodeText, repository=None)
Multiply the fill text.
getNewRepository()
Get new repository.
main()
Display the multiply dialog.
writeOutput(fileName, shouldAnalyze=True)
Multiply a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.oozebane.html000066400000000000000000000461521167321211700340320ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.oozebane
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.oozebane ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/oozebane.py

Previous / Next / Contents


Oozebane is a script to turn off the extruder before the end of a thread and turn it on before the beginning.

The oozebane manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Oozebane

After oozebane turns the extruder on, it slows the feed rate down where the thread starts. Then it speeds it up in steps so in theory the thread will remain at roughly the same thickness from the beginning.


Operation
Settings
  After Startup Distance
  Early Shutdown Distance
  Early Startup Maximum Distance
  Early Startup Distance Constant
  First Early Startup Distance
  Minimum Distance for Early Shutdown
  Minimum Distance for Early Startup
  Slowdown Startup Steps
Examples

Operation


The default 'Activate Oozebane' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


After Startup Distance

Default is 1.2.

When oozebane reaches the point where the extruder would of turned on, it slows down so that the thread will be thick at that point. Afterwards it speeds the extruder back up to operating speed. The speed up distance is the "After Startup Distance".

Early Shutdown Distance

Default is 1.2.

Defines the distance before the end of the thread that the extruder will be turned off. It is the most important oozebane setting. A higher distance means the extruder will turn off sooner and the end of the line will be thinner.

Early Startup Maximum Distance

Default is 1.2.

Defines the maximum distance before the thread starts that the extruder will be turned on

Early Startup Distance Constant

Default is twenty.

The longer the extruder has been off, the earlier the extruder will turn back on, the ratio is one minus one over e to the power of the distance the extruder has been off over the "Early Startup Distance Constant".

First Early Startup Distance

Default is twenty five.

Defines the distance before the first thread starts that the extruder will be turned off. This value should be high because, according to Marius, the extruder takes a second or two to extrude when starting for the first time.

Minimum Distance for Early Shutdown

Default is zero.

Defines the minimum distance that the extruder has to be off after the thread end for the early shutdown feature to activate.

Minimum Distance for Early Startup

Default is zero.

Defines the minimum distance that the extruder has to be off before the thread begins for the early start up feature to activate.

Slowdown Startup Steps

Default is three.

When oozebane turns the extruder off, it slows the feed rate down in steps so in theory the thread will remain at roughly the same thickness until the end. The "Slowdown Startup Steps" setting is the number of steps, the more steps the smaller the size of the step that the feed rate will be decreased and the larger the size of the resulting gcode file.

Examples


The following examples oozebane the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and oozebane.py.

> python oozebane.py
This brings up the oozebane dialog.

> python oozebane.py Screw Holder Bottom.stl
The oozebane tool is parsing the file:
Screw Holder Bottom.stl
..
The oozebane tool has created the file:
.. Screw Holder Bottom_oozebane.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
OozebaneRepository
OozebaneSkein

 
class OozebaneRepository
    A class to handle the oozebane settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Oozebane button has been clicked.

 
class OozebaneSkein
    A class to oozebane a skein of extrusions.
 
  Methods defined here:
__init__(self)
addAfterStartupLine(self, splitLine)
Add the after startup lines.
addLineSetShutdowns(self, line)
Add a line and set the shutdown variables.
getActiveFeedRateRatio(self)
Get the feed rate of the first active move over the operating feed rate.
getAddAfterStartupLines(self, line)
Get and / or add after the startup lines.
getAddBeforeStartupLines(self, line)
Get and / or add before the startup lines.
getAddShutSlowDownLine(self, line)
Add the shutdown and slowdown lines.
getAddShutSlowDownLines(self, line)
Get and / or add the shutdown and slowdown lines.
getCraftedGcode(self, gcodeText, oozebaneRepository)
Parse gcode text and store the oozebane gcode.
getDistanceAfterThreadBeginning(self)
Get the distance after the beginning of the thread.
getDistanceToExtruderOffCommand(self, remainingDistance)
Get the distance to the word.
getDistanceToThreadBeginning(self)
Get the distance to the beginning of the thread.
getDistanceToThreadBeginningAfterThreadEnd(self, remainingDistance)
Get the distance to the thread beginning after the end of this thread.
getDistanceToThreadEnd(self)
Get the distance to the end of the thread.
getLinearMoveWithFeedRate(self, feedRate, location)
Get a linear move line with the feed rate.
getLinearMoveWithFeedRateSplitLine(self, feedRate, splitLine)
Get a linear move line with the feed rate and split line.
getOozebaneLine(self, line)
Get oozebaned gcode line.
getShutdownFlowRateMultiplier(self, along, numberOfDistances)
Get the shut down flow rate multipler.
getStartupFlowRateMultiplier(self, along, numberOfDistances)
Get the startup flow rate multipler.
isClose(self, location, otherLocation)
Determine if the location is close to the other location.
isCloseToEither(self, location, otherLocationFirst, otherLocationSecond)
Determine if the location is close to the other locations.
isDistanceAfterThreadBeginningGreater(self)
Determine if the distance after the thread beginning is greater than the step index after startup distance.
parseInitialization(self, oozebaneRepository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the bevel gcode.
setAfterStartupFlowRates(self, afterStartupRatio)
Set the after startup flow rates.
setEarlyShutdown(self)
Set the early shutdown variables.
setEarlyShutdownFlowRates(self, earlyShutdownRatio)
Set the extrusion width.
setEarlyStartupDistance(self, splitLine)
Set the early startup distance.
setExtrusionWidth(self, oozebaneRepository)
Set the extrusion width.

 
Functions
       
getCraftedText(fileName, text, oozebaneRepository=None)
Oozebane a gcode linear move file or text.
getCraftedTextFromText(gcodeText, oozebaneRepository=None)
Oozebane a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the oozebane dialog.
writeOutput(fileName, shouldAnalyze=True)
Oozebane a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.outset.html000066400000000000000000000240261167321211700335470ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.outset
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.outset ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/outset.py

Previous / Next / Contents


Outset outsets the perimeters of the slices of a gcode file. The outside perimeters will be outset by half the perimeter width, and the inside perimeters will be inset by half the perimeter width. Outset is needed for subtractive machining, like cutting or milling.


Operation
Examples

Operation


The default 'Activate Outset' checkbox is on. When it is on, the gcode will be outset, when it is off, the gcode will not be changed.

Examples


The following examples outset the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and outset.py.

> python outset.py
This brings up the outset dialog.

> python outset.py Screw Holder Bottom.stl
The outset tool is parsing the file:
Screw Holder Bottom.stl
..
The outset tool has created the file:
.. Screw Holder Bottom_outset.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
OutsetRepository
OutsetSkein

 
class OutsetRepository
    A class to handle the outset settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Outset button has been clicked.

 
class OutsetSkein
    A class to outset a skein of extrusions.
 
  Methods defined here:
__init__(self)
addGcodeFromRemainingLoop(self, loop, radius, z)
Add the remainder of the loop.
addOutset(self, loopLayer)
Add outset to the layer.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the bevel gcode.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, lineIndex)
Parse a gcode line and add it to the outset skein.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Outset the preface file or text.
getCraftedTextFromText(gcodeText, repository=None)
Outset the preface gcode text.
getNewRepository()
Get new repository.
main()
Display the outset dialog.
writeOutput(fileName, shouldAnalyze=True)
Outset the carving of a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.preface.html000066400000000000000000000306221167321211700336300ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.preface
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.preface ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/preface.py

Previous / Next / Contents


Preface converts the svg slices into gcode extrusion layers, optionally with home, positioning, turn off, and unit commands.

The preface manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Preface


Settings
  Meta
  Set Positioning to Absolute
  Set Units to Millimeters
  Start at Home
  Turn Extruder Off
    Turn Extruder Off at Shut Down
    Turn Extruder Off at Start Up
Examples

Settings


Meta

Default is empty.

The 'Meta' field is to add meta tags or a note to all your files. Whatever is in that field will be added in a meta tagged line to the output.

Set Positioning to Absolute

Default is on.

When selected, preface will add the G90 command to set positioning to absolute.

Set Units to Millimeters

Default is on.

When selected, preface will add the G21 command to set the units to millimeters.

Start at Home

Default is off.

When selected, the G28 go to home gcode will be added at the beginning of the file.

Turn Extruder Off

Turn Extruder Off at Shut Down

Default is on.

When selected, the M103 turn extruder off gcode will be added at the end of the file.

Turn Extruder Off at Start Up

Default is on.

When selected, the M103 turn extruder off gcode will be added at the beginning of the file.

Examples


The following examples preface the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and preface.py.

> python preface.py
This brings up the preface dialog.

> python preface.py Screw Holder Bottom.stl
The preface tool is parsing the file:
Screw Holder Bottom.stl
..
The preface tool has created the file:
.. Screw Holder Bottom_preface.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
fabmetheus_utilities.svg_writer
sys

 
Classes
       
PrefaceRepository
PrefaceSkein

 
class PrefaceRepository
    A class to handle the preface settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Preface button has been clicked.

 
class PrefaceSkein
    A class to preface a skein of extrusions.
 
  Methods defined here:
__init__(self)
addInitializationToOutput(self)
Add initialization gcode to the output.
addPreface(self, loopLayer)
Add preface to the carve layer.
addShutdownToOutput(self)
Add shutdown gcode to the output.
addToolSettingLines(self, pluginName)
Add tool setting lines.
getCraftedGcode(self, repository, gcodeText)
Parse gcode text and store the bevel gcode.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Preface and convert an svg file or text.
getCraftedTextFromText(text, repository=None)
Preface and convert an svg text.
getNewRepository()
Get new repository.
main()
Display the preface dialog.
strftime(...)
strftime(format[, tuple]) -> string
 
Convert a time tuple to a string according to a format specification.
See the library reference manual for formatting codes. When the time tuple
is not present, current time as returned by localtime() is used.
writeOutput(fileName, shouldAnalyze=True)
Preface the carving of a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.raft.html000066400000000000000000001041441167321211700331600ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.raft
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.raft ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/raft.py

Previous / Next / Contents


Raft is a plugin to create a raft, elevate the nozzle and set the temperature. A raft is a flat base structure on top of which your object is being build and has a few different purposes. It fills irregularities like scratches and pits in your printbed and gives you a nice base parallel to the printheads movement. It also glues your object to the bed so to prevent warping in bigger object. The rafts base layer performs these tricks while the sparser interface layer(s) help you removing the object from the raft after printing. It is based on the Nophead's reusable raft, which has a base layer running one way, and a couple of perpendicular layers above. Each set of layers can be set to a different temperature. There is the option of having the extruder orbit the raft for a while, so the heater barrel has time to reach a different temperature, without ooze accumulating around the nozzle.

The raft manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Raft

The important values for the raft settings are the temperatures of the raft, the first layer and the next layers. These will be different for each material. The default settings for ABS, HDPE, PCL & PLA are extrapolated from Nophead's experiments.

You don't necessarily need a raft and especially small object will print fine on a flat bed without one, sometimes its even better when you need a water tight base to print directly on the bed. If you want to only set the temperature or only create support material or only elevate the nozzle without creating a raft, set the Base Layers and Interface Layers to zero.

<gallery perRow="1">
Image:Raft.jpg|Raft
</gallery>

Example of a raft on the left with the interface layers partially removed exposing the base layer. Notice that the first line of the base is rarely printed well because of the startup time of the extruder. On the right you see an object with its raft still attached.

The Raft panel has some extra settings, it probably made sense to have them there but they have not that much to do with the actual Raft. First are the Support material settings. Since close to all RepRap style printers have no second extruder for support material Skeinforge offers the option to print support structures with the same material set at a different speed and temperature. The idea is that the support sticks less to the actual object when it is extruded around the minimum possible working temperature. This results in a temperature change EVERY layer so build time will increase seriously.

Allan Ecker aka The Masked Retriever's has written two quicktips for raft which follow below.
"Skeinforge Quicktip: The Raft, Part 1" at:
http://blog.thingiverse.com/2009/07/14/skeinforge-quicktip-the-raft-part-1/
"Skeinforge Quicktip: The Raft, Part II" at:
http://blog.thingiverse.com/2009/08/04/skeinforge-quicktip-the-raft-part-ii/

Nophead has written about rafts on his blog:
http://hydraraptor.blogspot.com/2009/07/thoughts-on-rafts.html

More pictures of rafting in action are available from the Metalab blog at:
http://reprap.soup.io/?search=rafting


Operation
Settings
  Add Raft, Elevate Nozzle, Orbit
  Base
    Base Feed Rate Multiplier
    Base Flow Rate Multiplier
    Base Infill Density
    Base Layer Height over Layer Thickness
    Base Layers
    Base Nozzle Lift over Base Layer Thickness
  Initial Circling
  Infill Overhang over Extrusion Width
  Interface
    Interface Feed Rate Multiplier
    Interface Flow Rate Multiplier
    Interface Infill Density
    Interface Layer Thickness over Extrusion Height
    Interface Layers
    Interface Nozzle Lift over Interface Layer Thickness
  Name of Alteration Files
    Name of Support End File
    Name of Support Start File
  Operating Nozzle Lift over Layer Thickness
  Raft Size
    Raft Additional Margin over Length
    Raft Margin
  Support
    Support Cross Hatch
    Support Flow Rate over Operating Flow Rate
    Support Gap over Perimeter Extrusion Width
    Support Material Choice
      Empty Layers Only
      Everywhere
      Exterior Only
      None
    Support Minimum Angle
Examples

Operation


Default: On

When it is on, the functions described below will work, when it is off, nothing will be done, so no temperatures will be set, nozzle will not be lifted..

Settings


Add Raft, Elevate Nozzle, Orbit

Default: On

When selected, the script will also create a raft, elevate the nozzle, orbit and set the altitude of the bottom of the raft. It also turns on support generation.

Base

Base layer is the part of the raft that touches the bed.

Base Feed Rate Multiplier

Default is one.

Defines the base feed rate multiplier. The greater the 'Base Feed Rate Multiplier', the thinner the base, the lower the 'Base Feed Rate Multiplier', the thicker the base.

Base Flow Rate Multiplier

Default is one.

Defines the base flow rate multiplier. The greater the 'Base Flow Rate Multiplier', the thicker the base, the lower the 'Base Flow Rate Multiplier', the thinner the base.

Base Infill Density

Default is 0.5.

Defines the infill density ratio of the base of the raft.

Base Layer Height over Layer Thickness

Default is two.

Defines the ratio of the height & width of the base layer compared to the height and width of the object infill. The feed rate will be slower for raft layers which have thicker extrusions than the object infill.

Base Layers

Default is one.

Defines the number of base layers.

Base Nozzle Lift over Base Layer Thickness

Default is 0.4.

Defines the amount the nozzle is above the center of the base extrusion divided by the base layer thickness.

Initial Circling

Default is off.

When selected, the extruder will initially circle around until it reaches operating temperature.

Infill Overhang over Extrusion Width

Default is 0.05.

Defines the ratio of the infill overhang over the the extrusion width of the raft.

Interface

Interface Feed Rate Multiplier

Default is one.

Defines the interface feed rate multiplier. The greater the 'Interface Feed Rate Multiplier', the thinner the interface, the lower the 'Interface Feed Rate Multiplier', the thicker the interface.

Interface Flow Rate Multiplier

Default is one.

Defines the interface flow rate multiplier. The greater the 'Interface Flow Rate Multiplier', the thicker the interface, the lower the 'Interface Flow Rate Multiplier', the thinner the interface.

Interface Infill Density

Default is 0.5.

Defines the infill density ratio of the interface of the raft.

Interface Layer Thickness over Extrusion Height

Default is one.

Defines the ratio of the height & width of the interface layer compared to the height and width of the object infill. The feed rate will be slower for raft layers which have thicker extrusions than the object infill.

Interface Layers

Default is two.

Defines the number of interface layers to print.

Interface Nozzle Lift over Interface Layer Thickness

Default is 0.45.

Defines the amount the nozzle is above the center of the interface extrusion divided by the interface layer thickness.

Name of Alteration Files

If support material is generated, raft looks for alteration files in the alterations folder in the .skeinforge folder in the home directory. Raft does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.

Name of Support End File

Default is support_end.gcode.

If support material is generated and if there is a file with the name of the "Name of Support End File" setting, it will be added to the end of the support gcode.

Name of Support Start File

If support material is generated and if there is a file with the name of the "Name of Support Start File" setting, it will be added to the start of the support gcode.

Operating Nozzle Lift over Layer Thickness

Default is 0.5.

Defines the amount the nozzle is above the center of the operating extrusion divided by the layer thickness.

Raft Size

The raft fills a rectangle whose base size is the rectangle around the bottom layer of the object expanded on each side by the 'Raft Margin' plus the 'Raft Additional Margin over Length (%)' percentage times the length of the side.

Raft Additional Margin over Length

Default is 1 percent.

Raft Margin

Default is three millimeters.

Support

Good articles on support material are at:
http://davedurant.wordpress.com/2010/07/31/skeinforge-support-part-1/
http://davedurant.wordpress.com/2010/07/31/skeinforge-support-part-2/

Support Cross Hatch

Default is off.

When selected, the support material will cross hatched. Cross hatching the support makes it stronger and harder to remove, which is why the default is off.

Support Flow Rate over Operating Flow Rate

Default: 0.9.

Defines the ratio of the flow rate when the support is extruded over the operating flow rate. With a number less than one, the support flow rate will be smaller so the support will be thinner and easier to remove.

Support Gap over Perimeter Extrusion Width

Default: 0.5.

Defines the gap between the support material and the object over the perimeter extrusion width.

Support Material Choice

Default is 'None' because the raft takes time to generate.

Empty Layers Only
When selected, support material will be only on the empty layers. This is useful when making identical objects in a stack.

Everywhere
When selected, support material will be added wherever there are overhangs, even inside the object. Because support material inside objects is hard or impossible to remove, this option should only be chosen if the object has a cavity that needs support and there is some way to extract the support material.

Exterior Only
When selected, support material will be added only the exterior of the object. This is the best option for most objects which require support material.

None
When selected, raft will not add support material.

Support Minimum Angle

Default is sixty degrees.

Defines the minimum angle that a surface overhangs before support material is added. If angle is lower then this value the support will be generated. This angle is defined from the vertical, so zero is a vertical wall, ten is a wall with a bit of overhang, thirty is the typical safe angle for filament extrusion, sixty is a really high angle for extrusion and ninety is an unsupported horizontal ceiling.

Examples


The following examples raft the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and raft.py.

> python raft.py
This brings up the raft dialog.

> python raft.py Screw Holder Bottom.stl
The raft tool is parsing the file:
Screw Holder Bottom.stl
..
The raft tool has created the file:
Screw Holder Bottom_raft.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
RaftRepository
RaftSkein
SupportLayer

 
class RaftRepository
    A class to handle the raft settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Raft button has been clicked.

 
class RaftSkein
    A class to raft a skein of extrusions.
 
  Methods defined here:
__init__(self)
addBaseLayer(self)
Add a base layer.
addBaseSegments(self, baseExtrusionWidth)
Add the base segments.
addEmptyLayerSupport(self, boundaryLayerIndex)
Add support material to a layer if it is empty.
addFlowRate(self, flowRate)
Add a flow rate value if different.
addInterfaceLayer(self)
Add an interface layer.
addInterfaceTables(self, interfaceExtrusionWidth)
Add interface tables.
addLayerFromEndpoints(self, endpoints, feedRateMultiplier, flowRateMultiplier, layerLayerThickness, layerThicknessRatio, step, z)
Add a layer from endpoints and raise the extrusion top.
addLayerLine(self, z)
Add the layer gcode line and close the last layer gcode block.
addOperatingOrbits(self, boundaryLoops, pointComplex, temperatureChangeTime, z)
Add the orbits before the operating layers.
addRaft(self)
Add the raft.
addRaftPerimeters(self)
Add raft perimeters if there is a raft.
addRaftPerimetersByLoops(self, loops, outset)
Add raft perimeters to the gcode for loops.
addRaftedLine(self, splitLine)
Add elevated gcode line with operating feed rate.
addSegmentTablesToSupportLayers(self)
Add segment tables to the support layers.
addSupportLayerTemperature(self, endpoints, z)
Add support layer and temperature before the object layer.
addSupportSegmentTable(self, layerIndex)
Add support segments from the boundary layers.
addTemperatureLineIfDifferent(self, temperature)
Add a line of temperature if different.
addTemperatureOrbits(self, endpoints, temperature, z)
Add the temperature and orbits around the support layer.
addToFillXIntersectionIndexTables(self, supportLayer)
Add fill segments from the boundary layers.
extendXIntersections(self, loops, radius, xIntersectionsTable)
Extend the support segments.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the raft gcode.
getElevatedBoundaryLine(self, splitLine)
Get elevated boundary gcode line.
getInsetLoops(self, boundaryLayerIndex)
Inset the support loops if they are not already inset.
getInsetLoopsAbove(self, boundaryLayerIndex)
Get the inset loops above the boundary layer index.
getInsetLoopsBelow(self, boundaryLayerIndex)
Get the inset loops below the boundary layer index.
getStepsUntilEnd(self, begin, end, stepSize)
Get steps from the beginning until the end.
getSupportEndpoints(self)
Get the support layer segments.
getTemperatureChangeTime(self, temperature)
Get the temperature change time.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the raft skein.
setBoundaryLayers(self)
Set the boundary layers.
setCornersZ(self)
Set maximum and minimum corners and z.
subtractJoinedFill(self, supportLayerIndex)
Join the fill then subtract it from the support layer table.
truncateSupportSegmentTables(self)
Truncate the support segments after the last support segment which contains elements.

 
class SupportLayer
    Support loops with segment tables.
 
  Methods defined here:
__init__(self, supportLoops)
__repr__(self)
Get the string representation of this loop layer.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Raft the file or text.
getCraftedTextFromText(gcodeText, repository=None)
Raft a gcode linear move text.
getCrossHatchPointLine(crossHatchPointLineTable, y)
Get the cross hatch point line.
getEndpointsFromYIntersections(x, yIntersections)
Get endpoints from the y intersections.
getExtendedLineSegment(extensionDistance, lineSegment, loopXIntersections)
Get extended line segment.
getLoopsBySegmentsDictionary(segmentsDictionary, width)
Get loops from a horizontal segments dictionary.
getNewRepository()
Get new repository.
getVerticalEndpoints(horizontalSegmentsTable, horizontalStep, verticalOverhang, verticalStep)
Get vertical endpoints.
main()
Display the raft dialog.
setExtendedPoint(lineSegmentEnd, pointOriginal, x)
Set the point in the extended line segment.
writeOutput(fileName, shouldAnalyze=True)
Raft a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.scale.html000066400000000000000000000257531167321211700333230ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.scale
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.scale ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/scale.py

Previous / Next / Contents


Scale scales the carving to compensate for shrinkage after the extrusion has cooled.

The scale manual page is at:

http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Scale

It is best to only change the XY Plane Scale, because that does not affect other variables. If you choose to change the Z Axis Scale, that increases the layer thickness so you must increase the feed rate in speed by the same amount and maybe some other variables which depend on layer thickness.


Operation
Settings
  XY Plane Scale
  Z Axis Scale
  SVG Viewer
Examples

Operation


The default 'Activate Scale' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


XY Plane Scale

Default is 1.01.

Defines the amount the xy plane of the carving will be scaled. The xy coordinates will be scaled, but the perimeterWidth is not changed, so this can be changed without affecting other variables.

Z Axis Scale

Default is one.

Defines the amount the z axis of the carving will be scaled. The default is one because changing this changes many variables related to the layer thickness. For example, the feedRate should be multiplied by the Z Axis Scale because the layers would be farther apart.

SVG Viewer

Default is webbrowser.

If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened.

Examples


The following examples scale the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and scale.py.

> python scale.py
This brings up the scale dialog.

> python scale.py Screw Holder Bottom.stl
The scale tool is parsing the file:
Screw Holder Bottom.stl
..
The scale tool has created the file:
.. Screw Holder Bottom_scale.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
cStringIO
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
fabmetheus_utilities.svg_writer
sys
time
fabmetheus_utilities.xml_simple_writer

 
Classes
       
ScaleRepository
ScaleSkein

 
class ScaleRepository
    A class to handle the scale settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Scale button has been clicked.

 
class ScaleSkein
    A class to scale a skein of extrusions.
 
  Methods defined here:
getCraftedGcode(self, fileName, repository, svgText)
Parse svgText and store the scale svgText.

 
Functions
       
getCraftedText(fileName, svgText='', repository=None)
Scale and convert an svg file or svgText.
getCraftedTextFromText(fileName, svgText, repository=None)
Scale and convert an svgText.
getNewRepository()
Get new repository.
main()
Display the scale dialog.
setLoopLayerScale(loopLayer, xyPlaneScale, zAxisScale)
Set the slice element scale.
writeOutput(fileName, shouldAnalyze=True)
Scale the carving.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.skin.html000066400000000000000000000350421167321211700331700ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.skin
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.skin ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/skin.py

Previous / Next / Contents


Skin is a plugin to smooth the surface skin of an object by replacing the perimeter surface with a surface printed at a fraction of the carve
height. This gives the impression that the object was carved at a much thinner height giving a high-quality finish, but still prints
in a relatively short time. The latest process has some similarities with a description at:

http://adventuresin3-dprinting.blogspot.com/2011/05/skinning.html

The skin manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skin


Operation
Settings
  Division
    Horizontal Infill Divisions
    Horizontal Perimeter Divisions
    Vertical Divisions
  Hop When Extruding Infill
  Layers From
Tips
Examples

Operation


The default 'Activate Skin' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Division

Horizontal Infill Divisions

Default: 2

Defines the number of times the skinned infill is divided horizontally.

Horizontal Perimeter Divisions

Default: 1

Defines the number of times the skinned perimeters are divided horizontally.

Vertical Divisions

Default: 2

Defines the number of times the skinned infill and perimeters are divided vertically.

Hop When Extruding Infill

Default is off.

When selected, the extruder will hop before and after extruding the lower infill in order to avoid the regular thickness threads.

Layers From

Default: 1

Defines which layer of the print the skinning process starts from. It is not wise to set this to zero, skinning the bottom layer is likely to cause the bottom perimeter not to adhere well to the print surface.

Tips


Due to the very small Z-axis moves skinning can generate as it prints the perimeter, it can cause the Z-axis speed to be limited by the Limit plug-in, if you have it enabled. This can cause some printers to pause excessively during each layer change. To overcome this, ensure that the Z-axis max speed in the Limit tool is set to an appropriate value for your printer, e.g. 10mm/s

Since Skin prints a number of fractional-height perimeter layers for each layer, printing the perimeter last causes the print head to travel down from the current print height. Depending on the shape of your extruder nozzle, you may get higher quality prints if you print the perimeters first, so the print head always travels up. This is set via the Thread Sequence Choice setting in the Fill tool.

Examples


The following examples skin the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and skin.py.

> python skin.py
This brings up the skin dialog.

> python skin.py Screw Holder Bottom.stl
The skin tool is parsing the file:
Screw Holder Bottom.stl
..
The skin tool has created the file:
.. Screw Holder Bottom_skin.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
SkinRepository
SkinSkein

 
class SkinRepository
    A class to handle the skin settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Skin button has been clicked.

 
class SkinSkein
    A class to skin a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize.
addFlowRateLine(self, flowRate)
Add a flow rate line.
addPerimeterLoop(self, thread, z)
Add the perimeter loop to the gcode.
addSkinnedInfill(self)
Add skinned infill.
addSkinnedInfillBoundary(self, infillBoundaries, offsetY, upperZ, z)
Add skinned infill boundary.
addSkinnedPerimeter(self)
Add skinned perimeter.
getClippedSimplifiedLoopPathByLoop(self, loop)
Get clipped and simplified loop path from a loop.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the skin gcode.
parseBoundaries(self)
Parse the boundaries and add them to the boundary layers.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the skin skein.

 
Functions
       
getCraftedText(fileName, gcodeText, repository=None)
Skin a gcode linear move text.
getCraftedTextFromText(gcodeText, repository=None)
Skin a gcode linear move text.
getIsMinimumSides(loops, sides=3)
Determine if all the loops have at least the given number of sides.
getNewRepository()
Get new repository.
main()
Display the skin dialog.
writeOutput(fileName, shouldAnalyze=True)
Skin a gcode linear move file.  Chain skin the gcode if it is not already skinned.

 
Data
        __author__ = 'Enrique Perez (perez_enrique aht yahoo.com) & James Blackwell (jim_blag ahht hotmail.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique aht yahoo.com) & James Blackwell (jim_blag ahht hotmail.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.skirt.html000066400000000000000000000363571167321211700333720ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.skirt
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.skirt ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/skirt.py

Previous / Next / Contents


Skirt is a plugin to give the extruder some extra time to begin extruding properly before beginning the object, and to put a baffle around the model in order to keep the extrusion warm.

The skirt manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skirt

It is loosely based on Lenbook's outline plugin:

http://www.thingiverse.com/thing:4918

it is also loosely based on the outline that Nophead sometimes uses:

http://hydraraptor.blogspot.com/2010/01/hot-metal-and-serendipity.html

and also loosely based on the baffles that Nophead made to keep corners warm:

http://hydraraptor.blogspot.com/2010/09/some-corners-like-it-hot.html

If you want only an outline, set 'Layers To' to one. This gives the extruder some extra time to begin extruding properly before beginning your object, and gives you an early verification of where your object will be extruded.

If you also want an insulating skirt around the entire object, set 'Layers To' to a huge number, like 912345678. This will additionally make an insulating baffle around the object; to prevent moving air from cooling the object, which increases warping, especially in corners.


Operation
Settings
  Convex
  Gap over Perimeter Width
  Layers To
Examples

Operation


The default 'Activate Skirt' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Convex

Default is on.

When selected, the skirt will be convex, going around the model with only convex angles. If convex is not selected, the skirt will hug the model, going into every nook and cranny.

Gap over Perimeter Width

Default is three.

Defines the ratio of the gap between the object and the skirt over the perimeter width. If the ratio is too low, the skirt will connect to the object, if the ratio is too high, the skirt willl not provide much insulation for the object.

Layers To

Default is a one.

Defines the number of layers of the skirt. If you want only an outline, set 'Layers To' to one. If you want an insulating skirt around the entire object, set 'Layers To' to a huge number, like 912345678.

Examples


The following examples skirt the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and skirt.py.

> python skirt.py
This brings up the skirt dialog.

> python skirt.py Screw Holder Bottom.stl
The skirt tool is parsing the file:
Screw Holder Bottom.stl
..
The skirt tool has created the file:
.. Screw Holder Bottom_skirt.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
LoopCrossDictionary
SkirtRepository
SkirtSkein

 
class LoopCrossDictionary
    Loop with a horizontal and vertical dictionary.
 
  Methods defined here:
__init__(self)
Initialize LoopCrossDictionary.
__repr__(self)
Get the string representation of this LoopCrossDictionary.

 
class SkirtRepository
    A class to handle the skirt settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Skirt button has been clicked.

 
class SkirtSkein
    A class to skirt a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize variables.
addFlowRate(self, flowRate)
Add a line of temperature if different.
addSkirt(self, z)
At skirt at z to gcode output.
addTemperatureLineIfDifferent(self, temperature)
Add a line of temperature if different.
createSegmentDictionaries(self, loopCrossDictionary)
Create horizontal and vertical segment dictionaries.
createSkirtLoops(self)
Create the skirt loops.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the skirt gcode.
getHorizontalXIntersectionsTable(self, loop)
Get the horizontal x intersections table from the loop.
parseBoundaries(self)
Parse the boundaries and union them.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the skirt skein.
setSkirtFeedFlowTemperature(self)
Set the skirt feed rate, flow rate and temperature to that of the next extrusion.
unifyLayer(self, loopCrossDictionary)
Union the loopCrossDictionary with the unifiedLoop.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Skirt the fill file or text.
getCraftedTextFromText(gcodeText, repository=None)
Skirt the fill text.
getNewRepository()
Get new repository.
getOuterLoops(loops)
Get widdershins outer loops.
main()
Display the skirt dialog.
writeOutput(fileName, shouldAnalyze=True)
Skirt a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.smooth.html000066400000000000000000000272661167321211700335460ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.smooth
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.smooth ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/smooth.py

Previous / Next / Contents


This plugin smooths jagged extruder paths. It takes shortcuts through jagged paths and decreases the feed rate to compensate.

Smooth is based on ideas in Nophead's frequency limit post:

http://hydraraptor.blogspot.com/2010/12/frequency-limit.html

The smooth manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Smooth


Operation
Settings
  Layers From
  Maximum Shortening over Width
Examples

Operation


The default 'Activate Smooth' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Layers From

Default: 1

Defines which layer of the print the smoothing process starts from. If this is set this to zero, that might cause the smoothed parts of the bottom perimeter not to adhere well to the print surface. However, this is just a potential problem in theory, no bottom adhesion problem has been reported.

Maximum Shortening over Width

Default: 1.2

Defines the maximum shortening of the shortcut compared to the original path. Smooth goes over the path and if the shortcut between the midpoint of one line and the midpoint of the second line after is not too short compared to the original and the shortcut is not too long, it replaces the jagged original with the shortcut. If the maximum shortening is too much, smooth will shorten paths which should not of been shortened and will leave blobs and holes in the model. If the maximum shortening is too little, even jagged paths that could be shortened safely won't be smoothed.

Examples


The following examples smooth the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and smooth.py.

> python smooth.py
This brings up the smooth dialog.

> python smooth.py Screw Holder Bottom.stl
The smooth tool is parsing the file:
Screw Holder Bottom.stl
..
The smooth tool has created the file:
.. Screw Holder Bottom_smooth.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
SmoothRepository
SmoothSkein

 
class SmoothRepository
    A class to handle the smooth settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Smooth button has been clicked.

 
class SmoothSkein
    A class to smooth a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize.
addSmoothedInfill(self)
Add smoothed infill.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the smooth gcode.
getIsParallelToRotation(self, segment)
Determine if the segment is parallel to the rotation.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the smooth skein.

 
Functions
       
getCraftedText(fileName, gcodeText, repository=None)
Smooth a gcode linear move text.
getCraftedTextFromText(gcodeText, repository=None)
Smooth a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the smooth dialog.
writeOutput(fileName, shouldAnalyze=True)
Smooth a gcode linear move file.  Chain smooth the gcode if it is not already smoothed.

 
Data
        __author__ = 'Enrique Perez (perez_enrique aht yahoo.com) & James Blackwell (jim_blag ahht hotmail.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique aht yahoo.com) & James Blackwell (jim_blag ahht hotmail.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.speed.html000066400000000000000000000462721167321211700333330ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.speed
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.speed ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/speed.py

Previous / Next / Contents


Speed is a plugin to set the feed rate and flow rate.

The speed manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Speed


Operation
Settings
  Add Flow Rate
  Bridge
    Bridge Feed Rate Multiplier
    Bridge Flow Rate Multiplier
  Duty Cyle
    Duty Cyle at Beginning
    Duty Cyle at Ending
  Feed Rate
  Flow Rate Setting
  Maximum Z Feed Rate
  Object First Layer
    Object First Layer Feed Rate Infill Multiplier
    Object First Layer Feed Rate Perimeter Multiplier
    Object First Layer Flow Rate Infill Multiplier
    Object First Layer Flow Rate Perimeter Multiplier
  Orbital Feed Rate over Operating Feed Rate
  Perimeter
    Perimeter Feed Rate Multiplier
    Perimeter Flow Rate Multiplier
  Travel Feed Rate
Examples

Operation


The default 'Activate Speed' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Add Flow Rate

Default is on.

When selected, the flow rate will be added to the gcode.

Bridge

Bridge Feed Rate Multiplier

Default is one.

Defines the ratio of the feed rate (head speed) on the bridge layers over the feed rate of the typical non bridge layers.

Bridge Flow Rate Multiplier

Default is one.

Defines the ratio of the flow rate (extruder speed) on the bridge layers over the flow rate of the typical non bridge layers.

Duty Cyle

Duty Cyle at Beginning

Default is one, which will set the extruder motor to full current.

Defines the duty cycle of the stepper motor pulse width modulation by adding an M113 command toward the beginning of the gcode text. If the hardware has the option of using a potentiometer to set the duty cycle, to select the potentiometer option set 'Duty Cyle at Beginning' to an empty string. To turn off the extruder, set the 'Duty Cyle at Beginning' to zero.

Duty Cyle at Ending

Default is zero, which will turn off the extruder motor.

Defines the duty cycle of the stepper motor pulse width modulation by adding an M113 command toward the ending of the gcode text. If the hardware has the option of using a potentiometer to set the duty cycle, to select the potentiometer option set 'Duty Cyle at Beginning' to an empty string. To turn off the extruder, set the 'Duty Cyle at Ending' to zero.

Feed Rate

Default is sixteen millimeters per second.

Defines the operating feed rate, the speed your printing head moves in XY plane, before any modifiers.

Flow Rate Setting

Default is 210.

Defines the operating flow rate.

RapMan uses this parameter to define the RPM of the extruder motor. The extruder motor RPM is flow rate / 10 so if your flow rate is 150.0 that will set the extruder stepper to run at 15 RPM, different printers might read this value differently.

Maximum Z Feed Rate

Default is one millimeter per second.

Defines the speed of a vertical hop, like the infill hop in skin. Also, if the Limit plugin is activated, it will limit the maximum speed of the tool head in the z direction to this value.

Object First Layer


Object First Layer Feed Rate Infill Multiplier

Default is 0.4.

Defines the object first layer infill feed rate multiplier. The greater the 'Object First Layer Feed Rate Infill Multiplier, the thinner the infill, the lower the 'Object First Layer Feed Rate Infill Multiplier', the thicker the infill.

Object First Layer Feed Rate Perimeter Multiplier

Default is 0.4.

Defines the object first layer perimeter feed rate multiplier. The greater the 'Object First Layer Feed Rate Perimeter Multiplier, the thinner the perimeter, the lower the 'Object First Layer Feed Rate Perimeter Multiplier', the thicker the perimeter.

Object First Layer Flow Rate Infill Multiplier

Default is 0.4.

Defines the object first layer infill flow rate multiplier. The greater the 'Object First Layer Flow Rate Infill Multiplier', the thicker the infill, the lower the 'Object First Layer Flow Rate Infill Multiplier, the thinner the infill.

Object First Layer Flow Rate Perimeter Multiplier

Default is 0.4.

Defines the object first layer perimeter flow rate multiplier. The greater the 'Object First Layer Flow Rate Perimeter Multiplier', the thicker the perimeter, the lower the 'Object First Layer Flow Rate Perimeter Multiplier, the thinner the perimeter.

Orbital Feed Rate over Operating Feed Rate

Default is 0.5.

Defines the speed when the head is orbiting compared to the operating extruder speed. If you want the orbit to be very short, set the "Orbital Feed Rate over Operating Feed Rate" setting to a low value like 0.1.

Perimeter

To have higher build quality on the outside at the expense of slower build speed, a typical setting for the 'Perimeter Feed Rate over Operating Feed Rate' would be 0.5. To go along with that, if you are using a speed controlled extruder like a stepper extruder, the 'Perimeter Flow Rate over Operating Flow Rate' should also be 0.5.

A stepper motor is the best way of driving the extruder; however, if you are stuck with a DC motor extruder using Pulse Width Modulation to control the speed, then you'll probably need a slightly higher ratio because there is a minimum voltage 'Flow Rate PWM Setting' required for the extruder motor to turn. The flow rate PWM ratio would be determined by trial and error, with the first trial being:
Perimeter Flow Rate over Operating Flow Rate ~ Perimeter Feed Rate over Operating Feed Rate * (Flow Rate PWM Setting - Minimum Flow Rate PWM Setting) + Minimum Flow Rate PWM Setting

Perimeter Feed Rate Multiplier

Default: 1.0

Defines the ratio of the feed rate of the perimeter (outside shell) over the feed rate of the infill. If you for example set this to 0.8 you will have a "stronger" outside edge than inside extrusion as the outside edge will be printed slower hence better lamination will occur and more filament will be placed there.

Perimeter Flow Rate Multiplier

Default: 1.0

Defines the ratio of the flow rate of the perimeter (outside shell) over the flow rate of the infill. If you want the same thickness of the perimeter but better lamination you need to compensate for the slower feed rate by slowing down the flow rate, but all combinations are possible for different results.

Travel Feed Rate

Default is sixteen millimeters per second.

Defines the feed rate when the extruder is off (not printing). The 'Travel Feed Rate' could be set as high as the extruder can be moved, it is not limited by the maximum extrusion rate.

Examples


The following examples speed the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and speed.py.

> python speed.py
This brings up the speed dialog.

> python speed.py Screw Holder Bottom.stl
The speed tool is parsing the file:
Screw Holder Bottom.stl
..
The speed tool has created the file:
.. Screw Holder Bottom_speed.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
SpeedRepository
SpeedSkein

 
class SpeedRepository
    A class to handle the speed settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Speed button has been clicked.

 
class SpeedSkein
    A class to speed a skein of extrusions.
 
  Methods defined here:
__init__(self)
Initialize.
addFlowRateLine(self)
Add flow rate line.
addParameterString(self, firstWord, parameterWord)
Add parameter string.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the speed gcode.
getSpeededLine(self, line, splitLine)
Get gcode line with feed rate.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the speed skein.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Speed the file or text.
getCraftedTextFromText(gcodeText, repository=None)
Speed a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the speed dialog.
writeOutput(fileName, shouldAnalyze=True)
Speed a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.splodge.html000066400000000000000000000352121167321211700336600ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.splodge
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.splodge ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/splodge.py

Previous / Next / Contents


Splodge turns the extruder on just before the start of a thread. This is to give the extrusion a bit anchoring at the beginning.

The splodge manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Splodge


Operation
Settings
  Initial
    Initial Lift over Extra Thickness
    Initial Splodge Feed Rate
    Initial Splodge Quantity Length
  Operating
    Operating Lift over Extra Thickness
    Operating Splodge Feed Rate
    Operating Splodge Quantity Length
Examples

Operation


The default 'Activate Splodge' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Initial

Initial Lift over Extra Thickness

Default is one.

Defines the amount the extruder will be lifted over the extra thickness of the initial splodge thread. The higher the ratio, the more the extruder will be lifted over the splodge, if the ratio is too low the extruder might plow through the splodge extrusion.

Initial Splodge Feed Rate

Default is one millimeter per second.

Defines the feed rate at which the initial extra extrusion will be added. With the default feed rate, the splodge will be added slower so it will be thicker than the regular extrusion.

Initial Splodge Quantity Length

Default is thirty millimeters.

Defines the quantity length of extra extrusion at the operating feed rate that will be added to the initial thread. If a splodge quantity length is smaller than 0.1 times the perimeter width, no splodge of that type will be added.

Operating

Operating Lift over Extra Thickness

Default is one.

Defines the amount the extruder will be lifted over the extra thickness of the operating splodge thread.

Operating Splodge Feed Rate

Default is one millimeter per second.

Defines the feed rate at which the next extra extrusions will be added.

Operating Splodge Quantity Length

Default is thirty millimeters.

Defines the quantity length of extra extrusion at the operating feed rate that will be added for the next threads.

Examples


The following examples splodge the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and splodge.py.

> python splodge.py
This brings up the splodge dialog.

> python splodge.py Screw Holder Bottom.stl
The splodge tool is parsing the file:
Screw Holder Bottom.stl
..
The splodge tool has created the file:
.. Screw Holder Bottom_splodge.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
SplodgeRepository
SplodgeSkein

 
class SplodgeRepository
    A class to handle the splodge settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Splodge button has been clicked.

 
class SplodgeSkein
    A class to splodge a skein of extrusions.
 
  Methods defined here:
__init__(self)
addLineUnlessIdentical(self, line)
Add a line, unless it is identical to the last line.
addLineUnlessIdenticalReactivate(self, line)
Add a line, unless it is identical to the last line or another M101.
getCraftedGcode(self, gcodeText, splodgeRepository)
Parse gcode text and store the splodge gcode.
getInitialSplodgeLine(self, line, location)
Add the initial splodge line.
getNextActiveLocationComplex(self)
Get the next active line.
getOperatingSplodgeLine(self, line, location)
Get the operating splodge line.
getSplodgeLine(self, line, location, splitLine)
Get splodged gcode line.
getSplodgeLineGivenDistance(self, feedRateMinute, line, liftOverExtraThickness, location, startupDistance)
Add the splodge line.
getStartInsideBoundingRectangle(self, locationComplex, relativeStartComplex)
Get a start inside the bounding rectangle.
isJustBeforeExtrusion(self)
Determine if activate command is before linear move command.
parseInitialization(self, splodgeRepository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the bevel gcode.
setRotations(self)
Set the rotations.

 
Functions
       
getCraftedText(fileName, text, splodgeRepository=None)
Splodge a gcode linear move file or text.
getCraftedTextFromText(gcodeText, splodgeRepository=None)
Splodge a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the splodge dialog.
writeOutput(fileName, shouldAnalyze=True)
Splodge a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.stretch.html000066400000000000000000000463041167321211700337030ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.stretch
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.stretch ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/stretch.py

Previous / Next / Contents


Stretch is very important Skeinforge plugin that allows you to partially compensate for the fact that extruded holes are smaller then they should be. It stretches the threads to partially compensate for filament shrinkage when extruded.

The stretch manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Stretch

Extruded holes are smaller than the model because while printing an arc the head is depositing filament on both sides of the arc but in the inside of the arc you actually need less material then on the outside of the arc. You can read more about this on the RepRap ArcCompensation page:
http://reprap.org/bin/view/Main/ArcCompensation

In general, stretch will widen holes and push corners out. In practice the filament contraction will not be identical to the algorithm, so even once the optimal parameters are determined, the stretch script will not be able to eliminate the inaccuracies caused by contraction, but it should reduce them.

All the defaults assume that the thread sequence choice setting in fill is the perimeter being extruded first, then the loops, then the infill. If the thread sequence choice is different, the optimal thread parameters will also be different. In general, if the infill is extruded first, the infill would have to be stretched more so that even after the filament shrinkage, it would still be long enough to connect to the loop or perimeter.

Holes should be made with the correct area for their radius. In other words, for example if your modeling program approximates a hole of radius one (area = pi) by making a square with the points at [(1,0), (0,1), (-1,0), (0,-1)] (area = 2), the radius should be increased by sqrt(pi/2). This can be done in fabmetheus xml by writing:
radiusAreal='True'

in the attributes of the object or any parent of that object. In other modeling programs, you'll have to this manually or make a script. If area compensation is not done, then changing the stretch parameters to over compensate for too small hole areas will lead to incorrect compensation in other shapes.


Operation
Settings
  Loop Stretch Over Perimeter Width
  Path Stretch Over Perimeter Width
  Perimeter
    Perimeter Inside Stretch Over Perimeter Width
    Perimeter Outside Stretch Over Perimeter Width
  Stretch from Distance over Perimeter Width
Examples

Operation


The default 'Activate Stretch' checkbox is off. When it is on, the functions described below will work, when it is off, the functions will not be called.

Settings


Loop Stretch Over Perimeter Width

Default is 0.1.

Defines the ratio of the maximum amount the loop aka inner shell threads will be stretched compared to the perimeter width, in general this value should be the same as the 'Perimeter Outside Stretch Over Perimeter Width' setting.

Path Stretch Over Perimeter Width

Default is zero.

Defines the ratio of the maximum amount the threads which are not loops, like the infill threads, will be stretched compared to the perimeter width.

Perimeter

Perimeter Inside Stretch Over Perimeter Width

Default is 0.32.

Defines the ratio of the maximum amount the inside perimeter thread will be stretched compared to the perimeter width, this is the most important setting in stretch. The higher the value the more it will stretch the perimeter and the wider holes will be. If the value is too small, the holes could be drilled out after fabrication, if the value is too high, the holes would be too wide and the part would have to junked.

Perimeter Outside Stretch Over Perimeter Width

Default is 0.1.

Defines the ratio of the maximum amount the outside perimeter thread will be stretched compared to the perimeter width, in general this value should be around a third of the 'Perimeter Inside Stretch Over Perimeter Width' setting.

Stretch from Distance over Perimeter Width

Default is two.

The stretch algorithm works by checking at each turning point on the extrusion path what the direction of the thread is at a distance of 'Stretch from Distance over Perimeter Width' times the perimeter width, on both sides, and moves the thread in the opposite direction. So it takes the current turning-point, goes "Stretch from Distance over Perimeter Width" * "Perimeter Width" ahead, reads the direction at that point. Then it goes the same distance in back in time, reads the direction at that other point. It then moves the thread in the opposite direction, away from the center of the arc formed by these 2 points+directions.

The magnitude of the stretch increases with:
the amount that the direction of the two threads is similar and
by the '..Stretch Over Perimeter Width' ratio.

Examples


The following examples stretch the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and stretch.py.

> python stretch.py
This brings up the stretch dialog.

> python stretch.py Screw Holder Bottom.stl
The stretch tool is parsing the file:
Screw Holder Bottom.stl
..
The stretch tool has created the file:
.. Screw Holder Bottom_stretch.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
LineIteratorBackward
LineIteratorForward
StretchRepository
StretchSkein

 
class LineIteratorBackward
    Backward line iterator class.
 
  Methods defined here:
__init__(self, isLoop, lineIndex, lines)
getIndexBeforeNextDeactivate(self)
Get index two lines before the deactivate command.
getNext(self)
Get next line going backward or raise exception.
isBeforeExtrusion(self)
Determine if index is two or more before activate command.

 
class LineIteratorForward
    Forward line iterator class.
 
  Methods defined here:
__init__(self, isLoop, lineIndex, lines)
getIndexJustAfterActivate(self)
Get index just after the activate command.
getNext(self)
Get next line or raise exception.

 
class StretchRepository
    A class to handle the stretch settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Stretch button has been clicked.

 
class StretchSkein
    A class to stretch a skein of extrusions.
 
  Methods defined here:
__init__(self)
getCraftedGcode(self, gcodeText, stretchRepository)
Parse gcode text and store the stretch gcode.
getCrossLimitedStretch(self, crossLimitedStretch, crossLineIterator, locationComplex)
Get cross limited relative stretch for a location.
getRelativeStretch(self, locationComplex, lineIterator)
Get relative stretch for a location.
getStretchedLine(self, splitLine)
Get stretched gcode line.
getStretchedLineFromIndexLocation(self, indexPreviousStart, indexNextStart, location)
Get stretched gcode line from line index and location.
isJustBeforeExtrusion(self)
Determine if activate command is before linear move command.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseStretch(self, line)
Parse a gcode line and add it to the stretch skein.
setStretchToPath(self)
Set the thread stretch to path stretch and is loop false.

 
Functions
       
getCraftedText(fileName, gcodeText, stretchRepository=None)
Stretch a gcode linear move text.
getCraftedTextFromText(gcodeText, stretchRepository=None)
Stretch a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the stretch dialog.
writeOutput(fileName, shouldAnalyze=True)
Stretch a gcode linear move file.  Chain stretch the gcode if it is not already stretched.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.craft_plugins.temperature.html000066400000000000000000000320011167321211700344720ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.craft_plugins.temperature
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.temperature ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/temperature.py

Previous / Next / Contents


Temperature is a plugin to set the temperature for the entire extrusion.

The temperature manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Temperature


Operation
Settings
  Rate
    Cooling Rate
    Heating Rate
  Temperature
    Base Temperature
    Interface Temperature
    Object First Layer Infill Temperature
    Object First Layer Perimeter Temperature
    Object Next Layers Temperature
    Support Layers Temperature
    Supported Layers Temperature
Examples

Operation


The default 'Activate Temperature' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Rate

The default cooling rate and heating rate for the extruder were both been derived from bothacker's graph at:
http://bothacker.com/wp-content/uploads/2009/09/18h5m53s9.29.2009.png

Cooling Rate

Default is three degrees Celcius per second.

Defines the cooling rate of the extruder.

Heating Rate

Default is ten degrees Celcius per second.

Defines the heating rate of the extruder.

Temperature

Base Temperature

Default for ABS is two hundred degrees Celcius.

Defines the raft base temperature.

Interface Temperature

Default for ABS is two hundred degrees Celcius.

Defines the raft interface temperature.

Object First Layer Infill Temperature

Default for ABS is 195 degrees Celcius.

Defines the infill temperature of the first layer of the object.

Object First Layer Perimeter Temperature

Default for ABS is two hundred and twenty degrees Celcius.

Defines the perimeter temperature of the first layer of the object.

Object Next Layers Temperature

Default for ABS is two hundred and thirty degrees Celcius.

Defines the temperature of the next layers of the object.

Support Layers Temperature

Default for ABS is two hundred degrees Celcius.

Defines the support layers temperature.

Supported Layers Temperature

Default for ABS is two hundred and thirty degrees Celcius.

Defines the temperature of the supported layers of the object, those layers which are right above a support layer.

Examples


The following examples add temperature information to the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and temperature.py.

> python temperature.py
This brings up the temperature dialog.

> python temperature.py Screw Holder Bottom.stl
The temperature tool is parsing the file:
Screw Holder Bottom.stl
..
The temperature tool has created the file:
.. Screw Holder Bottom_temperature.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
TemperatureRepository
TemperatureSkein

 
class TemperatureRepository
    A class to handle the temperature settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Temperature button has been clicked.

 
class TemperatureSkein
    A class to temperature a skein of extrusions.
 
  Methods defined here:
__init__(self)
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the temperature gcode.
parseInitialization(self)
Parse gcode initialization and store the parameters.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Temperature the file or text.
getCraftedTextFromText(gcodeText, repository=None)
Temperature a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the temperature dialog.
writeOutput(fileName, shouldAnalyze=True)
Temperature a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.tower.html000066400000000000000000000402331167321211700333620ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.tower
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.tower ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/tower.py

Previous / Next / Contents


Tower commands the fabricator to extrude a disconnected region for a few layers, then go to another disconnected region and extrude there. Its purpose is to reduce the number of stringers between a shape and reduce extruder travel.

The tower manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Tower


Operation
Settings
  Maximum Tower Height
  Extruder Possible Collision Cone Angle
  Tower Start Layer
Examples

Operation


The default 'Activate Tower' checkbox is off. The default is off because tower could result in the extruder colliding with an already extruded part of the shape and because extruding in one region for more than one layer could result in the shape melting. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Maximum Tower Height

Default: 5

Defines the maximum number of layers that the extruder will extrude in one region before going to another. This is the most important value for tower.

Extruder Possible Collision Cone Angle

Default: 60 degrees

Tower works by looking for islands in each layer and if it finds another island in the layer above, it goes to the next layer above instead of going across to other regions on the original layer. It checks for collision with shapes already extruded within a cone from the nozzle tip. The 'Extruder Possible Collision Cone Angle' setting is the angle of that cone. Realistic values for the cone angle range between zero and ninety. The higher the angle, the less likely a collision with the rest of the shape is, generally the extruder will stay in the region for only a few layers before a collision is detected with the wide cone.

Tower Start Layer

Default: 1

Defines the layer index which the script starts extruding towers, after the last raft layer which does not have support material. It is best to not tower at least the first layer because the temperature of the first layer is sometimes different than that of the other layers.

Examples


The following examples tower the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and tower.py.

> python tower.py
This brings up the tower dialog.

> python tower.py Screw Holder Bottom.stl
The tower tool is parsing the file:
Screw Holder Bottom.stl
..
The tower tool has created the file:
.. Screw Holder Bottom_tower.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
Island
ThreadLayer
TowerRepository
TowerSkein

 
class Island
    A class to hold the boundary and lines.
 
  Methods defined here:
__init__(self)
addToBoundary(self, splitLine)
Add to the boundary if it is not complete.
createBoundingLoop(self)
Create the bounding loop if it is not already created.

 
class ThreadLayer
    A layer of loops and paths.
 
  Methods defined here:
__init__(self)
Thread layer constructor.
__repr__(self)
Get the string representation of this thread layer.

 
class TowerRepository
    A class to handle the tower settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Tower button has been clicked.

 
class TowerSkein
    A class to tower a skein of extrusions.
 
  Methods defined here:
__init__(self)
addEntireLayer(self, threadLayer)
Add entire thread layer.
addHighThread(self, location)
Add thread with a high move if necessary to clear the previous extrusion.
addThreadLayerIfNone(self)
Add a thread layer if it is none.
addTowers(self)
Add towers.
climbTower(self, removedIsland)
Climb up the island to any islands directly above.
getBottomLayerIndex(self)
Get the index of the first island layer which has islands.
getCraftedGcode(self, gcodeText, towerRepository)
Parse gcode text and store the tower gcode.
getRemovedIslandAddLayerLinesIfDifferent(self, islands, layerIndex)
Add gcode lines for the layer if it is different than the old bottom layer index.
getTransferClosestNestedRingLines(self, oldOrderedLocation, remainingNestedRings)
Get and transfer the closest remaining nested ring.
isInsideRemovedOutsideCone(self, island, removedBoundingLoop, untilLayerIndex)
Determine if the island is entirely inside the removed bounding loop and outside the collision cone of the remaining islands.
parseIfWordUntilWord(self, word)
Parse gcode if there is a word until the word is reached.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, lineIndex)
Parse a gcode line.

 
Functions
       
getCraftedText(fileName, text, towerRepository=None)
Tower a gcode linear move file or text.
getCraftedTextFromText(gcodeText, towerRepository=None)
Tower a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the tower dialog.
writeOutput(fileName, shouldAnalyze=True)
Tower a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.unpause.html000066400000000000000000000261671167321211700337140ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.unpause
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.unpause ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/unpause.py

Previous / Next / Contents


The unpause plugin is based on the Shane Hathaway's patch to speed up a line segment to compensate for the delay of the microprocessor. The description is at:
http://shane.willowrise.com/archives/delay-compensation-in-firmware/

The unpause manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Unpause


Operation
Settings
  Delay
  Maximum Speed
Examples

Operation


The default 'Activate Unpause' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Delay

Default is 28 milliseconds, which Shane found for the Arduino.

Defines the delay on the microprocessor that will be at least partially compensated for.

Maximum Speed

Default is 1.3.

Defines the maximum amount that the feed rate will be sped up to, compared to the original feed rate.

Examples


The following examples unpause the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and unpause.py.

> python unpause.py
This brings up the unpause dialog.

> python unpause.py Screw Holder Bottom.stl
The unpause tool is parsing the file:
Screw Holder Bottom.stl
..
The unpause tool has created the file:
.. Screw Holder Bottom_unpause.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
UnpauseRepository
UnpauseSkein

 
class UnpauseRepository
    A class to handle the unpause settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Unpause button has been clicked.

 
class UnpauseSkein
    A class to unpause a skein of extrusions.
 
  Methods defined here:
__init__(self)
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the unpause gcode.
getUnpausedArcMovement(self, line, splitLine)
Get an unpaused arc movement.
getUnpausedLinearMovement(self, line, splitLine)
Get an unpaused linear movement.
getUnpausedMovement(self, distance, line, splitLine)
Get an unpaused movement.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line.

 
Functions
       
getCraftedText(fileName, gcodeText, repository=None)
Unpause a gcode linear move file or text.
getCraftedTextFromText(gcodeText, repository=None)
Unpause a gcode linear move text.
getNewRepository()
Get new repository.
getSelectedPlugin(repository)
Get the selected plugin.
main()
Display the unpause dialog.
writeOutput(fileName, shouldAnalyze=True)
Unpause a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.whittle.html000066400000000000000000000253331167321211700337060ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.whittle
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.whittle ($Date: 2008/02/05 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/whittle.py

Previous / Next / Contents


Whittle will convert each polygon of a gcode file into a helix which has a vertical step down on each rotation.


Operation
Settings
  Maximum Vertical Step'
Examples

Operation


The default 'Activate Whittle' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. If the cutting tool can cut the slab in one cut, the 'Activate Whittle' checkbox should be off, the default is off.

Settings


Maximum Vertical Step'

Default is 0.1 mm.

Defines the maximum distance that the helix will step down on each rotation. The number of steps in the helix will be the layer thickness divided by the 'Maximum Vertical Step', rounded up. The amount the helix will step down is the layer thickness divided by the number of steps. The thinner the 'Maximum Vertical Step', the more times the cutting tool will circle around on its way to the bottom of the slab.

Examples


The following examples whittle the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and whittle.py.

> python whittle.py
This brings up the whittle dialog.

> python whittle.py Screw Holder Bottom.stl
The whittle tool is parsing the file:
Screw Holder Bottom.stl
..
The whittle tool has created the file:
.. Screw Holder Bottom_whittle.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
WhittleRepository
WhittleSkein

 
class WhittleRepository
    A class to handle the whittle settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Whittle button has been clicked.

 
class WhittleSkein
    A class to whittle a skein of extrusions.
 
  Methods defined here:
__init__(self)
getCraftedGcode(self, whittleRepository, gcodeText)
Parse gcode text and store the whittle gcode.
getLinearMove(self, line, splitLine)
Get the linear move.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the whittle skein.
repeatLines(self)
Repeat the lines at decreasing altitude.
setLayerThinknessVerticalDeltas(self, splitLine)
Set the layer thickness and the vertical deltas.

 
Functions
       
getCraftedText(fileName, text='', whittleRepository=None)
Whittle the preface file or text.
getCraftedTextFromText(gcodeText, whittleRepository=None)
Whittle the preface gcode text.
getNewRepository()
Get new repository.
main()
Display the whittle dialog.
writeOutput(fileName, shouldAnalyze=True)
Whittle the carving of a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/02/05 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.widen.html000066400000000000000000000267001167321211700333330ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.widen
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.widen ($Date: 2008/28/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/widen.py

Previous / Next / Contents


Widen will widen the outside perimeters away from the inside perimeters, so that the outsides will be at least two perimeter widths away from the insides and therefore the outside filaments will not overlap the inside filaments.

For example, if a mug has a very thin wall, widen would widen the outside of the mug so that the wall of the mug would be two perimeter widths wide, and the outside wall filament would not overlap the inside filament.

For another example, if the outside of the object runs right next to a hole, widen would widen the wall around the hole so that the wall would bulge out around the hole, and the outside filament would not overlap the hole filament.

The widen manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Widen


Operation
Examples

Operation


The default 'Activate Widen' checkbox is off. When it is on, widen will work, when it is off, nothing will be done.

Examples


The following examples widen the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and widen.py.

> python widen.py
This brings up the widen dialog.

> python widen.py Screw Holder Bottom.stl
The widen tool is parsing the file:
Screw Holder Bottom.stl
..
The widen tool has created the file:
.. Screw Holder Bottom_widen.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.geometry.geometry_utilities.boolean_solid
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
fabmetheus_utilities.intercircle
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
fabmetheus_utilities.geometry.solids.triangle_mesh

 
Classes
       
WidenRepository
WidenSkein

 
class WidenRepository
    A class to handle the widen settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Widen button has been clicked.

 
class WidenSkein
    A class to widen a skein of extrusions.
 
  Methods defined here:
__init__(self)
addWiden(self, loopLayer)
Add widen to the layer.
getCraftedGcode(self, gcodeText, repository)
Parse gcode text and store the widen gcode.
parseInitialization(self)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the widen skein.

 
Functions
       
getCraftedText(fileName, text='', repository=None)
Widen the preface file or text.
getCraftedTextFromText(gcodeText, repository=None)
Widen the preface gcode text.
getIntersectingWithinLoops(loop, loopList, outsetLoop)
Get the loops which are intersecting or which it is within.
getIsIntersectingWithinLoop(loop, otherLoop, outsetLoop)
Determine if the loop is intersecting or is within the other loop.
getIsPointInsideALoop(loops, point)
Determine if a point is inside a loop of a loop list.
getNewRepository()
Get new repository.
getWidenedLoop(loop, loopList, outsetLoop, radius)
Get the widened loop.
main()
Display the widen dialog.
writeOutput(fileName, shouldAnalyze=True)
Widen the carving of a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/28/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.craft_plugins.wipe.html000066400000000000000000000326731167321211700331770ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.craft_plugins.wipe
 
 
skeinforge_application.skeinforge_plugins.craft_plugins.wipe ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/wipe.py

Previous / Next / Contents


At the beginning of a layer, depending on the settings, wipe will move the nozzle with the extruder off to the arrival point, then to the wipe point, then to the departure point, then back to the layer.

The wipe path is machine specific, so you'll probably have to change all the default locations.

The wipe manual page is at:
http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Wipe


Operation
Settings
  Location Arrival
    Location Arrival X
    Location Arrival Y
    Location Arrival Z
  Location Departure
    Location Departure X
    Location Departure Y
    Location Departure Z
  Location Wipe
    Location Wipe X
    Location Wipe Y
    Location Wipe Z
  Wipe Period
Examples

Operation


The default 'Activate Wipe' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done.

Settings


Location Arrival

Location Arrival X

Default is minus seventy millimeters.

Defines the x coordinate of the arrival location.

Location Arrival Y

Default is minus fifty millimeters.

Defines the y coordinate of the arrival location.

Location Arrival Z

Default is fifty millimeters.

Defines the z coordinate of the arrival location.

Location Departure

Location Departure X

Default is minus seventy millimeters.

Defines the x coordinate of the departure location.

Location Departure Y

Default is minus forty millimeters.

Defines the y coordinate of the departure location.

Location Departure Z

Default is fifty millimeters.

Defines the z coordinate of the departure location.

Location Wipe

Location Wipe X

Default is minus seventy millimeters.

Defines the x coordinate of the wipe location.

Location Wipe Y

Default is minus seventy millimeters.

Defines the y coordinate of the wipe location.

Location Wipe Z

Default is fifty millimeters.

Defines the z coordinate of the wipe location.

Wipe Period

Default is three.

Defines the number of layers between wipes. Wipe will always wipe just before layer zero, afterwards it will wipe every "Wipe Period" layers. With the default of three, wipe will wipe just before layer zero, layer three, layer six and so on.

Examples


The following examples wipe the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and wipe.py.

> python wipe.py
This brings up the wipe dialog.

> python wipe.py Screw Holder Bottom.stl
The wipe tool is parsing the file:
Screw Holder Bottom.stl
..
The wipe tool has created the file:
.. Screw Holder Bottom_wipe.gcode


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
math
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_craft
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
WipeRepository
WipeSkein

 
class WipeRepository
    A class to handle the wipe settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Wipe button has been clicked.

 
class WipeSkein
    A class to wipe a skein of extrusions.
 
  Methods defined here:
__init__(self)
addHop(self, begin, end)
Add hop to highest point.
addWipeTravel(self, splitLine)
Add the wipe travel gcode.
getCraftedGcode(self, gcodeText, wipeRepository)
Parse gcode text and store the wipe gcode.
getLinearMoveWithFeedRate(self, feedRate, location)
Get a linear move line with the feedRate.
parseInitialization(self, wipeRepository)
Parse gcode initialization and store the parameters.
parseLine(self, line)
Parse a gcode line and add it to the bevel gcode.

 
Functions
       
getCraftedText(fileName, text, wipeRepository=None)
Wipe a gcode linear move text.
getCraftedTextFromText(gcodeText, wipeRepository=None)
Wipe a gcode linear move text.
getNewRepository()
Get new repository.
main()
Display the wipe dialog.
writeOutput(fileName, shouldAnalyze=True)
Wipe a gcode linear move file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.help.html000066400000000000000000000203631167321211700303150ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.help
 
 
skeinforge_application.skeinforge_plugins.help ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/help.py

Previous / Next / Contents


Help has buttons and menu items to open help, blog and forum pages in your primary browser.



Link Buttons
  Announcements
    Fabmetheus Blog
  Documentation
    Index of Local Documentation
    Wiki Manual
    Skeinforge Overview
  Forums
    Bits from Bytes Printing Board
    Bits from Bytes Software Board
    Skeinforge Contributions Thread
    Skeinforge Settings Thread
Settings
  Wiki Manual Primary

Link Buttons


Announcements

Fabmetheus Blog

The skeinforge announcements blog and the place to post questions, bugs and skeinforge requests.

Documentation

Index of Local Documentation

The list of the pages in the documentation folder.

Wiki Manual

The skeinforge wiki with pictures and charts. It is the best and most readable source of skeinforge information and you are welcome to contribute.

Skeinforge Overview

A general description of skeinforge, has answers to frequently asked questions and has many links to skeinforge, fabrication and python pages. It is also the help page of the skeinforge tool.

Forums

Bits from Bytes Printing Board

Board about printing questions, problems and solutions. Most of the people on that forum use the rapman, but many of the solutions apply to any reprap.

Bits from Bytes Software Board

Board about software, and has some skeinforge threads.

Skeinforge Contributions Thread

Forum thread about how to contribute to skeinforge development.

Skeinforge Settings Thread

Forum thread for people to post, download and discuss skeinforge settings.

Settings


Wiki Manual Primary

Default is on.

The help menu has an item for each button on the help page. Also, at the very top, it has a link to the local documentation and if there is a separate page for that tool in the wiki manual, a link to that page on the manual. If the 'Wiki Manual Primary' checkbutton is selected and there is a separate wiki manual page, the wiki page will be the primary document page, otherwise the local page will be primary. The help button (? symbol button) on the tool page will open the primary page, as will pressing <F1>. For example, if you click the the help button from the chamber tool, which has a separate page in the wiki, and 'Wiki Manual Primary' is selected, the wiki manual chamber page will be opened. Clicking F1 will also open the wiki manual chamber page.


Previous / Next / Contents


 
Modules
       
__init__
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_help

 
Functions
       
addToMenu(master, menu, repository, window)
Add a tool plugin menu.
getNewRepository()
Get new repository.
main()
Display the help dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.html000066400000000000000000000060331167321211700273640ustar00rootroot00000000000000 Python: package skeinforge_application.skeinforge_plugins
 
 
skeinforge_application.skeinforge_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
analyze
analyze_plugins (package)
craft
craft_plugins (package)
help
meta
meta_plugins (package)
profile
profile_plugins (package)

 
Data
        level = 2
numberOfLevelsDeepInPackageHierarchy = 2
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.meta.html000066400000000000000000000104701167321211700303110ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.meta
 
 
skeinforge_application.skeinforge_plugins.meta ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/meta.py

Previous / Next / Contents


Meta is a script to access the plugins which handle meta information.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_meta

 
Functions
       
addToMenu(master, menu, repository, window)
Add a tool plugin menu.
getNewRepository()
Get new repository.
main()
Display the meta dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.meta_plugins.description.html000066400000000000000000000143121167321211700343140ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.meta_plugins.description
 
 
skeinforge_application.skeinforge_plugins.meta_plugins.description ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/meta_plugins/description.py

Previous / Next / Contents


Description is a script to store a description of the profile.


Settings
  Description Text
Example

Settings


Description Text

Default is 'Write your profile description here.'

The suggested format is a description, followed by a link to a profile post or web page.

Example


Example of using description follows below.

> python description.py
This brings up the description dialog.


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile

 
Classes
       
DescriptionRepository

 
class DescriptionRepository
    A class to handle the description settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.

 
Functions
       
getNewRepository()
Get new repository.
main()
Display the file or directory dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.meta_plugins.html000066400000000000000000000047601167321211700320570ustar00rootroot00000000000000 Python: package skeinforge_application.skeinforge_plugins.meta_plugins
 
 
skeinforge_application.skeinforge_plugins.meta_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/meta_plugins/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
description
polyfile

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.meta_plugins.polyfile.html000066400000000000000000000125621167321211700337000ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.meta_plugins.polyfile
 
 
skeinforge_application.skeinforge_plugins.meta_plugins.polyfile ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/meta_plugins/polyfile.py

Previous / Next / Contents


Polyfile is a script to choose whether the skeinforge toolchain will operate on one file or all the files in a directory.


Settings
  Polyfile Choice
    Execute File
    Execute All Unmodified Files in a Directory'
Example

Settings


Polyfile Choice

Default is 'Execute File',

Execute File

When selected, the toolchain will operate on only the chosen file.

Execute All Unmodified Files in a Directory'

When selected, the toolchain will operate on all the unmodifed files in the directory that the chosen file is in.

Example


Example of using polyfile follows below.

> python polyfile.py
This brings up the polyfile dialog.


Previous / Next / Contents


 
Modules
       
__init__
skeinforge_application.skeinforge_utilities.skeinforge_polyfile

 
Functions
       
getNewRepository()
Get new repository.
main()
Display the file or directory dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.profile.html000066400000000000000000000175361167321211700310350ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_plugins.profile
 
 
skeinforge_application.skeinforge_plugins.profile ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/profile.py

Previous / Next / Contents


Profile is a script to set the craft types setting for the skeinforge chain.

Profile presents the user with a choice of the craft types in the profile_plugins folder. The chosen craft type is used to determine the craft type profile for the skeinforge chain. The default craft type is extrusion.

The setting is the selection. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved.

To change the profile setting, in a shell in the profile folder type:
> python profile.py


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile

 
Classes
       
ProfileMenuRadio
ProfileMenuSaveListener

 
class ProfileMenuRadio
    A class to display a profile menu radio button.
 
  Methods defined here:
__init__(self, profilePluginFileName, menu, name, radioVar, value)
Create a profile menu radio.
clickRadio(self)
Workaround for Tkinter bug, invoke and set the value when clicked.

 
class ProfileMenuSaveListener
    A class to update a profile menu.
 
  Methods defined here:
__init__(self, menu, window)
Set the menu.
save(self)
Profile has been saved and profile menu should be updated.

 
Functions
       
addSubmenus(craftTypeName, menu, pluginFileName, pluginPath, profileRadioVar)
Add a tool plugin menu.
addToMenu(master, menu, repository, window)
Add a tool plugin menu.
addToProfileMenu(menu)
Add a profile menu.
getNewRepository()
Get new repository.
main()
Display the profile dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.profile_plugins.cutting.html000066400000000000000000000151251167321211700341630ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.profile_plugins.cutting
 
 
skeinforge_application.skeinforge_plugins.profile_plugins.cutting ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/profile_plugins/cutting.py

Previous / Next / Contents


Cutting is a script to set the cutting profile for the skeinforge chain.

The displayed craft sequence is the sequence in which the tools craft the model and export the output.

On the cutting dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm. The 'Delete Profile' button deletes the selected profile.

The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles.

To change the cutting profile, in a shell in the profile_plugins folder type:
> python cutting.py


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
CuttingRepository

 
class CuttingRepository
    A class to handle the cutting settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.

 
Functions
       
getCraftSequence()
Get the cutting craft sequence.
getNewRepository()
Get new repository.
main()
Display the export dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.profile_plugins.extrusion.html000066400000000000000000000152121167321211700345430ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.profile_plugins.extrusion
 
 
skeinforge_application.skeinforge_plugins.profile_plugins.extrusion ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/profile_plugins/extrusion.py

Previous / Next / Contents


Extrusion is a script to set the extrusion profile for the skeinforge chain.

The displayed craft sequence is the sequence in which the tools craft the model and export the output.

On the extrusion dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if ABS is selected and the name ABS_black is in the input field, clicking the 'Add Profile' button will duplicate ABS and save it as ABS_black. The 'Delete Profile' button deletes the selected profile.

The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles.

To change the extrusion profile, in a shell in the profile_plugins folder type:
> python extrusion.py


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
ExtrusionRepository

 
class ExtrusionRepository
    A class to handle the export settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.

 
Functions
       
getCraftSequence()
Get the extrusion craft sequence.
getNewRepository()
Get new repository.
main()
Display the export dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_plugins.profile_plugins.html000066400000000000000000000052761167321211700325740ustar00rootroot00000000000000 Python: package skeinforge_application.skeinforge_plugins.profile_plugins
 
 
skeinforge_application.skeinforge_plugins.profile_plugins
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/profile_plugins/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
cutting
extrusion
milling
winding

 
Data
        level = 3
numberOfLevelsDeepInPackageHierarchy = 3
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
skeinforge_application.skeinforge_plugins.profile_plugins.milling.html000066400000000000000000000151651167321211700341450ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.profile_plugins.milling
 
 
skeinforge_application.skeinforge_plugins.profile_plugins.milling ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/profile_plugins/milling.py

Previous / Next / Contents


Milling is a script to set the milling profile for the skeinforge chain.

The displayed craft sequence is the sequence in which the tools craft the model and export the output.

On the milling dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm. The 'Delete Profile' button deletes the selected profile.

The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles.

To change the milling profile, in a shell in the profile_plugins folder type:
> python milling.py


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
MillingRepository

 
class MillingRepository
    A class to handle the milling settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.

 
Functions
       
getCraftSequence()
Get the milling craft sequence.
getNewRepository()
Get new repository.
main()
Display the export dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
skeinforge_application.skeinforge_plugins.profile_plugins.winding.html000066400000000000000000000147771167321211700341610ustar00rootroot00000000000000sfact-2011.12.18/documentation Python: module skeinforge_application.skeinforge_plugins.profile_plugins.winding
 
 
skeinforge_application.skeinforge_plugins.profile_plugins.winding ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/profile_plugins/winding.py

Previous / Next / Contents


Winding is a script to set the winding profile for the skeinforge chain.

The displayed craft sequence is the sequence in which the tools craft the model and export the output.

On the winding dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm. The 'Delete Profile' button deletes the selected profile.

The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles.

To change the winding profile, in a shell in the profile_plugins folder type:
> python winding.py


Previous / Next / Contents


 
Modules
       
__init__
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys

 
Classes
       
WindingRepository

 
class WindingRepository
    A class to handle the winding settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.

 
Functions
       
getCraftSequence()
Get the winding craft sequence.
getNewRepository()
Get new repository.
main()
Display the export dialog.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_utilities.html000066400000000000000000000054141167321211700277200ustar00rootroot00000000000000 Python: package skeinforge_application.skeinforge_utilities
 
 
skeinforge_application.skeinforge_utilities
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_utilities/__init__.py

#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.

 
Package Contents
       
skeinforge_analyze
skeinforge_craft
skeinforge_help
skeinforge_meta
skeinforge_polyfile
skeinforge_profile

 
Data
        level = 2
numberOfLevelsDeepInPackageHierarchy = 2
packageFilePath = '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus'
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_utilities.skeinforge_analyze.html000066400000000000000000000141111167321211700335700ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_utilities.skeinforge_analyze
 
 
skeinforge_application.skeinforge_utilities.skeinforge_analyze ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_utilities/skeinforge_analyze.py

Analyze is a script to access the plugins which analyze a gcode file.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
traceback

 
Classes
       
AnalyzeRepository

 
class AnalyzeRepository
    A class to handle the analyze settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Analyze button has been clicked.

 
Functions
       
getNewRepository()
Get new repository.
getPluginFileNames()
Get analyze plugin fileNames.
getPluginsDirectoryPath()
Get the plugins directory path.
main()
Write analyze output.
writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText='')
Analyze a gcode file.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_utilities.skeinforge_craft.html000066400000000000000000000251411167321211700332310ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_utilities.skeinforge_craft
 
 
skeinforge_application.skeinforge_utilities.skeinforge_craft ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_utilities/skeinforge_craft.py

Craft is a script to access the plugins which craft a gcode file.

The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.fabmetheus_tools.fabmetheus_interpret
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_analyze
skeinforge_application.skeinforge_utilities.skeinforge_polyfile
skeinforge_application.skeinforge_utilities.skeinforge_profile
sys
time

 
Classes
       
CraftRadioButtonsSaveListener
CraftRepository

 
class CraftRadioButtonsSaveListener
    A class to update the craft radio buttons.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
getFromRadioPlugins(self, radioPlugins, repository)
Initialize.
save(self)
Profile has been saved and craft radio plugins should be updated.
setRadioButtons(self)
Profile has been saved and craft radio plugins should be updated.

 
class CraftRepository
    A class to handle the craft settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
execute(self)
Craft button has been clicked.

 
Functions
       
getChainText(fileName, procedure)
Get a crafted shape file.
getChainTextFromProcedures(fileName, procedures, text)
Get a crafted shape file from a list of procedures.
getCraftModule(pluginName)
Get craft module.
getCraftPreferences(pluginName)
Get craft preferences.
getCraftValue(preferenceName, preferences)
Get craft preferences value.
getLastModule()
Get the last tool.
getNewRepository()
Get new repository.
getPluginFileNames()
Get craft plugin fileNames.
getPluginsDirectoryPath()
Get the plugins directory path.
getProcedures(procedure, text)
Get the procedures up to and including the given procedure.
getReadCraftSequence()
Get profile sequence.
getSequenceIndexFromProcedure(procedure)
Get the profile sequence index of the procedure.  Return None if the procedure is not in the sequence
getSequenceIndexPlusOneFromText(fileText)
Get the profile sequence index of the file plus one.  Return zero if the procedure is not in the file
main()
Write craft output.
writeChainTextWithNounMessage(fileName, procedure, shouldAnalyze=True)
Get and write a crafted shape file.
writeOutput(fileName, shouldAnalyze=True)
Craft a gcode file with the last module.
writeSVGTextWithNounMessage(fileName, repository, shouldAnalyze=True)
Get and write an svg text and print messages.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_utilities.skeinforge_help.html000066400000000000000000000120531167321211700330600ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_utilities.skeinforge_help
 
 
skeinforge_application.skeinforge_utilities.skeinforge_help ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_utilities/skeinforge_help.py

Help has buttons and menu items to open help, blog and forum pages in your primary browser.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile

 
Classes
       
HelpRepository

 
class HelpRepository
    A class to handle the help settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.
save(self)
Write the entities.

 
Functions
       
getNewRepository()
Get new repository.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_utilities.skeinforge_meta.html000066400000000000000000000125071167321211700330620ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_utilities.skeinforge_meta
 
 
skeinforge_application.skeinforge_utilities.skeinforge_meta ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_utilities/skeinforge_meta.py

Meta is a script to access the plugins which handle meta information.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile

 
Classes
       
MetaRepository

 
class MetaRepository
    A class to handle the meta settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.

 
Functions
       
getNewRepository()
Get new repository.
getPluginFileNames()
Get meta plugin file names.
getPluginsDirectoryPath()
Get the plugins directory path.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_utilities.skeinforge_polyfile.html000066400000000000000000000151421167321211700337550ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_utilities.skeinforge_polyfile
 
 
skeinforge_application.skeinforge_utilities.skeinforge_polyfile ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_utilities/skeinforge_polyfile.py

Polyfile is a script to choose whether the skeinforge toolchain will operate on one file or all the files in a directory.

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.settings
skeinforge_application.skeinforge_utilities.skeinforge_profile

 
Classes
       
PolyfileRepository

 
class PolyfileRepository
    A class to handle the polyfile settings.
 
  Methods defined here:
__init__(self)
Set the default settings, execute title & settings fileName.

 
Functions
       
getFileOrDirectoryTypes(fileName, fileTypes, wasCancelled)
Get the gcode files in the directory the file is in if directory setting is true.  Otherwise, return the file in a list.
getFileOrDirectoryTypesUnmodifiedGcode(fileName, fileTypes, wasCancelled)
Get the gcode files in the directory the file is in if directory setting is true.  Otherwise, return the file in a list.
getFileOrGcodeDirectory(fileName, wasCancelled, words=[])
Get the gcode files in the directory the file is in if directory setting is true.  Otherwise, return the file in a list.
getNewRepository()
Get new repository.
isDirectorySetting()
Determine if the directory setting is true.
isEmptyOrCancelled(fileName, wasCancelled)
Determine if the fileName is empty or the dialog was cancelled.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/documentation/skeinforge_application.skeinforge_utilities.skeinforge_profile.html000066400000000000000000000575051167321211700336030ustar00rootroot00000000000000 Python: module skeinforge_application.skeinforge_utilities.skeinforge_profile
 
 
skeinforge_application.skeinforge_utilities.skeinforge_profile ($Date: 2008/21/04 $)
index
/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_utilities/skeinforge_profile.py

Profile is a script to set the craft types setting for the skeinforge chain.

Profile presents the user with a choice of the craft types in the profile_plugins folder. The chosen craft type is used to determine the craft type profile for the skeinforge chain. The default craft type is extrusion.

The setting is the selection. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved.

To change the profile setting, in a shell in the profile folder type:
> python profile.py

 
Modules
       
__init__
fabmetheus_utilities.archive
fabmetheus_utilities.euclidean
fabmetheus_utilities.gcodec
os
fabmetheus_utilities.settings
shutil

 
Classes
       
fabmetheus_utilities.settings.StringSetting
ProfileListboxSetting
AddProfile
DeleteProfile
DeleteProfileDialog
ProfileList
ProfilePluginRadioButtonsSaveListener
ProfileRepository
ProfileSelectionMenuRadio
ProfileTypeMenuRadio

 
class AddProfile
    A class to add a profile.
 
  Methods defined here:
addSelection(self)
Add the selection of a listbox setting.
addSelectionWithEvent(self, event)
Add the selection of a listbox setting, given an event.
addToDialog(self, gridPosition)
Add this to the dialog.
getFromProfileListboxSettingRepository(self, profileListboxSetting, repository)
Initialize.

 
class DeleteProfile(AddProfile)
    A class to delete the selection of a listbox profile.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
deleteSelection(self)
Delete the selection of a listbox setting.

Methods inherited from AddProfile:
addSelection(self)
Add the selection of a listbox setting.
addSelectionWithEvent(self, event)
Add the selection of a listbox setting, given an event.
getFromProfileListboxSettingRepository(self, profileListboxSetting, repository)
Initialize.

 
class DeleteProfileDialog
    A dialog to delete a profile.
 
  Methods defined here:
__init__(self, profileListboxSetting, root)
Display a delete dialog.
delete(self)
Delete the selection of a listbox setting.
no(self)
The dialog was closed.

 
class ProfileList
    A class to list the profiles.
 
  Methods defined here:
getFromName(self, name, repository)
Initialize.
setValueToFolders(self)
Set the value to the folders in the profiles directories.

 
class ProfileListboxSetting(fabmetheus_utilities.settings.StringSetting)
    A class to handle the profile listbox.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
buttonReleaseOne(self, event)
Button one released.
focusIn(self, event)
The root has gained focus.
getFromListSetting(self, listSetting, name, repository, value)
Initialize.
getSelectedFolder(self)
Get the selected folder.
setStateToValue(self)
Set the listbox items to the list setting.
setToDisplay(self)
Set the selection value to the listbox selection.
setValueToIndex(self, index)
Set the selection value to the index.
setValueToString(self, valueString)
Set the value to the value string.

Methods inherited from fabmetheus_utilities.settings.StringSetting:
__init__(self)
Set the update function to none.
__repr__(self)
Get the string representation of this StringSetting.
addToMenu(self, repositoryMenu)
Do nothing because this should only be added to a frameable repository menu.
addToMenuFrameable(self, repositoryMenu)
Add this to the frameable repository menu.
addToWindow(self)
Add this to the repository frame list.
bindEntry(self)
Bind the entry to the update function.
createEntry(self, root)
Create the entry.
getFromValue(self, name, repository, value)
Initialize.
getFromValueOnly(self, name, repository, value)
Initialize.
getFromValueOnlyAddToRepository(self, name, repository, value)
Initialize.
removeFromWindow(self)
Remove this from the repository frame list.
setUpdateFunction(self, updateFunction)
Set the update function.
setValueToSplitLine(self, lineIndex, lines, splitLine)
Set the value to the second word of a split line.
updateSaveListeners(self)
Update save listeners if any.
writeToRepositoryWriter(self, repositoryWriter)
Write tab separated name and value to the repository writer.

 
class ProfilePluginRadioButtonsSaveListener
    A class to update the profile radio buttons.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
getFromRadioPlugins(self, radioPlugins, repository)
Initialize.
save(self)
Profile has been saved and profile radio plugins should be updated.

 
class ProfileRepository
    A class to handle the profile entities.
 
  Methods defined here:
__init__(self)
Set the default entities, execute title & repository fileName.
updateRelay(self)
Update the plugin frame then the ProfileSaveListeners.

 
class ProfileSelectionMenuRadio
    A class to display a profile selection menu radio button.
 
  Methods defined here:
addToDialog(self, gridPosition)
Add this to the dialog.
clickRadio(self)
Workaround for Tkinter bug, invoke and set the value when clicked.
getFromMenuButtonDisplay(self, menuButtonDisplay, name, repository, value)
Initialize.
setToMenuButtonDisplay(self, menuButtonDisplay, name, repository, value)
Initialize.

 
class ProfileTypeMenuRadio(ProfileSelectionMenuRadio)
    A class to display a profile type menu radio button.
 
  Methods defined here:
clickRadio(self)
Workaround for Tkinter bug, invoke and set the value when clicked.
getFromMenuButtonDisplay(self, menuButtonDisplay, name, repository, value)
Initialize.

Methods inherited from ProfileSelectionMenuRadio:
addToDialog(self, gridPosition)
Add this to the dialog.
setToMenuButtonDisplay(self, menuButtonDisplay, name, repository, value)
Initialize.

 
Functions
       
addListsSetCraftProfile(craftSequence, defaultProfile, repository, fileNameHelp)
Set the craft profile repository.
addListsToCraftTypeRepository(fileNameHelp, repository)
Add the value to the lists.
cancelAll()
Cancel all the dialogs.
getCraftTypeName(subName='')
Get the craft type from the profile.
getCraftTypePluginModule(craftTypeName='')
Get the craft type plugin module.
getNewRepository()
Get new repository.
getPluginFileNames()
Get analyze plugin fileNames.
getPluginsDirectoryPath()
Get the plugins directory path.
getProfileDirectory()
Get the profile directory.
getProfileName(craftTypeName)
Get the profile name from the craft type name.
getReadProfileRepository()
Get the read profile repository.
updateProfileSaveListeners()
Call the save function of all the update profile save listeners.

 
Data
        __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
__date__ = '$Date: 2008/21/04 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
absolute_import = _Feature((2, 5, 0, 'alpha', 1), (2, 7, 0, 'alpha', 0), 16384)

 
Author
        Enrique Perez (perez_enrique@yahoo.com)
sfact-2011.12.18/fabmetheus_utilities/000077500000000000000000000000001167321211700174265ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/__init__.py000066400000000000000000000007361167321211700215450ustar00rootroot00000000000000""" This page is in the table of contents. This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. """ import os import sys numberOfLevelsDeepInPackageHierarchy = 1 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/archive.py000066400000000000000000000343371167321211700214330ustar00rootroot00000000000000""" Boolean geometry utilities. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ import os import sys import traceback __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalTemporarySettingsPath = os.path.join(os.getcwd(), 'sfact_profiles')#(os.path.expanduser('~'), '.skeinforge') #globalTemporarySettingsPath = os.path.join(os.path.expanduser('~'), '.skeinforge') def addToNamePathDictionary(directoryPath, namePathDictionary): 'Add to the name path dictionary.' pluginFileNames = getPluginFileNamesFromDirectoryPath(directoryPath) for pluginFileName in pluginFileNames: namePathDictionary[pluginFileName.replace('_', '')] = os.path.join(directoryPath, pluginFileName) def getAbsoluteFolderPath(filePath, folderName=''): 'Get the absolute folder path.' absoluteFolderPath = os.path.dirname(os.path.abspath(filePath)) if folderName == '': return absoluteFolderPath return os.path.join(absoluteFolderPath, folderName) def getAbsoluteFrozenFolderPath(filePath, folderName=''): 'Get the absolute frozen folder path.' if hasattr(sys, 'frozen'): if '.py' in filePath: filePath = ''.join(filePath.rpartition('\\')[: 2]) filePath = os.path.join(filePath, 'skeinforge_application') return getAbsoluteFolderPath(filePath, folderName) def getAnalyzePluginsDirectoryPath(subName=''): 'Get the analyze plugins directory path.' return getJoinedPath(getSkeinforgePluginsPath('analyze_plugins'), subName) def getCraftPluginsDirectoryPath(subName=''): 'Get the craft plugins directory path.' return getJoinedPath(getSkeinforgePluginsPath('craft_plugins'), subName) def getDocumentationPath(subName=''): 'Get the documentation file path.' return getJoinedPath(getFabmetheusPath('documentation'), subName) def getElementsPath(subName=''): 'Get the evaluate_elements directory path.' return getJoinedPath(getGeometryUtilitiesPath('evaluate_elements'), subName) def getEndsWithList(word, wordEndings): 'Determine if the word ends with a list.' for wordEnding in wordEndings: if word.endswith(wordEnding): return True return False def getFabmetheusPath(subName=''): 'Get the fabmetheus directory path.' fabmetheusFile = None if hasattr(sys, 'frozen'): fabmetheusFile = unicode(sys.executable, sys.getfilesystemencoding()) else: fabmetheusFile = os.path.dirname(os.path.abspath(__file__)) return getJoinedPath(os.path.dirname(fabmetheusFile), subName) def getFabmetheusToolsPath(subName=''): 'Get the fabmetheus tools directory path.' return getJoinedPath(getFabmetheusUtilitiesPath('fabmetheus_tools'), subName) def getFabmetheusUtilitiesPath(subName=''): 'Get the fabmetheus utilities directory path.' return getJoinedPath(getFabmetheusPath('fabmetheus_utilities'), subName) def getFileNamesByFilePaths(pluginFilePaths): 'Get the file names of the plugins by the file paths.' fileNames = [] for pluginFilePath in pluginFilePaths: pluginBasename = os.path.basename(pluginFilePath) pluginBasename = getUntilDot(pluginBasename) fileNames.append(pluginBasename) return fileNames def getFilePaths(fileInDirectory=''): 'Get the file paths in the directory of the file in directory.' directoryName = os.getcwd() if fileInDirectory != '': directoryName = os.path.dirname(fileInDirectory) return getFilePathsByDirectory(directoryName) def getFilePathsByDirectory(directoryName): 'Get the file paths in the directory of the file in directory.' absoluteDirectoryPath = os.path.abspath(directoryName) directory = os.listdir(directoryName) filePaths = [] for fileName in directory: filePaths.append(os.path.join(absoluteDirectoryPath, fileName)) return filePaths def getFilePathsRecursively(fileInDirectory=''): 'Get the file paths in the directory of the file in directory.' filePaths = getFilePaths(fileInDirectory) filePathsRecursively = filePaths[:] for filePath in filePaths: if os.path.isdir(filePath): directory = os.listdir(filePath) if len(directory) > 0: filePathsRecursively += getFilePathsRecursively(os.path.join(filePath, directory[0])) return filePathsRecursively def getFilePathWithUnderscoredBasename(fileName, suffix): 'Get the file path with all spaces in the basename replaced with underscores.' suffixFileName = getUntilDot(fileName) + suffix suffixDirectoryName = os.path.dirname(suffixFileName) suffixReplacedBaseName = os.path.basename(suffixFileName).replace(' ', '_') return os.path.join(suffixDirectoryName, suffixReplacedBaseName) def getFilesWithFileTypesWithoutWords(fileTypes, words = [], fileInDirectory=''): 'Get files which have a given file type, but with do not contain a word in a list.' filesWithFileTypes = [] for filePath in getFilePaths(fileInDirectory): for fileType in fileTypes: if isFileWithFileTypeWithoutWords(fileType, filePath, words): filesWithFileTypes.append(filePath) filesWithFileTypes.sort() return filesWithFileTypes def getFilesWithFileTypesWithoutWordsRecursively(fileTypes, words = [], fileInDirectory=''): 'Get files recursively which have a given file type, but with do not contain a word in a list.' filesWithFileTypesRecursively = [] for filePath in getFilePathsRecursively(fileInDirectory): for fileType in fileTypes: if isFileWithFileTypeWithoutWords(fileType, filePath, words): filesWithFileTypesRecursively.append(filePath) filesWithFileTypesRecursively.sort() return filesWithFileTypesRecursively def getFilesWithFileTypeWithoutWords(fileType, words = [], fileInDirectory=''): 'Get files which have a given file type, but with do not contain a word in a list.' filesWithFileType = [] for filePath in getFilePaths(fileInDirectory): if isFileWithFileTypeWithoutWords(fileType, filePath, words): filesWithFileType.append(filePath) filesWithFileType.sort() return filesWithFileType def getFileText(fileName, printWarning=True, readMode='r'): 'Get the entire text of a file.' try: file = open(fileName, readMode) fileText = file.read() file.close() return fileText except IOError: if printWarning: print('The file ' + fileName + ' does not exist.') return '' def getFileTextInFileDirectory(fileInDirectory, fileName, readMode='r'): 'Get the entire text of a file in the directory of the file in directory.' absoluteFilePathInFileDirectory = os.path.join(os.path.dirname(fileInDirectory), fileName) return getFileText(absoluteFilePathInFileDirectory, True, readMode) def getFundamentalsPath(subName=''): 'Get the evaluate_fundamentals directory path.' return getJoinedPath(getGeometryUtilitiesPath('evaluate_fundamentals'), subName) def getGeometryDictionary(folderName): 'Get to the geometry name path dictionary.' geometryDictionary={} geometryDirectory = getGeometryPath() addToNamePathDictionary(os.path.join(geometryDirectory, folderName), geometryDictionary) geometryPluginsDirectory = getFabmetheusUtilitiesPath('geometry_plugins') addToNamePathDictionary(os.path.join(geometryPluginsDirectory, folderName), geometryDictionary) return geometryDictionary def getGeometryPath(subName=''): 'Get the geometry directory path.' return getJoinedPath(getFabmetheusUtilitiesPath('geometry'), subName) def getGeometryToolsPath(subName=''): 'Get the geometry tools directory path.' return getJoinedPath(getGeometryPath('geometry_tools'), subName) def getGeometryUtilitiesPath(subName=''): 'Get the geometry_utilities directory path.' return getJoinedPath(getGeometryPath('geometry_utilities'), subName) def getInterpretPluginsPath(subName=''): 'Get the interpret plugins directory path.' return getJoinedPath(getFabmetheusToolsPath('interpret_plugins'), subName) def getJoinedPath(path, subName=''): 'Get the joined file path.' if subName == '': return path return os.path.join(path, subName) def getModuleWithDirectoryPath(directoryPath, fileName): 'Get the module from the fileName and folder name.' if fileName == '': print('The file name in getModule in archive was empty.') return None originalSystemPath = sys.path[:] try: sys.path.insert(0, directoryPath) folderPluginsModule = __import__(fileName) sys.path = originalSystemPath return folderPluginsModule except: sys.path = originalSystemPath print('') print('Exception traceback in getModuleWithDirectoryPath in archive:') traceback.print_exc(file=sys.stdout) print('') print('That error means; could not import a module with the fileName ' + fileName) print('and an absolute directory name of ' + directoryPath) print('') return None def getModuleWithPath(path): 'Get the module from the path.' return getModuleWithDirectoryPath(os.path.dirname(path), os.path.basename(path)) def getPluginFileNamesFromDirectoryPath(directoryPath): 'Get the file names of the python plugins in the directory path.' fileInDirectory = os.path.join(directoryPath, '__init__.py') return getFileNamesByFilePaths(getPythonFileNamesExceptInit(fileInDirectory)) def getProfilesPath(subName=''): 'Get the profiles directory path, which is the settings directory joined with profiles.' return getJoinedPath(getSettingsPath('profiles'), subName) def getPythonDirectoryNames(directoryName): 'Get the python directories.' pythonDirectoryNames = [] directory = os.listdir(directoryName) for fileName in directory: subdirectoryName = os.path.join(directoryName, fileName) if os.path.isdir(subdirectoryName): if os.path.isfile(os.path.join(subdirectoryName, '__init__.py')): pythonDirectoryNames.append(subdirectoryName) return pythonDirectoryNames def getPythonDirectoryNamesRecursively(directoryName=''): 'Get the python directories recursively.' recursivePythonDirectoryNames = [] if directoryName == '': directoryName = os.getcwd() if os.path.isfile(os.path.join(directoryName, '__init__.py')): recursivePythonDirectoryNames.append(directoryName) pythonDirectoryNames = getPythonDirectoryNames(directoryName) for pythonDirectoryName in pythonDirectoryNames: recursivePythonDirectoryNames += getPythonDirectoryNamesRecursively(pythonDirectoryName) else: return [] return recursivePythonDirectoryNames def getPythonFileNamesExceptInit(fileInDirectory=''): 'Get the python fileNames of the directory which the fileInDirectory is in, except for the __init__.py file.' pythonFileNamesExceptInit = getFilesWithFileTypeWithoutWords('py', ['__init__.py'], fileInDirectory) pythonFileNamesExceptInit.sort() return pythonFileNamesExceptInit def getPythonFileNamesExceptInitRecursively(directoryName=''): 'Get the python fileNames of the directory recursively, except for the __init__.py files.' pythonDirectoryNames = getPythonDirectoryNamesRecursively(directoryName) pythonFileNamesExceptInitRecursively = [] for pythonDirectoryName in pythonDirectoryNames: pythonFileNamesExceptInitRecursively += getPythonFileNamesExceptInit(os.path.join(pythonDirectoryName, '__init__.py')) pythonFileNamesExceptInitRecursively.sort() return pythonFileNamesExceptInitRecursively def getSettingsPath(subName=''): 'Get the settings directory path, which is the home directory joined with .skeinforge.' global globalTemporarySettingsPath return getJoinedPath(globalTemporarySettingsPath, subName) def getSkeinforgePath(subName=''): 'Get the skeinforge directory path.' return getJoinedPath(getFabmetheusPath('skeinforge_application'), subName) def getSkeinforgePluginsPath(subName=''): 'Get the skeinforge plugins directory path.' return getJoinedPath(getSkeinforgePath('skeinforge_plugins'), subName) def getSummarizedFileName(fileName): 'Get the fileName basename if the file is in the current working directory, otherwise return the original full name.' if os.getcwd() == os.path.dirname(fileName): return os.path.basename(fileName) return fileName def getTemplatesPath(subName=''): 'Get the templates directory path.' return getJoinedPath(getFabmetheusUtilitiesPath('templates'), subName) def getTextIfEmpty(fileName, text): 'Get the text from a file if it the text is empty.' if text != '': return text return getFileText(fileName) def getTextLines(text): 'Get the all the lines of text of a text.' if '\r' in text: text = text.replace('\r', '\n').replace('\n\n', '\n') textLines = text.split('\n') if len(textLines) == 1: if textLines[0] == '': return [] return textLines def getUntilDot(text): 'Get the text until the last dot, if any.' dotIndex = text.rfind('.') if dotIndex < 0: return text return text[: dotIndex] def getVersionFileName(): 'Get the file name of the version date.getFabmetheusUtilitiesPath(subName='')' return getFabmetheusUtilitiesPath('version.txt') def isFileWithFileTypeWithoutWords(fileType, fileName, words): 'Determine if file has a given file type, but with does not contain a word in a list.' fileName = os.path.basename(fileName) fileTypeDot = '.' + fileType if not fileName.endswith(fileTypeDot): return False for word in words: if fileName.find(word) >= 0: return False return True def makeDirectory(directoryPath): 'Make a directory if it does not already exist.' if os.path.isdir(directoryPath): return try: print('The following directory was made:') print(os.path.abspath(directoryPath)) os.makedirs(directoryPath) except OSError: print('Skeinforge can not make the directory %s so give it read/write permission for that directory and the containing directory.' % directoryPath) def removeBackupFilesByType(fileType): 'Remove backup files by type.' backupFilePaths = getFilesWithFileTypesWithoutWordsRecursively([fileType + '~']) for backupFilePath in backupFilePaths: os.remove(backupFilePath) def removeBackupFilesByTypes(fileTypes): 'Remove backup files by types.' for fileType in fileTypes: removeBackupFilesByType(fileType) def writeFileMessageEnd(end, fileName, fileText, message): 'Write to a fileName with a suffix and print a message.' suffixFileName = getUntilDot(fileName) + end writeFileText(suffixFileName, fileText) print( message + getSummarizedFileName(suffixFileName) ) def writeFileText(fileName, fileText, writeMode='w+'): 'Write a text to a file.' try: file = open(fileName, writeMode) file.write(fileText) file.close() except IOError: print('The file ' + fileName + ' can not be written to.') sfact-2011.12.18/fabmetheus_utilities/euclidean.py000066400000000000000000002744751167321211700217540ustar00rootroot00000000000000""" Euclidean is a collection of python utilities for complex numbers, paths, polygons & Vector3s. To use euclidean, install python 2.x on your machine, which is avaliable from http://www.python.org/download/ Then in the folder which euclidean is in, type 'python' in a shell to run the python interpreter. Finally type 'import euclidean' to import these utilities and 'from vector3 import Vector3' to import the Vector3 class. Below are examples of euclidean use. >>> from euclidean import * >>> origin=complex() >>> right=complex(1.0,0.0) >>> back=complex(0.0,1.0) >>> getMaximum(right,back) 1.0, 1.0 >>> polygon=[origin, right, back] >>> getLoopLength(polygon) 3.4142135623730949 >>> getAreaLoop(polygon) 0.5 """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import xml_simple_writer import cStringIO import math import random __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalGoldenAngle = 3.8832220774509332 # (math.sqrt(5.0) - 1.0) * math.pi globalGoldenRatio = 1.6180339887498948482045868 # math.sqrt(1.25) - .5 globalTau = math.pi + math.pi # http://tauday.com/ globalQuarterPi = math.pi/4 # 0.78543 def addElementToListDictionary(element, key, listDictionary): 'Add an element to the list table.' if key in listDictionary: listDictionary[key].append(element) else: listDictionary[key] = [element] def addElementToListDictionaryIfNotThere(element, key, listDictionary): 'Add the value to the lists.' if key in listDictionary: elements = listDictionary[key] if element not in elements: elements.append(element) else: listDictionary[key] = [element] def addElementToPixelList( element, pixelDictionary, x, y ): 'Add an element to the pixel list.' addElementToListDictionary( element, (x, y), pixelDictionary ) def addElementToPixelListFromPoint( element, pixelDictionary, point ): 'Add an element to the pixel list.' addElementToPixelList( element, pixelDictionary, int( round( point.real ) ), int( round( point.imag ) ) ) def addHorizontallyBoundedPoint(begin, center, end, horizontalBegin, horizontalEnd, path): 'Add point if it is within the horizontal bounds.' if center.real >= horizontalEnd and center.real <= horizontalBegin: path.append(center) return if end is not None: if center.real > horizontalBegin and end.real <= horizontalBegin: centerMinusEnd = center - end along = (center.real - horizontalBegin) / centerMinusEnd.real path.append(center - along * centerMinusEnd) return if begin is not None: if center.real < horizontalEnd and begin.real >= horizontalEnd: centerMinusBegin = center - begin along = (center.real - horizontalEnd) / centerMinusBegin.real path.append(center - along * centerMinusBegin) def addListToListTable( elementList, key, listDictionary ): 'Add a list to the list table.' if key in listDictionary: listDictionary[key] += elementList else: listDictionary[key] = elementList def addLoopToPixelTable( loop, pixelDictionary, width ): 'Add loop to the pixel table.' for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] addValueSegmentToPixelTable( pointBegin, pointEnd, pixelDictionary, None, width ) def addNestedRingBeginning(distanceFeedRate, loop, z): 'Add nested ring beginning to gcode output.' distanceFeedRate.addLine('()') distanceFeedRate.addLine('()') for point in loop: pointVector3 = Vector3(point.real, point.imag, z) distanceFeedRate.addLine(distanceFeedRate.getBoundaryLine(pointVector3)) def addPathToPixelTable( path, pixelDictionary, value, width ): 'Add path to the pixel table.' for pointIndex in xrange( len(path) - 1 ): pointBegin = path[pointIndex] pointEnd = path[pointIndex + 1] addValueSegmentToPixelTable( pointBegin, pointEnd, pixelDictionary, value, width ) def addPixelTableToPixelTable( fromPixelTable, intoPixelTable ): 'Add from pixel table to the into pixel table.' for fromPixelTableKey in fromPixelTable.keys(): intoPixelTable[ fromPixelTableKey ] = fromPixelTable[ fromPixelTableKey ] def addPixelToPixelTableWithSteepness( isSteep, pixelDictionary, value, x, y ): 'Add pixels to the pixel table with steepness.' if isSteep: pixelDictionary[(y, x)] = value else: pixelDictionary[(x, y)] = value def addPointToPath( path, pixelDictionary, point, value, width ): 'Add a point to a path and the pixel table.' path.append(point) if len(path) < 2: return begin = path[-2] addValueSegmentToPixelTable( begin, point, pixelDictionary, value, width ) def addSegmentToPixelTable( beginComplex, endComplex, pixelDictionary, shortenDistanceBegin, shortenDistanceEnd, width ): 'Add line segment to the pixel table.' if abs( beginComplex - endComplex ) <= 0.0: return beginComplex /= width endComplex /= width if shortenDistanceBegin > 0.0: endMinusBeginComplex = endComplex - beginComplex endMinusBeginComplexLength = abs( endMinusBeginComplex ) if endMinusBeginComplexLength < shortenDistanceBegin: return beginComplex = beginComplex + endMinusBeginComplex * shortenDistanceBegin / endMinusBeginComplexLength if shortenDistanceEnd > 0.0: beginMinusEndComplex = beginComplex - endComplex beginMinusEndComplexLength = abs( beginMinusEndComplex ) if beginMinusEndComplexLength < 0.0: return endComplex = endComplex + beginMinusEndComplex * shortenDistanceEnd / beginMinusEndComplexLength deltaX = endComplex.real - beginComplex.real deltaY = endComplex.imag - beginComplex.imag isSteep = abs( deltaY ) > abs( deltaX ) if isSteep: beginComplex = complex( beginComplex.imag, beginComplex.real ) endComplex = complex( endComplex.imag, endComplex.real ) if beginComplex.real > endComplex.real: endComplex, beginComplex = beginComplex, endComplex deltaX = endComplex.real - beginComplex.real deltaY = endComplex.imag - beginComplex.imag if deltaX > 0.0: gradient = deltaY / deltaX else: gradient = 0.0 print('This should never happen, deltaX in addSegmentToPixelTable in euclidean is 0.') print( beginComplex ) print( endComplex ) print( shortenDistanceBegin ) print( shortenDistanceEnd ) print( width ) xBegin = int(round(beginComplex.real)) xEnd = int(round(endComplex.real)) yIntersection = beginComplex.imag - beginComplex.real * gradient if isSteep: pixelDictionary[( int( round( beginComplex.imag ) ), xBegin)] = None pixelDictionary[( int( round( endComplex.imag ) ), xEnd )] = None for x in xrange( xBegin + 1, xEnd ): y = int( math.floor( yIntersection + x * gradient ) ) pixelDictionary[(y, x)] = None pixelDictionary[(y + 1, x)] = None else: pixelDictionary[(xBegin, int( round( beginComplex.imag ) ) )] = None pixelDictionary[(xEnd, int( round( endComplex.imag ) ) )] = None for x in xrange( xBegin + 1, xEnd ): y = int( math.floor( yIntersection + x * gradient ) ) pixelDictionary[(x, y)] = None pixelDictionary[(x, y + 1)] = None def addSquareTwoToPixelDictionary(pixelDictionary, point, value, width): 'Add square with two pixels around the center to pixel dictionary.' point /= width x = int(round(point.real)) y = int(round(point.imag)) for xStep in xrange(x - 2, x + 3): for yStep in xrange(y - 2, y + 3): pixelDictionary[(xStep, yStep)] = value def addToThreadsFromLoop(extrusionHalfWidth, gcodeType, loop, oldOrderedLocation, skein): 'Add to threads from the last location from loop.' loop = getLoopStartingClosest(extrusionHalfWidth, oldOrderedLocation.dropAxis(), loop) oldOrderedLocation.x = loop[0].real oldOrderedLocation.y = loop[0].imag gcodeTypeStart = gcodeType if isWiddershins(loop): skein.distanceFeedRate.addLine('(<%s> outer )' % gcodeType) else: skein.distanceFeedRate.addLine('(<%s> inner )' % gcodeType) skein.addGcodeFromThreadZ(loop + [loop[0]], oldOrderedLocation.z) skein.distanceFeedRate.addLine('()' % gcodeType) def addToThreadsRemove(extrusionHalfWidth, nestedRings, oldOrderedLocation, skein, threadSequence): 'Add to threads from the last location from nested rings.' while len(nestedRings) > 0: getTransferClosestNestedRing(extrusionHalfWidth, nestedRings, oldOrderedLocation, skein, threadSequence) def addValueSegmentToPixelTable( beginComplex, endComplex, pixelDictionary, value, width ): 'Add line segment to the pixel table.' if abs( beginComplex - endComplex ) <= 0.0: return beginComplex /= width endComplex /= width deltaX = endComplex.real - beginComplex.real deltaY = endComplex.imag - beginComplex.imag isSteep = abs( deltaY ) > abs( deltaX ) if isSteep: beginComplex = complex( beginComplex.imag, beginComplex.real ) endComplex = complex( endComplex.imag, endComplex.real ) if beginComplex.real > endComplex.real: endComplex, beginComplex = beginComplex, endComplex deltaX = endComplex.real - beginComplex.real deltaY = endComplex.imag - beginComplex.imag if deltaX > 0.0: gradient = deltaY / deltaX else: gradient = 0.0 print('This should never happen, deltaX in addValueSegmentToPixelTable in euclidean is 0.') print( beginComplex ) print(value) print( endComplex ) print( width ) xBegin = int(round(beginComplex.real)) xEnd = int(round(endComplex.real)) yIntersection = beginComplex.imag - beginComplex.real * gradient if isSteep: pixelDictionary[(int( round( beginComplex.imag ) ), xBegin)] = value pixelDictionary[(int( round( endComplex.imag ) ), xEnd)] = value for x in xrange( xBegin + 1, xEnd ): y = int( math.floor( yIntersection + x * gradient ) ) pixelDictionary[(y, x)] = value pixelDictionary[(y + 1, x)] = value else: pixelDictionary[(xBegin, int( round( beginComplex.imag ) ))] = value pixelDictionary[(xEnd, int( round( endComplex.imag ) ))] = value for x in xrange( xBegin + 1, xEnd ): y = int( math.floor( yIntersection + x * gradient ) ) pixelDictionary[(x, y)] = value pixelDictionary[(x, y + 1)] = value def addValueToOutput(depth, keyInput, output, value): 'Add value to the output.' depthStart = ' ' * depth output.write('%s%s:' % (depthStart, keyInput)) if value.__class__ == dict: output.write('\n') keys = value.keys() keys.sort() for key in keys: addValueToOutput(depth + 1, key, output, value[key]) return if value.__class__ == list: output.write('\n') for elementIndex, element in enumerate(value): addValueToOutput(depth + 1, elementIndex, output, element) return output.write(' %s\n' % value) def addXIntersectionIndexesFromLoopListsY( loopLists, xIntersectionIndexList, y ): 'Add the x intersection indexes for the loop lists.' for loopListIndex in xrange( len(loopLists) ): loopList = loopLists[ loopListIndex ] addXIntersectionIndexesFromLoopsY( loopList, loopListIndex, xIntersectionIndexList, y ) def addXIntersectionIndexesFromLoopsY( loops, solidIndex, xIntersectionIndexList, y ): 'Add the x intersection indexes for the loops.' for loop in loops: addXIntersectionIndexesFromLoopY( loop, solidIndex, xIntersectionIndexList, y ) def addXIntersectionIndexesFromLoopY( loop, solidIndex, xIntersectionIndexList, y ): 'Add the x intersection indexes for a loop.' for pointIndex in xrange(len(loop)): pointFirst = loop[pointIndex] pointSecond = loop[(pointIndex + 1) % len(loop)] xIntersection = getXIntersectionIfExists( pointFirst, pointSecond, y ) if xIntersection is not None: xIntersectionIndexList.append( XIntersectionIndex( solidIndex, xIntersection ) ) def addXIntersectionIndexesFromSegment( index, segment, xIntersectionIndexList ): 'Add the x intersection indexes from the segment.' for endpoint in segment: xIntersectionIndexList.append( XIntersectionIndex( index, endpoint.point.real ) ) def addXIntersectionIndexesFromSegments( index, segments, xIntersectionIndexList ): 'Add the x intersection indexes from the segments.' for segment in segments: addXIntersectionIndexesFromSegment( index, segment, xIntersectionIndexList ) def addXIntersectionIndexesFromXIntersections( index, xIntersectionIndexList, xIntersections ): 'Add the x intersection indexes from the XIntersections.' for xIntersection in xIntersections: xIntersectionIndexList.append( XIntersectionIndex( index, xIntersection ) ) def addXIntersections( loop, xIntersections, y ): 'Add the x intersections for a loop.' for pointIndex in xrange(len(loop)): pointFirst = loop[pointIndex] pointSecond = loop[(pointIndex + 1) % len(loop)] xIntersection = getXIntersectionIfExists( pointFirst, pointSecond, y ) if xIntersection is not None: xIntersections.append( xIntersection ) def addXIntersectionsFromLoopForTable(loop, xIntersectionsTable, width): 'Add the x intersections for a loop into a table.' for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] if pointBegin.imag > pointEnd.imag: pointOriginal = pointBegin pointBegin = pointEnd pointEnd = pointOriginal fillBegin = int( math.ceil( pointBegin.imag / width ) ) fillEnd = int( math.ceil( pointEnd.imag / width ) ) if fillEnd > fillBegin: secondMinusFirstComplex = pointEnd - pointBegin secondMinusFirstImaginaryOverReal = secondMinusFirstComplex.real / secondMinusFirstComplex.imag beginRealMinusImaginary = pointBegin.real - pointBegin.imag * secondMinusFirstImaginaryOverReal for fillLine in xrange( fillBegin, fillEnd ): y = fillLine * width xIntersection = y * secondMinusFirstImaginaryOverReal + beginRealMinusImaginary addElementToListDictionary( xIntersection, fillLine, xIntersectionsTable ) def addXIntersectionsFromLoops(loops, xIntersections, y): 'Add the x intersections for the loops.' for loop in loops: addXIntersections(loop, xIntersections, y) def addXIntersectionsFromLoopsForTable(loops, xIntersectionsTable, width): 'Add the x intersections for a loop into a table.' for loop in loops: addXIntersectionsFromLoopForTable(loop, xIntersectionsTable, width) def compareSegmentLength( endpoint, otherEndpoint ): 'Get comparison in order to sort endpoints in ascending order of segment length.' if endpoint.segmentLength > otherEndpoint.segmentLength: return 1 if endpoint.segmentLength < otherEndpoint.segmentLength: return - 1 return 0 def concatenateRemovePath( connectedPaths, pathIndex, paths, pixelDictionary, segments, width ): 'Get connected paths from paths.' bottomSegment = segments[ pathIndex ] path = paths[ pathIndex ] if bottomSegment is None: connectedPaths.append(path) return endpoints = getEndpointsFromSegments( segments[ pathIndex + 1 : ] ) bottomSegmentEndpoint = bottomSegment[0] nextEndpoint = bottomSegmentEndpoint.getClosestMissCheckEndpointPath( endpoints, bottomSegmentEndpoint.path, pixelDictionary, width ) if nextEndpoint is None: bottomSegmentEndpoint = bottomSegment[1] nextEndpoint = bottomSegmentEndpoint.getClosestMissCheckEndpointPath( endpoints, bottomSegmentEndpoint.path, pixelDictionary, width ) if nextEndpoint is None: connectedPaths.append(path) return if len( bottomSegmentEndpoint.path ) > 0 and len( nextEndpoint.path ) > 0: bottomEnd = bottomSegmentEndpoint.path[-1] nextBegin = nextEndpoint.path[-1] nextMinusBottomNormalized = getNormalized( nextBegin - bottomEnd ) if len( bottomSegmentEndpoint.path ) > 1: bottomPenultimate = bottomSegmentEndpoint.path[-2] if getDotProduct( getNormalized( bottomPenultimate - bottomEnd ), nextMinusBottomNormalized ) > 0.9: connectedPaths.append(path) return if len( nextEndpoint.path ) > 1: nextPenultimate = nextEndpoint.path[-2] if getDotProduct( getNormalized( nextPenultimate - nextBegin ), - nextMinusBottomNormalized ) > 0.9: connectedPaths.append(path) return nextEndpoint.path.reverse() concatenatedPath = bottomSegmentEndpoint.path + nextEndpoint.path paths[ nextEndpoint.pathIndex ] = concatenatedPath segments[ nextEndpoint.pathIndex ] = getSegmentFromPath( concatenatedPath, nextEndpoint.pathIndex ) addValueSegmentToPixelTable( bottomSegmentEndpoint.point, nextEndpoint.point, pixelDictionary, None, width ) def getAngleAroundZAxisDifference( subtractFromVec3, subtractVec3 ): 'Get the angle around the Z axis difference between a pair of Vector3s.' subtractVectorMirror = complex( subtractVec3.x , - subtractVec3.y ) differenceVector = getRoundZAxisByPlaneAngle( subtractVectorMirror, subtractFromVec3 ) return math.atan2( differenceVector.y, differenceVector.x ) def getAngleDifferenceByComplex( subtractFromComplex, subtractComplex ): 'Get the angle between a pair of normalized complexes.' subtractComplexMirror = complex( subtractComplex.real , - subtractComplex.imag ) differenceComplex = subtractComplexMirror * subtractFromComplex return math.atan2( differenceComplex.imag, differenceComplex.real ) def getAreaLoop(loop): 'Get the area of a complex polygon.' areaLoopDouble = 0.0 for pointIndex, point in enumerate(loop): pointEnd = loop[(pointIndex + 1) % len(loop)] areaLoopDouble += point.real * pointEnd.imag - pointEnd.real * point.imag return 0.5 * areaLoopDouble def getAreaLoopAbsolute(loop): 'Get the absolute area of a complex polygon.' return abs(getAreaLoop(loop)) def getAreaLoops(loops): 'Get the area of a list of complex polygons.' areaLoops = 0.0 for loop in loops: areaLoops += getAreaLoop(loop) return areaLoops def getAreaVector3LoopAbsolute(loop): 'Get the absolute area of a vector3 polygon.' return getAreaLoopAbsolute(getComplexPath(loop)) def getAroundLoop(begin, end, loop): 'Get an arc around a loop.' aroundLoop = [] if end <= begin: end += len(loop) for pointIndex in xrange(begin, end): aroundLoop.append(loop[pointIndex % len(loop)]) return aroundLoop def getAwayPath(path, radius): 'Get a path with only the points that are far enough away from each other, except for the last point.' if len(path) < 2: return path lastPoint = path[-1] awayPath = getAwayPoints(path, radius) if len(awayPath) == 0: return [lastPoint] if abs(lastPoint - awayPath[-1]) > 0.001 * radius: awayPath.append(lastPoint) return awayPath def getAwayPoints(points, radius): 'Get a path with only the points that are far enough away from each other.' awayPoints = [] oneOverOverlapDistance = 1000.0 / radius pixelDictionary = {} for point in points: x = int(point.real * oneOverOverlapDistance) y = int(point.imag * oneOverOverlapDistance) if not getSquareIsOccupied(pixelDictionary, x, y): awayPoints.append(point) pixelDictionary[(x, y)] = None return awayPoints def getBooleanFromDictionary(defaultBoolean, dictionary, key): 'Get boolean from the dictionary and key.' if key not in dictionary: return defaultBoolean return getBooleanFromValue(dictionary[key]) def getBooleanFromValue(value): 'Get boolean from the word.' firstCharacter = str(value).lower().lstrip()[: 1] return firstCharacter == 't' or firstCharacter == '1' def getBottomByPath(path): 'Get the bottom of the path.' bottom = 987654321987654321.0 for point in path: bottom = min(bottom, point.z) return bottom def getBottomByPaths(paths): 'Get the bottom of the paths.' bottom = 987654321987654321.0 for path in paths: for point in path: bottom = min(bottom, point.z) return bottom def getClippedAtEndLoopPath( clip, loopPath ): 'Get a clipped loop path.' if clip <= 0.0: return loopPath loopPathLength = getPathLength(loopPath) clip = min( clip, 0.3 * loopPathLength ) lastLength = 0.0 pointIndex = 0 totalLength = 0.0 clippedLength = loopPathLength - clip while totalLength < clippedLength and pointIndex < len(loopPath) - 1: firstPoint = loopPath[pointIndex] secondPoint = loopPath[pointIndex + 1] pointIndex += 1 lastLength = totalLength totalLength += abs(firstPoint - secondPoint) remainingLength = clippedLength - lastLength clippedLoopPath = loopPath[ : pointIndex ] ultimateClippedPoint = loopPath[pointIndex] penultimateClippedPoint = clippedLoopPath[-1] segment = ultimateClippedPoint - penultimateClippedPoint segmentLength = abs(segment) if segmentLength <= 0.0: return clippedLoopPath newUltimatePoint = penultimateClippedPoint + segment * remainingLength / segmentLength return clippedLoopPath + [newUltimatePoint] def getClippedLoopPath(clip, loopPath): 'Get a clipped loop path.' if clip <= 0.0: return loopPath loopPathLength = getPathLength(loopPath) clip = min(clip, 0.3 * loopPathLength) lastLength = 0.0 pointIndex = 0 totalLength = 0.0 while totalLength < clip and pointIndex < len(loopPath) - 1: firstPoint = loopPath[pointIndex] secondPoint = loopPath[pointIndex + 1] pointIndex += 1 lastLength = totalLength totalLength += abs(firstPoint - secondPoint) remainingLength = clip - lastLength clippedLoopPath = loopPath[pointIndex :] ultimateClippedPoint = clippedLoopPath[0] penultimateClippedPoint = loopPath[pointIndex - 1] segment = ultimateClippedPoint - penultimateClippedPoint segmentLength = abs(segment) loopPath = clippedLoopPath if segmentLength > 0.0: newUltimatePoint = penultimateClippedPoint + segment * remainingLength / segmentLength loopPath = [newUltimatePoint] + loopPath return getClippedAtEndLoopPath(clip, loopPath) def getClippedSimplifiedLoopPath(clip, loopPath, radius): 'Get a clipped and simplified loop path.' return getSimplifiedPath(getClippedLoopPath(clip, loopPath), radius) def getClosestDistanceIndexToLine(point, loop): 'Get the distance squared to the closest segment of the loop and index of that segment.' smallestDistance = 987654321987654321.0 closestDistanceIndex = None for pointIndex in xrange(len(loop)): segmentBegin = loop[pointIndex] segmentEnd = loop[(pointIndex + 1) % len(loop)] distance = getDistanceToPlaneSegment(segmentBegin, segmentEnd, point) if distance < smallestDistance: smallestDistance = distance closestDistanceIndex = DistanceIndex(distance, pointIndex) return closestDistanceIndex def getClosestPointOnSegment(segmentBegin, segmentEnd, point): 'Get the closest point on the segment.' segmentDifference = segmentEnd - segmentBegin if abs(segmentDifference) <= 0.0: return segmentBegin pointMinusSegmentBegin = point - segmentBegin beginPlaneDot = getDotProduct(pointMinusSegmentBegin, segmentDifference) differencePlaneDot = getDotProduct(segmentDifference, segmentDifference) intercept = beginPlaneDot / differencePlaneDot intercept = max(intercept, 0.0) intercept = min(intercept, 1.0) return segmentBegin + segmentDifference * intercept def getComplexByCommaString( valueCommaString ): 'Get the commaString as a complex.' try: splitLine = valueCommaString.replace(',', ' ').split() return complex( float( splitLine[0] ), float(splitLine[1]) ) except: pass return None def getComplexByWords(words, wordIndex=0): 'Get the complex by the first two words.' try: return complex(float(words[wordIndex]), float(words[wordIndex + 1])) except: pass return None def getComplexDefaultByDictionary( defaultComplex, dictionary, key ): 'Get the value as a complex.' if key in dictionary: return complex( dictionary[key].strip().replace('(', '').replace(')', '') ) return defaultComplex def getComplexDefaultByDictionaryKeys( defaultComplex, dictionary, keyX, keyY ): 'Get the value as a complex.' x = getFloatDefaultByDictionary( defaultComplex.real, dictionary, keyX ) y = getFloatDefaultByDictionary( defaultComplex.real, dictionary, keyY ) return complex(x, y) def getComplexPath(vector3Path): 'Get the complex path from the vector3 path.' complexPath = [] for point in vector3Path: complexPath.append(point.dropAxis()) return complexPath def getComplexPathByMultiplier(multiplier, path): 'Get the multiplied complex path.' complexPath = [] for point in path: complexPath.append(multiplier * point) return complexPath def getComplexPaths(vector3Paths): 'Get the complex paths from the vector3 paths.' complexPaths = [] for vector3Path in vector3Paths: complexPaths.append(getComplexPath(vector3Path)) return complexPaths def getComplexPolygon(center, radius, sides, startAngle=0.0): 'Get the complex polygon.' complexPolygon = [] sideAngle = 2.0 * math.pi / float(sides) for side in xrange(abs(sides)): unitPolar = getWiddershinsUnitPolar(startAngle) complexPolygon.append(unitPolar * radius + center) startAngle += sideAngle return complexPolygon def getComplexPolygonByComplexRadius(radius, sides, startAngle=0.0): 'Get the complex polygon.' complexPolygon = [] sideAngle = 2.0 * math.pi / float(sides) for side in xrange(abs(sides)): unitPolar = getWiddershinsUnitPolar(startAngle) complexPolygon.append(complex(unitPolar.real * radius.real, unitPolar.imag * radius.imag)) startAngle += sideAngle return complexPolygon def getComplexPolygonByStartEnd(endAngle, radius, sides, startAngle=0.0): 'Get the complex polygon by start and end angle.' angleExtent = endAngle - startAngle sideAngle = 2.0 * math.pi / float(sides) sides = int(math.ceil(abs(angleExtent / sideAngle))) sideAngle = angleExtent / float(sides) complexPolygon = [] for side in xrange(abs(sides) + 1): unitPolar = getWiddershinsUnitPolar(startAngle) complexPolygon.append(unitPolar * radius) startAngle += sideAngle return getLoopWithoutCloseEnds(0.000001 * radius, complexPolygon) def getConcatenatedList(originalLists): 'Get the lists as one concatenated list.' concatenatedList = [] for originalList in originalLists: concatenatedList += originalList return concatenatedList def getConnectedPaths( paths, pixelDictionary, width ): 'Get connected paths from paths.' if len(paths) < 2: return paths connectedPaths = [] segments = [] for pathIndex in xrange( len(paths) ): path = paths[ pathIndex ] segments.append( getSegmentFromPath( path, pathIndex ) ) for pathIndex in xrange( 0, len(paths) - 1 ): concatenateRemovePath( connectedPaths, pathIndex, paths, pixelDictionary, segments, width ) connectedPaths.append( paths[-1] ) return connectedPaths def getCrossProduct(firstComplex, secondComplex): 'Get z component cross product of a pair of complexes.' return firstComplex.real * secondComplex.imag - firstComplex.imag * secondComplex.real def getDecimalPlacesCarried(extraDecimalPlaces, value): 'Get decimal places carried by the decimal places of the value plus the extraDecimalPlaces.' return max(0, 1 + int(math.ceil(extraDecimalPlaces - math.log10(value)))) def getDiagonalFlippedLoop(loop): 'Get loop flipped over the dialogonal, in other words with the x and y swapped.' diagonalFlippedLoop = [] for point in loop: diagonalFlippedLoop.append( complex( point.imag, point.real ) ) return diagonalFlippedLoop def getDiagonalFlippedLoops(loops): 'Get loops flipped over the dialogonal, in other words with the x and y swapped.' diagonalFlippedLoops = [] for loop in loops: diagonalFlippedLoops.append( getDiagonalFlippedLoop(loop) ) return diagonalFlippedLoops def getDictionaryString(dictionary): 'Get the dictionary string.' output = cStringIO.StringIO() keys = dictionary.keys() keys.sort() for key in keys: addValueToOutput(0, key, output, dictionary[key]) return output.getvalue() def getDistanceToLine(begin, end, point): 'Get the distance from a vector3 point to an infinite line.' pointMinusBegin = point - begin if begin == end: return abs(pointMinusBegin) endMinusBegin = end - begin return abs(endMinusBegin.cross(pointMinusBegin)) / abs(endMinusBegin) def getDistanceToLineByPath(begin, end, path): 'Get the maximum distance from a path to an infinite line.' distanceToLine = -987654321.0 for point in path: distanceToLine = max(getDistanceToLine(begin, end, point), distanceToLine) return distanceToLine def getDistanceToLineByPaths(begin, end, paths): 'Get the maximum distance from paths to an infinite line.' distanceToLine = -987654321.0 for path in paths: distanceToLine = max(getDistanceToLineByPath(begin, end, path), distanceToLine) return distanceToLine def getDistanceToPlaneSegment( segmentBegin, segmentEnd, point ): 'Get the distance squared from a point to the x & y components of a segment.' segmentDifference = segmentEnd - segmentBegin pointMinusSegmentBegin = point - segmentBegin beginPlaneDot = getDotProduct( pointMinusSegmentBegin, segmentDifference ) if beginPlaneDot <= 0.0: return abs( point - segmentBegin ) * abs( point - segmentBegin ) differencePlaneDot = getDotProduct( segmentDifference, segmentDifference ) if differencePlaneDot <= beginPlaneDot: return abs( point - segmentEnd ) * abs( point - segmentEnd ) intercept = beginPlaneDot / differencePlaneDot interceptPerpendicular = segmentBegin + segmentDifference * intercept return abs( point - interceptPerpendicular ) * abs( point - interceptPerpendicular ) def getDotProduct(firstComplex, secondComplex): 'Get the dot product of a pair of complexes.' return firstComplex.real * secondComplex.real + firstComplex.imag * secondComplex.imag def getDotProductPlusOne( firstComplex, secondComplex ): 'Get the dot product plus one of the x and y components of a pair of Vector3s.' return 1.0 + getDotProduct( firstComplex, secondComplex ) def getDurationString( seconds ): 'Get the duration string.' secondsRounded = int( round( seconds ) ) durationString = getPluralString( secondsRounded % 60, 'second') if seconds < 60: return durationString durationString = '%s %s' % ( getPluralString( ( secondsRounded / 60 ) % 60, 'minute'), durationString ) if seconds < 3600: return durationString return '%s %s' % ( getPluralString( secondsRounded / 3600, 'hour'), durationString ) def getEndpointFromPath( path, pathIndex ): 'Get endpoint segment from a path.' begin = path[-1] end = path[-2] endpointBegin = Endpoint() endpointEnd = Endpoint().getFromOtherPoint( endpointBegin, end ) endpointBegin.getFromOtherPoint( endpointEnd, begin ) endpointBegin.path = path endpointBegin.pathIndex = pathIndex return endpointBegin def getEndpointsFromSegments( segments ): 'Get endpoints from segments.' endpoints = [] for segment in segments: for endpoint in segment: endpoints.append( endpoint ) return endpoints def getEndpointsFromSegmentTable( segmentTable ): 'Get the endpoints from the segment table.' endpoints = [] segmentTableKeys = segmentTable.keys() segmentTableKeys.sort() for segmentTableKey in segmentTableKeys: for segment in segmentTable[ segmentTableKey ]: for endpoint in segment: endpoints.append( endpoint ) return endpoints def getEnumeratorKeys(enumerator, keys): 'Get enumerator keys.' if len(keys) == 1: return keys[0] return getEnumeratorKeysExceptForOneArgument(enumerator, keys) def getEnumeratorKeysAlwaysList(enumerator, keys): 'Get enumerator keys.' if keys.__class__ != list: return [keys] if len(keys) == 1: return keys return getEnumeratorKeysExceptForOneArgument(enumerator, keys) def getEnumeratorKeysExceptForOneArgument(enumerator, keys): 'Get enumerator keys, except when there is one argument.' if len(keys) == 0: return range(0, len(enumerator)) beginIndex = keys[0] endIndex = keys[1] if len(keys) == 2: if beginIndex is None: beginIndex = 0 if endIndex is None: endIndex = len(enumerator) return range(beginIndex, endIndex) step = keys[2] beginIndexDefault = 0 endIndexDefault = len(enumerator) if step < 0: beginIndexDefault = endIndexDefault - 1 endIndexDefault = -1 if beginIndex is None: beginIndex = beginIndexDefault if endIndex is None: endIndex = endIndexDefault return range(beginIndex, endIndex, step) def getFillOfSurroundings(nestedRings, penultimateFillLoops): 'Get extra fill loops of nested rings.' fillOfSurroundings = [] for nestedRing in nestedRings: fillOfSurroundings += nestedRing.getFillLoops(penultimateFillLoops) return fillOfSurroundings def getFlattenedNestedRings(nestedRings): 'Get flattened nested rings.' flattenedNestedRings = [] for nestedRing in nestedRings: nestedRing.addFlattenedNestedRings(flattenedNestedRings) return flattenedNestedRings def getFloatDefaultByDictionary( defaultFloat, dictionary, key ): 'Get the value as a float.' evaluatedFloat = None if key in dictionary: evaluatedFloat = getFloatFromValue(dictionary[key]) if evaluatedFloat is None: return defaultFloat return evaluatedFloat def getFloatFromValue(value): 'Get the value as a float.' try: return float(value) except: pass return None def getFourSignificantFigures(number): 'Get number rounded to four significant figures as a string.' if number is None: return None absoluteNumber = abs(number) if absoluteNumber >= 100.0: return getRoundedToPlacesString( 2, number ) if absoluteNumber < 0.000000001: return getRoundedToPlacesString( 13, number ) return getRoundedToPlacesString( 3 - math.floor( math.log10( absoluteNumber ) ), number ) def getHalfSimplifiedLoop( loop, radius, remainder ): 'Get the loop with half of the points inside the channel removed.' if len(loop) < 2: return loop channelRadius = radius * .01 simplified = [] addIndex = 0 if remainder == 1: addIndex = len(loop) - 1 for pointIndex in xrange(len(loop)): point = loop[pointIndex] if pointIndex % 2 == remainder or pointIndex == addIndex: simplified.append(point) elif not isWithinChannel( channelRadius, pointIndex, loop ): simplified.append(point) return simplified def getHalfSimplifiedPath(path, radius, remainder): 'Get the path with half of the points inside the channel removed.' if len(path) < 2: return path channelRadius = radius * .01 simplified = [path[0]] for pointIndex in xrange(1, len(path) - 1): point = path[pointIndex] if pointIndex % 2 == remainder: simplified.append(point) elif not isWithinChannel(channelRadius, pointIndex, path): simplified.append(point) simplified.append(path[-1]) return simplified def getHorizontallyBoundedPath(horizontalBegin, horizontalEnd, path): 'Get horizontally bounded path.' horizontallyBoundedPath = [] for pointIndex, point in enumerate(path): begin = None previousIndex = pointIndex - 1 if previousIndex >= 0: begin = path[previousIndex] end = None nextIndex = pointIndex + 1 if nextIndex < len(path): end = path[nextIndex] addHorizontallyBoundedPoint(begin, point, end, horizontalBegin, horizontalEnd, horizontallyBoundedPath) return horizontallyBoundedPath def getIncrementFromRank( rank ): 'Get the increment from the rank which is 0 at 1 and increases by three every power of ten.' rankZone = int( math.floor( rank / 3 ) ) rankModulo = rank % 3 powerOfTen = pow( 10, rankZone ) moduloMultipliers = ( 1, 2, 5 ) return float( powerOfTen * moduloMultipliers[ rankModulo ] ) def getInsidesAddToOutsides( loops, outsides ): 'Add loops to either the insides or outsides.' insides = [] for loopIndex in xrange( len(loops) ): loop = loops[loopIndex] if isInsideOtherLoops( loopIndex, loops ): insides.append(loop) else: outsides.append(loop) return insides def getIntermediateLocation( alongWay, begin, end ): 'Get the intermediate location between begin and end.' return begin * ( 1.0 - alongWay ) + end * alongWay def getIntersectionOfXIntersectionIndexes( totalSolidSurfaceThickness, xIntersectionIndexList ): 'Get x intersections from surrounding layers.' xIntersectionList = [] solidTable = {} solid = False xIntersectionIndexList.sort() for xIntersectionIndex in xIntersectionIndexList: toggleHashtable(solidTable, xIntersectionIndex.index, '') oldSolid = solid solid = len(solidTable) >= totalSolidSurfaceThickness if oldSolid != solid: xIntersectionList.append(xIntersectionIndex.x) return xIntersectionList def getIntersectionOfXIntersectionsTables(xIntersectionsTables): 'Get the intersection of the XIntersections tables.' if len(xIntersectionsTables) == 0: return {} intersectionOfXIntersectionsTables = {} firstIntersectionTable = xIntersectionsTables[0] for firstIntersectionTableKey in firstIntersectionTable.keys(): xIntersectionIndexList = [] for xIntersectionsTableIndex in xrange(len(xIntersectionsTables)): xIntersectionsTable = xIntersectionsTables[xIntersectionsTableIndex] if firstIntersectionTableKey in xIntersectionsTable: addXIntersectionIndexesFromXIntersections(xIntersectionsTableIndex, xIntersectionIndexList, xIntersectionsTable[firstIntersectionTableKey]) xIntersections = getIntersectionOfXIntersectionIndexes(len(xIntersectionsTables), xIntersectionIndexList) if len(xIntersections) > 0: intersectionOfXIntersectionsTables[firstIntersectionTableKey] = xIntersections return intersectionOfXIntersectionsTables def getIntFromValue(value): 'Get the value as an int.' try: return int(value) except: pass return None def getIsInFilledRegion(loops, point): 'Determine if the point is in the filled region of the loops.' return getNumberOfIntersectionsToLeftOfLoops(loops, point) % 2 == 1 def getIsInFilledRegionByPaths(loops, paths): 'Determine if the point of any path is in the filled region of the loops.' for path in paths: if len(path) > 0: if getIsInFilledRegion(loops, path[0]): return True return False def getIsRadianClose(firstRadian, secondRadian): 'Determine if the firstRadian is close to the secondRadian.' return abs(math.pi - abs(math.pi - ((firstRadian - secondRadian) % (math.pi + math.pi) ))) < 0.000001 def getIsWiddershinsByVector3( polygon ): 'Determine if the polygon goes round in the widdershins direction.' return isWiddershins( getComplexPath( polygon ) ) def getJoinOfXIntersectionIndexes( xIntersectionIndexList ): 'Get joined x intersections from surrounding layers.' xIntersections = [] solidTable = {} solid = False xIntersectionIndexList.sort() for xIntersectionIndex in xIntersectionIndexList: toggleHashtable(solidTable, xIntersectionIndex.index, '') oldSolid = solid solid = len(solidTable) > 0 if oldSolid != solid: xIntersections.append(xIntersectionIndex.x) return xIntersections def getLargestLoop(loops): 'Get largest loop from loops.' if len(loops) == 1: return loops[0] largestArea = - 987654321.0 largestLoop = [] for loop in loops: loopArea = abs( getAreaLoop(loop) ) if loopArea > largestArea: largestArea = loopArea largestLoop = loop return largestLoop def getLeftPoint(points): 'Get the leftmost complex point in the points.' leftmost = 987654321.0 leftPointComplex = None for pointComplex in points: if pointComplex.real < leftmost: leftmost = pointComplex.real leftPointComplex = pointComplex return leftPointComplex def getLeftPointIndex(points): 'Get the index of the leftmost complex point in the points.' if len(points) < 1: return None leftPointIndex = 0 for pointIndex in xrange( len(points) ): if points[pointIndex].real < points[ leftPointIndex ].real: leftPointIndex = pointIndex return leftPointIndex def getListTableElements( listDictionary ): 'Get all the element in a list table.' listDictionaryElements = [] for listDictionaryValue in listDictionary.values(): listDictionaryElements += listDictionaryValue return listDictionaryElements def getLoopCentroid(polygonComplex): 'Get the area of a complex polygon using http://en.wikipedia.org/wiki/Centroid.' polygonDoubleArea = 0.0 polygonTorque = 0.0 for pointIndex in xrange( len(polygonComplex) ): pointBegin = polygonComplex[pointIndex] pointEnd = polygonComplex[ (pointIndex + 1) % len(polygonComplex) ] doubleArea = pointBegin.real * pointEnd.imag - pointEnd.real * pointBegin.imag doubleCenter = complex( pointBegin.real + pointEnd.real, pointBegin.imag + pointEnd.imag ) polygonDoubleArea += doubleArea polygonTorque += doubleArea * doubleCenter torqueMultiplier = 0.333333333333333333333333 / polygonDoubleArea return polygonTorque * torqueMultiplier def getLoopConvex(points): 'Get convex hull of points using gift wrap algorithm.' loopConvex = [] pointSet = set() for point in points: if point not in pointSet: pointSet.add(point) loopConvex.append(point) if len(loopConvex) < 4: return loopConvex leftPoint = getLeftPoint(loopConvex) lastPoint = leftPoint pointSet.remove(leftPoint) loopConvex = [leftPoint] lastSegment = complex(0.0, 1.0) while True: greatestDotProduct = -9.9 greatestPoint = None greatestSegment = None if len(loopConvex) > 2: nextSegment = getNormalized(leftPoint - lastPoint) if abs(nextSegment) > 0.0: greatestDotProduct = getDotProduct(nextSegment, lastSegment) for point in pointSet: nextSegment = getNormalized(point - lastPoint) if abs(nextSegment) > 0.0: dotProduct = getDotProduct(nextSegment, lastSegment) if dotProduct > greatestDotProduct: greatestDotProduct = dotProduct greatestPoint = point greatestSegment = nextSegment if greatestPoint is None: return loopConvex lastPoint = greatestPoint loopConvex.append(greatestPoint) pointSet.remove(greatestPoint) lastSegment = greatestSegment return loopConvex def getLoopConvexCentroid(polygonComplex): 'Get centroid of the convex hull of a complex polygon.' return getLoopCentroid( getLoopConvex(polygonComplex) ) def getLoopInsideContainingLoop( containingLoop, loops ): 'Get a loop that is inside the containing loop.' for loop in loops: if loop != containingLoop: if isPathInsideLoop( containingLoop, loop ): return loop return None def getLoopLength( polygon ): 'Get the length of a polygon perimeter.' polygonLength = 0.0 for pointIndex in xrange( len( polygon ) ): point = polygon[pointIndex] secondPoint = polygon[ (pointIndex + 1) % len( polygon ) ] polygonLength += abs( point - secondPoint ) return polygonLength def getLoopStartingClosest(extrusionHalfWidth, location, loop): 'Add to threads from the last location from loop.' closestIndex = getClosestDistanceIndexToLine(location, loop).index loop = getAroundLoop(closestIndex, closestIndex, loop) closestPoint = getClosestPointOnSegment(loop[0], loop[1], location) if abs(closestPoint - loop[0]) > extrusionHalfWidth and abs(closestPoint - loop[1]) > extrusionHalfWidth: loop = [closestPoint] + loop[1 :] + [loop[0]] elif abs(closestPoint - loop[0]) > abs(closestPoint - loop[1]): loop = loop[1 :] + [loop[0]] return loop def getLoopWithoutCloseEnds(close, loop): 'Get loop without close ends.' if len(loop) < 2: return loop if abs(loop[0] - loop[-1]) > close: return loop return loop[: -1] def getLoopWithoutCloseSequentialPoints(close, loop): 'Get loop without close sequential points.' if len(loop) < 2: return loop lastPoint = loop[-1] loopWithoutCloseSequentialPoints = [] for point in loop: if abs(point - lastPoint) > close: loopWithoutCloseSequentialPoints.append(point) lastPoint = point return loopWithoutCloseSequentialPoints def getMaximum(firstComplex, secondComplex): 'Get a complex with each component the maximum of the respective components of a pair of complexes.' return complex(max(firstComplex.real, secondComplex.real), max(firstComplex.imag, secondComplex.imag)) def getMaximumByComplexPath(path): 'Get a complex with each component the maximum of the respective components of a complex path.' maximum = complex(-987654321987654321.0, -987654321987654321.0) for point in path: maximum = getMaximum(maximum, point) return maximum def getMaximumByComplexPaths(paths): 'Get a complex with each component the maximum of the respective components of complex paths.' maximum = complex(-987654321987654321.0, -987654321987654321.0) for path in paths: for point in path: maximum = getMaximum(maximum, point) return maximum def getMaximumByVector3Path(path): 'Get a vector3 with each component the maximum of the respective components of a vector3 path.' maximum = Vector3(-987654321987654321.0, -987654321987654321.0, -987654321987654321.0) for point in path: maximum.maximize(point) return maximum def getMaximumByVector3Paths(paths): 'Get a complex with each component the maximum of the respective components of a complex path.' maximum = Vector3(-987654321987654321.0, -987654231987654321.0, -987654321987654321.0) for path in paths: for point in path: maximum.maximize(point) return maximum def getMaximumSpan(loop): 'Get the maximum span of the loop.' extent = getMaximumByComplexPath(loop) - getMinimumByComplexPath(loop) return max(extent.real, extent.imag) def getMinimum(firstComplex, secondComplex): 'Get a complex with each component the minimum of the respective components of a pair of complexes.' return complex(min(firstComplex.real, secondComplex.real), min(firstComplex.imag, secondComplex.imag)) def getMinimumByComplexPath(path): 'Get a complex with each component the minimum of the respective components of a complex path.' minimum = complex(987654321987654321.0, 987654321987654321.0) for point in path: minimum = getMinimum(minimum, point) return minimum def getMinimumByComplexPaths(paths): 'Get a complex with each component the minimum of the respective components of complex paths.' minimum = complex(987654321987654321.0, 987654321987654321.0) for path in paths: for point in path: minimum = getMinimum(minimum, point) return minimum def getMinimumByVector3Path(path): 'Get a vector3 with each component the minimum of the respective components of a vector3 path.' minimum = Vector3(987654321987654321.0, 987654321987654321.0, 987654321987654321.0) for point in path: minimum.minimize(point) return minimum def getMinimumByVector3Paths(paths): 'Get a complex with each component the minimum of the respective components of a complex path.' minimum = Vector3(987654321987654321.0, 987654321987654321.0, 987654321987654321.0) for path in paths: for point in path: minimum.minimize(point) return minimum def getMirrorPath(path): "Get mirror path." close = 0.001 * getPathLength(path) for pointIndex in xrange(len(path) - 1, -1, -1): point = path[pointIndex] flipPoint = complex(-point.real, point.imag) if abs(flipPoint - path[-1]) > close: path.append(flipPoint) return path def getNormal(begin, center, end): 'Get normal.' centerMinusBegin = (center - begin).getNormalized() endMinusCenter = (end - center).getNormalized() return centerMinusBegin.cross(endMinusCenter) def getNormalByPath(path): 'Get normal by path.' totalNormal = Vector3() for pointIndex, point in enumerate(path): center = path[(pointIndex + 1) % len(path)] end = path[(pointIndex + 2) % len(path)] totalNormal += getNormalWeighted(point, center, end) return totalNormal.getNormalized() def getNormalized(complexNumber): 'Get the normalized complex.' complexNumberLength = abs(complexNumber) if complexNumberLength > 0.0: return complexNumber / complexNumberLength return complexNumber def getNormalWeighted(begin, center, end): 'Get weighted normal.' return (center - begin).cross(end - center) def getNumberOfIntersectionsToLeft(loop, point): 'Get the number of intersections through the loop for the line going left.' numberOfIntersectionsToLeft = 0 for pointIndex in xrange(len(loop)): firstPointComplex = loop[pointIndex] secondPointComplex = loop[(pointIndex + 1) % len(loop)] xIntersection = getXIntersectionIfExists(firstPointComplex, secondPointComplex, point.imag) if xIntersection is not None: if xIntersection < point.real: numberOfIntersectionsToLeft += 1 return numberOfIntersectionsToLeft def getNumberOfIntersectionsToLeftOfLoops(loops, point): 'Get the number of intersections through the loop for the line starting from the left point and going left.' totalNumberOfIntersectionsToLeft = 0 for loop in loops: totalNumberOfIntersectionsToLeft += getNumberOfIntersectionsToLeft(loop, point) return totalNumberOfIntersectionsToLeft def getOrderedNestedRings(nestedRings): 'Get ordered nestedRings from nestedRings.' insides = [] orderedNestedRings = [] for loopIndex in xrange(len(nestedRings)): nestedRing = nestedRings[loopIndex] otherLoops = [] for beforeIndex in xrange(loopIndex): otherLoops.append(nestedRings[beforeIndex].boundary) for afterIndex in xrange(loopIndex + 1, len(nestedRings)): otherLoops.append(nestedRings[afterIndex].boundary) if isPathEntirelyInsideLoops(otherLoops, nestedRing.boundary): insides.append(nestedRing) else: orderedNestedRings.append(nestedRing) for outside in orderedNestedRings: outside.getFromInsideSurroundings(insides) return orderedNestedRings def getPathCopy(path): 'Get path copy.' pathCopy = [] for point in path: pathCopy.append(point.copy()) return pathCopy def getPathLength(path): 'Get the length of a path ( an open polyline ).' pathLength = 0.0 for pointIndex in xrange( len(path) - 1 ): firstPoint = path[pointIndex] secondPoint = path[pointIndex + 1] pathLength += abs(firstPoint - secondPoint) return pathLength def getPathsFromEndpoints(endpoints, maximumConnectionLength, pixelDictionary, width): 'Get paths from endpoints.' if len(endpoints) < 2: return [] endpoints = endpoints[:] # so that the first two endpoints aren't removed when used again for beginningEndpoint in endpoints[: : 2]: beginningPoint = beginningEndpoint.point addSegmentToPixelTable(beginningPoint, beginningEndpoint.otherEndpoint.point, pixelDictionary, 0, 0, width) endpointFirst = endpoints[0] endpoints.remove(endpointFirst) otherEndpoint = endpointFirst.otherEndpoint endpoints.remove(otherEndpoint) nextEndpoint = None path = [] paths = [path] if len(endpoints) > 1: nextEndpoint = otherEndpoint.getClosestMiss(endpoints, path, pixelDictionary, width) if nextEndpoint is not None: if abs(nextEndpoint.point - endpointFirst.point) < abs(nextEndpoint.point - otherEndpoint.point): endpointFirst = endpointFirst.otherEndpoint otherEndpoint = endpointFirst.otherEndpoint addPointToPath(path, pixelDictionary, endpointFirst.point, None, width) addPointToPath(path, pixelDictionary, otherEndpoint.point, len(paths) - 1, width) oneOverEndpointWidth = 1.0 / maximumConnectionLength endpointTable = {} for endpoint in endpoints: addElementToPixelListFromPoint(endpoint, endpointTable, endpoint.point * oneOverEndpointWidth) while len(endpointTable) > 0: if len(endpointTable) == 1: if len(endpointTable.values()[0]) < 2: return [] endpoints = getSquareValuesFromPoint(endpointTable, otherEndpoint.point * oneOverEndpointWidth) nextEndpoint = otherEndpoint.getClosestMiss(endpoints, path, pixelDictionary, width) if nextEndpoint is None: path = [] paths.append(path) endpoints = getListTableElements(endpointTable) nextEndpoint = otherEndpoint.getClosestEndpoint(endpoints) # this commented code should be faster than the getListTableElements code, but it isn't, someday a spiral algorithim could be tried # endpoints = getSquareValuesFromPoint( endpointTable, otherEndpoint.point * oneOverEndpointWidth ) # nextEndpoint = otherEndpoint.getClosestEndpoint(endpoints) # if nextEndpoint is None: # endpoints = [] # for endpointTableValue in endpointTable.values(): # endpoints.append( endpointTableValue[0] ) # nextEndpoint = otherEndpoint.getClosestEndpoint(endpoints) # endpoints = getSquareValuesFromPoint( endpointTable, nextEndpoint.point * oneOverEndpointWidth ) # nextEndpoint = otherEndpoint.getClosestEndpoint(endpoints) addPointToPath(path, pixelDictionary, nextEndpoint.point, len(paths) - 1, width) removeElementFromPixelListFromPoint(nextEndpoint, endpointTable, nextEndpoint.point * oneOverEndpointWidth) otherEndpoint = nextEndpoint.otherEndpoint addPointToPath(path, pixelDictionary, otherEndpoint.point, len(paths) - 1, width) removeElementFromPixelListFromPoint(otherEndpoint, endpointTable, otherEndpoint.point * oneOverEndpointWidth) return paths def getPlaneDot( vec3First, vec3Second ): 'Get the dot product of the x and y components of a pair of Vector3s.' return vec3First.x * vec3Second.x + vec3First.y * vec3Second.y def getPluralString( number, suffix ): 'Get the plural string.' if number == 1: return '1 %s' % suffix return '%s %ss' % ( number, suffix ) def getPointPlusSegmentWithLength( length, point, segment ): 'Get point plus a segment scaled to a given length.' return segment * length / abs(segment) + point def getPointsByHorizontalDictionary(width, xIntersectionsDictionary): 'Get points from the horizontalXIntersectionsDictionary.' points = [] xIntersectionsDictionaryKeys = xIntersectionsDictionary.keys() xIntersectionsDictionaryKeys.sort() for xIntersectionsDictionaryKey in xIntersectionsDictionaryKeys: for xIntersection in xIntersectionsDictionary[xIntersectionsDictionaryKey]: points.append(complex(xIntersection, xIntersectionsDictionaryKey * width)) return points def getPointsByVerticalDictionary(width, xIntersectionsDictionary): 'Get points from the verticalXIntersectionsDictionary.' points = [] xIntersectionsDictionaryKeys = xIntersectionsDictionary.keys() xIntersectionsDictionaryKeys.sort() for xIntersectionsDictionaryKey in xIntersectionsDictionaryKeys: for xIntersection in xIntersectionsDictionary[xIntersectionsDictionaryKey]: points.append(complex(xIntersectionsDictionaryKey * width, xIntersection)) return points def getRadiusArealizedMultiplier(sides): 'Get the radius multiplier for a polygon of equal area.' return math.sqrt(globalTau / sides / math.sin(globalTau / sides)) def getRandomComplex(begin, end): 'Get random complex.' endMinusBegin = end - begin return begin + complex(random.random() * endMinusBegin.real, random.random() * endMinusBegin.imag) def getRank(width): 'Get the rank which is 0 at 1 and increases by three every power of ten.' return int(math.floor(3.0 * math.log10(width))) def getRotatedComplexes(planeAngle, points): 'Get points rotated by the plane angle' rotatedComplexes = [] for point in points: rotatedComplexes.append(planeAngle * point) return rotatedComplexes def getRotatedComplexLists(planeAngle, pointLists): 'Get point lists rotated by the plane angle' rotatedComplexLists = [] for pointList in pointLists: rotatedComplexLists.append(getRotatedComplexes(planeAngle, pointList)) return rotatedComplexLists def getRotatedWiddershinsQuarterAroundZAxis(vector3): 'Get Vector3 rotated a quarter widdershins turn around Z axis.' return Vector3(-vector3.y, vector3.x, vector3.z) def getRoundedPoint(point): 'Get point with each component rounded.' return Vector3(round(point.x), round( point.y ), round(point.z)) def getRoundedToPlaces(decimalPlaces, number): 'Get number rounded to a number of decimal places.' decimalPlacesRounded = max(1, int(round(decimalPlaces))) return round(number, decimalPlacesRounded ) def getRoundedToPlacesString(decimalPlaces, number): 'Get number rounded to a number of decimal places as a string, without exponential formatting.' roundedToPlaces = getRoundedToPlaces(decimalPlaces, number) roundedToPlacesString = str(roundedToPlaces) if 'e' in roundedToPlacesString: return ('%.15f' % roundedToPlaces).rstrip('0') return roundedToPlacesString def getRoundedToThreePlaces(number): 'Get number rounded to three places as a string.' return str(round(number, 3)) def getRoundZAxisByPlaneAngle( planeAngle, vector3 ): 'Get Vector3 rotated by a plane angle.' return Vector3( vector3.x * planeAngle.real - vector3.y * planeAngle.imag, vector3.x * planeAngle.imag + vector3.y * planeAngle.real, vector3.z ) def getSegmentFromPath( path, pathIndex ): 'Get endpoint segment from a path.' if len(path) < 2: return None begin = path[-1] end = path[-2] forwardEndpoint = getEndpointFromPath( path, pathIndex ) reversePath = path[:] reversePath.reverse() reverseEndpoint = getEndpointFromPath( reversePath, pathIndex ) return ( forwardEndpoint, reverseEndpoint ) def getSegmentFromPoints( begin, end ): 'Get endpoint segment from a pair of points.' endpointFirst = Endpoint() endpointSecond = Endpoint().getFromOtherPoint( endpointFirst, end ) endpointFirst.getFromOtherPoint( endpointSecond, begin ) return ( endpointFirst, endpointSecond ) def getSegmentsFromXIntersectionIndexes( xIntersectionIndexList, y ): 'Get endpoint segments from the x intersection indexes.' xIntersections = getXIntersectionsFromIntersections( xIntersectionIndexList ) return getSegmentsFromXIntersections( xIntersections, y ) def getSegmentsFromXIntersections( xIntersections, y ): 'Get endpoint segments from the x intersections.' segments = [] end = len( xIntersections ) if len( xIntersections ) % 2 == 1: end -= 1 for xIntersectionIndex in xrange( 0, end, 2 ): firstX = xIntersections[ xIntersectionIndex ] secondX = xIntersections[ xIntersectionIndex + 1 ] if firstX != secondX: segments.append( getSegmentFromPoints( complex( firstX, y ), complex( secondX, y ) ) ) return segments def getSimplifiedLoop( loop, radius ): 'Get loop with points inside the channel removed.' if len(loop) < 2: return loop simplificationMultiplication = 256 simplificationRadius = radius / float( simplificationMultiplication ) maximumIndex = len(loop) * simplificationMultiplication pointIndex = 1 while pointIndex < maximumIndex: oldLoopLength = len(loop) loop = getHalfSimplifiedLoop( loop, simplificationRadius, 0 ) loop = getHalfSimplifiedLoop( loop, simplificationRadius, 1 ) simplificationRadius += simplificationRadius if oldLoopLength == len(loop): if simplificationRadius > radius: return getAwayPoints( loop, radius ) else: simplificationRadius *= 1.5 simplificationRadius = min( simplificationRadius, radius ) pointIndex += pointIndex return getAwayPoints( loop, radius ) def getSimplifiedLoops( loops, radius ): 'Get the simplified loops.' simplifiedLoops = [] for loop in loops: simplifiedLoops.append( getSimplifiedLoop( loop, radius ) ) return simplifiedLoops def getSimplifiedPath(path, radius): 'Get path with points inside the channel removed.' if len(path) < 2: return path simplificationMultiplication = 256 simplificationRadius = radius / float(simplificationMultiplication) maximumIndex = len(path) * simplificationMultiplication pointIndex = 1 while pointIndex < maximumIndex: oldPathLength = len(path) path = getHalfSimplifiedPath(path, simplificationRadius, 0) path = getHalfSimplifiedPath(path, simplificationRadius, 1) simplificationRadius += simplificationRadius if oldPathLength == len(path): if simplificationRadius > radius: return getAwayPath(path, radius) else: simplificationRadius *= 1.5 simplificationRadius = min(simplificationRadius, radius) pointIndex += pointIndex return getAwayPath(path, radius) def getSquareIsOccupied( pixelDictionary, x, y ): 'Determine if a square around the x and y pixel coordinates is occupied.' squareValues = [] for xStep in xrange(x - 1, x + 2): for yStep in xrange(y - 1, y + 2): if (xStep, yStep) in pixelDictionary: return True return False def getSquareLoopWiddershins(beginComplex, endComplex): 'Get a square loop from the beginning to the end and back.' loop = [beginComplex, complex(endComplex.real, beginComplex.imag), endComplex] loop.append(complex(beginComplex.real, endComplex.imag)) return loop def getSquareValues( pixelDictionary, x, y ): 'Get a list of the values in a square around the x and y pixel coordinates.' squareValues = [] for xStep in xrange(x - 1, x + 2): for yStep in xrange(y - 1, y + 2): stepKey = (xStep, yStep) if stepKey in pixelDictionary: squareValues += pixelDictionary[ stepKey ] return squareValues def getSquareValuesFromPoint( pixelDictionary, point ): 'Get a list of the values in a square around the point.' return getSquareValues(pixelDictionary, int(round(point.real)), int(round(point.imag))) def getStepKeyFromPoint(point): 'Get step key for the point.' return (int(round(point.real)), int(round(point.imag))) def getThreeSignificantFigures(number): 'Get number rounded to three significant figures as a string.' absoluteNumber = abs(number) if absoluteNumber >= 10.0: return getRoundedToPlacesString( 1, number ) if absoluteNumber < 0.000000001: return getRoundedToPlacesString( 12, number ) return getRoundedToPlacesString( 1 - math.floor( math.log10( absoluteNumber ) ), number ) def getTopPath(path): 'Get the top of the path.' top = -987654321987654321.0 for point in path: top = max(top, point.z) return top def getTopPaths(paths): 'Get the top of the paths.' top = -987654321987654321.0 for path in paths: for point in path: top = max(top, point.z) return top def getTransferClosestNestedRing(extrusionHalfWidth, nestedRings, oldOrderedLocation, skein, threadSequence): 'Get and transfer the closest remaining nested ring.' if len(nestedRings) > 0: oldOrderedLocation.z = nestedRings[0].z closestDistance = 987654321987654321.0 closestNestedRing = None for remainingNestedRing in nestedRings: distance = getClosestDistanceIndexToLine(oldOrderedLocation.dropAxis(), remainingNestedRing.boundary).distance if distance < closestDistance: closestDistance = distance closestNestedRing = remainingNestedRing nestedRings.remove(closestNestedRing) closestNestedRing.addToThreads(extrusionHalfWidth, oldOrderedLocation, skein, threadSequence) return closestNestedRing def getTransferredNestedRings( insides, loop ): 'Get transferred paths from inside nested rings.' transferredSurroundings = [] for insideIndex in xrange( len( insides ) - 1, - 1, - 1 ): insideSurrounding = insides[ insideIndex ] if isPathInsideLoop( loop, insideSurrounding.boundary ): transferredSurroundings.append( insideSurrounding ) del insides[ insideIndex ] return transferredSurroundings def getTransferredPaths( insides, loop ): 'Get transferred paths from inside paths.' transferredPaths = [] for insideIndex in xrange( len( insides ) - 1, - 1, - 1 ): inside = insides[ insideIndex ] if isPathInsideLoop( loop, inside ): transferredPaths.append( inside ) del insides[ insideIndex ] return transferredPaths def getTranslatedComplexPath(path, translateComplex): 'Get the translated complex path.' translatedComplexPath = [] for point in path: translatedComplexPath.append(point + translateComplex) return translatedComplexPath def getVector3Path(complexPath, z=0.0): 'Get the vector3 path from the complex path.' vector3Path = [] for complexPoint in complexPath: vector3Path.append(Vector3(complexPoint.real, complexPoint.imag, z)) return vector3Path def getVector3Paths(complexPaths, z=0.0): 'Get the vector3 paths from the complex paths.' vector3Paths = [] for complexPath in complexPaths: vector3Paths.append(getVector3Path(complexPath, z)) return vector3Paths def getWiddershinsUnitPolar(angle): 'Get polar complex from counterclockwise angle from 1, 0.' return complex(math.cos(angle), math.sin(angle)) def getXIntersectionIfExists( beginComplex, endComplex, y ): 'Get the x intersection if it exists.' if ( y > beginComplex.imag ) == ( y > endComplex.imag ): return None endMinusBeginComplex = endComplex - beginComplex return ( y - beginComplex.imag ) / endMinusBeginComplex.imag * endMinusBeginComplex.real + beginComplex.real def getXIntersectionsFromIntersections( xIntersectionIndexList ): 'Get x intersections from the x intersection index list, in other words subtract non negative intersections from negatives.' xIntersections = [] fill = False solid = False solidTable = {} xIntersectionIndexList.sort() for solidX in xIntersectionIndexList: if solidX.index >= 0: toggleHashtable( solidTable, solidX.index, '' ) else: fill = not fill oldSolid = solid solid = ( len( solidTable ) == 0 and fill ) if oldSolid != solid: xIntersections.append( solidX.x ) return xIntersections def getXYComplexFromVector3(vector3): 'Get an xy complex from a vector3 if it exists, otherwise return None.' if vector3 is None: return None return vector3.dropAxis() def getYIntersectionIfExists( beginComplex, endComplex, x ): 'Get the y intersection if it exists.' if ( x > beginComplex.real ) == ( x > endComplex.real ): return None endMinusBeginComplex = endComplex - beginComplex return ( x - beginComplex.real ) / endMinusBeginComplex.real * endMinusBeginComplex.imag + beginComplex.imag def getZComponentCrossProduct( vec3First, vec3Second ): 'Get z component cross product of a pair of Vector3s.' return vec3First.x * vec3Second.y - vec3First.y * vec3Second.x def isInsideOtherLoops( loopIndex, loops ): 'Determine if a loop in a list is inside another loop in that list.' return isPathInsideLoops( loops[ : loopIndex ] + loops[loopIndex + 1 :], loops[loopIndex] ) def isLineIntersectingInsideXSegment( beginComplex, endComplex, segmentFirstX, segmentSecondX, y ): 'Determine if the line is crossing inside the x segment.' xIntersection = getXIntersectionIfExists( beginComplex, endComplex, y ) if xIntersection is None: return False if xIntersection < min( segmentFirstX, segmentSecondX ): return False return xIntersection <= max( segmentFirstX, segmentSecondX ) def isLineIntersectingLoop( loop, pointBegin, pointEnd ): 'Determine if the line is intersecting loops.' normalizedSegment = pointEnd - pointBegin normalizedSegmentLength = abs( normalizedSegment ) if normalizedSegmentLength > 0.0: normalizedSegment /= normalizedSegmentLength segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd if isLoopIntersectingInsideXSegment( loop, pointBeginRotated.real, pointEndRotated.real, segmentYMirror, pointBeginRotated.imag ): return True return False def isLineIntersectingLoops( loops, pointBegin, pointEnd ): 'Determine if the line is intersecting loops.' normalizedSegment = pointEnd - pointBegin normalizedSegmentLength = abs( normalizedSegment ) if normalizedSegmentLength > 0.0: normalizedSegment /= normalizedSegmentLength segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd if isLoopListIntersectingInsideXSegment( loops, pointBeginRotated.real, pointEndRotated.real, segmentYMirror, pointBeginRotated.imag ): return True return False def isLoopIntersectingInsideXSegment( loop, segmentFirstX, segmentSecondX, segmentYMirror, y ): 'Determine if the loop is intersecting inside the x segment.' rotatedLoop = getRotatedComplexes( segmentYMirror, loop ) for pointIndex in xrange( len( rotatedLoop ) ): pointFirst = rotatedLoop[pointIndex] pointSecond = rotatedLoop[ (pointIndex + 1) % len( rotatedLoop ) ] if isLineIntersectingInsideXSegment( pointFirst, pointSecond, segmentFirstX, segmentSecondX, y ): return True return False def isLoopIntersectingLoop( loop, otherLoop ): 'Determine if the loop is intersecting the other loop.' for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] if isLineIntersectingLoop( otherLoop, pointBegin, pointEnd ): return True return False def isLoopIntersectingLoops( loop, otherLoops ): 'Determine if the loop is intersecting other loops.' for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] if isLineIntersectingLoops( otherLoops, pointBegin, pointEnd ): return True return False def isLoopListIntersecting(loops): 'Determine if a loop in the list is intersecting the other loops.' for loopIndex in xrange(len(loops) - 1): loop = loops[loopIndex] if isLoopIntersectingLoops(loop, loops[loopIndex + 1 :]): return True return False def isLoopListIntersectingInsideXSegment( loopList, segmentFirstX, segmentSecondX, segmentYMirror, y ): 'Determine if the loop list is crossing inside the x segment.' for alreadyFilledLoop in loopList: if isLoopIntersectingInsideXSegment( alreadyFilledLoop, segmentFirstX, segmentSecondX, segmentYMirror, y ): return True return False def isPathEntirelyInsideLoop(loop, path): 'Determine if a path is entirely inside another loop.' for point in path: if not isPointInsideLoop(loop, point): return False return True def isPathEntirelyInsideLoops(loops, path): 'Determine if a path is entirely inside another loop in a list.' for loop in loops: if isPathEntirelyInsideLoop(loop, path): return True return False def isPathInsideLoop(loop, path): 'Determine if a path is inside another loop.' return isPointInsideLoop(loop, getLeftPoint(path)) def isPathInsideLoops(loops, path): 'Determine if a path is inside another loop in a list.' for loop in loops: if isPathInsideLoop(loop, path): return True return False def isPixelTableIntersecting( bigTable, littleTable, maskTable = {} ): 'Add path to the pixel table.' littleTableKeys = littleTable.keys() for littleTableKey in littleTableKeys: if littleTableKey not in maskTable: if littleTableKey in bigTable: return True return False def isPointInsideLoop(loop, point): 'Determine if a point is inside another loop.' return getNumberOfIntersectionsToLeft(loop, point) % 2 == 1 def isSegmentCompletelyInX( segment, xFirst, xSecond ): 'Determine if the segment overlaps within x.' segmentFirstX = segment[0].point.real segmentSecondX = segment[1].point.real if max( segmentFirstX, segmentSecondX ) > max( xFirst, xSecond ): return False return min( segmentFirstX, segmentSecondX ) >= min( xFirst, xSecond ) def isWiddershins(polygonComplex): 'Determine if the complex polygon goes round in the widdershins direction.' return getAreaLoop(polygonComplex) > 0.0 def isWithinChannel( channelRadius, pointIndex, loop ): 'Determine if the the point is within the channel between two adjacent points.' point = loop[pointIndex] behindSegmentComplex = loop[(pointIndex + len(loop) - 1) % len(loop)] - point behindSegmentComplexLength = abs( behindSegmentComplex ) if behindSegmentComplexLength < channelRadius: return True aheadSegmentComplex = loop[(pointIndex + 1) % len(loop)] - point aheadSegmentComplexLength = abs( aheadSegmentComplex ) if aheadSegmentComplexLength < channelRadius: return True behindSegmentComplex /= behindSegmentComplexLength aheadSegmentComplex /= aheadSegmentComplexLength absoluteZ = getDotProductPlusOne( aheadSegmentComplex, behindSegmentComplex ) if behindSegmentComplexLength * absoluteZ < channelRadius: return True return aheadSegmentComplexLength * absoluteZ < channelRadius def isXSegmentIntersectingPath( path, segmentFirstX, segmentSecondX, segmentYMirror, y ): 'Determine if a path is crossing inside the x segment.' rotatedPath = getRotatedComplexes( segmentYMirror, path ) for pointIndex in xrange( len( rotatedPath ) - 1 ): pointFirst = rotatedPath[pointIndex] pointSecond = rotatedPath[pointIndex + 1] if isLineIntersectingInsideXSegment( pointFirst, pointSecond, segmentFirstX, segmentSecondX, y ): return True return False def isXSegmentIntersectingPaths( paths, segmentFirstX, segmentSecondX, segmentYMirror, y ): 'Determine if a path list is crossing inside the x segment.' for path in paths: if isXSegmentIntersectingPath( path, segmentFirstX, segmentSecondX, segmentYMirror, y ): return True return False def joinSegmentTables( fromTable, intoTable ): 'Join both segment tables and put the join into the intoTable.' intoTableKeys = intoTable.keys() fromTableKeys = fromTable.keys() joinedKeyTable = {} concatenatedTableKeys = intoTableKeys + fromTableKeys for concatenatedTableKey in concatenatedTableKeys: joinedKeyTable[ concatenatedTableKey ] = None joinedKeys = joinedKeyTable.keys() joinedKeys.sort() for joinedKey in joinedKeys: xIntersectionIndexList = [] if joinedKey in intoTable: addXIntersectionIndexesFromSegments( 0, intoTable[ joinedKey ], xIntersectionIndexList ) if joinedKey in fromTable: addXIntersectionIndexesFromSegments( 1, fromTable[ joinedKey ], xIntersectionIndexList ) xIntersections = getJoinOfXIntersectionIndexes( xIntersectionIndexList ) lineSegments = getSegmentsFromXIntersections( xIntersections, joinedKey ) if len( lineSegments ) > 0: intoTable[ joinedKey ] = lineSegments else: print('This should never happen, there are no line segments in joinSegments in euclidean') def joinXIntersectionsTables( fromTable, intoTable ): 'Join both XIntersections tables and put the join into the intoTable.' joinedKeyTable = {} concatenatedTableKeys = fromTable.keys() + intoTable.keys() for concatenatedTableKey in concatenatedTableKeys: joinedKeyTable[ concatenatedTableKey ] = None for joinedKey in joinedKeyTable.keys(): xIntersectionIndexList = [] if joinedKey in intoTable: addXIntersectionIndexesFromXIntersections( 0, xIntersectionIndexList, intoTable[ joinedKey ] ) if joinedKey in fromTable: addXIntersectionIndexesFromXIntersections( 1, xIntersectionIndexList, fromTable[ joinedKey ] ) xIntersections = getJoinOfXIntersectionIndexes( xIntersectionIndexList ) if len( xIntersections ) > 0: intoTable[ joinedKey ] = xIntersections else: print('This should never happen, there are no line segments in joinSegments in euclidean') def overwriteDictionary(fromDictionary, keys, toDictionary): 'Overwrite the dictionary.' for key in keys: if key in fromDictionary: toDictionary[key] = fromDictionary[key] def removeElementFromDictionary(dictionary, key): 'Remove element from the dictionary.' if key in dictionary: del dictionary[key] def removeElementFromListTable(element, key, listDictionary): 'Remove an element from the list table.' if key not in listDictionary: return elementList = listDictionary[key] if len( elementList ) < 2: del listDictionary[key] return if element in elementList: elementList.remove(element) def removeElementFromPixelListFromPoint( element, pixelDictionary, point ): 'Remove an element from the pixel list.' stepKey = getStepKeyFromPoint(point) removeElementFromListTable( element, stepKey, pixelDictionary ) def removeElementsFromDictionary(dictionary, keys): 'Remove list from the dictionary.' for key in keys: removeElementFromDictionary(dictionary, key) def removePixelTableFromPixelTable( pixelDictionaryToBeRemoved, pixelDictionaryToBeRemovedFrom ): 'Remove pixel from the pixel table.' removeElementsFromDictionary( pixelDictionaryToBeRemovedFrom, pixelDictionaryToBeRemoved.keys() ) def removePrefixFromDictionary( dictionary, prefix ): 'Remove the attributes starting with the prefix from the dictionary.' for key in dictionary.keys(): if key.startswith( prefix ): del dictionary[key] def removeTrueFromDictionary(dictionary, key): 'Remove key from the dictionary in the value is true.' if key in dictionary: if getBooleanFromValue(dictionary[key]): del dictionary[key] def removeTrueListFromDictionary( dictionary, keys ): 'Remove list from the dictionary in the value is true.' for key in keys: removeTrueFromDictionary( dictionary, key ) def subtractXIntersectionsTable( subtractFromTable, subtractTable ): 'Subtract the subtractTable from the subtractFromTable.' subtractFromTableKeys = subtractFromTable.keys() subtractFromTableKeys.sort() for subtractFromTableKey in subtractFromTableKeys: xIntersectionIndexList = [] addXIntersectionIndexesFromXIntersections( - 1, xIntersectionIndexList, subtractFromTable[ subtractFromTableKey ] ) if subtractFromTableKey in subtractTable: addXIntersectionIndexesFromXIntersections( 0, xIntersectionIndexList, subtractTable[ subtractFromTableKey ] ) xIntersections = getXIntersectionsFromIntersections( xIntersectionIndexList ) if len( xIntersections ) > 0: subtractFromTable[ subtractFromTableKey ] = xIntersections else: del subtractFromTable[ subtractFromTableKey ] def swapList( elements, indexBegin, indexEnd ): 'Swap the list elements.' elements[ indexBegin ], elements[ indexEnd ] = elements[ indexEnd ], elements[ indexBegin ] def toggleHashtable( hashtable, key, value ): 'Toggle a hashtable between having and not having a key.' if key in hashtable: del hashtable[key] else: hashtable[key] = value def transferClosestFillLoop(extrusionHalfWidth, oldOrderedLocation, remainingFillLoops, skein): 'Transfer the closest remaining fill loop.' closestDistance = 987654321987654321.0 closestFillLoop = None for remainingFillLoop in remainingFillLoops: distance = getClosestDistanceIndexToLine(oldOrderedLocation.dropAxis(), remainingFillLoop).distance if distance < closestDistance: closestDistance = distance closestFillLoop = remainingFillLoop newClosestFillLoop = getLoopInsideContainingLoop(closestFillLoop, remainingFillLoops) while newClosestFillLoop is not None: closestFillLoop = newClosestFillLoop newClosestFillLoop = getLoopInsideContainingLoop(closestFillLoop, remainingFillLoops) remainingFillLoops.remove(closestFillLoop) addToThreadsFromLoop(extrusionHalfWidth, 'loop', closestFillLoop[:], oldOrderedLocation, skein) def transferClosestPath( oldOrderedLocation, remainingPaths, skein ): 'Transfer the closest remaining path.' closestDistance = 987654321987654321.0 closestPath = None oldOrderedLocationComplex = oldOrderedLocation.dropAxis() for remainingPath in remainingPaths: distance = min( abs( oldOrderedLocationComplex - remainingPath[0] ), abs( oldOrderedLocationComplex - remainingPath[-1] ) ) if distance < closestDistance: closestDistance = distance closestPath = remainingPath remainingPaths.remove( closestPath ) skein.addGcodeFromThreadZ( closestPath, oldOrderedLocation.z ) oldOrderedLocation.x = closestPath[-1].real oldOrderedLocation.y = closestPath[-1].imag def transferClosestPaths(oldOrderedLocation, remainingPaths, skein): 'Transfer the closest remaining paths.' while len(remainingPaths) > 0: transferClosestPath(oldOrderedLocation, remainingPaths, skein) def transferPathsToNestedRings(nestedRings, paths): 'Transfer paths to nested rings.' for nestedRing in nestedRings: nestedRing.transferPaths(paths) def translateVector3Path(path, translateVector3): 'Translate the vector3 path.' for point in path: point.setToVector3(point + translateVector3) def translateVector3Paths(paths, translateVector3): 'Translate the vector3 paths.' for path in paths: translateVector3Path(path, translateVector3) def unbuckleBasis( basis, maximumUnbuckling, normal ): 'Unbuckle space.' normalDot = basis.dot( normal ) dotComplement = math.sqrt( 1.0 - normalDot * normalDot ) unbuckling = maximumUnbuckling if dotComplement > 0.0: unbuckling = min( 1.0 / dotComplement, maximumUnbuckling ) basis.setToVector3( basis * unbuckling ) class DistanceIndex: 'A class to hold the distance and the index of the loop.' def __init__( self, distance, index ): 'Initialize.' self.distance = distance self.index = index def __repr__(self): 'Get the string representation of this distance index.' return '%s, %s' % ( self.distance, self.index ) class Endpoint: 'The endpoint of a segment.' def __repr__(self): 'Get the string representation of this Endpoint.' return 'Endpoint %s, %s' % ( self.point, self.otherEndpoint.point ) def getClosestEndpoint( self, endpoints ): 'Get closest endpoint.' smallestDistance = 987654321987654321.0 closestEndpoint = None for endpoint in endpoints: distance = abs( self.point - endpoint.point ) if distance < smallestDistance: smallestDistance = distance closestEndpoint = endpoint return closestEndpoint def getClosestMiss(self, endpoints, path, pixelDictionary, width): 'Get the closest endpoint which the segment to that endpoint misses the other extrusions.' pathMaskTable = {} smallestDistance = 987654321.0 penultimateMinusPoint = complex(0.0, 0.0) if len(path) > 1: penultimatePoint = path[-2] addSegmentToPixelTable(penultimatePoint, self.point, pathMaskTable, 0, 0, width) penultimateMinusPoint = penultimatePoint - self.point if abs(penultimateMinusPoint) > 0.0: penultimateMinusPoint /= abs(penultimateMinusPoint) for endpoint in endpoints: endpoint.segment = endpoint.point - self.point endpoint.segmentLength = abs(endpoint.segment) if endpoint.segmentLength <= 0.0: # print('This should never happen, the endpoints are touching') # print( endpoint ) # print(path) return endpoint endpoints.sort(compareSegmentLength) for endpoint in endpoints[: 15]: # increasing the number of searched endpoints increases the search time, with 20 fill took 600 seconds for cilinder.gts, with 10 fill took 533 seconds normalizedSegment = endpoint.segment / endpoint.segmentLength isOverlappingSelf = getDotProduct(penultimateMinusPoint, normalizedSegment) > 0.9 if not isOverlappingSelf: if len(path) > 2: segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointRotated = segmentYMirror * self.point endpointPointRotated = segmentYMirror * endpoint.point if isXSegmentIntersectingPath(path[max(0, len(path) - 21) : -1], pointRotated.real, endpointPointRotated.real, segmentYMirror, pointRotated.imag): isOverlappingSelf = True if not isOverlappingSelf: totalMaskTable = pathMaskTable.copy() addSegmentToPixelTable(endpoint.point, endpoint.otherEndpoint.point, totalMaskTable, 0, 0, width) segmentTable = {} addSegmentToPixelTable(self.point, endpoint.point, segmentTable, 0, 0, width) if not isPixelTableIntersecting(pixelDictionary, segmentTable, totalMaskTable): return endpoint return None def getClosestMissCheckEndpointPath( self, endpoints, path, pixelDictionary, width ): 'Get the closest endpoint which the segment to that endpoint misses the other extrusions, also checking the path of the endpoint.' pathMaskTable = {} smallestDistance = 987654321.0 penultimateMinusPoint = complex(0.0, 0.0) if len(path) > 1: penultimatePoint = path[-2] addSegmentToPixelTable( penultimatePoint, self.point, pathMaskTable, 0, 0, width ) penultimateMinusPoint = penultimatePoint - self.point if abs(penultimateMinusPoint) > 0.0: penultimateMinusPoint /= abs(penultimateMinusPoint) for endpoint in endpoints: endpoint.segment = endpoint.point - self.point endpoint.segmentLength = abs(endpoint.segment) if endpoint.segmentLength <= 0.0: # print('This should never happen, the endpoints are touching') # print( endpoint ) # print(path) return endpoint endpoints.sort( compareSegmentLength ) for endpoint in endpoints[ : 15 ]: # increasing the number of searched endpoints increases the search time, with 20 fill took 600 seconds for cilinder.gts, with 10 fill took 533 seconds normalizedSegment = endpoint.segment / endpoint.segmentLength isOverlappingSelf = getDotProduct( penultimateMinusPoint, normalizedSegment ) > 0.9 if not isOverlappingSelf: if len(path) > 2: segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointRotated = segmentYMirror * self.point endpointPointRotated = segmentYMirror * endpoint.point if isXSegmentIntersectingPath( path[ max( 0, len(path) - 21 ) : - 1 ], pointRotated.real, endpointPointRotated.real, segmentYMirror, pointRotated.imag ): isOverlappingSelf = True endpointPath = endpoint.path if len( endpointPath ) > 2: segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointRotated = segmentYMirror * self.point endpointPointRotated = segmentYMirror * endpoint.point if isXSegmentIntersectingPath( endpointPath, pointRotated.real, endpointPointRotated.real, segmentYMirror, pointRotated.imag ): isOverlappingSelf = True if not isOverlappingSelf: totalMaskTable = pathMaskTable.copy() addSegmentToPixelTable( endpoint.point, endpoint.otherEndpoint.point, totalMaskTable, 0, 0, width ) segmentTable = {} addSegmentToPixelTable( self.point, endpoint.point, segmentTable, 0, 0, width ) if not isPixelTableIntersecting( pixelDictionary, segmentTable, totalMaskTable ): return endpoint return None def getFromOtherPoint( self, otherEndpoint, point ): 'Initialize from other endpoint.' self.otherEndpoint = otherEndpoint self.point = point return self class LoopLayer: 'Loops with a z.' def __init__(self, z): 'Initialize.' self.loops = [] self.z = z def __repr__(self): 'Get the string representation of this loop layer.' return '%s, %s' % ( self.z, self.loops ) class NestedRing: 'A nested ring.' def __init__(self): 'Initialize.' self.boundary = [] self.innerNestedRings = None def __repr__(self): 'Get the string representation of this nested ring.' return str(self.__dict__) def addFlattenedNestedRings(self, flattenedNestedRings): 'Add flattened nested rings.' flattenedNestedRings.append(self) for innerNestedRing in self.innerNestedRings: flattenedNestedRings += getFlattenedNestedRings(innerNestedRing.innerNestedRings) def getFromInsideSurroundings(self, inputSurroundingInsides): 'Initialize from inside nested rings.' transferredSurroundings = getTransferredNestedRings(inputSurroundingInsides, self.boundary) self.innerNestedRings = getOrderedNestedRings(transferredSurroundings) return self class NestedBand(NestedRing): 'A loop that surrounds paths.' def __init__(self): 'Initialize.' NestedRing.__init__(self) self.extraLoops = [] self.infillBoundaries = [] self.infillPaths = [] # self.lastExistingFillLoops = None self.lastFillLoops = None self.loop = None self.penultimateFillLoops = [] self.perimeterPaths = [] self.z = None def __repr__(self): 'Get the string representation of this nested ring.' stringRepresentation = 'boundary\n%s\n' % self.boundary stringRepresentation += 'loop\n%s\n' % self.loop stringRepresentation += 'inner nested rings\n%s\n' % self.innerNestedRings stringRepresentation += 'infillPaths\n' for infillPath in self.infillPaths: stringRepresentation += 'infillPath\n%s\n' % infillPath stringRepresentation += 'perimeterPaths\n' for perimeterPath in self.perimeterPaths: stringRepresentation += 'perimeterPath\n%s\n' % perimeterPath return stringRepresentation + '\n' def addPerimeterInner(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence): 'Add to the perimeter and the inner island.' if self.loop is None: skein.distanceFeedRate.addLine('()') transferClosestPaths(oldOrderedLocation, self.perimeterPaths[:], skein) skein.distanceFeedRate.addLine('()') else: addToThreadsFromLoop(extrusionHalfWidth, 'perimeter', self.loop[:], oldOrderedLocation, skein) skein.distanceFeedRate.addLine('()') addToThreadsRemove(extrusionHalfWidth, self.innerNestedRings[:], oldOrderedLocation, skein, threadSequence) def addToBoundary(self, vector3): 'Add vector3 to boundary.' self.boundary.append(vector3.dropAxis()) self.z = vector3.z def addToLoop(self, vector3): 'Add vector3 to loop.' if self.loop is None: self.loop = [] self.loop.append(vector3.dropAxis()) self.z = vector3.z def addToThreads(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence): 'Add to paths from the last location. perimeter>inner >fill>paths or fill> perimeter>inner >paths' addNestedRingBeginning(skein.distanceFeedRate, self.boundary, self.z) threadFunctionDictionary = { 'infill' : self.transferInfillPaths, 'loops' : self.transferClosestFillLoops, 'perimeter' : self.addPerimeterInner} for threadType in threadSequence: threadFunctionDictionary[threadType](extrusionHalfWidth, oldOrderedLocation, skein, threadSequence) skein.distanceFeedRate.addLine('()') def getFillLoops(self, penultimateFillLoops): 'Get last fill loops from the outside loop and the loops inside the inside loops.' fillLoops = self.getLoopsToBeFilled()[:] surroundingBoundaries = self.getSurroundingBoundaries() withinLoops = [] if penultimateFillLoops is None: penultimateFillLoops = self.penultimateFillLoops if penultimateFillLoops is None: print('Warning, penultimateFillLoops is None in getFillLoops in NestedBand in euclidean.') return fillLoops for penultimateFillLoop in penultimateFillLoops: if len(penultimateFillLoop) > 2: if getIsInFilledRegion(surroundingBoundaries, penultimateFillLoop[0]): withinLoops.append(penultimateFillLoop) if not getIsInFilledRegionByPaths(self.penultimateFillLoops, fillLoops): fillLoops += self.penultimateFillLoops for nestedRing in self.innerNestedRings: fillLoops += getFillOfSurroundings(nestedRing.innerNestedRings, penultimateFillLoops) return fillLoops # # def getLastExistingFillLoops(self): # 'Get last existing fill loops.' # lastExistingFillLoops = self.lastExistingFillLoops[:] # for nestedRing in self.innerNestedRings: # lastExistingFillLoops += nestedRing.getLastExistingFillLoops() # return lastExistingFillLoops def getLoopsToBeFilled(self): 'Get last fill loops from the outside loop and the loops inside the inside loops.' if self.lastFillLoops is None: return self.getSurroundingBoundaries() return self.lastFillLoops def getSurroundingBoundaries(self): 'Get the boundary of the surronding loop plus any boundaries of the innerNestedRings.' surroundingBoundaries = [self.boundary] for nestedRing in self.innerNestedRings: surroundingBoundaries.append(nestedRing.boundary) return surroundingBoundaries def transferClosestFillLoops(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence): 'Transfer closest fill loops.' if len( self.extraLoops ) < 1: return remainingFillLoops = self.extraLoops[:] while len( remainingFillLoops ) > 0: transferClosestFillLoop(extrusionHalfWidth, oldOrderedLocation, remainingFillLoops, skein) def transferInfillPaths(self, extrusionHalfWidth, oldOrderedLocation, skein, threadSequence): 'Transfer the infill paths.' if len(self.infillBoundaries) == 0 and len(self.infillPaths) == 0: return skein.distanceFeedRate.addLine('()') for infillBoundary in self.infillBoundaries: skein.distanceFeedRate.addLine('()') for infillPoint in infillBoundary: infillPointVector3 = Vector3(infillPoint.real, infillPoint.imag, self.z) skein.distanceFeedRate.addLine(skein.distanceFeedRate.getInfillBoundaryLine(infillPointVector3)) skein.distanceFeedRate.addLine('()') transferClosestPaths(oldOrderedLocation, self.infillPaths[:], skein) skein.distanceFeedRate.addLine('()') def transferPaths(self, paths): 'Transfer paths.' for nestedRing in self.innerNestedRings: transferPathsToNestedRings(nestedRing.innerNestedRings, paths) self.infillPaths = getTransferredPaths(paths, self.boundary) class PathZ: 'Complex path with a z.' def __init__( self, z ): self.path = [] self.z = z def __repr__(self): 'Get the string representation of this path z.' return '%s, %s' % ( self.z, self.path ) class ProjectiveSpace: 'Class to define a projective space.' def __init__( self, basisX = Vector3(1.0, 0.0, 0.0), basisY = Vector3( 0.0, 1.0, 0.0 ), basisZ = Vector3(0.0, 0.0, 1.0) ): 'Initialize the basis vectors.' self.basisX = basisX self.basisY = basisY self.basisZ = basisZ def __repr__(self): 'Get the string representation of this ProjectivePlane.' return '%s, %s, %s' % ( self.basisX, self.basisY, self.basisZ ) def getByBasisXZ( self, basisX, basisZ ): 'Get by x basis x and y basis.' self.basisX = basisX self.basisZ = basisZ self.basisX.normalize() self.basisY = basisZ.cross(self.basisX) self.basisY.normalize() return self def getByBasisZFirst(self, basisZ, firstVector3): 'Get by basisZ and first.' self.basisZ = basisZ self.basisY = basisZ.cross(firstVector3) self.basisY.normalize() self.basisX = self.basisY.cross(self.basisZ) self.basisX.normalize() return self def getByBasisZTop(self, basisZ, top): 'Get by basisZ and top.' return self.getByBasisXZ(top.cross(basisZ), basisZ) def getByLatitudeLongitude( self, viewpointLatitude, viewpointLongitude ): 'Get by latitude and longitude.' longitudeComplex = getWiddershinsUnitPolar( math.radians( 90.0 - viewpointLongitude ) ) viewpointLatitudeRatio = getWiddershinsUnitPolar( math.radians( viewpointLatitude ) ) basisZ = Vector3( viewpointLatitudeRatio.imag * longitudeComplex.real, viewpointLatitudeRatio.imag * longitudeComplex.imag, viewpointLatitudeRatio.real ) return self.getByBasisXZ( Vector3( - longitudeComplex.imag, longitudeComplex.real, 0.0 ), basisZ ) def getByTilt( self, tilt ): 'Get by latitude and longitude.' xPlaneAngle = getWiddershinsUnitPolar( tilt.real ) self.basisX = Vector3( xPlaneAngle.real, 0.0, xPlaneAngle.imag ) yPlaneAngle = getWiddershinsUnitPolar( tilt.imag ) self.basisY = Vector3( 0.0, yPlaneAngle.real, yPlaneAngle.imag ) self.basisZ = self.basisX.cross(self.basisY) return self def getComplexByComplex( self, pointComplex ): 'Get complex by complex point.' return self.basisX.dropAxis() * pointComplex.real + self.basisY.dropAxis() * pointComplex.imag def getCopy(self): 'Get copy.' return ProjectiveSpace( self.basisX, self.basisY, self.basisZ ) def getDotComplex(self, point): 'Get the dot complex.' return complex( point.dot(self.basisX), point.dot(self.basisY) ) def getDotVector3(self, point): 'Get the dot vector3.' return Vector3(point.dot(self.basisX), point.dot(self.basisY), point.dot(self.basisZ)) def getNextSpace( self, nextNormal ): 'Get next space by next normal.' nextSpace = self.getCopy() nextSpace.normalize() dotNext = nextSpace.basisZ.dot( nextNormal ) if dotNext > 0.999999: return nextSpace if dotNext < - 0.999999: nextSpace.basisX = - nextSpace.basisX return nextSpace crossNext = nextSpace.basisZ.cross( nextNormal ) oldBasis = ProjectiveSpace().getByBasisZTop( nextSpace.basisZ, crossNext ) newBasis = ProjectiveSpace().getByBasisZTop( nextNormal, crossNext ) nextSpace.basisX = newBasis.getVector3ByPoint( oldBasis.getDotVector3( nextSpace.basisX ) ) nextSpace.basisY = newBasis.getVector3ByPoint( oldBasis.getDotVector3( nextSpace.basisY ) ) nextSpace.basisZ = newBasis.getVector3ByPoint( oldBasis.getDotVector3( nextSpace.basisZ ) ) nextSpace.normalize() return nextSpace def getSpaceByXYScaleAngle( self, angle, scale ): 'Get space by angle and scale.' spaceByXYScaleRotation = ProjectiveSpace() planeAngle = getWiddershinsUnitPolar(angle) spaceByXYScaleRotation.basisX = self.basisX * scale.real * planeAngle.real + self.basisY * scale.imag * planeAngle.imag spaceByXYScaleRotation.basisY = - self.basisX * scale.real * planeAngle.imag + self.basisY * scale.imag * planeAngle.real spaceByXYScaleRotation.basisZ = self.basisZ return spaceByXYScaleRotation def getVector3ByPoint(self, point): 'Get vector3 by point.' return self.basisX * point.x + self.basisY * point.y + self.basisZ * point.z def normalize(self): 'Normalize.' self.basisX.normalize() self.basisY.normalize() self.basisZ.normalize() def unbuckle( self, maximumUnbuckling, normal ): 'Unbuckle space.' unbuckleBasis( self.basisX, maximumUnbuckling, normal ) unbuckleBasis( self.basisY, maximumUnbuckling, normal ) class XIntersectionIndex: 'A class to hold the x intersection position and the index of the loop which intersected.' def __init__( self, index, x ): 'Initialize.' self.index = index self.x = x def __cmp__(self, other): 'Get comparison in order to sort x intersections in ascending order of x.' if self.x < other.x: return - 1 return int( self.x > other.x ) def __eq__(self, other): 'Determine whether this XIntersectionIndex is identical to other one.' if other is None: return False if other.__class__ != self.__class__: return False return self.index == other.index and self.x == other.x def __ne__(self, other): 'Determine whether this XIntersectionIndex is not identical to other one.' return not self.__eq__(other) def __repr__(self): 'Get the string representation of this x intersection.' return 'XIntersectionIndex index %s; x %s ' % ( self.index, self.x ) sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/000077500000000000000000000000001167321211700227715ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/__init__.py000066400000000000000000000006571167321211700251120ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 2 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/alphabetize.py000066400000000000000000000163471167321211700256460ustar00rootroot00000000000000""" Alphabetize is a script to alphabetize functions and signatures. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive import cStringIO import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addTogetherList(functionList, togetherLists): 'Add the togetherList to the togetherLists is the sorted is different.' sortedList = functionList[:] sortedList.sort(compareFunctionName) togetherList = None for functionIndex in xrange(len(functionList)): function = functionList[functionIndex] sorted = sortedList[functionIndex] if function != sorted: together = (function, sorted) if togetherList is None: togetherList = [] togetherLists.append(togetherList) togetherList.append(together) def compareFunctionName(first, second): 'Compare the function names.' first = getConvertedName(first) second = getConvertedName(second) if first < second: return -1 return first < second def getConvertedName(name): 'Get converted name with init at the beginning and main at the endCompare the function names.' if name == 'def __init__': return 'def !__init__' if name == 'def main': return 'def |main' return name.lower() def getFunctionLists(fileName): 'Get the function lists in the file.' fileText = archive.getFileText(fileName) functionList = [] functionLists = [functionList] lines = archive.getTextLines(fileText) for line in lines: lineStripped = line.strip() if lineStripped.startswith('def '): bracketIndex = lineStripped.find('(') if bracketIndex > -1: lineStripped = lineStripped[: bracketIndex] functionList.append(lineStripped) elif line.startswith('class'): functionList = [] functionLists.append(functionList) return functionLists def getFunctionsWithStringByFileName(fileName, searchString): 'Get the functions with the search string in the file.' fileText = archive.getFileText(fileName) functions = [] lines = archive.getTextLines(fileText) for line in lines: lineStripped = line.strip() # if lineStripped.startswith('def ') and searchString in lineStripped and '=' in lineStripped: if lineStripped.startswith('def ') and searchString in lineStripped: if '(self, ' not in lineStripped or lineStripped.count(',') > 1: functions.append(lineStripped[len('def ') :].strip()) functions.sort() return functions def getFunctionsWithStringByFileNames(fileNames, searchString): 'Get the functions with the search string in the files.' functions = [] for fileName in fileNames: functions += getFunctionsWithStringByFileName(fileName, searchString) functions.sort() return functions def getParameterSequence(functionName): 'Get the parameter sequence.' parameterDictionary = {} parameterSequence = [] parameterText = functionName[functionName.find('(') + 1 :].replace('xmlElement', 'elementNode') snippet = Snippet(0, parameterText) strippedParameters = [] for parameter in snippet.parameters: strippedParameter = parameter.strip() if strippedParameter != 'self': strippedParameters.append(strippedParameter) for parameterIndex, parameter in enumerate(strippedParameters): parameterDictionary[parameter] = parameterIndex sortedParameters = strippedParameters[:] sortedParameters.sort() for sortedParameter in sortedParameters: parameterSequence.append(parameterDictionary[sortedParameter]) return parameterSequence def getSnippetsByFileName(fileName, functionName): 'Get the function signature snippets by the file name.' fileText = archive.getFileText(fileName) snippets = [] functionStart = functionName[: functionName.find('(') + 1] tokenEnd = getTokenEnd(0, fileText, functionStart) while tokenEnd != -1: snippet = Snippet(tokenEnd, fileText) snippets.append(snippet) tokenEnd = getTokenEnd(snippet.characterIndex, fileText, functionStart) return snippets def getTogetherLists(fileName): 'Get the lists of the unsorted and sorted functions in the file.' functionLists = getFunctionLists(fileName) togetherLists = [] for functionList in functionLists: addTogetherList(functionList, togetherLists) return togetherLists def getTokenEnd(characterIndex, fileText, token): 'Get the token end index for the file text and token.' tokenIndex = fileText.find(token, characterIndex) if tokenIndex == -1: return -1 return tokenIndex + len(token) def printTogetherListsByFileNames(fileNames): 'Print the together lists of the file names, if the file name has a together list.' for fileName in fileNames: togetherLists = getTogetherLists(fileName) if len(togetherLists) > 0: for togetherList in togetherLists: for together in togetherList: function = together[0] sorted = together[1] return class EndCharacterMonad: 'A monad to return the parent monad when it encounters the end character.' def __init__(self, endCharacter, parentMonad): 'Initialize.' self.endCharacter = endCharacter self.parentMonad = parentMonad def getNextMonad(self, character): 'Get the next monad.' self.getSnippet().input.write(character) if character == self.endCharacter: return self.parentMonad return self def getSnippet(self): 'Get the snippet.' return self.parentMonad.getSnippet() class ParameterMonad: 'A monad to handle parameters.' def __init__(self, snippet): 'Initialize.' self.snippet = snippet def addParameter(self): 'Add parameter to the snippet.' parameterString = self.snippet.input.getvalue() if len(parameterString) != 0: self.snippet.input = cStringIO.StringIO() self.snippet.parameters.append(parameterString) def getNextMonad(self, character): 'Get the next monad.' if character == '"': self.snippet.input.write(character) return EndCharacterMonad('"', self) if character == '"': self.snippet.input.write(character) return EndCharacterMonad('"', self) if character == '(': self.snippet.input.write(character) return EndCharacterMonad(')', self) if character == ')': self.addParameter() return None if character == ',': self.addParameter() return self self.snippet.input.write(character) return self def getSnippet(self): 'Get the snippet.' return self.snippet class Snippet: 'A class to get the variables for a function.' def __init__(self, characterIndex, fileText): 'Initialize.' self.characterIndex = characterIndex self.input = cStringIO.StringIO() self.parameters = [] monad = ParameterMonad(self) for characterIndex in xrange(self.characterIndex, len(fileText)): character = fileText[characterIndex] monad = monad.getNextMonad(character) if monad is None: return def __repr__(self): 'Get the string representation of this Snippet.' return '%s %s' % (self.characterIndex, self.parameters) def main(): 'Run main function.' # printTogetherListsByFileNames(archive.getPythonFileNamesExceptInitRecursively('/home/enrique/Desktop/fabmetheus')) functions = getFunctionsWithStringByFileNames(archive.getPythonFileNamesExceptInitRecursively('/home/enrique/Desktop/fabmetheus'), ', xmlElement') print(functions) if __name__ == "__main__": main() sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/fabmetheus_interpret.py000066400000000000000000000131331167321211700275630ustar00rootroot00000000000000""" Fabmetheus interpret is a fabmetheus utility to interpret a file, turning it into fabmetheus constructive solid geometry xml. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import os import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCarving(fileName): "Get carving." pluginModule = getInterpretPlugin(fileName) if pluginModule is None: return None return pluginModule.getCarving(fileName) def getGNUTranslatorFilesUnmodified(): "Get the file types from the translators in the import plugins folder." return archive.getFilesWithFileTypesWithoutWords(getImportPluginFileNames()) def getGNUTranslatorGcodeFileTypeTuples(): "Get the file type tuples from the translators in the import plugins folder plus gcode." fileTypeTuples = getTranslatorFileTypeTuples() fileTypeTuples.append( ('Gcode text files', '*.gcode') ) fileTypeTuples.sort() return fileTypeTuples def getImportPluginFileNames(): "Get interpret plugin fileNames." return archive.getPluginFileNamesFromDirectoryPath( getPluginsDirectoryPath() ) def getInterpretPlugin(fileName): "Get the interpret plugin for the file." importPluginFileNames = getImportPluginFileNames() for importPluginFileName in importPluginFileNames: fileTypeDot = '.' + importPluginFileName if fileName[ - len(fileTypeDot) : ].lower() == fileTypeDot: importPluginsDirectoryPath = getPluginsDirectoryPath() pluginModule = archive.getModuleWithDirectoryPath( importPluginsDirectoryPath, importPluginFileName ) if pluginModule is not None: return pluginModule print('Could not find plugin to handle ' + fileName ) return None def getNewRepository(): 'Get new repository.' return InterpretRepository() def getPluginsDirectoryPath(): "Get the plugins directory path." return archive.getInterpretPluginsPath() def getTranslatorFileTypeTuples(): "Get the file types from the translators in the import plugins folder." importPluginFileNames = getImportPluginFileNames() fileTypeTuples = [] for importPluginFileName in importPluginFileNames: fileTypeTitle = importPluginFileName.upper() + ' files' fileType = ( fileTypeTitle, '*.' + importPluginFileName ) fileTypeTuples.append( fileType ) fileTypeTuples.sort() return fileTypeTuples def getWindowAnalyzeFile(fileName): "Get file interpretion." startTime = time.time() carving = getCarving(fileName) if carving is None: return None interpretGcode = str( carving ) if interpretGcode == '': return None repository = settings.getReadRepository( InterpretRepository() ) if repository.printInterpretion.value: print( interpretGcode ) suffixFileName = fileName[ : fileName.rfind('.') ] + '_interpret.' + carving.getInterpretationSuffix() suffixDirectoryName = os.path.dirname(suffixFileName) suffixReplacedBaseName = os.path.basename(suffixFileName).replace(' ', '_') suffixFileName = os.path.join( suffixDirectoryName, suffixReplacedBaseName ) archive.writeFileText( suffixFileName, interpretGcode ) print('The interpret file is saved as ' + archive.getSummarizedFileName(suffixFileName) ) print('It took %s to interpret the file.' % euclidean.getDurationString( time.time() - startTime ) ) textProgram = repository.textProgram.value if textProgram == '': return None if textProgram == 'webbrowser': settings.openWebPage(suffixFileName) return None textFilePath = '"' + os.path.normpath(suffixFileName) + '"' # " to send in file name with spaces shellCommand = textProgram + ' ' + textFilePath print('Sending the shell command:') print(shellCommand) commandResult = os.system(shellCommand) if commandResult != 0: print('It may be that the system could not find the %s program.' % textProgram ) print('If so, try installing the %s program or look for another one, like Open Office which can be found at:' % textProgram ) print('http://www.openoffice.org/') print('Open office writer can then be started from the command line with the command "soffice -writer".') class InterpretRepository: "A class to handle the interpret settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.analyze_plugins.interpret.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Interpret', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Interpret') self.activateInterpret = settings.BooleanSetting().getFromValue('Activate Interpret', self, False ) self.printInterpretion = settings.BooleanSetting().getFromValue('Print Interpretion', self, False ) self.textProgram = settings.StringSetting().getFromValue('Text Program:', self, 'webbrowser') self.executeTitle = 'Interpret' def execute(self): "Write button has been clicked." fileNames = skeinforge_polyfile.getFileOrGcodeDirectory( self.fileNameInput.value, self.fileNameInput.wasCancelled ) for fileName in fileNames: getWindowAnalyzeFile(fileName) sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/000077500000000000000000000000001167321211700265465ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/__init__.py000066400000000000000000000007351167321211700306640ustar00rootroot00000000000000""" This page is in the table of contents. This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. """ import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/csv.py000066400000000000000000000132531167321211700277170ustar00rootroot00000000000000""" This page is in the table of contents. The csv.py script is an import translator plugin to get a carving from an csv file. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an csv file and returns the carving. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import xml_simple_reader import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCarving(fileName=''): "Get the carving for the csv file." csvText = archive.getFileText(fileName) if csvText == '': return None csvParser = CSVSimpleParser( fileName, None, csvText ) lowerLocalName = csvParser.getDocumentElement().getNodeName().lower() pluginModule = archive.getModuleWithDirectoryPath( getPluginsDirectoryPath(), lowerLocalName ) if pluginModule is None: return None return pluginModule.getCarvingFromParser( csvParser ) def getLineDictionary(line): "Get the line dictionary." lineDictionary = {} splitLine = line.split('\t') for splitLineIndex in xrange( len(splitLine) ): word = splitLine[ splitLineIndex ] if word != '': lineDictionary[ splitLineIndex ] = word return lineDictionary def getPluginsDirectoryPath(): "Get the plugins directory path." return archive.getInterpretPluginsPath('xml_plugins') class CSVElement( xml_simple_reader.XMLElement ): "A csv element." def continueParsingObject( self, line, lineStripped ): "Parse replaced line." splitLineStripped = lineStripped.split('\t') key = splitLineStripped[0] value = splitLineStripped[1] self.attributes[key] = value self.addToIdentifierDictionaries() def continueParsingTable( self, line, lineStripped ): "Parse replaced line." if self.headingDictionary is None: self.headingDictionary = getLineDictionary(line) return csvElement = self oldAttributesLength = len( self.attributes ) if oldAttributesLength > 0: csvElement = CSVElement() csvElement.parentNode = self.parentNode csvElement.localName = self.localName lineDictionary = getLineDictionary(line) for columnIndex in lineDictionary.keys(): if columnIndex in self.headingDictionary: key = self.headingDictionary[ columnIndex ] value = lineDictionary[ columnIndex ] csvElement.attributes[key] = value csvElement.addToIdentifierDictionaries() if len( csvElement.attributes ) == 0 or oldAttributesLength == 0 or self.parentNode is None: return self.parentNode.childNodes.append( csvElement ) def getElementFromObject( self, leadingTabCount, lineStripped, oldElement ): "Parse replaced line." splitLine = lineStripped.split('\t') self.localName = splitLine[1] if leadingTabCount == 0: return self self.parentNode = oldElement while leadingTabCount <= self.parentNode.getNumberOfParents(): self.parentNode = self.parentNode.parentNode self.parentNode.childNodes.append(self) return self def getElementFromTable( self, leadingTabCount, lineStripped, oldElement ): "Parse replaced line." self.headingDictionary = None return self.getElementFromObject( leadingTabCount, lineStripped, oldElement ) def getNumberOfParents(self): "Get the number of parent nodes." if self.parentNode is None: return 0 return self.parentNode.getNumberOfParents() + 1 class CSVSimpleParser( xml_simple_reader.DocumentNode ): "A simple csv parser." def __init__( self, parentNode, csvText ): "Add empty lists." self.continueFunction = None self.extraLeadingTabCount = None self.lines = archive.getTextLines( csvText ) self.oldCSVElement = None self.documentElement = None for line in self.lines: self.parseLine(line) def getNewCSVElement( self, leadingTabCount, lineStripped ): "Get a new csv element." if self.documentElement is not None and self.extraLeadingTabCount is None: self.extraLeadingTabCount = 1 - leadingTabCount if self.extraLeadingTabCount is not None: leadingTabCount += self.extraLeadingTabCount if lineStripped[ : len('_table') ] == '_table' or lineStripped[ : len('_t') ] == '_t': self.oldCSVElement = CSVElement().getElementFromTable( leadingTabCount, lineStripped, self.oldCSVElement ) self.continueFunction = self.oldCSVElement.continueParsingTable return self.oldCSVElement = CSVElement().getElementFromObject( leadingTabCount, lineStripped, self.oldCSVElement ) self.continueFunction = self.oldCSVElement.continueParsingObject def parseLine(self, line): "Parse a gcode line and add it to the inset skein." lineStripped = line.lstrip() if len( lineStripped ) < 1: return leadingPart = line[ : line.find( lineStripped ) ] leadingTabCount = leadingPart.count('\t') if lineStripped[ : len('_') ] == '_': self.getNewCSVElement( leadingTabCount, lineStripped ) if self.documentElement is None: self.documentElement = self.oldCSVElement self.documentElement.document = self return if self.continueFunction is not None: self.continueFunction( line, lineStripped ) def main(): "Display the inset dialog." if len(sys.argv) > 1: getCarving(' '.join(sys.argv[1 :])) if __name__ == "__main__": main() sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/gts.py000066400000000000000000000101721167321211700277160ustar00rootroot00000000000000""" This page is in the table of contents. The gts.py script is an import translator plugin to get a carving from an gts file. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an gts file and returns the carving. The GNU Triangulated Surface (.gts) format is described at: http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE Quoted from http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE "All the lines beginning with GTS_COMMENTS (#!) are ignored. The first line contains three unsigned integers separated by spaces. The first integer is the number of vertexes, nv, the second is the number of edges, ne and the third is the number of faces, nf. Follows nv lines containing the x, y and z coordinates of the vertexes. Follows ne lines containing the two indices (starting from one) of the vertexes of each edge. Follows nf lines containing the three ordered indices (also starting from one) of the edges of each face. The format described above is the least common denominator to all GTS files. Consistent with an object-oriented approach, the GTS file format is extensible. Each of the lines of the file can be extended with user-specific attributes accessible through the read() and write() virtual methods of each of the objects written (surface, vertexes, edges or faces). When read with different object classes, these extra attributes are just ignored." """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import face from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCarving(fileName): "Get the carving for the gts file." return getFromGNUTriangulatedSurfaceText( archive.getFileText(fileName), triangle_mesh.TriangleMesh() ) def getFromGNUTriangulatedSurfaceText( gnuTriangulatedSurfaceText, triangleMesh ): "Initialize from a GNU Triangulated Surface Text." if gnuTriangulatedSurfaceText == '': return None lines = archive.getTextLines( gnuTriangulatedSurfaceText ) linesWithoutComments = [] for line in lines: if len(line) > 0: firstCharacter = line[0] if firstCharacter != '#' and firstCharacter != '!': linesWithoutComments.append(line) splitLine = linesWithoutComments[0].split() numberOfVertexes = int( splitLine[0] ) numberOfEdges = int(splitLine[1]) numberOfFaces = int( splitLine[2] ) faceTriples = [] for vertexIndex in xrange( numberOfVertexes ): line = linesWithoutComments[ vertexIndex + 1 ] splitLine = line.split() vertex = Vector3( float( splitLine[0] ), float(splitLine[1]), float( splitLine[2] ) ) triangleMesh.vertexes.append(vertex) edgeStart = numberOfVertexes + 1 for edgeIndex in xrange( numberOfEdges ): line = linesWithoutComments[ edgeIndex + edgeStart ] splitLine = line.split() vertexIndexes = [] for word in splitLine[ : 2 ]: vertexIndexes.append( int(word) - 1 ) edge = face.Edge().getFromVertexIndexes( edgeIndex, vertexIndexes ) triangleMesh.edges.append( edge ) faceStart = edgeStart + numberOfEdges for faceIndex in xrange( numberOfFaces ): line = linesWithoutComments[ faceIndex + faceStart ] splitLine = line.split() edgeIndexes = [] for word in splitLine[ : 3 ]: edgeIndexes.append( int(word) - 1 ) triangleMesh.faces.append( face.Face().getFromEdgeIndexes( edgeIndexes, triangleMesh.edges, faceIndex ) ) return triangleMesh sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/obj.py000066400000000000000000000060251167321211700276750ustar00rootroot00000000000000""" This page is in the table of contents. The obj.py script is an import translator plugin to get a carving from an obj file. An example obj file is box.obj in the models folder. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an obj file and returns the carving. From wikipedia, OBJ (or .OBJ) is a geometry definition file format first developed by Wavefront Technologies for its Advanced Visualizer animation package: http://en.wikipedia.org/wiki/Obj The Object File specification is at: http://local.wasp.uwa.edu.au/~pbourke/dataformats/obj/ An excellent link page about obj files is at: http://people.sc.fsu.edu/~burkardt/data/obj/obj.html """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import face from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from struct import unpack __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addFacesGivenText( objText, triangleMesh ): "Add faces given obj text." lines = archive.getTextLines( objText ) for line in lines: splitLine = line.split() firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'v': triangleMesh.vertexes.append( getVertexGivenLine(line) ) elif firstWord == 'f': triangleMesh.faces.append( getFaceGivenLine( line, triangleMesh ) ) def getCarving(fileName=''): "Get the triangle mesh for the obj file." if fileName == '': return None objText = archive.getFileText(fileName, True, 'rb') if objText == '': return None triangleMesh = triangle_mesh.TriangleMesh() addFacesGivenText(objText, triangleMesh) return triangleMesh def getFaceGivenLine( line, triangleMesh ): "Add face given line index and lines." faceGivenLine = face.Face() faceGivenLine.index = len( triangleMesh.faces ) splitLine = line.split() for vertexStringIndex in xrange( 1, 4 ): vertexString = splitLine[ vertexStringIndex ] vertexStringWithSpaces = vertexString.replace('/', ' ') vertexStringSplit = vertexStringWithSpaces.split() vertexIndex = int( vertexStringSplit[0] ) - 1 faceGivenLine.vertexIndexes.append(vertexIndex) return faceGivenLine def getVertexGivenLine(line): "Get vertex given obj vertex line." splitLine = line.split() return Vector3( float(splitLine[1]), float( splitLine[2] ), float( splitLine[3] ) ) sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/slc.py000066400000000000000000000141741167321211700277100ustar00rootroot00000000000000""" This page is in the table of contents. The slc.py script is an import translator plugin to get a carving from an [http://rapid.lpt.fi/archives/rp-ml-1999/0713.html slc file]. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an slc file and returns the carving. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import svg_writer from struct import unpack import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCarving(fileName=''): "Get the triangle mesh for the slc file." carving = SLCCarving() carving.readFile(fileName) return carving def getLittleEndianFloatGivenFile( file ): "Get little endian float given a file." return unpack(' 2: loopLayer.loops.append( getPointsFromFile( numPoints, file ) ) def readFile( self, fileName ): "Read SLC and store the layers." self.fileName = fileName pslcfile = open( fileName, 'rb') readHeader( pslcfile ) pslcfile.read( 256 ) #Go past the 256 byte 3D Reserved Section. self.readTableEntry( pslcfile ) self.processContourLayers( pslcfile ) pslcfile.close() self.cornerMaximum = Vector3(-987654321.0, -987654321.0, self.maximumZ) self.cornerMinimum = Vector3(987654321.0, 987654321.0, self.minimumZ) for loopLayer in self.loopLayers: for loop in loopLayer.loops: for point in loop: pointVector3 = Vector3(point.real, point.imag, loopLayer.z) self.cornerMaximum.maximize(pointVector3) self.cornerMinimum.minimize(pointVector3) halfLayerThickness = 0.5 * self.layerThickness self.cornerMaximum.z += halfLayerThickness self.cornerMinimum.z -= halfLayerThickness def readTableEntry( self, file ): "Read in the sampling table section. It contains a table length (byte) and the table entries." tableEntrySize = ord( file.read( 1 ) ) if tableEntrySize == 0: print( "Sampling table size is zero!" ) exit() for index in xrange( tableEntrySize ): sampleTableEntry = SampleTableEntry( file ) self.layerThickness = sampleTableEntry.layer_thickness def setCarveImportRadius( self, importRadius ): "Set the import radius." pass def setCarveIsCorrectMesh( self, isCorrectMesh ): "Set the is correct mesh flag." pass def setCarveLayerThickness( self, layerThickness ): "Set the layer thickness." pass def main(): "Display the inset dialog." if len(sys.argv) > 1: getCarving(' '.join(sys.argv[1 :])) if __name__ == "__main__": main() sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/stl.py000066400000000000000000000113401167321211700277210ustar00rootroot00000000000000""" This page is in the table of contents. The stl.py script is an import translator plugin to get a carving from an stl file. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an stl file and returns the carving. STL is an inferior triangle surface format, described at: http://en.wikipedia.org/wiki/STL_(file_format) A good triangle surface format is the GNU Triangulated Surface format which is described at: http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import face from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from struct import unpack __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addFacesGivenBinary( stlData, triangleMesh, vertexIndexTable ): "Add faces given stl binary." numberOfVertexes = ( len( stlData ) - 84 ) / 50 vertexes = [] for vertexIndex in xrange( numberOfVertexes ): byteIndex = 84 + vertexIndex * 50 vertexes.append( getVertexGivenBinary( byteIndex + 12, stlData ) ) vertexes.append( getVertexGivenBinary( byteIndex + 24, stlData ) ) vertexes.append( getVertexGivenBinary( byteIndex + 36, stlData ) ) addFacesGivenVertexes( triangleMesh, vertexIndexTable, vertexes ) def addFacesGivenText( stlText, triangleMesh, vertexIndexTable ): "Add faces given stl text." lines = archive.getTextLines( stlText ) vertexes = [] for line in lines: if line.find('vertex') != - 1: vertexes.append( getVertexGivenLine(line) ) addFacesGivenVertexes( triangleMesh, vertexIndexTable, vertexes ) def addFacesGivenVertexes( triangleMesh, vertexIndexTable, vertexes ): "Add faces given stl text." for vertexIndex in xrange( 0, len(vertexes), 3 ): triangleMesh.faces.append( getFaceGivenLines( triangleMesh, vertexIndex, vertexIndexTable, vertexes ) ) def getCarving(fileName=''): "Get the triangle mesh for the stl file." if fileName == '': return None stlData = archive.getFileText(fileName, True, 'rb') if stlData == '': return None triangleMesh = triangle_mesh.TriangleMesh() vertexIndexTable = {} numberOfVertexStrings = stlData.count('vertex') requiredVertexStringsForText = max( 2, len( stlData ) / 8000 ) if numberOfVertexStrings > requiredVertexStringsForText: addFacesGivenText( stlData, triangleMesh, vertexIndexTable ) else: # A binary stl should never start with the word "solid". Because this error is common the file is been parsed as binary regardless. addFacesGivenBinary( stlData, triangleMesh, vertexIndexTable ) return triangleMesh def getFaceGivenLines( triangleMesh, vertexStartIndex, vertexIndexTable, vertexes ): "Add face given line index and lines." faceGivenLines = face.Face() faceGivenLines.index = len( triangleMesh.faces ) for vertexIndex in xrange( vertexStartIndex, vertexStartIndex + 3 ): vertex = vertexes[vertexIndex] vertexUniqueIndex = len( vertexIndexTable ) if str(vertex) in vertexIndexTable: vertexUniqueIndex = vertexIndexTable[ str(vertex) ] else: vertexIndexTable[ str(vertex) ] = vertexUniqueIndex triangleMesh.vertexes.append(vertex) faceGivenLines.vertexIndexes.append( vertexUniqueIndex ) return faceGivenLines def getFloat(floatString): "Get the float, replacing commas if necessary because an inferior program is using a comma instead of a point for the decimal point." try: return float(floatString) except: return float( floatString.replace(',', '.') ) def getFloatGivenBinary( byteIndex, stlData ): "Get vertex given stl vertex line." return unpack('f', stlData[ byteIndex : byteIndex + 4 ] )[0] def getVertexGivenBinary( byteIndex, stlData ): "Get vertex given stl vertex line." return Vector3( getFloatGivenBinary( byteIndex, stlData ), getFloatGivenBinary( byteIndex + 4, stlData ), getFloatGivenBinary( byteIndex + 8, stlData ) ) def getVertexGivenLine(line): "Get vertex given stl vertex line." splitLine = line.split() return Vector3( getFloat(splitLine[1]), getFloat( splitLine[2] ), getFloat( splitLine[3] ) ) sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/svg.py000066400000000000000000000071451167321211700277260ustar00rootroot00000000000000""" This page is in the table of contents. The svg.py script is an import translator plugin to get a carving from an svg file. This script will read an svg file made by skeinforge or by inkscape. An example inkscape svg file is inkscape_star.svg in the models folder. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an svg file and returns the carving. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.svg_reader import SVGReader from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import svg_writer from fabmetheus_utilities import xml_simple_writer import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCarving(fileName=''): 'Get the triangle mesh for the gts file.' carving = SVGCarving() carving.parseSVG(fileName, archive.getFileText(fileName)) return carving class SVGCarving: 'An svg carving.' def __init__(self): 'Add empty lists.' self.layerThickness = 1.0 self.maximumZ = - 987654321.0 self.minimumZ = 987654321.0 self.svgReader = SVGReader() def __repr__(self): 'Get the string representation of this carving.' return self.getCarvedSVG() def addXML(self, depth, output): 'Add xml for this object.' xml_simple_writer.addXMLFromObjects(depth, self.svgReader.loopLayers, output) def getCarveBoundaryLayers(self): 'Get the boundary layers.' return self.svgReader.loopLayers def getCarveCornerMaximum(self): 'Get the corner maximum of the vertexes.' return self.cornerMaximum def getCarveCornerMinimum(self): 'Get the corner minimum of the vertexes.' return self.cornerMinimum def getCarvedSVG(self): 'Get the carved svg text.' return svg_writer.getSVGByLoopLayers(True, self, self.svgReader.loopLayers) def getCarveLayerThickness(self): 'Get the layer thickness.' return self.layerThickness def getFabmetheusXML(self): 'Return the fabmetheus XML.' return None def getInterpretationSuffix(self): 'Return the suffix for a carving.' return 'svg' def parseSVG(self, fileName, svgText): 'Parse SVG text and store the layers.' if svgText == '': return self.fileName = fileName self.svgReader.parseSVG(fileName, svgText) self.layerThickness = euclidean.getFloatDefaultByDictionary( self.layerThickness, self.svgReader.sliceDictionary, 'layerThickness') self.cornerMaximum = Vector3(-987654321.0, -987654321.0, self.maximumZ) self.cornerMinimum = Vector3(987654321.0, 987654321.0, self.minimumZ) svg_writer.setSVGCarvingCorners( self.cornerMaximum, self.cornerMinimum, self.layerThickness, self.svgReader.loopLayers) def setCarveImportRadius(self, importRadius): 'Set the import radius.' pass def setCarveIsCorrectMesh(self, isCorrectMesh): 'Set the is correct mesh flag.' pass def setCarveLayerThickness(self, layerThickness): 'Set the layer thickness.' self.layerThickness = layerThickness sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/xml.py000066400000000000000000000134071167321211700277250ustar00rootroot00000000000000""" This page is in the table of contents. The xml.py script is an import translator plugin to get a carving from an xml file. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an xml file and returns the carving. An example of an xml boolean geometry format file follows below. In the 'fabmetheus' format, all class names are lower case. The defined geometric objects are cube, cylinder, difference, group, sphere, trianglemesh and union. The id attribute is not necessary. The default matrix is a four by four identity matrix. The attributes of the cube, cylinder and sphere default to one. The attributes of the vertexes in the triangle mesh default to zero. The boolean solids are difference, intersection and union. The difference solid is the first solid minus the remaining solids. The combined_shape.xml example in the xml_models folder in the models folder is pasted below. The 'fabmetheus' xml format is the preferred skeinforge format. When the Interpret button in the Interpret tool in Analyze is clicked, any xml format for which there is a plugin will be converted to the 'fabmetheus' format. There is a plugin for the 'Art of Illusion' xml format. An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice. This will bring up the XML file chooser window, choose a place to save the file then click "OK". Leave the "compressFile" checkbox unchecked. All the objects from the scene will be exported, the artofillusion plugin will ignore the light and camera. If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.xml_simple_reader import DocumentNode from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCarving(fileName=''): "Get the carving for the xml file." xmlText = archive.getFileText(fileName) if xmlText == '': return None xmlParser = DocumentNode(fileName, xmlText) lowerLocalName = xmlParser.getDocumentElement().getNodeName().lower() pluginModule = archive.getModuleWithDirectoryPath( getPluginsDirectoryPath(), lowerLocalName ) if pluginModule is None: return None return pluginModule.getCarvingFromParser( xmlParser ) def getPluginsDirectoryPath(): "Get the plugins directory path." return archive.getInterpretPluginsPath('xml_plugins') def main(): "Display the inset dialog." if len(sys.argv) > 1: getCarving(' '.join(sys.argv[1 :])) if __name__ == "__main__": main() sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/xml_plugins/000077500000000000000000000000001167321211700311075ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/xml_plugins/__init__.py000066400000000000000000000006571167321211700332300ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 4 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) artofillusion.py000066400000000000000000000245511167321211700343030ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/xml_plugins""" This page is in the table of contents. The xml.py script is an import translator plugin to get a carving from an Art of Illusion xml file. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an xml file and returns the carving. An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice. This will bring up the XML file chooser window, choose a place to save the file then click "OK". Leave the "compressFile" checkbox unchecked. All the objects from the scene will be exported, this plugin will ignore the light and camera. If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import face from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry from fabmetheus_utilities.geometry.geometry_utilities import boolean_solid from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.geometry.solids import cube from fabmetheus_utilities.geometry.solids import cylinder from fabmetheus_utilities.geometry.solids import group from fabmetheus_utilities.geometry.solids import sphere from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCarvableObject(elementNode, globalObject, object): "Get new carvable object info." object.xmlObject = globalObject() object.xmlObject.elementNode = object object.attributes['id'] = elementNode.getFirstChildByLocalName('name').getTextContent() coords = elementNode.getFirstChildByLocalName('coords') transformElementNode = getTransformElementNode(coords, 'transformFrom') if len(transformElementNode.attributes) < 16: transformElementNode = getTransformElementNode(coords, 'transformTo') matrix.setElementNodeDictionaryMatrix(object, object.xmlObject.matrix4X4.getFromElementNode(transformElementNode, '')) return object.xmlObject def getCarvingFromParser( xmlParser ): "Get the carving for the parser." booleanGeometry = boolean_geometry.BooleanGeometry() artOfIllusionElement = xmlParser.getDocumentElement() artOfIllusionElement.xmlObject = booleanGeometry euclidean.removeElementsFromDictionary( artOfIllusionElement.attributes, ['fileversion', 'xmlns:bf'] ) sceneElement = artOfIllusionElement.getFirstChildByLocalName('Scene') elementNodes = sceneElement.getFirstChildByLocalName('objects').getChildElementsByLocalName('bf:Elem') for elementNode in elementNodes: processAppendElementNode(booleanGeometry.archivableObjects, elementNode, artOfIllusionElement) return booleanGeometry def getTransformElementNode( coords, transformName ): "Get the transform attributes." transformElementNode = coords.getFirstChildByLocalName( transformName ) if len( transformElementNode.attributes ) < 16: if 'bf:ref' in transformElementNode.attributes: idReference = transformElementNode.attributes['bf:ref'] return coords.getDocumentElement().getSubChildWithID( idReference ) return transformElementNode def processAppendElementNode(archivableObjects, elementNode, parentNode): "Add the object info if it is carvable." if elementNode is None: return object = elementNode.getFirstChildByLocalName('object') if 'bf:type' not in object.attributes: return shapeType = object.attributes['bf:type'] if shapeType not in globalCarvableClassObjectTable: return carvableClassObject = globalCarvableClassObjectTable[ shapeType ] archivableObject = getCarvableObject(elementNode, carvableClassObject, object) archivableObject.elementNode.attributes['visible'] = elementNode.attributes['visible'] archivableObject.setToArtOfIllusionDictionary() archivableObject.elementNode.parentNode = parentNode archivableObjects.append(archivableObject) def processElementNode(elementNode): "Process the xml element." evaluate.processArchivable(group.Group, elementNode) def removeListArtOfIllusionFromDictionary( dictionary, scrubKeys ): "Remove the list and art of illusion keys from the dictionary." euclidean.removeElementsFromDictionary( dictionary, ['bf:id', 'bf:type'] ) euclidean.removeElementsFromDictionary( dictionary, scrubKeys ) class BooleanSolid( boolean_solid.BooleanSolid ): "An Art of Illusion CSG object info." def setToArtOfIllusionDictionary(self): "Set the shape of this carvable object info." processAppendElementNode(self.archivableObjects, self.elementNode.getFirstChildByLocalName('obj1'), self.elementNode) processAppendElementNode(self.archivableObjects, self.elementNode.getFirstChildByLocalName('obj2'), self.elementNode) operationString = self.elementNode.attributes['operation'] self.operationFunction = { '0': self.getUnion, '1': self.getIntersection, '2': self.getDifference, '3': self.getDifference }[ operationString ] if operationString == '3': self.archivableObjects.reverse() removeListArtOfIllusionFromDictionary( self.elementNode.attributes, ['operation'] ) class Cube( cube.Cube ): "An Art of Illusion Cube object." def setToArtOfIllusionDictionary(self): "Set the shape of this carvable object info." self.inradius = Vector3( float( self.elementNode.attributes['halfx'] ), float( self.elementNode.attributes['halfy'] ), float( self.elementNode.attributes['halfz'] ) ) self.elementNode.attributes['inradius.x'] = self.elementNode.attributes['halfx'] self.elementNode.attributes['inradius.y'] = self.elementNode.attributes['halfy'] self.elementNode.attributes['inradius.z'] = self.elementNode.attributes['halfz'] removeListArtOfIllusionFromDictionary( self.elementNode.attributes, ['halfx', 'halfy', 'halfz'] ) self.createShape() class Cylinder(cylinder.Cylinder): "An Art of Illusion Cylinder object." def setToArtOfIllusionDictionary(self): "Set the shape of this carvable object info." self.inradius = Vector3() self.inradius.x = float(self.elementNode.attributes['rx']) self.inradius.y = float(self.elementNode.attributes['rz']) self.inradius.z = float(self.elementNode.attributes['height']) self.topOverBottom = float(self.elementNode.attributes['ratio']) self.elementNode.attributes['radius.x'] = self.elementNode.attributes['rx'] self.elementNode.attributes['radius.y'] = self.elementNode.attributes['rz'] self.elementNode.attributes['topOverBottom'] = self.elementNode.attributes['ratio'] xmlObject = self.elementNode.xmlObject xmlObject.matrix4X4 = xmlObject.matrix4X4.getOtherTimesSelf(matrix.getDiagonalSwitchedTetragrid(90.0, [0, 2])) removeListArtOfIllusionFromDictionary(self.elementNode.attributes, ['rx', 'rz', 'ratio']) self.createShape() class Group( group.Group ): "An Art of Illusion Group object." def setToArtOfIllusionDictionary(self): "Set the shape of this group." childNodesElement = self.elementNode.parentNode.getFirstChildByLocalName('children') childNodes = childNodesElement.getChildElementsByLocalName('bf:Elem') for childNode in childNodes: processAppendElementNode(self.archivableObjects, childNode, self.elementNode) removeListArtOfIllusionFromDictionary( self.elementNode.attributes, [] ) class Sphere( sphere.Sphere ): "An Art of Illusion Sphere object." def setToArtOfIllusionDictionary(self): "Set the shape of this carvable object." self.radius = Vector3( float( self.elementNode.attributes['rx'] ), float( self.elementNode.attributes['ry'] ), float( self.elementNode.attributes['rz'] ) ) self.elementNode.attributes['radius.x'] = self.elementNode.attributes['rx'] self.elementNode.attributes['radius.y'] = self.elementNode.attributes['ry'] self.elementNode.attributes['radius.z'] = self.elementNode.attributes['rz'] removeListArtOfIllusionFromDictionary( self.elementNode.attributes, ['rx', 'ry', 'rz'] ) self.createShape() class TriangleMesh(triangle_mesh.TriangleMesh): "An Art of Illusion triangle mesh object." def setToArtOfIllusionDictionary(self): "Set the shape of this carvable object info." vertexElement = self.elementNode.getFirstChildByLocalName('vertex') vertexPointElements = vertexElement.getChildElementsByLocalName('bf:Elem') for vertexPointElement in vertexPointElements: coordinateElement = vertexPointElement.getFirstChildByLocalName('r') vertex = Vector3( float( coordinateElement.attributes['x'] ), float( coordinateElement.attributes['y'] ), float( coordinateElement.attributes['z'] ) ) self.vertexes.append(vertex) edgeElement = self.elementNode.getFirstChildByLocalName('edge') edgeSubelements = edgeElement.getChildElementsByLocalName('bf:Elem') for edgeSubelementIndex in xrange( len( edgeSubelements ) ): edgeSubelement = edgeSubelements[ edgeSubelementIndex ] vertexIndexes = [ int( edgeSubelement.attributes['v1'] ), int( edgeSubelement.attributes['v2'] ) ] edge = face.Edge().getFromVertexIndexes( edgeSubelementIndex, vertexIndexes ) self.edges.append( edge ) faceElement = self.elementNode.getFirstChildByLocalName('face') faceSubelements = faceElement.getChildElementsByLocalName('bf:Elem') for faceSubelementIndex in xrange( len( faceSubelements ) ): faceSubelement = faceSubelements[ faceSubelementIndex ] edgeIndexes = [ int( faceSubelement.attributes['e1'] ), int( faceSubelement.attributes['e2'] ), int( faceSubelement.attributes['e3'] ) ] self.faces.append( face.Face().getFromEdgeIndexes( edgeIndexes, self.edges, faceSubelementIndex ) ) removeListArtOfIllusionFromDictionary( self.elementNode.attributes, ['closed', 'smoothingMethod'] ) globalCarvableClassObjectTable = { 'CSGObject' : BooleanSolid, 'Cube' : Cube, 'Cylinder' : Cylinder, 'artofillusion.object.NullObject' : Group, 'Sphere' : Sphere, 'TriangleMesh' : TriangleMesh } sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/xml_plugins/fabmetheus.py000066400000000000000000000130221167321211700336020ustar00rootroot00000000000000""" This page is in the table of contents. The xml.py script is an import translator plugin to get a carving from an Art of Illusion xml file. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an xml file and returns the carving. An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice. This will bring up the XML file chooser window, choose a place to save the file then click "OK". Leave the "compressFile" checkbox unchecked. All the objects from the scene will be exported, this plugin will ignore the light and camera. If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools.interpret_plugins import xml from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import group from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from fabmetheus_utilities import xml_simple_reader import os import sys import traceback __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCarvingFromParser(xmlParser): "Get the carving for the parser." booleanGeometryElement = xmlParser.getDocumentElement() booleanGeometryElement.xmlObject = boolean_geometry.BooleanGeometry() booleanGeometryElement.xmlProcessor = XMLBooleanGeometryProcessor() booleanGeometryElement.xmlProcessor.processChildNodes(booleanGeometryElement) return booleanGeometryElement.xmlObject def processElementNode(elementNode): "Process the xml element." evaluate.processArchivable(group.Group, elementNode) class XMLBooleanGeometryProcessor(): "A class to process xml boolean geometry elements." def __init__(self): "Initialize processor." self.functions = [] self.manipulationMatrixDictionary = archive.getGeometryDictionary('manipulation_matrix') self.manipulationPathDictionary = archive.getGeometryDictionary('manipulation_paths') self.manipulationShapeDictionary = archive.getGeometryDictionary('manipulation_shapes') self.namePathDictionary = {} self.namePathDictionary.update(evaluate.globalCreationDictionary) self.namePathDictionary.update(archive.getGeometryDictionary('manipulation_meta')) self.namePathDictionary.update(self.manipulationMatrixDictionary) self.namePathDictionary.update(self.manipulationPathDictionary) self.namePathDictionary.update(self.manipulationShapeDictionary) archive.addToNamePathDictionary(archive.getGeometryToolsPath(), self.namePathDictionary) archive.addToNamePathDictionary(archive.getGeometryToolsPath('path_elements'), self.namePathDictionary) archive.addToNamePathDictionary(archive.getGeometryPath('solids'), self.namePathDictionary) archive.addToNamePathDictionary(archive.getGeometryPath('statements'), self.namePathDictionary) archive.addToNamePathDictionary(xml.getPluginsDirectoryPath(), self.namePathDictionary) def __repr__(self): 'Get the string representation of this XMLBooleanGeometryProcessor.' return 'XMLBooleanGeometryProcessor with %s functions.' % len(self.functions) def convertElementNode(self, elementNode, geometryOutput): "Convert the xml element." geometryOutputKeys = geometryOutput.keys() if len( geometryOutputKeys ) < 1: return None firstKey = geometryOutputKeys[0] lowerLocalName = firstKey.lower() if lowerLocalName not in self.namePathDictionary: return None pluginModule = archive.getModuleWithPath( self.namePathDictionary[ lowerLocalName ] ) if pluginModule is None: return None elementNode.localName = lowerLocalName return pluginModule.convertElementNode(elementNode, geometryOutput[ firstKey ]) def createChildNodes( self, geometryOutput, parentNode ): "Create childNodes for the parentNode." for geometryOutputChild in geometryOutput: childNode = xml_simple_reader.ElementNode() childNode.setParentAddToChildNodes( parentNode ) self.convertElementNode(childNode, geometryOutputChild) def processChildNodes(self, elementNode): "Process the childNodes of the xml element." for childNode in elementNode.childNodes: self.processElementNode(childNode) def processElementNode(self, elementNode): 'Process the xml element.' lowerLocalName = elementNode.getNodeName().lower() if lowerLocalName not in self.namePathDictionary: return None pluginModule = archive.getModuleWithPath(self.namePathDictionary[lowerLocalName]) if pluginModule is None: return None try: return pluginModule.processElementNode(elementNode) except: print('Warning, could not processElementNode in fabmetheus for:') print(pluginModule) print(elementNode) traceback.print_exc(file=sys.stdout) return None sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/prepare.py000066400000000000000000000056051167321211700250070ustar00rootroot00000000000000""" Prepare is a script to remove the generated files, run wikifier, and finally zip the package. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities.fabmetheus_tools import wikifier import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def prepareWikify(): 'Remove generated files, then wikify the file comments.' removeGeneratedFiles() wikifier.main() removeZip() def removeCSVFile(csvFilePath): 'Remove csv file.' if 'alterations' in csvFilePath and 'example_' not in csvFilePath: os.remove(csvFilePath) print('removeGeneratedFiles deleted ' + csvFilePath) def removeGcodeFile(gcodeFilePath): 'Remove gcode file.' if 'alterations' not in gcodeFilePath: os.remove(gcodeFilePath) print('removeGeneratedFiles deleted ' + gcodeFilePath) return if 'example_' not in gcodeFilePath: os.remove(gcodeFilePath) print('removeGeneratedFiles deleted ' + gcodeFilePath) def removeGeneratedFiles(): 'Remove generated files.' csvFilePaths = archive.getFilesWithFileTypesWithoutWordsRecursively(['csv']) for csvFilePath in csvFilePaths: removeCSVFile(csvFilePath) gcodeFilePaths = archive.getFilesWithFileTypesWithoutWordsRecursively(['gcode']) for gcodeFilePath in gcodeFilePaths: removeGcodeFile(gcodeFilePath) svgFilePaths = archive.getFilesWithFileTypesWithoutWordsRecursively(['svg']) for svgFilePath in svgFilePaths: removeSVGFile(svgFilePath) xmlFilePaths = archive.getFilesWithFileTypesWithoutWordsRecursively(['xml']) for xmlFilePath in xmlFilePaths: removeXMLFile(xmlFilePath) archive.removeBackupFilesByTypes(['gcode', 'svg', 'xml']) def removeSVGFile(svgFilePath): 'Remove svg file.' if archive.getEndsWithList(svgFilePath, ['_bottom.svg', '_carve.svg', '_chop.svg', '_cleave.svg', '_scale.svg', '_vectorwrite.svg']): os.remove(svgFilePath) print('removeGeneratedFiles deleted ' + svgFilePath) def removeXMLFile(xmlFilePath): 'Remove xml file.' if archive.getEndsWithList(xmlFilePath, ['_interpret.xml']): os.remove(xmlFilePath) print('removeGeneratedFiles deleted ' + xmlFilePath) def removeZip(): 'Remove the zip file, then generate a new one.zip -r reprap_python_beanshell * -x \*.pyc \*~' zipName = 'reprap_python_beanshell' zipNameExtension = zipName + '.zip' if zipNameExtension in os.listdir(os.getcwd()): os.remove(zipNameExtension) shellCommand = 'zip -r %s * -x \*.pyc \*~' % zipName if os.system(shellCommand) != 0: print('Failed to execute the following command in removeZip in prepare.') print(shellCommand) def main(): 'Run main function.' prepareWikify() if __name__ == "__main__": main() sfact-2011.12.18/fabmetheus_utilities/fabmetheus_tools/wikifier.py000066400000000000000000000215221167321211700251560ustar00rootroot00000000000000""" Wikifier is a script to add spaces to the pydoc files and move them to the documentation folder. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings import cStringIO import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalWikiLinkStart = '[', linkStartIndex, squareEndBracketIndex) greaterThanIndexPlusOne = greaterThanIndex + 1 closeATagIndex = line.find('', greaterThanIndexPlusOne, squareEndBracketIndex) linkText = line[closeATagIndex + len('') + 1: squareEndBracketIndex] linkLine = line[: linkStartIndex] + line[linkStartIndex + 1: greaterThanIndexPlusOne] + linkText + '' + line[squareEndBracketIndex + 1 :] return linkLine def getNavigationHypertext(fileText, transferredFileNameIndex, transferredFileNames): 'Get the hypertext help with navigation lines.' helpTextEnd = fileText.find('

') helpTextStart = fileText.find('

') helpText = fileText[helpTextStart : helpTextEnd] lines = archive.getTextLines(helpText) headings = [] headingLineTable = {} for line in lines: addToHeadings(headingLineTable, headings, line) headingsToBeenAdded = True output = cStringIO.StringIO() for line in lines: if line[: 2] == '==': if headingsToBeenAdded: output.write('
\n') for heading in headings: heading.addToOutput(output) output.write('
\n') headingsToBeenAdded = False if line in headingLineTable: line = headingLineTable[line] if '<a href=' in line: line = line.replace('<', '<').replace('>', '>') while globalWikiLinkStart in line and ']' in line: line = getLinkLine(line) output.write(line + '\n') helpText = output.getvalue() previousFileName = 'contents.html' previousIndex = transferredFileNameIndex - 1 if previousIndex >= 0: previousFileName = transferredFileNames[previousIndex] previousLinkText = 'Previous' % previousFileName nextLinkText = getNextLinkText(transferredFileNames, transferredFileNameIndex + 1) navigationLine = getNavigationLine('Contents', previousLinkText, nextLinkText) helpText = navigationLine + helpText + '
\n
\n' + navigationLine + '


\n' return fileText[: helpTextStart] + helpText + fileText[helpTextEnd :] def getNavigationLine(contentsLinkText, previousLinkText, nextLinkText): 'Get the wrapped pydoc hypertext help.' return '

\n%s / %s / %s\n

\n' % (previousLinkText, nextLinkText, contentsLinkText) def getNextLinkText(hypertextFiles, nextIndex): 'Get the next link text.' nextFileName = 'contents.html' if nextIndex < len(hypertextFiles): nextFileName = hypertextFiles[nextIndex] return 'Next' % nextFileName def getWrappedHypertext(fileText, hypertextFileIndex, hypertextFiles): 'Get the wrapped pydoc hypertext help.' helpTextEnd = fileText.find('

') if helpTextEnd < 0: print('Failed to find the helpTextEnd in getWrappedHypertext in docwrap.') helpTextStart = fileText.find('

') if helpTextStart < 0: print('Failed to find the helpTextStart in getWrappedHypertext in docwrap.') helpText = fileText[helpTextStart : helpTextEnd] helpText = helpText.replace(' ', ' ') return fileText[: helpTextStart] + helpText + fileText[helpTextEnd :] def readWriteDeleteHypertextHelp(documentDirectoryPath, hypertextFileIndex, hypertextFiles, transferredFileNames): 'Read the pydoc hypertext help documents, write them in the documentation folder then delete the originals.' fileName = os.path.basename(hypertextFiles[hypertextFileIndex]) print('readWriteDeleteHypertextHelp ' + fileName) filePath = os.path.join(documentDirectoryPath, fileName) fileText = archive.getFileText(fileName) fileText = getWrappedHypertext(fileText, hypertextFileIndex, hypertextFiles) if fileText.find('This page is in the table of contents.') > - 1: fileText = fileText.replace('This page is in the table of contents.', '') transferredFileNames.append(fileName) archive.writeFileText(filePath, fileText) os.remove(fileName) def readWriteNavigationHelp(documentDirectoryPath, transferredFileNameIndex, transferredFileNames): 'Read the hypertext help documents, and add the navigation lines to them.' fileName = os.path.basename(transferredFileNames[transferredFileNameIndex]) print('readWriteNavigationHelp ' + fileName) filePath = os.path.join(documentDirectoryPath, fileName) fileText = archive.getFileText(filePath) fileText = getNavigationHypertext(fileText, transferredFileNameIndex, transferredFileNames) archive.writeFileText(filePath, fileText) def removeFilesInDirectory(directoryPath): 'Remove all the files in a directory.' fileNames = os.listdir(directoryPath) for fileName in fileNames: filePath = os.path.join(directoryPath, fileName) os.remove(filePath) def writeContentsFile(documentDirectoryPath, hypertextFiles): 'Write the contents file.' output = cStringIO.StringIO() output.write('\n \n Contents\n \n \n') navigationLine = getNavigationLine('Contents', 'Previous', getNextLinkText(hypertextFiles, 0)) output.write(navigationLine) for hypertextFile in hypertextFiles: writeContentsLine(hypertextFile, output) output.write(navigationLine) output.write(' \n\n') filePath = os.path.join( documentDirectoryPath, 'contents.html') archive.writeFileText(filePath, output.getvalue()) def writeContentsLine(hypertextFile, output): 'Write a line of the contents file.' summarizedFileName = hypertextFile[: hypertextFile.rfind('.')] numberOfDots = summarizedFileName.count('.') prefixSpaces = '  ' * numberOfDots if numberOfDots > 0: summarizedFileName = summarizedFileName[summarizedFileName.rfind('.') + 1 :] capitalizedSummarizedFileName = settings.getEachWordCapitalized(summarizedFileName) output.write('%s%s
\n' % (prefixSpaces, hypertextFile, capitalizedSummarizedFileName)) def writeHypertext(): 'Run pydoc, then read, write and delete each of the files.' shellCommand = 'pydoc -w ./' commandResult = os.system(shellCommand) if commandResult != 0: print('Failed to execute the following command in writeHypertext in docwrap.') print(shellCommand) hypertextFiles = archive.getFilesWithFileTypeWithoutWords('html') if len( hypertextFiles ) <= 0: print('Failed to find any help files in writeHypertext in docwrap.') return documentDirectoryPath = archive.getAbsoluteFolderPath( hypertextFiles[0], 'documentation') removeFilesInDirectory(documentDirectoryPath) sortedReplaceFiles = [] for hypertextFile in hypertextFiles: sortedReplaceFiles.append(hypertextFile.replace('.html', '. html')) sortedReplaceFiles.sort() hypertextFiles = [] for sortedReplaceFile in sortedReplaceFiles: hypertextFiles.append(sortedReplaceFile.replace('. html', '.html')) transferredFileNames = [] for hypertextFileIndex in xrange(len(hypertextFiles)): readWriteDeleteHypertextHelp(documentDirectoryPath, hypertextFileIndex, hypertextFiles, transferredFileNames) for transferredFileNameIndex in xrange(len(transferredFileNames)): readWriteNavigationHelp(documentDirectoryPath, transferredFileNameIndex, transferredFileNames) writeContentsFile(documentDirectoryPath, transferredFileNames) print('%s files were wrapped.' % len(transferredFileNames)) class Heading: 'A class to hold the heading and subheadings.' def __init__(self, depth=0): 'Initialize.' self.depth = depth def addToOutput(self, output): 'Add to the output.' line = '  ' * self.depth + '%s
\n' % (self.name, self.name) output.write(line) def getFromLine(self, headingLineTable, line): 'Get the heading from a line.' heading = 'h%s' % (self.depth + 2) nextLine = '\n


\n' if self.depth > 0: nextLine = '\n' self.name = line.replace('=', '').replace('
', '') name = self.name headingLine = '<%s>%s%s' % (name, name, heading, name, heading, nextLine) headingLineTable[line] = headingLine return self def main(): 'Display the craft dialog.' writeHypertext() if __name__ == '__main__': main() sfact-2011.12.18/fabmetheus_utilities/fonts/000077500000000000000000000000001167321211700205575ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/fonts/gentium_basic_regular.svg000066400000000000000000001200641167321211700256350ustar00rootroot00000000000000 sfact-2011.12.18/fabmetheus_utilities/gcodec.py000066400000000000000000000413031167321211700212250ustar00rootroot00000000000000""" Gcodec is a collection of utilities to decode and encode gcode. To run gcodec, install python 2.x on your machine, which is avaliable from http://www.python.org/download/ Then in the folder which gcodec is in, type 'python' in a shell to run the python interpreter. Finally type 'from gcodec import *' to import this program. Below is an example of gcodec use. This example is run in a terminal in the folder which contains gcodec and Screw Holder Bottom_export.gcode. >>> from gcodec import * >>> getFileText('Screw Holder Bottom_export.gcode') 'G90\nG21\nM103\nM105\nM106\nM110 S60.0\nM111 S30.0\nM108 S210.0\nM104 S235.0\nG1 X0.37 Y-4.07 Z1.9 F60.0\nM101\n .. many lines of text .. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean import cStringIO import math import os import sys import traceback __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addLineAndNewlineIfNecessary(line, output): 'Add the line and if the line does not end with a newline add a newline.' output.write(line) if len(line) < 1: return if not line.endswith('\n'): output.write('\n') def addLinesToCString(cString, lines): 'Add lines which have something to cStringIO.' for line in lines: if line != '': cString.write(line + '\n') def getArcDistance(relativeLocation, splitLine): 'Get arc distance.' halfPlaneLineDistance = 0.5 * abs(relativeLocation.dropAxis()) radius = getDoubleFromCharacterSplitLine('R', splitLine) if radius is None: iFloat = getDoubleFromCharacterSplitLine('I', splitLine) jFloat = getDoubleFromCharacterSplitLine('J', splitLine) radius = abs(complex(iFloat, jFloat)) angle = 0.0 if radius > 0.0: halfPlaneLineDistanceOverRadius = halfPlaneLineDistance / radius if halfPlaneLineDistance < radius: angle = 2.0 * math.asin(halfPlaneLineDistanceOverRadius) else: angle = math.pi * halfPlaneLineDistanceOverRadius return abs(complex(angle * radius, relativeLocation.z)) def getDoubleAfterFirstLetter(word): 'Get the double value of the word after the first letter.' return float(word[1 :]) def getDoubleForLetter(letter, splitLine): 'Get the double value of the word after the first occurence of the letter in the split line.' return getDoubleAfterFirstLetter(splitLine[getIndexOfStartingWithSecond(letter, splitLine)]) def getDoubleFromCharacterSplitLine(character, splitLine): 'Get the double value of the string after the first occurence of the character in the split line.' indexOfCharacter = getIndexOfStartingWithSecond(character, splitLine) if indexOfCharacter < 0: return None floatString = splitLine[indexOfCharacter][1 :] try: return float(floatString) except ValueError: return None def getDoubleFromCharacterSplitLineValue(character, splitLine, value): 'Get the double value of the string after the first occurence of the character in the split line, if it does not exist return the value.' splitLineFloat = getDoubleFromCharacterSplitLine(character, splitLine) if splitLineFloat is None: return value return splitLineFloat def getFeedRateMinute(feedRateMinute, splitLine): 'Get the feed rate per minute if the split line has a feed rate.' indexOfF = getIndexOfStartingWithSecond('F', splitLine) if indexOfF > 0: return getDoubleAfterFirstLetter( splitLine[indexOfF] ) return feedRateMinute def getFirstWord(splitLine): 'Get the first word of a split line.' if len(splitLine) > 0: return splitLine[0] return '' def getFirstWordFromLine(line): 'Get the first word of a line.' return getFirstWord(line.split()) def getFirstWordIndexReverse(firstWord, lines, startIndex): 'Parse gcode in reverse order until the first word if there is one, otherwise return -1.' for lineIndex in xrange(len(lines) - 1, startIndex - 1, -1): if firstWord == getFirstWord(getSplitLineBeforeBracketSemicolon(lines[lineIndex])): return lineIndex return -1 def getGcodeFileText(fileName, gcodeText): 'Get the gcode text from a file if it the gcode text is empty and if the file is a gcode file.' if gcodeText != '': return gcodeText if fileName.endswith('.gcode'): return archive.getFileText(fileName) return '' def getGcodeWithoutDuplication(duplicateWord, gcodeText): 'Get gcode text without duplicate first words.' lines = archive.getTextLines(gcodeText) oldWrittenLine = None output = cStringIO.StringIO() for line in lines: firstWord = getFirstWordFromLine(line) if firstWord == duplicateWord: if line != oldWrittenLine: output.write(line + '\n') oldWrittenLine = line else: if len(line) > 0: output.write(line + '\n') return output.getvalue() ### return gcodeText isExtruderActive = False lines = archive.getTextLines(gcodeText) oldDuplicationIndex = None oldWrittenLine = None output = cStringIO.StringIO() for lineIndex, line in enumerate(lines): firstWord = getFirstWordFromLine(line) if firstWord is duplicateWord: if oldDuplicationIndex is None: oldDuplicationIndex = lineIndex else: lines[oldDuplicationIndex] = line lines[lineIndex] = '' elif firstWord.startswith('G'): if isExtruderActive: oldDuplicationIndex = None elif firstWord == 'M101': isExtruderActive = True oldDuplicationIndex = None elif firstWord == 'M103': isExtruderActive = False for line in lines: firstWord = getFirstWordFromLine(line) if firstWord is duplicateWord: if line != oldWrittenLine: output.write(line + '\n') oldWrittenLine = line else: if len(line) > 0: output.write(line + '\n') return output.getvalue() def getIndexOfStartingWithSecond(letter, splitLine): 'Get index of the first occurence of the given letter in the split line, starting with the second word. Return - 1 if letter is not found' for wordIndex in xrange( 1, len(splitLine) ): word = splitLine[ wordIndex ] firstLetter = word[0] if firstLetter == letter: return wordIndex return - 1 def getLineWithValueString(character, line, splitLine, valueString): 'Get the line with a valueString.' roundedValueString = character + valueString indexOfValue = getIndexOfStartingWithSecond(character, splitLine) if indexOfValue == -1: return line + ' ' + roundedValueString word = splitLine[indexOfValue] return line.replace(word, roundedValueString) def getLocationFromSplitLine(oldLocation, splitLine): 'Get the location from the split line.' if oldLocation is None: oldLocation = Vector3() return Vector3( getDoubleFromCharacterSplitLineValue('X', splitLine, oldLocation.x), getDoubleFromCharacterSplitLineValue('Y', splitLine, oldLocation.y), getDoubleFromCharacterSplitLineValue('Z', splitLine, oldLocation.z)) def getRotationBySplitLine(splitLine): 'Get the complex rotation from the split gcode line.' return complex(splitLine[1].replace('(', '').replace(')', '')) def getSplitLineBeforeBracketSemicolon(line): 'Get the split line before a bracket or semicolon.' if ';' in line: line = line[: line.find(';')] bracketIndex = line.find('(') if bracketIndex > 0: return line[: bracketIndex].split() return line.split() def getStringFromCharacterSplitLine(character, splitLine): 'Get the string after the first occurence of the character in the split line.' indexOfCharacter = getIndexOfStartingWithSecond(character, splitLine) if indexOfCharacter < 0: return None return splitLine[indexOfCharacter][1 :] def getTagBracketedLine(tagName, value): 'Get line with a begin tag, value and end tag.' return '(<%s> %s )' % (tagName, value, tagName) def getTagBracketedProcedure(procedure): 'Get line with a begin procedure tag, procedure and end procedure tag.' return getTagBracketedLine('procedureName', procedure) def isProcedureDone(gcodeText, procedure): 'Determine if the procedure has been done on the gcode text.' if gcodeText == '': return False extruderInitializationIndex = gcodeText.find('()') if extruderInitializationIndex == -1: return False return gcodeText.find(getTagBracketedProcedure(procedure), 0, extruderInitializationIndex) != -1 def isProcedureDoneOrFileIsEmpty(gcodeText, procedure): 'Determine if the procedure has been done on the gcode text or the file is empty.' if gcodeText == '': return True return isProcedureDone(gcodeText, procedure) def isThereAFirstWord(firstWord, lines, startIndex): 'Parse gcode until the first word if there is one.' for lineIndex in xrange(startIndex, len(lines)): line = lines[lineIndex] splitLine = getSplitLineBeforeBracketSemicolon(line) if firstWord == getFirstWord(splitLine): return True return False class BoundingRectangle: 'A class to get the corners of a gcode text.' def getFromGcodeLines(self, lines, radius): 'Parse gcode text and get the minimum and maximum corners.' self.cornerMaximum = complex(-987654321.0, -987654321.0) self.cornerMinimum = complex(987654321.0, 987654321.0) self.oldLocation = None self.cornerRadius = complex(radius, radius) for line in lines: self.parseCorner(line) return self def isPointInside(self, point): 'Determine if the point is inside the bounding rectangle.' return point.imag >= self.cornerMinimum.imag and point.imag <= self.cornerMaximum.imag and point.real >= self.cornerMinimum.real and point.real <= self.cornerMaximum.real def parseCorner(self, line): 'Parse a gcode line and use the location to update the bounding corners.' splitLine = getSplitLineBeforeBracketSemicolon(line) firstWord = getFirstWord(splitLine) if firstWord == '(': locationComplex = getLocationFromSplitLine(None, splitLine).dropAxis() self.cornerMaximum = euclidean.getMaximum(self.cornerMaximum, locationComplex) self.cornerMinimum = euclidean.getMinimum(self.cornerMinimum, locationComplex) elif firstWord == 'G1': location = getLocationFromSplitLine(self.oldLocation, splitLine) locationComplex = location.dropAxis() self.cornerMaximum = euclidean.getMaximum(self.cornerMaximum, locationComplex + self.cornerRadius) self.cornerMinimum = euclidean.getMinimum(self.cornerMinimum, locationComplex - self.cornerRadius) self.oldLocation = location class DistanceFeedRate: 'A class to limit the z feed rate and round values.' def __init__(self): 'Initialize.' self.isAlteration = False self.decimalPlacesCarried = 3 self.output = cStringIO.StringIO() def addGcodeFromFeedRateThreadZ(self, feedRateMinute, thread, travelFeedRateMinute, z): 'Add a thread to the output.' if len(thread) > 0: self.addGcodeMovementZWithFeedRate(travelFeedRateMinute, thread[0], z) else: print('zero length vertex positions array which was skipped over, this should never happen.') if len(thread) < 2: print('thread of only one point in addGcodeFromFeedRateThreadZ in gcodec, this should never happen.') print(thread) return self.addLine('M101') # Turn extruder on. for point in thread[1 :]: self.addGcodeMovementZWithFeedRate(feedRateMinute, point, z) self.addLine('M103') # Turn extruder off. def addGcodeFromLoop(self, loop, z): 'Add the gcode loop.' euclidean.addNestedRingBeginning(self, loop, z) self.addPerimeterBlock(loop, z) self.addLine('()') self.addLine('()') def addGcodeFromThreadZ(self, thread, z): 'Add a thread to the output.' if len(thread) > 0: self.addGcodeMovementZ(thread[0], z) else: print('zero length vertex positions array which was skipped over, this should never happen.') if len(thread) < 2: print('thread of only one point in addGcodeFromThreadZ in gcodec, this should never happen.') print(thread) return self.addLine('M101') # Turn extruder on. for point in thread[1 :]: self.addGcodeMovementZ(point, z) self.addLine('M103') # Turn extruder off. def addGcodeMovementZ(self, point, z): 'Add a movement to the output.' self.addLine(self.getLinearGcodeMovement(point, z)) def addGcodeMovementZWithFeedRate(self, feedRateMinute, point, z): 'Add a movement to the output.' self.addLine(self.getLinearGcodeMovementWithFeedRate(feedRateMinute, point, z)) def addLine(self, line): 'Add a line of text and a newline to the output.' if len(line) > 0: self.output.write(line + '\n') def addLineCheckAlteration(self, line): 'Add a line of text and a newline to the output and check to see if it is an alteration line.' firstWord = getFirstWord(getSplitLineBeforeBracketSemicolon(line)) if firstWord == '()': self.isAlteration = True elif firstWord == '()': self.isAlteration = False if len(line) > 0: self.output.write(line + '\n') def addLines(self, lines): 'Add lines of text to the output.' addLinesToCString(self.output, lines) def addLinesSetAbsoluteDistanceMode(self, lines): 'Add lines of text to the output and ensure the absolute mode is set.' if len(lines) < 1: return if len(lines[0]) < 1: return absoluteDistanceMode = True self.addLine('()') for line in lines: splitLine = getSplitLineBeforeBracketSemicolon(line) firstWord = getFirstWord(splitLine) if firstWord == 'G90': absoluteDistanceMode = True elif firstWord == 'G91': absoluteDistanceMode = False self.addLine('()' + line) if not absoluteDistanceMode: self.addLine('G90') self.addLine('()') def addParameter(self, firstWord, parameter): 'Add the parameter.' self.addLine(firstWord + ' S' + euclidean.getRoundedToThreePlaces(parameter)) def addPerimeterBlock(self, loop, z): 'Add the perimeter gcode block for the loop.' if len(loop) < 2: return if euclidean.isWiddershins(loop): # Indicate that a perimeter is beginning. self.addLine('( outer )') else: self.addLine('( inner )') self.addGcodeFromThreadZ(loop + [loop[0]], z) self.addLine('()') # Indicate that a perimeter is beginning. def addTagBracketedLine(self, tagName, value): 'Add a begin tag, value and end tag.' self.addLine(getTagBracketedLine(tagName, value)) def addTagRoundedLine(self, tagName, value): 'Add a begin tag, rounded value and end tag.' self.addLine('(<%s> %s )' % (tagName, self.getRounded(value), tagName)) def addTagBracketedProcedure(self, procedure): 'Add a begin procedure tag, procedure and end procedure tag.' self.addLine(getTagBracketedProcedure(procedure)) def getBoundaryLine(self, location): 'Get boundary gcode line.' return '( X%s Y%s Z%s )' % (self.getRounded(location.x), self.getRounded(location.y), self.getRounded(location.z)) def getFirstWordMovement(self, firstWord, location): 'Get the start of the arc line.' return '%s X%s Y%s Z%s' % (firstWord, self.getRounded(location.x), self.getRounded(location.y), self.getRounded(location.z)) def getInfillBoundaryLine(self, location): 'Get infill boundary gcode line.' return '( X%s Y%s Z%s )' % (self.getRounded(location.x), self.getRounded(location.y), self.getRounded(location.z)) def getIsAlteration(self, line): 'Determine if it is an alteration.' if self.isAlteration: self.addLineCheckAlteration(line) return True return False def getLinearGcodeMovement(self, point, z): 'Get a linear gcode movement.' return 'G1 X%s Y%s Z%s' % ( self.getRounded( point.real ), self.getRounded( point.imag ), self.getRounded(z) ) def getLinearGcodeMovementWithFeedRate(self, feedRateMinute, point, z): 'Get a z limited gcode movement.' linearGcodeMovement = self.getLinearGcodeMovement(point, z) if feedRateMinute is None: return linearGcodeMovement return linearGcodeMovement + ' F' + self.getRounded(feedRateMinute) def getLineWithFeedRate(self, feedRateMinute, line, splitLine): 'Get the line with a feed rate.' return getLineWithValueString('F', line, splitLine, self.getRounded(feedRateMinute)) def getLineWithX(self, line, splitLine, x): 'Get the line with an x.' return getLineWithValueString('X', line, splitLine, self.getRounded(x)) def getLineWithY(self, line, splitLine, y): 'Get the line with a y.' return getLineWithValueString('Y', line, splitLine, self.getRounded(y)) def getLineWithZ(self, line, splitLine, z): 'Get the line with a z.' return getLineWithValueString('Z', line, splitLine, self.getRounded(z)) def getRounded(self, number): 'Get number rounded to the number of carried decimal places as a string.' return euclidean.getRoundedToPlacesString(self.decimalPlacesCarried, number) def parseSplitLine(self, firstWord, splitLine): 'Parse gcode split line and store the parameters.' if firstWord == '(': self.decimalPlacesCarried = int(splitLine[1]) sfact-2011.12.18/fabmetheus_utilities/geometry/000077500000000000000000000000001167321211700212615ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/__init__.py000066400000000000000000000007351167321211700233770ustar00rootroot00000000000000""" This page is in the table of contents. This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. """ import os import sys numberOfLevelsDeepInPackageHierarchy = 2 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/000077500000000000000000000000001167321211700230655ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/creation/__init__.py000066400000000000000000000007351167321211700252030ustar00rootroot00000000000000""" This page is in the table of contents. This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. """ import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/_drill.py000066400000000000000000000044461167321211700247140ustar00rootroot00000000000000""" Drill negative solid. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import extrude from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.creation import teardrop from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = DrillDerivation(elementNode) negatives = [] teardrop.addNegativesByRadius(elementNode, derivation.end, negatives, derivation.radius, derivation.start) return solid.getGeometryOutputByManipulation(elementNode, negatives[0]) def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." evaluate.setAttributesByArguments(['radius', 'start', 'end'], arguments, elementNode) return getGeometryOutput(None, elementNode) def getNewDerivation(elementNode): 'Get new derivation.' return DrillDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." solid.processElementNodeByGeometry(elementNode, getGeometryOutput(None, elementNode)) class DrillDerivation: "Class to hold drill variables." def __init__(self, elementNode): 'Set defaults.' self.elementNode = elementNode self.end = evaluate.getVector3ByPrefix(Vector3(0.0, 0.0, 1.0), elementNode, 'end') self.start = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'start') self.radius = lineation.getFloatByPrefixBeginEnd(elementNode, 'radius', 'diameter', 1.0) size = evaluate.getEvaluatedFloat(None, elementNode, 'size') if size is not None: self.radius = 0.5 * size sfact-2011.12.18/fabmetheus_utilities/geometry/creation/_svg.py000066400000000000000000000040651167321211700244020ustar00rootroot00000000000000""" Svg reader. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities import euclidean from fabmetheus_utilities import svg_reader __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = SVGDerivation(elementNode) return getGeometryOutputBySVGReader(elementNode, derivation.svgReader) def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." derivation = SVGDerivation() derivation.svgReader.parseSVG('', arguments[0]) return getGeometryOutput(derivation, elementNode) def getGeometryOutputBySVGReader(elementNode, svgReader): "Get vector3 vertexes from svgReader." geometryOutput = [] for loopLayer in svgReader.loopLayers: for loop in loopLayer.loops: vector3Path = euclidean.getVector3Path(loop, loopLayer.z) sideLoop = lineation.SideLoop(vector3Path) sideLoop.rotate(elementNode) geometryOutput += lineation.getGeometryOutputByManipulation(elementNode, sideLoop) return geometryOutput def getNewDerivation(elementNode): 'Get new derivation.' return SVGDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class SVGDerivation: "Class to hold svg variables." def __init__(self, elementNode): 'Set defaults.' self.svgReader = svg_reader.SVGReader() self.svgReader.parseSVGByElementNode(elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/circle.py000066400000000000000000000064641167321211700247120ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = CircleDerivation(elementNode) angleTotal = math.radians(derivation.start) loop = [] sidesCeiling = int(math.ceil(abs(derivation.sides) * derivation.extent / 360.0)) sideAngle = math.radians(derivation.extent) / sidesCeiling if derivation.sides < 0.0: sideAngle = -sideAngle spiral = lineation.Spiral(derivation.spiral, 0.5 * sideAngle / math.pi) for side in xrange(sidesCeiling + 1): unitPolar = euclidean.getWiddershinsUnitPolar(angleTotal) x = unitPolar.real * derivation.radiusArealized.real y = unitPolar.imag * derivation.radiusArealized.imag vertex = spiral.getSpiralPoint(unitPolar, Vector3(x, y)) angleTotal += sideAngle loop.append(vertex) radiusMaximum = 0.000001 * max(derivation.radiusArealized.real, derivation.radiusArealized.imag) loop = euclidean.getLoopWithoutCloseEnds(radiusMaximum, loop) lineation.setClosedAttribute(elementNode, derivation.revolutions) return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop, sideAngle)) def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." evaluate.setAttributesByArguments(['radius', 'start', 'end', 'revolutions'], arguments, elementNode) return getGeometryOutput(None, elementNode) def getNewDerivation(elementNode): 'Get new derivation.' return CircleDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class CircleDerivation: "Class to hold circle variables." def __init__(self, elementNode): 'Set defaults.' self.radius = lineation.getRadiusComplex(elementNode, complex(1.0, 1.0)) self.sides = evaluate.getEvaluatedFloat(None, elementNode, 'sides') if self.sides is None: radiusMaximum = max(self.radius.real, self.radius.imag) self.sides = evaluate.getSidesMinimumThreeBasedOnPrecisionSides(elementNode, radiusMaximum) self.radiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.radius, self.sides) self.start = evaluate.getEvaluatedFloat(0.0, elementNode, 'start') end = evaluate.getEvaluatedFloat(360.0, elementNode, 'end') self.revolutions = evaluate.getEvaluatedFloat(1.0, elementNode, 'revolutions') self.extent = evaluate.getEvaluatedFloat(end - self.start, elementNode, 'extent') self.extent += 360.0 * (self.revolutions - 1.0) self.spiral = evaluate.getVector3ByPrefix(None, elementNode, 'spiral') sfact-2011.12.18/fabmetheus_utilities/geometry/creation/concatenate.py000066400000000000000000000036501167321211700257270ustar00rootroot00000000000000""" Boolean geometry concatenation. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): 'Get triangle mesh from attribute dictionary.' if derivation is None: derivation = ConcatenateDerivation(elementNode) concatenatedList = euclidean.getConcatenatedList(derivation.target)[:] if len(concatenatedList) == 0: print('Warning, in concatenate there are no paths.') print(elementNode.attributes) return None if 'closed' not in elementNode.attributes: elementNode.attributes['closed'] = 'true' return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(concatenatedList)) def getGeometryOutputByArguments(arguments, elementNode): 'Get triangle mesh from attribute dictionary by arguments.' return getGeometryOutput(None, elementNode) def getNewDerivation(elementNode): 'Get new derivation.' return ConcatenateDerivation(elementNode) def processElementNode(elementNode): 'Process the xml element.' path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class ConcatenateDerivation: 'Class to hold concatenate variables.' def __init__(self, elementNode): 'Initialize.' self.target = evaluate.getTransformedPathsByKey([], elementNode, 'target') sfact-2011.12.18/fabmetheus_utilities/geometry/creation/extrude.py000066400000000000000000000460701167321211700251260ustar00rootroot00000000000000""" Boolean geometry extrusion. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities.vector3index import Vector3Index from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addLoop(derivation, endMultiplier, loopLists, path, portionDirectionIndex, portionDirections, vertexes): 'Add an indexed loop to the vertexes.' portionDirection = portionDirections[ portionDirectionIndex ] if portionDirection.directionReversed == True: loopLists.append([]) loops = loopLists[-1] interpolationOffset = derivation.interpolationDictionary['offset'] offset = interpolationOffset.getVector3ByPortion( portionDirection ) if endMultiplier is not None: if portionDirectionIndex == 0: setOffsetByMultiplier( interpolationOffset.path[1], interpolationOffset.path[0], endMultiplier, offset ) elif portionDirectionIndex == len( portionDirections ) - 1: setOffsetByMultiplier( interpolationOffset.path[-2], interpolationOffset.path[-1], endMultiplier, offset ) scale = derivation.interpolationDictionary['scale'].getComplexByPortion( portionDirection ) twist = derivation.interpolationDictionary['twist'].getYByPortion( portionDirection ) projectiveSpace = euclidean.ProjectiveSpace() if derivation.tiltTop is None: tilt = derivation.interpolationDictionary['tilt'].getComplexByPortion( portionDirection ) projectiveSpace = projectiveSpace.getByTilt( tilt ) else: normals = getNormals( interpolationOffset, offset, portionDirection ) normalFirst = normals[0] normalAverage = getNormalAverage(normals) if derivation.tiltFollow and derivation.oldProjectiveSpace is not None: projectiveSpace = derivation.oldProjectiveSpace.getNextSpace( normalAverage ) else: projectiveSpace = projectiveSpace.getByBasisZTop( normalAverage, derivation.tiltTop ) derivation.oldProjectiveSpace = projectiveSpace projectiveSpace.unbuckle( derivation.maximumUnbuckling, normalFirst ) projectiveSpace = projectiveSpace.getSpaceByXYScaleAngle( twist, scale ) loop = [] if ( abs( projectiveSpace.basisX ) + abs( projectiveSpace.basisY ) ) < 0.0001: vector3Index = Vector3Index(len(vertexes)) addOffsetAddToLists( loop, offset, vector3Index, vertexes ) loops.append(loop) return for point in path: vector3Index = Vector3Index(len(vertexes)) projectedVertex = projectiveSpace.getVector3ByPoint(point) vector3Index.setToVector3( projectedVertex ) addOffsetAddToLists( loop, offset, vector3Index, vertexes ) loops.append(loop) def addNegatives(derivation, negatives, paths): 'Add pillars output to negatives.' portionDirections = getSpacedPortionDirections(derivation.interpolationDictionary) for path in paths: loopLists = getLoopListsByPath(derivation, 1.000001, path, portionDirections) geometryOutput = triangle_mesh.getPillarsOutput(loopLists) negatives.append(geometryOutput) def addNegativesPositives(derivation, negatives, paths, positives): 'Add pillars output to negatives and positives.' portionDirections = getSpacedPortionDirections(derivation.interpolationDictionary) for path in paths: endMultiplier = None if not euclidean.getIsWiddershinsByVector3(path): endMultiplier = 1.000001 loopLists = getLoopListsByPath(derivation, endMultiplier, path, portionDirections) geometryOutput = triangle_mesh.getPillarsOutput(loopLists) if endMultiplier is None: positives.append(geometryOutput) else: negatives.append(geometryOutput) def addOffsetAddToLists(loop, offset, vector3Index, vertexes): 'Add an indexed loop to the vertexes.' vector3Index += offset loop.append(vector3Index) vertexes.append(vector3Index) def addPositives(derivation, paths, positives): 'Add pillars output to positives.' portionDirections = getSpacedPortionDirections(derivation.interpolationDictionary) for path in paths: loopLists = getLoopListsByPath(derivation, None, path, portionDirections) geometryOutput = triangle_mesh.getPillarsOutput(loopLists) positives.append(geometryOutput) def addSpacedPortionDirection( portionDirection, spacedPortionDirections ): 'Add spaced portion directions.' lastSpacedPortionDirection = spacedPortionDirections[-1] if portionDirection.portion - lastSpacedPortionDirection.portion > 0.003: spacedPortionDirections.append( portionDirection ) return if portionDirection.directionReversed > lastSpacedPortionDirection.directionReversed: spacedPortionDirections.append( portionDirection ) def addTwistPortions( interpolationTwist, remainderPortionDirection, twistPrecision ): 'Add twist portions.' lastPortionDirection = interpolationTwist.portionDirections[-1] if remainderPortionDirection.portion == lastPortionDirection.portion: return lastTwist = interpolationTwist.getYByPortion( lastPortionDirection ) remainderTwist = interpolationTwist.getYByPortion( remainderPortionDirection ) twistSegments = int( math.floor( abs( remainderTwist - lastTwist ) / twistPrecision ) ) if twistSegments < 1: return portionDifference = remainderPortionDirection.portion - lastPortionDirection.portion twistSegmentsPlusOne = float( twistSegments + 1 ) for twistSegment in xrange( twistSegments ): additionalPortion = portionDifference * float( twistSegment + 1 ) / twistSegmentsPlusOne portionDirection = PortionDirection( lastPortionDirection.portion + additionalPortion ) interpolationTwist.portionDirections.append( portionDirection ) def comparePortionDirection( portionDirection, otherPortionDirection ): 'Comparison in order to sort portion directions in ascending order of portion then direction.' if portionDirection.portion > otherPortionDirection.portion: return 1 if portionDirection.portion < otherPortionDirection.portion: return - 1 if portionDirection.directionReversed < otherPortionDirection.directionReversed: return - 1 return portionDirection.directionReversed > otherPortionDirection.directionReversed def getGeometryOutput(derivation, elementNode): 'Get triangle mesh from attribute dictionary.' if derivation is None: derivation = ExtrudeDerivation(elementNode) if len(euclidean.getConcatenatedList(derivation.target)) == 0: print('Warning, in extrude there are no paths.') print(elementNode.attributes) return None return getGeometryOutputByLoops(derivation, derivation.target) def getGeometryOutputByArguments(arguments, elementNode): 'Get triangle mesh from attribute dictionary by arguments.' return getGeometryOutput(None, elementNode) def getGeometryOutputByLoops(derivation, loops): 'Get geometry output by sorted, nested loops.' loops.sort(key=euclidean.getAreaVector3LoopAbsolute, reverse=True) complexLoops = euclidean.getComplexPaths(loops) nestedRings = [] for loopIndex, loop in enumerate(loops): complexLoop = complexLoops[loopIndex] leftPoint = euclidean.getLeftPoint(complexLoop) isInFilledRegion = euclidean.getIsInFilledRegion(complexLoops[: loopIndex] + complexLoops[loopIndex + 1 :], leftPoint) if isInFilledRegion == euclidean.isWiddershins(complexLoop): loop.reverse() nestedRing = euclidean.NestedRing() nestedRing.boundary = complexLoop nestedRing.vector3Loop = loop nestedRings.append(nestedRing) nestedRings = euclidean.getOrderedNestedRings(nestedRings) nestedRings = euclidean.getFlattenedNestedRings(nestedRings) portionDirections = getSpacedPortionDirections(derivation.interpolationDictionary) if len(nestedRings) < 1: return {} if len(nestedRings) == 1: geometryOutput = getGeometryOutputByNestedRing(derivation, nestedRings[0], portionDirections) return solid.getGeometryOutputByManipulation(derivation.elementNode, geometryOutput) shapes = [] for nestedRing in nestedRings: shapes.append(getGeometryOutputByNestedRing(derivation, nestedRing, portionDirections)) return solid.getGeometryOutputByManipulation(derivation.elementNode, {'union' : {'shapes' : shapes}}) def getGeometryOutputByNegativesPositives(elementNode, negatives, positives): 'Get triangle mesh from elementNode, negatives and positives.' positiveOutput = triangle_mesh.getUnifiedOutput(positives) if len(negatives) < 1: return solid.getGeometryOutputByManipulation(elementNode, positiveOutput) if len(positives) < 1: negativeOutput = triangle_mesh.getUnifiedOutput(negatives) return solid.getGeometryOutputByManipulation(elementNode, negativeOutput) return solid.getGeometryOutputByManipulation(elementNode, {'difference' : {'shapes' : [positiveOutput] + negatives}}) def getGeometryOutputByNestedRing(derivation, nestedRing, portionDirections): 'Get geometry output by sorted, nested loops.' loopLists = getLoopListsByPath(derivation, None, nestedRing.vector3Loop, portionDirections) outsideOutput = triangle_mesh.getPillarsOutput(loopLists) if len(nestedRing.innerNestedRings) < 1: return outsideOutput shapes = [outsideOutput] for nestedRing.innerNestedRing in nestedRing.innerNestedRings: loopLists = getLoopListsByPath(derivation, 1.000001, nestedRing.innerNestedRing.vector3Loop, portionDirections) shapes.append(triangle_mesh.getPillarsOutput(loopLists)) return {'difference' : {'shapes' : shapes}} def getLoopListsByPath(derivation, endMultiplier, path, portionDirections): 'Get loop lists from path.' vertexes = [] loopLists = [[]] derivation.oldProjectiveSpace = None for portionDirectionIndex in xrange(len(portionDirections)): addLoop(derivation, endMultiplier, loopLists, path, portionDirectionIndex, portionDirections, vertexes) return loopLists def getNewDerivation(elementNode): 'Get new derivation.' return ExtrudeDerivation(elementNode) def getNormalAverage(normals): 'Get normal.' if len(normals) < 2: return normals[0] return (normals[0] + normals[1]).getNormalized() def getNormals( interpolationOffset, offset, portionDirection ): 'Get normals.' normals = [] portionFrom = portionDirection.portion - 0.0001 portionTo = portionDirection.portion + 0.0001 if portionFrom >= 0.0: normals.append( ( offset - interpolationOffset.getVector3ByPortion( PortionDirection( portionFrom ) ) ).getNormalized() ) if portionTo <= 1.0: normals.append( ( interpolationOffset.getVector3ByPortion( PortionDirection( portionTo ) ) - offset ).getNormalized() ) return normals def getSpacedPortionDirections( interpolationDictionary ): 'Get sorted portion directions.' portionDirections = [] for interpolationDictionaryValue in interpolationDictionary.values(): portionDirections += interpolationDictionaryValue.portionDirections portionDirections.sort( comparePortionDirection ) if len( portionDirections ) < 1: return [] spacedPortionDirections = [ portionDirections[0] ] for portionDirection in portionDirections[1 :]: addSpacedPortionDirection( portionDirection, spacedPortionDirections ) return spacedPortionDirections def insertTwistPortions(derivation, elementNode): 'Insert twist portions and radian the twist.' interpolationDictionary = derivation.interpolationDictionary interpolationTwist = Interpolation().getByPrefixX(elementNode, derivation.twistPathDefault, 'twist') interpolationDictionary['twist'] = interpolationTwist for point in interpolationTwist.path: point.y = math.radians(point.y) remainderPortionDirections = interpolationTwist.portionDirections[1 :] interpolationTwist.portionDirections = [interpolationTwist.portionDirections[0]] if elementNode is not None: twistPrecision = setting.getTwistPrecisionRadians(elementNode) for remainderPortionDirection in remainderPortionDirections: addTwistPortions(interpolationTwist, remainderPortionDirection, twistPrecision) interpolationTwist.portionDirections.append(remainderPortionDirection) def processElementNode(elementNode): 'Process the xml element.' solid.processElementNodeByGeometry(elementNode, getGeometryOutput(None, elementNode)) def setElementNodeToEndStart(elementNode, end, start): 'Set elementNode attribute dictionary to a tilt following path from the start to end.' elementNode.attributes['path'] = [start, end] elementNode.attributes['tiltFollow'] = 'true' elementNode.attributes['tiltTop'] = Vector3(0.0, 0.0, 1.0) def setOffsetByMultiplier(begin, end, multiplier, offset): 'Set the offset by the multiplier.' segment = end - begin delta = segment * multiplier - segment offset.setToVector3(offset + delta) class ExtrudeDerivation: 'Class to hold extrude variables.' def __init__(self, elementNode): 'Initialize.' self.elementNode = elementNode self.interpolationDictionary = {} self.tiltFollow = evaluate.getEvaluatedBoolean(True, elementNode, 'tiltFollow') self.tiltTop = evaluate.getVector3ByPrefix(None, elementNode, 'tiltTop') self.maximumUnbuckling = evaluate.getEvaluatedFloat(5.0, elementNode, 'maximumUnbuckling') scalePathDefault = [Vector3(1.0, 1.0, 0.0), Vector3(1.0, 1.0, 1.0)] self.interpolationDictionary['scale'] = Interpolation().getByPrefixZ(elementNode, scalePathDefault, 'scale') self.target = evaluate.getTransformedPathsByKey([], elementNode, 'target') if self.tiltTop is None: offsetPathDefault = [Vector3(), Vector3(0.0, 0.0, 1.0)] self.interpolationDictionary['offset'] = Interpolation().getByPrefixZ(elementNode, offsetPathDefault, '') tiltPathDefault = [Vector3(), Vector3(0.0, 0.0, 1.0)] self.interpolationDictionary['tilt'] = Interpolation().getByPrefixZ(elementNode, tiltPathDefault, 'tilt') for point in self.interpolationDictionary['tilt'].path: point.x = math.radians(point.x) point.y = math.radians(point.y) else: offsetAlongDefault = [Vector3(), Vector3(1.0, 0.0, 0.0)] self.interpolationDictionary['offset'] = Interpolation().getByPrefixAlong(elementNode, offsetAlongDefault, '') self.twist = evaluate.getEvaluatedFloat(0.0, elementNode, 'twist') self.twistPathDefault = [Vector3(), Vector3(1.0, self.twist) ] insertTwistPortions(self, elementNode) class Interpolation: 'Class to interpolate a path.' def __init__(self): 'Set index.' self.interpolationIndex = 0 def __repr__(self): 'Get the string representation of this Interpolation.' return str(self.__dict__) def getByDistances(self): 'Get by distances.' beginDistance = self.distances[0] self.interpolationLength = self.distances[-1] - beginDistance self.close = abs(0.000001 * self.interpolationLength) self.portionDirections = [] oldDistance = -self.interpolationLength # so the difference should not be close for distance in self.distances: deltaDistance = distance - beginDistance portionDirection = PortionDirection(deltaDistance / self.interpolationLength) if abs(deltaDistance - oldDistance) < self.close: portionDirection.directionReversed = True self.portionDirections.append(portionDirection) oldDistance = deltaDistance return self def getByPrefixAlong(self, elementNode, path, prefix): 'Get interpolation from prefix and xml element along the path.' if len(path) < 2: print('Warning, path is too small in evaluate in Interpolation.') return if elementNode is None: self.path = path else: self.path = evaluate.getTransformedPathByPrefix(elementNode, path, prefix) self.distances = [0.0] previousPoint = self.path[0] for point in self.path[1 :]: distanceDifference = abs(point - previousPoint) self.distances.append(self.distances[-1] + distanceDifference) previousPoint = point return self.getByDistances() def getByPrefixX(self, elementNode, path, prefix): 'Get interpolation from prefix and xml element in the z direction.' if len(path) < 2: print('Warning, path is too small in evaluate in Interpolation.') return if elementNode is None: self.path = path else: self.path = evaluate.getTransformedPathByPrefix(elementNode, path, prefix) self.distances = [] for point in self.path: self.distances.append(point.x) return self.getByDistances() def getByPrefixZ(self, elementNode, path, prefix): 'Get interpolation from prefix and xml element in the z direction.' if len(path) < 2: print('Warning, path is too small in evaluate in Interpolation.') return if elementNode is None: self.path = path else: self.path = evaluate.getTransformedPathByPrefix(elementNode, path, prefix) self.distances = [] for point in self.path: self.distances.append(point.z) return self.getByDistances() def getComparison( self, first, second ): 'Compare the first with the second.' if abs( second - first ) < self.close: return 0 if second > first: return 1 return - 1 def getComplexByPortion( self, portionDirection ): 'Get complex from z portion.' self.setInterpolationIndexFromTo( portionDirection ) return self.oneMinusInnerPortion * self.startVertex.dropAxis() + self.innerPortion * self.endVertex.dropAxis() def getInnerPortion(self): 'Get inner x portion.' fromDistance = self.distances[ self.interpolationIndex ] innerLength = self.distances[ self.interpolationIndex + 1 ] - fromDistance if abs( innerLength ) == 0.0: return 0.0 return ( self.absolutePortion - fromDistance ) / innerLength def getVector3ByPortion( self, portionDirection ): 'Get vector3 from z portion.' self.setInterpolationIndexFromTo( portionDirection ) return self.oneMinusInnerPortion * self.startVertex + self.innerPortion * self.endVertex def getYByPortion( self, portionDirection ): 'Get y from x portion.' self.setInterpolationIndexFromTo( portionDirection ) return self.oneMinusInnerPortion * self.startVertex.y + self.innerPortion * self.endVertex.y def setInterpolationIndex( self, portionDirection ): 'Set the interpolation index.' self.absolutePortion = self.distances[0] + self.interpolationLength * portionDirection.portion interpolationIndexes = range( 0, len( self.distances ) - 1 ) if portionDirection.directionReversed: interpolationIndexes.reverse() for self.interpolationIndex in interpolationIndexes: begin = self.distances[ self.interpolationIndex ] end = self.distances[ self.interpolationIndex + 1 ] if self.getComparison( begin, self.absolutePortion ) != self.getComparison( end, self.absolutePortion ): return def setInterpolationIndexFromTo( self, portionDirection ): 'Set the interpolation index, the start vertex and the end vertex.' self.setInterpolationIndex( portionDirection ) self.innerPortion = self.getInnerPortion() self.oneMinusInnerPortion = 1.0 - self.innerPortion self.startVertex = self.path[ self.interpolationIndex ] self.endVertex = self.path[ self.interpolationIndex + 1 ] class PortionDirection: 'Class to hold a portion and direction.' def __init__( self, portion ): 'Initialize.' self.directionReversed = False self.portion = portion def __repr__(self): 'Get the string representation of this PortionDirection.' return '%s: %s' % ( self.portion, self.directionReversed ) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/gear.py000066400000000000000000001502351167321211700243630ustar00rootroot00000000000000""" This page is in the table of contents. The gear script can generate a spur gear couple, a bevel gear couple, a ring gear couple and a rack & pinion couple. A helix pattern can be added to each gear type. All the gear types have a clearance and all the teeth can be beveled. A keyway, shaft and lightening holes can be added to all the round gears, and rack holes can be added to the rack. The script can output solid gears or only the gear profiles. Both gears of the couple can be generated or just one. The couple has a pinion gear and a complement. ==Examples== The link text includes the distinguishing parameters. Each svg page was generated from an xml page of the same root name using carve. For example, gear.svg was generated by clicking 'Carve' on the carve tool panel and choosing gear.xml in the file chooser. Each generated svg file has the xml fabmetheus element without comments towards the end of the file. To see it, open the svg file in a text editor and search for 'fabmetheus' If you copy that into a new text document, add the line '' at the beginning and then give it a file name with the extension '.xml', you could then generate another svg file using carve. ===Bevel=== Bevel gear couple. gear operatingAngle=90 ===Collar=== Spur gear couple and each gear has a collar. gear complementCollarLengthOverFaceWidth='1' pinionCollarLengthOverFaceWidth='1' shaftRadius='5' ===Gear=== Default spur gear with no parameters. gear ===Keyway=== Spur gear couple and each gear has a collar and defined keyway. gear complementCollarLengthOverFaceWidth='1' keywayRadius='2' pinionCollarLengthOverFaceWidth='1' shaftRadius='5' ===Rack=== Rack and pinion couple. gear teethComplement='0' ===Rack Hole=== Rack and pinion couple, with holes in the rack. gear rackHoleRadiusOverWidth='0.2' rackWidthOverFaceWidth='2' teethComplement='0' ===Ring=== Pinion and ring gear. gear teethComplement='-23' ===Shaft=== Spur gear couple and each gear has a square shaft hole. gear shaftRadius='5' ===Shaft Top=== Spur gear couple and each gear has a round shaft hole, truncated on top. gear shaftRadius='5' shaftSides='13' shaftDepthTop='2' ===Spur Helix=== Spur gear couple with the gear teeth following a helix path. gear helixAngle='45' ===Spur Herringbone=== Spur gear couple with the gear teeth following a herringbone path. gear helixAngle='45' helixType='herringbone' ===Spur Parabolic=== Spur gear couple with the gear teeth following a parabolic path. gear helixAngle='45' helixType='parabolic' ===Spur Profile=== Spur gear couple profile. Since this is just a horizontal path, it can not be sliced, so the path is then extruded to create a solid which can be sliced and viewed. gear id='spurProfile' faceWidth='0' | extrude target='=document.getElementByID(spurProfile) ==Parameters== ===Center Distance=== Default is such that the pitch radius works out to twenty. Defines the distance between the gear centers. ===Clearance Couplet=== ====Clearance Over Wavelength==== Default is 0.1. Defines the ratio of the clearance over the wavelength of the gear profile. The wavelength is the arc distance between the gear teeth. ====Clearance==== Default is the 'Clearance Over Wavelength' times the wavelength. Defines the clearance between the gear tooth and the other gear of the couple. If the clearance is zero, the outside of the gear tooth will touch the other gear. If the clearance is too high, the gear teeth will be long and weak. ===Collar Addendum Couplet=== ====Collar Addendum Over Radius==== Default is one. Defines the ratio of the collar addendum over the shaft radius. ====Collar Addendum==== Default is the 'Collar Addendum Over Radius' times the shaft radius. Defines the collar addendum. ===Complement Collar Length Couplet=== ====Complement Collar Length Over Face Width==== Default is zero. Defines the ratio of the complement collar length over the face width. ====Complement Collar Length==== Default is the 'Complement Collar Length Over Face Width' times the face width. Defines the complement collar length. If the complement collar length is zero, there will not be a collar on the complement gear. ===Creation Type=== Default is 'both'. ====Both==== When selected, the pinion and complement will be generated. ====Complement==== When selected, only the complement gear or rack will be generated. ====Pinion==== When selected, only the pinion will be generated. ===Face Width=== Default is ten. Defines the face width. ===Gear Hole Paths=== Default is empty. Defines the centers of the gear holes. If the gear hole paths parameter is the default empty, then the centers of the gear holes will be generated from other parameters. ===Helix Angle=== Default is zero. ===Helix Path=== Default is empty. Defines the helix path of the gear teeth. If the helix path is the default empty, then the helix will be generated from the helix angle and helix type. ===Helix Type=== Default is 'basic'. ====Basic==== When selected, the helix will be basic. ====Herringbone==== When selected, the helix will have a herringbone pattern. ====Parabolic==== When selected, the helix will have a parabolic pattern. ===Keyway Radius Couplet=== ====Keyway Radius Over Radius==== Default is half. Defines the ratio of the keyway radius over the shaft radius. ====Keyway Radius==== Default is the 'Keyway Radius Over Radius' times the shaft radius. Defines the keyway radius. If the keyway radius is zero, there will not be a keyway on the collar. ===Lightening Hole Margin Couplet=== ====Lightening Hole Margin Over Rim Dedendum==== Default is one. Defines the ratio of the lightening hole margin over the rim dedendum. ====Lightening Hole Margin==== Default is the 'Lightening Hole Margin Over Rim Dedendum' times the rim dedendum. Defines the minimum margin between lightening holes. ===Lightening Hole Minimum Radius=== Default is one. Defines the minimum radius of the lightening holes. ===Move Type=== Default is 'separate'. ====None==== When selected, the gears will be not be moved and will therefore overlap. Afterwards the write plugin could be used to write each gear to a different file, so they can be fabricated in separate operations. ====Mesh==== When selected, the gears will be separated horizontally so that they just mesh. This is useful to test if the gears mesh properly. ====Separate==== When selected, the gears will be separated horizontally with a gap between them. ====Vertical==== When selected, the gears will be separated vertically. ===Operating Angle=== Default is 180 degrees. Defines the operating angle between the gear axes. If the operating angle is not 180 degrees, a bevel gear couple will be generated. ===Pinion Collar Length Couplet=== ====Pinion Collar Length Over Face Width==== Default is zero. Defines the ratio of the pinion collar length over the face width. ====Pinion Collar Length==== Default is the 'Pinion Collar Length Over Face Width' times the face width. Defines the pinion collar length. If the pinion collar length is zero, there will not be a collar on the pinion gear. ===Pitch Radius=== Default is twenty if the pitch radius has not been set. If the center distance is set, the default pitch radius is the center distance times the number of pinion teeth divided by the total number of gear teeth. Defines the pinion pitch radius. ===Plate Clearance Couplet=== ====Plate Clearance Over Length==== Default is 0.2. Defines the ratio of the plate clearance over the plate length. ====Plate Clearance==== Default is the 'Plate Clearance Over Length' times the plate length. Defines the clearance between the pinion and the plate of the ring gear. If the clearance is zero, they will touch. ===Plate Length Couplet=== ====Plate Length Over Face Width==== Default is half. Defines the ratio of the plate length over the face width. ====Plate Length==== Default is the 'Plate Length Over Face Width' times the face width. Defines the length of the plate of the ring gear. ===Pressure Angle=== Default is twenty degrees. Defines the pressure angle of the gear couple. ===Profile Surfaces=== Default is eleven. Defines the number of profile surfaces. ===Rack Hole Below Over Width Couplet=== ====Rack Hole Below Over Width==== Default is 0.6. Defines the ratio of the distance below the pitch of the rack holes over the rack width. ====Rack Hole Below==== Default is the 'Rack Hole Below Over Width' times the rack width. Defines the the distance below the pitch of the rack holes. ===Rack Hole Radius Couplet=== ====Rack Hole Radius Over Width==== Default is zero. Defines the ratio of the rack hole radius over the rack width. ====Rack Hole Radius==== Default is the 'Rack Hole Radius Over Width' times the rack width. Defines the radius of the rack holes. If the rack hole radius is zero, there won't be any rack holes. ===Rack Hole Step Over Width Couplet=== ====Rack Hole Step Over Width==== Default is one. Defines the ratio of the rack hole step over the rack width. ====Rack Hole Step==== Default is the 'Rack Hole Step Over Width' times the rack width. Defines the horizontal step distance between the rack holes. ===Rack Length Over Radius Couplet=== ====Rack Length Over Radius==== Default is two times pi. Defines the ratio of the rack length over the pitch radius. ====Rack Length==== Default is the 'Rack Length Over Radius' times the pitch radius. Defines the rack length. ===Rack Width Couplet=== ====Rack Width Over Face Width==== Default is one. Defines the ratio of the rack width over the face width. ====Rack Width==== Default is the 'Rack Width Over Face Width' times the face width. Defines the rack width. ===Rim Dedendum Couplet=== ====Rim Dedendum Over Radius==== Default is 0.2. Defines the ratio of the rim dedendum over the pitch radius. ====Rim Dedendum==== Default is the 'Rim Dedendum Over Radius' times the pitch radius. Defines the rim dedendum of the gear. ===Root Bevel Couplet=== ====Root Bevel Over Clearance==== Default is half. Defines the ratio of the root bevel over the clearance. ====Root Bevel==== Default is the 'Root Bevel Over Clearance' times the clearance. Defines the bevel at the root of the gear tooth. ===Shaft Depth Bottom Couplet=== ====Shaft Depth Bottom Over Radius==== Default is zero. Defines the ratio of the bottom shaft depth over the shaft radius. ====Shaft Depth Bottom==== Default is the 'Shaft Depth Bottom Over Radius' times the shaft radius. Defines the bottom shaft depth. ===Shaft Depth Top Couplet=== ====Shaft Depth Top Over Radius==== Default is zero. Defines the ratio of the top shaft depth over the shaft radius. ====Shaft Depth Top==== Default is the 'Shaft Depth Top Over Radius' times the shaft radius. Defines the top shaft depth. ===Shaft Path=== Default is empty. Defines the path of the shaft hole. If the shaft path is the default empty, then the shaft path will be generated from the shaft depth bottom, shaft depth top, shaft radius and shaft sides. ===Shaft Radius Couplet=== ====Shaft Radius Over Pitch Radius==== Default is zero. Defines the ratio of the shaft radius over the pitch radius. ====Shaft Radius==== Default is the 'Shaft Radius Over Pitch Radius' times the pitch radius. Defines the shaft radius. If the shaft radius is zero there will not be a shaft hole. ===Shaft Sides=== Default is four. Defines the number of shaft sides. ===Teeth Pinion=== Default is seven. Defines the number of teeth in the pinion. ===Teeth Complement=== Default is seventeen. Defines the number of teeth in the complement of the gear couple. If the number of teeth is positive, the gear couple will be a spur or bevel type. If the number of teeth is zero, the gear couple will be a rack and pinion. If the number of teeth is negative, the gear couple will be a spur and ring. ===Tip Bevel Couplet=== ====Tip Bevel Over Clearance==== Default is 0.1. Defines the ratio of the tip bevel over the clearance. ====Tip Bevel==== Default is the 'Tip Bevel Over Clearance' times the clearance. Defines the bevel at the tip of the gear tooth. ===Tooth Thickness Multiplier=== Default is 0.99999. Defines the amount the thickness of the tooth will multiplied. If when the gears are produced, they mesh too tightly, you can reduce the tooth thickness multiplier so that they mesh with reasonable tightness. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import extrude from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import shaft from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.creation import teardrop from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities.vector3index import Vector3Index from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addBevelGear(derivation, extrudeDerivation, pitchRadius, positives, teeth, vector3GearProfile): "Get extrude output for a cylinder gear." totalPitchRadius = derivation.pitchRadiusComplement + derivation.pitchRadius totalTeeth = derivation.teethPinion + derivation.teethComplement portionDirections = extrude.getSpacedPortionDirections(extrudeDerivation.interpolationDictionary) loopLists = extrude.getLoopListsByPath(extrudeDerivation, None, vector3GearProfile[0], portionDirections) firstLoopList = loopLists[0] gearOverPinion = float(totalTeeth - teeth) / float(teeth) thirdLayerHeight = 0.33333333333 * setting.getLayerThickness(derivation.elementNode) pitchRadian = math.atan(math.sin(derivation.operatingRadian) / (gearOverPinion + math.cos(derivation.operatingRadian))) coneDistance = pitchRadius / math.sin(pitchRadian) apex = Vector3(0.0, 0.0, math.sqrt(coneDistance * coneDistance - pitchRadius * pitchRadius)) cosPitch = apex.z / coneDistance sinPitch = math.sin(pitchRadian) for loop in firstLoopList: for point in loop: alongWay = point.z / coneDistance oneMinusAlongWay = 1.0 - alongWay pointComplex = point.dropAxis() pointComplexLength = abs(pointComplex) deltaRadius = pointComplexLength - pitchRadius cosDeltaRadius = cosPitch * deltaRadius sinDeltaRadius = sinPitch * deltaRadius pointComplex *= (cosDeltaRadius + pitchRadius) / pointComplexLength point.x = pointComplex.real point.y = pointComplex.imag point.z += sinDeltaRadius point.x *= oneMinusAlongWay point.y *= oneMinusAlongWay addBottomLoop(-thirdLayerHeight, firstLoopList) topLoop = firstLoopList[-1] topAddition = [] topZ = euclidean.getTopPath(topLoop) + thirdLayerHeight oldIndex = topLoop[-1].index for point in topLoop: oldIndex += 1 topAddition.append(Vector3Index(oldIndex, 0.8 * point.x, 0.8 * point.y, topZ)) firstLoopList.append(topAddition) translation = Vector3(0.0, 0.0, -euclidean.getBottomByPaths(firstLoopList)) euclidean.translateVector3Paths(firstLoopList, translation) geometryOutput = triangle_mesh.getPillarsOutput(loopLists) positives.append(geometryOutput) def addBottomLoop(deltaZ, loops): "Add bottom loop to loops." bottomLoop = loops[0] bottomAddition = [] bottomZ = euclidean.getBottomByPath(bottomLoop) + deltaZ for point in bottomLoop: bottomAddition.append(Vector3Index(len(bottomAddition), point.x, point.y, bottomZ)) loops.insert(0, bottomAddition) numberOfVertexes = 0 for loop in loops: for point in loop: point.index = numberOfVertexes numberOfVertexes += 1 def addCollarShaft(collarLength, derivation, elementNode, negatives, positives): 'Add collar.' if collarLength <= 0.0: addShaft(derivation, negatives, positives) return connectionEnd = Vector3(0.0, 0.0, derivation.faceWidth + collarLength) copyShallow = derivation.elementNode.getCopyShallow() copyShallow.attributes['path'] = [Vector3(0.0, 0.0, derivation.faceWidth), connectionEnd] collarDerivation = extrude.ExtrudeDerivation(copyShallow) addCollarShaftSetDerivation(collarDerivation, collarLength, derivation, elementNode, negatives, positives) def addCollarShaftSetDerivation(collarDerivation, collarLength, derivation, elementNode, negatives, positives): 'Add collar and shaft.' collarSides = evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, derivation.shaftRimRadius) collarProfile = euclidean.getComplexPolygon(complex(), derivation.shaftRimRadius, collarSides) vector3CollarProfile = euclidean.getVector3Path(collarProfile) extrude.addPositives(collarDerivation, [vector3CollarProfile], positives) addShaft(derivation, negatives, positives) drillZ = derivation.faceWidth + 0.5 * collarLength drillEnd = Vector3(0.0, derivation.shaftRimRadius, drillZ) drillStart = Vector3(0.0, 0.0, drillZ) teardrop.addNegativesByRadius(elementNode, drillEnd, negatives, derivation.keywayRadius, drillStart) def addLighteningHoles(derivation, gearHolePaths, negatives, pitchRadius, positives): "Add lightening holes." positiveVertexes = matrix.getVertexes(positives) bottomPath = euclidean.getTopPath(positiveVertexes) topPath = euclidean.getBottomByPath(positiveVertexes) copyShallow = derivation.elementNode.getCopyShallow() copyShallow.attributes['path'] = [Vector3(0.0, 0.0, bottomPath), Vector3(0.0, 0.0, topPath)] extrudeDerivation = extrude.ExtrudeDerivation(copyShallow) vector3LighteningHoles = getLighteningHoles(derivation, gearHolePaths, pitchRadius) extrude.addNegativesPositives(extrudeDerivation, negatives, vector3LighteningHoles, positives) def addRackHole(derivation, elementNode, vector3RackProfiles, x): "Add rack hole to vector3RackProfiles." rackHole = euclidean.getComplexPolygon(complex(x, -derivation.rackHoleBelow), derivation.rackHoleRadius, -13) vector3RackProfiles.append(euclidean.getVector3Path(rackHole)) def addRackHoles(derivation, elementNode, vector3RackProfiles): "Add rack holes to vector3RackProfiles." if len(derivation.gearHolePaths) > 0: vector3RackProfiles += derivation.gearHolePaths return if derivation.rackHoleRadius <= 0.0: return addRackHole(derivation, elementNode, vector3RackProfiles, 0.0) rackHoleMargin = derivation.rackHoleRadius + derivation.rackHoleRadius rackHoleSteps = int(math.ceil((derivation.rackDemilength - rackHoleMargin) / derivation.rackHoleStep)) for rackHoleIndex in xrange(1, rackHoleSteps): x = float(rackHoleIndex) * derivation.rackHoleStep addRackHole(derivation, elementNode, vector3RackProfiles, -x) addRackHole(derivation, elementNode, vector3RackProfiles, x) def addShaft(derivation, negatives, positives): "Add shaft." if len(derivation.shaftPath) < 3: return positiveVertexes = matrix.getVertexes(positives) bottomPath = euclidean.getTopPath(positiveVertexes) topPath = euclidean.getBottomByPath(positiveVertexes) copyShallow = derivation.elementNode.getCopyShallow() copyShallow.attributes['path'] = [Vector3(0.0, 0.0, bottomPath), Vector3(0.0, 0.0, topPath)] extrudeDerivation = extrude.ExtrudeDerivation(copyShallow) extrude.addNegativesPositives(extrudeDerivation, negatives, [derivation.shaftPath], positives) def getAxialMargin(circleRadius, numberOfSides, polygonRadius): 'Get axial margin.' return polygonRadius * math.sin(math.pi / float(numberOfSides)) - circleRadius def getBevelPath(begin, bevel, center, end): 'Get bevel path.' centerMinusBegin = center - begin centerMinusBeginLength = abs(centerMinusBegin) endMinusCenter = end - center endMinusCenterLength = abs(endMinusCenter) endMinusCenter /= endMinusCenterLength maximumExtensionLength = 0.333333333 * endMinusCenterLength if centerMinusBeginLength <= bevel * 1.5: extensionLength = min(maximumExtensionLength, centerMinusBeginLength) return [complex(center.real, center.imag) + extensionLength * endMinusCenter] centerMinusBegin *= (centerMinusBeginLength - bevel) / centerMinusBeginLength extensionLength = min(maximumExtensionLength, bevel) bevelPath = [complex(center.real, center.imag) + extensionLength * endMinusCenter] bevelPath.append(begin + centerMinusBegin) return bevelPath def getGearPaths(derivation, pitchRadius, teeth, toothProfile): 'Get gear paths.' if teeth < 0: return getGearProfileAnnulus(derivation, pitchRadius, teeth, toothProfile) if teeth == 0: return [getGearProfileRack(derivation, toothProfile)] return [getGearProfileCylinder(teeth, toothProfile)] def getGearProfileAnnulus(derivation, pitchRadius, teeth, toothProfile): 'Get gear profile for an annulus gear.' gearProfileCylinder = getGearProfileCylinder(teeth, toothProfile) annulusRadius = derivation.dedendum + derivation.rimDedendum - pitchRadius return [euclidean.getComplexPolygon(complex(), annulusRadius, -teeth, 0.5 * math.pi), gearProfileCylinder] def getGearProfileCylinder(teeth, toothProfile): 'Get gear profile for a cylinder gear.' gearProfile = [] toothAngleRadian = 2.0 * math.pi / float(teeth) totalToothAngle = 0.0 for toothIndex in xrange(abs(teeth)): for toothPoint in toothProfile: gearProfile.append(toothPoint * euclidean.getWiddershinsUnitPolar(totalToothAngle)) totalToothAngle += toothAngleRadian return gearProfile def getGearProfileRack(derivation, toothProfile): 'Get gear profile for rack.' derivation.extraRackDemilength = 0.0 for complexPoint in derivation.helixPath: derivation.extraRackDemilength = max(abs(derivation.helixHeight * complexPoint.imag), derivation.extraRackDemilength) rackDemilengthPlus = derivation.rackDemilength if derivation.faceWidth > 0.0: derivation.extraRackDemilength *= 1.1 rackDemilengthPlus += derivation.extraRackDemilength teethRack = int(math.ceil(rackDemilengthPlus / derivation.wavelength)) gearProfile = [] for toothIndex in xrange(-teethRack, teethRack + 1): translateComplex = complex(-toothIndex * derivation.wavelength, 0.0) translatedPath = euclidean.getTranslatedComplexPath(toothProfile, translateComplex) gearProfile += translatedPath gearProfile = euclidean.getHorizontallyBoundedPath(rackDemilengthPlus, -rackDemilengthPlus, gearProfile) firstPoint = gearProfile[0] lastPoint = gearProfile[-1] rackWidth = derivation.rackWidth minimumRackWidth = 1.1 * derivation.dedendum if rackWidth < minimumRackWidth: rackWidth = minimumRackWidth print('Warning, rackWidth is too small in getGearProfileRack in gear.') print('RackWidth will be set to a bit more than the dedendum.') gearProfile += [complex(lastPoint.real, -rackWidth),complex(firstPoint.real, -rackWidth)] return gearProfile def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = GearDerivation(elementNode) creationFirst = derivation.creationType.lower()[: 1] toothProfileComplement = getToothProfile(derivation, derivation.pitchRadiusComplement, derivation.teethComplement) pinionProfile = getGearProfileCylinder(derivation.teethPinion, derivation.pinionToothProfile) complementPaths = getGearPaths( derivation, derivation.pitchRadiusComplement, derivation.teethComplement, toothProfileComplement) vector3PinionProfile = euclidean.getVector3Path(pinionProfile) vector3ComplementPaths = euclidean.getVector3Paths(complementPaths) translation = Vector3() moveFirst = derivation.moveType.lower()[: 1] if moveFirst != 'n': distance = derivation.pitchRadius if moveFirst == 'm': distance += derivation.pitchRadiusComplement else: distance += abs(derivation.pitchRadiusComplement) decimalPlaces = 1 - int(math.floor(math.log10(distance))) distance += derivation.halfWavelength + derivation.halfWavelength distance = round(1.15 * distance, decimalPlaces) translation = Vector3(0.0, -distance) if derivation.faceWidth <=0.0: return getPathOutput( creationFirst, derivation, elementNode, translation, vector3ComplementPaths, vector3PinionProfile) pitchRadius = derivation.pitchRadius teeth = derivation.teethPinion twist = derivation.helixHeight / derivation.pitchRadius extrudeOutputPinion = getOutputCylinder( derivation.pinionCollarLength, derivation, elementNode, None, pitchRadius, teeth, twist, [vector3PinionProfile]) if creationFirst == 'p': return extrudeOutputPinion teeth = derivation.teethComplement extrudeOutputSecond = None if teeth == 0: extrudeOutputSecond = getOutputRack(derivation, elementNode, vector3ComplementPaths[0]) else: twist = -derivation.helixHeight / derivation.pitchRadiusComplement extrudeOutputSecond = getOutputCylinder( derivation.complementCollarLength, derivation, elementNode, derivation.gearHolePaths, derivation.pitchRadiusComplement, teeth, twist, vector3ComplementPaths) if creationFirst == 'c': return extrudeOutputSecond gearVertexes = matrix.getVertexes(extrudeOutputSecond) if moveFirst == 'v': translation = Vector3(0.0, 0.0, euclidean.getTopPath(gearVertexes)) euclidean.translateVector3Path(matrix.getVertexes(extrudeOutputPinion), translation) else: euclidean.translateVector3Path(gearVertexes, translation) return {'group' : {'shapes' : [extrudeOutputPinion, extrudeOutputSecond]}} def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." return getGeometryOutput(None, elementNode) def getHalfwave(pitchRadius, teeth): 'Get tooth halfwave.' return pitchRadius * math.pi / float(teeth) def getHelixComplexPath(derivation, elementNode): 'Set gear helix path.' helixTypeFirstCharacter = derivation.helixType.lower()[: 1] if helixTypeFirstCharacter == 'b': return [complex(), complex(1.0, 1.0)] if helixTypeFirstCharacter == 'h': return [complex(), complex(0.5, 0.5), complex(1.0, 0.0)] if helixTypeFirstCharacter == 'p': helixComplexPath = [] x = 0.0 xStep = setting.getLayerThickness(elementNode) / derivation.faceWidth justBelowOne = 1.0 - 0.5 * xStep while x < justBelowOne: distanceFromCenter = 0.5 - x parabolicTwist = 0.25 - distanceFromCenter * distanceFromCenter helixComplexPath.append(complex(x, parabolicTwist)) x += xStep helixComplexPath.append(complex(1.0, 0.0)) return helixComplexPath print('Warning, the helix type was not one of (basic, herringbone or parabolic) in getHelixComplexPath in gear for:') print(derivation.helixType) print(derivation.elementNode) def getLiftedOutput(derivation, geometryOutput): "Get extrude output for a rack." if derivation.moveType.lower()[: 1] == 'm': return geometryOutput geometryOutputVertexes = matrix.getVertexes(geometryOutput) translation = Vector3(0.0, 0.0, -euclidean.getBottomByPath(geometryOutputVertexes)) euclidean.translateVector3Path(geometryOutputVertexes, translation) return geometryOutput def getLighteningHoles(derivation, gearHolePaths, pitchRadius): 'Get cutout circles.' if gearHolePaths is not None: if len(gearHolePaths) > 0: return gearHolePaths innerRadius = abs(pitchRadius) - derivation.dedendum lighteningHoleOuterRadius = innerRadius - derivation.rimDedendum shaftRimRadius = max(derivation.shaftRimRadius, (lighteningHoleOuterRadius) * (0.5 - math.sqrt(0.1875))) lighteningHoleRadius = 0.5 * (lighteningHoleOuterRadius - derivation.shaftRimRadius) if lighteningHoleRadius < derivation.lighteningHoleMinimumRadius: return [] lighteningHoles = [] numberOfLighteningHoles = 3 polygonRadius = lighteningHoleOuterRadius - lighteningHoleRadius rimDemiwidth = 0.5 * derivation.lighteningHoleMargin axialMargin = getAxialMargin(lighteningHoleRadius, numberOfLighteningHoles, polygonRadius) if axialMargin < rimDemiwidth: while axialMargin < rimDemiwidth: lighteningHoleRadius *= 0.999 if lighteningHoleRadius < derivation.lighteningHoleMinimumRadius: return [] axialMargin = getAxialMargin(lighteningHoleRadius, numberOfLighteningHoles, polygonRadius) else: newNumberOfLighteningHoles = numberOfLighteningHoles while axialMargin > rimDemiwidth: numberOfLighteningHoles = newNumberOfLighteningHoles newNumberOfLighteningHoles += 2 axialMargin = getAxialMargin(lighteningHoleRadius, newNumberOfLighteningHoles, polygonRadius) sideAngle = 2.0 * math.pi / float(numberOfLighteningHoles) startAngle = 0.0 for lighteningHoleIndex in xrange(numberOfLighteningHoles): unitPolar = euclidean.getWiddershinsUnitPolar(startAngle) lighteningHole = euclidean.getComplexPolygon(unitPolar * polygonRadius, lighteningHoleRadius, -13) lighteningHoles.append(lighteningHole) startAngle += sideAngle return euclidean.getVector3Paths(lighteningHoles) def getNewDerivation(elementNode): 'Get new derivation.' return GearDerivation(elementNode) def getOutputCylinder( collarLength, derivation, elementNode, gearHolePaths, pitchRadius, teeth, twist, vector3GearProfile): "Get extrude output for a cylinder gear." copyShallow = derivation.elementNode.getCopyShallow() copyShallow.attributes['path'] = [Vector3(), Vector3(0.0, 0.0, derivation.faceWidth)] extrudeDerivation = extrude.ExtrudeDerivation(copyShallow) negatives = [] positives = [] if twist != 0.0: twistDegrees = math.degrees(twist) extrudeDerivation.twistPathDefault = [] for complexPoint in derivation.helixPath: extrudeDerivation.twistPathDefault.append(Vector3(complexPoint.real, twistDegrees * complexPoint.imag)) extrude.insertTwistPortions(extrudeDerivation, elementNode) if derivation.operatingAngle != 180.0: addBevelGear(derivation, extrudeDerivation, pitchRadius, positives, teeth, vector3GearProfile) addCollarShaft(collarLength, derivation, elementNode, negatives, positives) return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives) if pitchRadius > 0: extrude.addNegativesPositives(extrudeDerivation, negatives, vector3GearProfile, positives) addLighteningHoles(derivation, gearHolePaths, negatives, pitchRadius, positives) addCollarShaft(collarLength, derivation, elementNode, negatives, positives) return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives) if derivation.plateLength <= 0.0: extrude.addNegativesPositives(extrudeDerivation, negatives, vector3GearProfile, positives) return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives) portionDirections = extrude.getSpacedPortionDirections(extrudeDerivation.interpolationDictionary) outerGearProfile = vector3GearProfile[0] outerLoopLists = extrude.getLoopListsByPath(extrudeDerivation, None, outerGearProfile, portionDirections) addBottomLoop(-derivation.plateClearance, outerLoopLists[0]) geometryOutput = triangle_mesh.getPillarsOutput(outerLoopLists) positives.append(geometryOutput) innerLoopLists = extrude.getLoopListsByPath(extrudeDerivation, None, vector3GearProfile[1], portionDirections) addBottomLoop(-derivation.plateClearance, innerLoopLists[0]) geometryOutput = triangle_mesh.getPillarsOutput(innerLoopLists) negatives.append(geometryOutput) connectionStart = Vector3(0.0, 0.0, -derivation.plateLength) copyShallow = derivation.elementNode.getCopyShallow() copyShallow.attributes['path'] = [connectionStart, Vector3(0.0, 0.0, -derivation.plateClearance)] plateDerivation = extrude.ExtrudeDerivation(copyShallow) extrude.addNegativesPositives(plateDerivation, negatives, [outerGearProfile], positives) vector3LighteningHoles = getLighteningHoles(derivation, gearHolePaths, pitchRadius) extrude.addNegativesPositives(plateDerivation, negatives, vector3LighteningHoles, positives) addShaft(derivation, negatives, positives) positiveOutput = triangle_mesh.getUnifiedOutput(positives) annulusPlateOutput = {'difference' : {'shapes' : [positiveOutput] + negatives}} if collarLength <= 0.0: outputCylinder = solid.getGeometryOutputByManipulation(elementNode, annulusPlateOutput) return getLiftedOutput(derivation, outputCylinder) negatives = [] positives = [] connectionEnd = Vector3(0.0, 0.0, derivation.faceWidth + collarLength) copyShallow = derivation.elementNode.getCopyShallow() copyShallow.attributes['path'] = [Vector3(0.0, 0.0, -derivation.plateClearance), connectionEnd] collarDerivation = extrude.ExtrudeDerivation(copyShallow) addCollarShaftSetDerivation(collarDerivation, collarLength, derivation, elementNode, negatives, positives) collarOutput = {'difference' : {'shapes' : positives + negatives}} cylinderOutput = {'union' : {'shapes' : [annulusPlateOutput, collarOutput]}} outputCylinder = solid.getGeometryOutputByManipulation(elementNode, cylinderOutput) return getLiftedOutput(derivation, outputCylinder) def getOutputRack(derivation, elementNode, vector3GearProfile): "Get extrude output for a rack." path = [] for complexPoint in derivation.helixPath: point = Vector3(derivation.helixHeight * complexPoint.imag, 0.0, derivation.faceWidth * complexPoint.real) path.append(point) copyShallow = derivation.elementNode.getCopyShallow() copyShallow.attributes['path'] = path extrudeDerivation = extrude.ExtrudeDerivation(copyShallow) negatives = [] positives = [] vector3RackProfiles = [vector3GearProfile] if derivation.extraRackDemilength > 0.0: yMaximum = -912345678.0 yMinimum = 912345678.0 for point in vector3GearProfile: yMaximum = max(point.y, yMaximum) yMinimum = min(point.y, yMinimum) muchLessThanWidth = 0.01 * derivation.rackWidth yMaximum += muchLessThanWidth yMinimum -= muchLessThanWidth extraRackLength = derivation.extraRackDemilength + derivation.extraRackDemilength rackDemilengthPlus = derivation.rackDemilength + extraRackLength leftNegative = [ Vector3(-derivation.rackDemilength, yMaximum), Vector3(-derivation.rackDemilength, yMinimum), Vector3(-rackDemilengthPlus, yMinimum), Vector3(-rackDemilengthPlus, yMaximum)] vector3RackProfiles.append(leftNegative) rightNegative = [ Vector3(rackDemilengthPlus, yMaximum), Vector3(rackDemilengthPlus, yMinimum), Vector3(derivation.rackDemilength, yMinimum), Vector3(derivation.rackDemilength, yMaximum)] vector3RackProfiles.append(rightNegative) addRackHoles(derivation, elementNode, vector3RackProfiles) extrude.addNegativesPositives(extrudeDerivation, negatives, vector3RackProfiles, positives) return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives) def getPathOutput(creationFirst, derivation, elementNode, translation, vector3ComplementPaths, vector3PinionProfile): "Get gear path output." vector3PinionProfile = lineation.getPackedGeometryOutputByLoop(elementNode, lineation.SideLoop(vector3PinionProfile)) if creationFirst == 'p': return vector3PinionProfile packedGearGeometry = [] for vector3ComplementPath in vector3ComplementPaths: sideLoop = lineation.SideLoop(vector3ComplementPath) packedGearGeometry += lineation.getPackedGeometryOutputByLoop(elementNode, sideLoop) if creationFirst == 'c': return packedGearGeometry euclidean.translateVector3Paths(packedGearGeometry, translation) return vector3PinionProfile + packedGearGeometry def getThicknessMultipliedPath(path, thicknessMultiplier): "Get thickness multiplied path." for pointIndex, point in enumerate(path): path[pointIndex] = complex(point.real * thicknessMultiplier, point.imag) return path def getToothProfile(derivation, pitchRadius, teeth): 'Get profile for one tooth.' if teeth < 0: return getToothProfileAnnulus(derivation, pitchRadius, teeth) if teeth == 0: return getToothProfileRack(derivation) return getToothProfileCylinder(derivation, pitchRadius, teeth) def getToothProfileAnnulus(derivation, pitchRadius, teeth): 'Get profile for one tooth of an annulus.' toothProfileHalf = [] toothProfileHalfCylinder = getToothProfileHalfCylinder(derivation, pitchRadius) pitchRadius = -pitchRadius innerRadius = pitchRadius - derivation.addendum # tooth is multiplied by 1.02 because at around 1.01 for a 7/-23/20.0 test case, there is intersection since the paths are bending together for point in getThicknessMultipliedPath(toothProfileHalfCylinder, 1.02 / derivation.toothThicknessMultiplier): if abs(point) >= innerRadius: toothProfileHalf.append(point) profileFirst = toothProfileHalf[0] profileSecond = toothProfileHalf[1] firstMinusSecond = profileFirst - profileSecond remainingAddendum = abs(profileFirst) - innerRadius firstMinusSecond *= remainingAddendum / abs(firstMinusSecond) extensionPoint = profileFirst + firstMinusSecond if derivation.tipBevel > 0.0: unitPolar = euclidean.getWiddershinsUnitPolar(2.0 / float(teeth) * math.pi) mirrorPoint = complex(-extensionPoint.real, extensionPoint.imag) * unitPolar bevelPath = getBevelPath(profileFirst, derivation.tipBevel, extensionPoint, mirrorPoint) toothProfileHalf = bevelPath + toothProfileHalf else: toothProfileHalf.insert(0, extensionPoint) profileLast = toothProfileHalf[-1] profilePenultimate = toothProfileHalf[-2] lastMinusPenultimate = profileLast - profilePenultimate remainingDedendum = pitchRadius - abs(profileLast) + derivation.dedendum lastMinusPenultimate *= remainingDedendum / abs(lastMinusPenultimate) extensionPoint = profileLast + lastMinusPenultimate if derivation.rootBevel > 0.0: mirrorPoint = complex(-extensionPoint.real, extensionPoint.imag) bevelPath = getBevelPath(profileLast, derivation.rootBevel, extensionPoint, mirrorPoint) bevelPath.reverse() toothProfileHalf += bevelPath else: toothProfileHalf.append(extensionPoint) toothProfileAnnulus = euclidean.getMirrorPath(toothProfileHalf) toothProfileAnnulus.reverse() return toothProfileAnnulus def getToothProfileCylinder(derivation, pitchRadius, teeth): 'Get profile for one tooth of a cylindrical gear.' toothProfileHalfCylinder = getToothProfileHalfCylinder(derivation, pitchRadius) toothProfileHalfCylinder = getThicknessMultipliedPath(toothProfileHalfCylinder, derivation.toothThicknessMultiplier) toothProfileHalf = [] innerRadius = pitchRadius - derivation.dedendum for point in toothProfileHalfCylinder: if abs(point) >= innerRadius: toothProfileHalf.append(point) return getToothProfileCylinderByProfile(derivation, pitchRadius, teeth, toothProfileHalf) def getToothProfileCylinderByProfile(derivation, pitchRadius, teeth, toothProfileHalf): 'Get profile for one tooth of a cylindrical gear.' profileFirst = toothProfileHalf[0] profileSecond = toothProfileHalf[1] firstMinusSecond = profileFirst - profileSecond remainingDedendum = abs(profileFirst) - pitchRadius + derivation.dedendum firstMinusSecond *= remainingDedendum / abs(firstMinusSecond) extensionPoint = profileFirst + firstMinusSecond if derivation.rootBevel > 0.0: unitPolar = euclidean.getWiddershinsUnitPolar(-2.0 / float(teeth) * math.pi) mirrorPoint = complex(-extensionPoint.real, extensionPoint.imag) * unitPolar bevelPath = getBevelPath(profileFirst, derivation.rootBevel, extensionPoint, mirrorPoint) toothProfileHalf = bevelPath + toothProfileHalf else: toothProfileHalf.insert(0, extensionPoint) if derivation.tipBevel > 0.0: profileLast = toothProfileHalf[-1] profilePenultimate = toothProfileHalf[-2] mirrorPoint = complex(-profileLast.real, profileLast.imag) bevelPath = getBevelPath(profilePenultimate, derivation.tipBevel, profileLast, mirrorPoint) bevelPath.reverse() toothProfileHalf = toothProfileHalf[: -1] + bevelPath return euclidean.getMirrorPath(toothProfileHalf) def getToothProfileHalfCylinder(derivation, pitchRadius): 'Get profile for half of a one tooth of a cylindrical gear.' toothProfile=[] # x = -y * tan(p) + 1 # x*x + y*y = (2-cos(p))^2 # y*y*t*t-2yt+1+y*y=4-4c-c*c # y*y*(t*t+1)-2yt=3-4c-c*c # y*y*(t*t+1)-2yt-3+4c-c*c=0 # a=tt+1 # b=-2t # c=c(4-c)-3 a = derivation.tanPressure * derivation.tanPressure + 1.0 b = -derivation.tanPressure - derivation.tanPressure cEnd = derivation.cosPressure * (4.0 - derivation.cosPressure) - 3.0 yEnd = (-b - math.sqrt(b*b - 4 * a * cEnd)) * 0.5 / a yEnd *= derivation.pitchRadius / abs(pitchRadius) yEnd -= derivation.clearance / abs(pitchRadius) # to prevent intersections, yBegin is moved towards the base circle, giving a thinner tooth yBegin = -yEnd if pitchRadius > 0.0: yBegin = 0.5 * derivation.sinPressure + 0.5 * yBegin beginComplex = complex(1.0 - yBegin * derivation.tanPressure, yBegin) endComplex = complex(1.0 - yEnd * derivation.tanPressure, yEnd) endMinusBeginComplex = endComplex - beginComplex wholeAngle = -abs(endMinusBeginComplex) / derivation.cosPressure wholeAngleIncrement = wholeAngle / float(derivation.profileSurfaces) stringStartAngle = abs(beginComplex - complex(1.0, 0.0)) / derivation.cosPressure wholeDepthIncrementComplex = endMinusBeginComplex / float(derivation.profileSurfaces) for profileIndex in xrange(derivation.profileSurfaces + 1): contactPoint = beginComplex + wholeDepthIncrementComplex * float(profileIndex) stringAngle = stringStartAngle + wholeAngleIncrement * float(profileIndex) angle = math.atan2(contactPoint.imag, contactPoint.real) - stringAngle angle += 0.5 * math.pi - derivation.quarterWavelength / abs(pitchRadius) toothPoint = abs(contactPoint) * euclidean.getWiddershinsUnitPolar(angle) * abs(pitchRadius) toothProfile.append(toothPoint) return toothProfile def getToothProfileRack(derivation): 'Get profile for one rack tooth.' addendumSide = derivation.quarterWavelength - derivation.addendum * derivation.tanPressure addendumComplex = complex(addendumSide, derivation.addendum) dedendumSide = derivation.quarterWavelength + derivation.dedendum * derivation.tanPressure dedendumComplex = complex(dedendumSide, -derivation.dedendum) toothProfile = [dedendumComplex] if derivation.rootBevel > 0.0: mirrorPoint = complex(derivation.wavelength - dedendumSide, -derivation.dedendum) toothProfile = getBevelPath(addendumComplex, derivation.rootBevel, dedendumComplex, mirrorPoint) if derivation.tipBevel > 0.0: mirrorPoint = complex(-addendumComplex.real, addendumComplex.imag) bevelPath = getBevelPath(dedendumComplex, derivation.tipBevel, addendumComplex, mirrorPoint) bevelPath.reverse() toothProfile += bevelPath else: toothProfile.append(addendumComplex) return euclidean.getMirrorPath(getThicknessMultipliedPath(toothProfile, derivation.toothThicknessMultiplier)) def processElementNode(elementNode): "Process the xml element." geometryOutput = getGeometryOutput(None, elementNode) if geometryOutput.__class__ == list: path.convertElementNode(elementNode, geometryOutput) else: solid.processElementNodeByGeometry(elementNode, geometryOutput) class GearDerivation: "Class to hold gear variables." def __init__(self, elementNode): 'Set defaults.' self.clearanceOverWavelength = evaluate.getEvaluatedFloat(0.1, elementNode, 'clearanceOverWavelength') self.collarAddendumOverRadius = evaluate.getEvaluatedFloat(1.0, elementNode, 'collarAddendumOverRadius') self.complementCollarLengthOverFaceWidth = evaluate.getEvaluatedFloat( 0.0, elementNode, 'complementCollarLengthOverFaceWidth') self.copyShallow = elementNode.getCopyShallow() self.creationType = evaluate.getEvaluatedString('both', elementNode, 'creationType') self.creationTypeMenuRadioStrings = 'both complement pinion'.split() self.elementNode = elementNode self.faceWidth = evaluate.getEvaluatedFloat(10.0, elementNode, 'faceWidth') self.helixAngle = evaluate.getEvaluatedFloat(0.0, elementNode, 'helixAngle') self.helixType = evaluate.getEvaluatedString('basic', elementNode, 'helixType') self.helixTypeMenuRadioStrings = 'basic herringbone parabolic'.split() self.keywayRadiusOverRadius = evaluate.getEvaluatedFloat(0.5, elementNode, 'keywayRadiusOverRadius') self.lighteningHoleMarginOverRimDedendum = evaluate.getEvaluatedFloat( 1.0, elementNode, 'lighteningHoleMarginOverRimDedendum') self.lighteningHoleMinimumRadius = evaluate.getEvaluatedFloat( 1.0, elementNode, 'lighteningHoleMinimumRadius') self.moveType = evaluate.getEvaluatedString('separate', elementNode, 'moveType') self.moveTypeMenuRadioStrings = 'mesh none separate vertical'.split() self.operatingAngle = evaluate.getEvaluatedFloat(180.0, elementNode, 'operatingAngle') self.pinionCollarLengthOverFaceWidth = evaluate.getEvaluatedFloat( 0.0, elementNode, 'pinionCollarLengthOverFaceWidth') self.plateClearanceOverLength = evaluate.getEvaluatedFloat(0.2, elementNode, 'plateClearanceOverLength') self.plateLengthOverFaceWidth = evaluate.getEvaluatedFloat(0.5, elementNode, 'plateLengthOverFaceWidth') self.pressureAngle = evaluate.getEvaluatedFloat(20.0, elementNode, 'pressureAngle') self.profileSurfaces = evaluate.getEvaluatedInt(11, elementNode, 'profileSurfaces') self.rackHoleBelowOverWidth = evaluate.getEvaluatedFloat(0.6, elementNode, 'rackHoleBelowOverWidth') self.rackHoleRadiusOverWidth = evaluate.getEvaluatedFloat(0.0, elementNode, 'rackHoleRadiusOverWidth') self.rackHoleStepOverWidth = evaluate.getEvaluatedFloat(1.0, elementNode, 'rackHoleStepOverWidth') self.rackLengthOverRadius = evaluate.getEvaluatedFloat(math.pi + math.pi, elementNode, 'rackLengthOverRadius') self.rackWidthOverFaceWidth = evaluate.getEvaluatedFloat(1.0, elementNode, 'rackWidthOverFaceWidth') self.rimDedendumOverRadius = evaluate.getEvaluatedFloat(0.2, elementNode, 'rimDedendumOverRadius') self.rootBevelOverClearance = evaluate.getEvaluatedFloat(0.5, elementNode, 'rootBevelOverClearance') self.shaftDepthBottomOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'shaftDepthBottomOverRadius') self.shaftDepthTopOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'shaftDepthOverRadius') self.shaftRadiusOverPitchRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'shaftRadiusOverPitchRadius') self.shaftSides = evaluate.getEvaluatedInt(4, elementNode, 'shaftSides') self.teethComplement = evaluate.getEvaluatedInt(17, elementNode, 'teethComplement') self.teethPinion = evaluate.getEvaluatedInt(7, elementNode, 'teeth') totalTeethOverPinionTeeth = float(self.teethComplement + self.teethPinion) / float(self.teethPinion) self.centerDistance = evaluate.getEvaluatedFloat(20.0 * totalTeethOverPinionTeeth, elementNode, 'centerDistance') derivedPitchRadius = self.centerDistance / totalTeethOverPinionTeeth self.pitchRadius = evaluate.getEvaluatedFloat(derivedPitchRadius, elementNode, 'pitchRadius') self.tipBevelOverClearance = evaluate.getEvaluatedFloat(0.1, elementNode, 'tipBevelOverClearance') # tooth multiplied by 0.99999 to avoid an intersection self.toothThicknessMultiplier = evaluate.getEvaluatedFloat(0.99999, elementNode, 'toothThicknessMultiplier') # Set derived variables. self.wavelength = self.pitchRadius * 2.0 * math.pi / float(self.teethPinion) self.clearance = self.wavelength * self.clearanceOverWavelength self.clearance = evaluate.getEvaluatedFloat(self.clearance, elementNode, 'clearance') self.complementCollarLength = self.faceWidth * self.complementCollarLengthOverFaceWidth self.complementCollarLength = evaluate.getEvaluatedFloat(self.complementCollarLength, elementNode, 'complementCollarLength') self.gearHolePaths = evaluate.getTransformedPathsByKey([], elementNode, 'gearHolePaths') self.pinionCollarLength = self.faceWidth * self.pinionCollarLengthOverFaceWidth self.pinionCollarLength = evaluate.getEvaluatedFloat(self.pinionCollarLength, elementNode, 'pinionCollarLength') self.plateLength = self.faceWidth * self.plateLengthOverFaceWidth self.plateLength = evaluate.getEvaluatedFloat(self.plateLength, elementNode, 'plateLength') self.plateClearance = self.plateLength * self.plateClearanceOverLength self.plateClearance = evaluate.getEvaluatedFloat(self.plateClearance, elementNode, 'plateClearance') self.rackLength = self.pitchRadius * self.rackLengthOverRadius self.rackLength = evaluate.getEvaluatedFloat(self.rackLength, elementNode, 'rackLength') self.rackDemilength = 0.5 * self.rackLength self.rackWidth = self.faceWidth * self.rackWidthOverFaceWidth self.rackWidth = evaluate.getEvaluatedFloat(self.rackWidth, elementNode, 'rackWidth') self.rimDedendum = self.pitchRadius * self.rimDedendumOverRadius self.rimDedendum = evaluate.getEvaluatedFloat(self.rimDedendum, elementNode, 'rimDedendum') self.rootBevel = self.clearance * self.rootBevelOverClearance self.rootBevel = evaluate.getEvaluatedFloat(self.rootBevel, elementNode, 'rootBevel') self.shaftRadius = self.pitchRadius * self.shaftRadiusOverPitchRadius self.shaftRadius = evaluate.getEvaluatedFloat(self.shaftRadius, elementNode, 'shaftRadius') self.collarAddendum = self.shaftRadius * self.collarAddendumOverRadius self.collarAddendum = evaluate.getEvaluatedFloat(self.collarAddendum, elementNode, 'collarWidth') self.keywayRadius = self.shaftRadius * self.keywayRadiusOverRadius self.keywayRadius = lineation.getFloatByPrefixBeginEnd(elementNode, 'keywayRadius', 'keywayDiameter', self.keywayRadius) self.lighteningHoleMargin = self.rimDedendum * self.lighteningHoleMarginOverRimDedendum self.lighteningHoleMargin = evaluate.getEvaluatedFloat( self.lighteningHoleMargin, elementNode, 'lighteningHoleMargin') self.rackHoleBelow = self.rackWidth * self.rackHoleBelowOverWidth self.rackHoleBelow = evaluate.getEvaluatedFloat(self.rackHoleBelow, elementNode, 'rackHoleBelow') self.rackHoleRadius = self.rackWidth * self.rackHoleRadiusOverWidth self.rackHoleRadius = lineation.getFloatByPrefixBeginEnd(elementNode, 'rackHoleRadius', 'rackHoleDiameter', self.rackHoleRadius) self.rackHoleStep = self.rackWidth * self.rackHoleStepOverWidth self.rackHoleStep = evaluate.getEvaluatedFloat(self.rackHoleStep, elementNode, 'rackHoleStep') self.shaftDepthBottom = self.shaftRadius * self.shaftDepthBottomOverRadius self.shaftDepthBottom = evaluate.getEvaluatedFloat(self.shaftDepthBottom, elementNode, 'shaftDepthBottom') self.shaftDepthTop = self.shaftRadius * self.shaftDepthTopOverRadius self.shaftDepthTop = evaluate.getEvaluatedFloat(self.shaftDepthTop, elementNode, 'shaftDepthTop') self.shaftPath = evaluate.getTransformedPathByKey([], elementNode, 'shaftPath') if len(self.shaftPath) < 3: self.shaftPath = shaft.getShaftPath(self.shaftDepthBottom, self.shaftDepthTop, self.shaftRadius, -self.shaftSides) self.tipBevel = self.clearance * self.tipBevelOverClearance self.tipBevel = evaluate.getEvaluatedFloat(self.tipBevel, elementNode, 'tipBevel') # Set derived values. self.helixRadian = math.radians(self.helixAngle) if self.teethComplement <= 0.0 and self.operatingAngle != 180.0: print('Warning, an operatingAngle other than 180 degrees can only work with a positive number of gear teeth.') print('Therefore the operatingAngle will be reset to 180 degrees.') self.operatingAngle = 180.0 self.tanHelix = math.tan(self.helixRadian) self.helixHeight = self.tanHelix * self.faceWidth self.operatingRadian = math.radians(self.operatingAngle) self.pitchRadiusComplement = self.pitchRadius * float(self.teethComplement) / float(self.teethPinion) self.pressureRadian = math.radians(self.pressureAngle) self.cosPressure = math.cos(self.pressureRadian) self.sinPressure = math.sin(self.pressureRadian) self.tanPressure = math.tan(self.pressureRadian) self.halfWavelength = 0.5 * self.wavelength self.helixPath = euclidean.getComplexPath(evaluate.getTransformedPathByKey([], elementNode, 'helixPath')) if len(self.helixPath) < 1: self.helixPath = getHelixComplexPath(self, elementNode) self.quarterWavelength = 0.25 * self.wavelength self.shaftRimRadius = self.shaftRadius + self.collarAddendum self.toothProfileHalf = getToothProfileHalfCylinder(self, self.pitchRadius) self.toothProfileHalf = getThicknessMultipliedPath(self.toothProfileHalf, self.toothThicknessMultiplier) self.addendum = self.toothProfileHalf[-1].imag - self.pitchRadius self.dedendum = abs(self.toothProfileHalf[-1]) - self.pitchRadius + self.clearance self.pinionToothProfile = getToothProfileCylinderByProfile(self, self.pitchRadius, self.teethPinion, self.toothProfileHalf) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/grid.py000066400000000000000000000161501167321211700243670ustar00rootroot00000000000000""" Grid path points. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math import random __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addGridRow(diameter, gridPath, loopsComplex, maximumComplex, rowIndex, x, y, zigzag): 'Add grid row.' row = [] while x < maximumComplex.real: point = complex(x, y) if euclidean.getIsInFilledRegion(loopsComplex, point): row.append(point) x += diameter.real if zigzag and rowIndex % 2 == 1: row.reverse() gridPath += row def getGeometryOutput(elementNode): 'Get vector3 vertexes from attribute dictionary.' derivation = GridDerivation(elementNode) diameter = derivation.radius + derivation.radius typeStringTwoCharacters = derivation.typeString.lower()[: 2] typeStringFirstCharacter = typeStringTwoCharacters[: 1] topRight = complex(derivation.demiwidth, derivation.demiheight) loopsComplex = [euclidean.getSquareLoopWiddershins(-topRight, topRight)] if len(derivation.target) > 0: loopsComplex = euclidean.getComplexPaths(derivation.target) maximumComplex = euclidean.getMaximumByComplexPaths(loopsComplex) minimumComplex = euclidean.getMinimumByComplexPaths(loopsComplex) gridPath = None if typeStringTwoCharacters == 'he': gridPath = getHexagonalGrid(diameter, loopsComplex, maximumComplex, minimumComplex, derivation.zigzag) elif typeStringTwoCharacters == 'ra' or typeStringFirstCharacter == 'a': gridPath = getRandomGrid(derivation, diameter, elementNode, loopsComplex, maximumComplex, minimumComplex) elif typeStringTwoCharacters == 're' or typeStringFirstCharacter == 'e': gridPath = getRectangularGrid(diameter, loopsComplex, maximumComplex, minimumComplex, derivation.zigzag) if gridPath is None: print('Warning, the step type was not one of (hexagonal, random or rectangular) in getGeometryOutput in grid for:') print(derivation.typeString) print(elementNode) return [] loop = euclidean.getVector3Path(gridPath) elementNode.attributes['closed'] = 'false' return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop, 0.5 * math.pi)) def getGeometryOutputByArguments(arguments, elementNode): 'Get vector3 vertexes from attribute dictionary by arguments.' if len(arguments) < 1: return getGeometryOutput(elementNode) inradius = 0.5 * euclidean.getFloatFromValue(arguments[0]) elementNode.attributes['inradius.x'] = str(inradius) if len(arguments) > 1: inradius = 0.5 * euclidean.getFloatFromValue(arguments[1]) elementNode.attributes['inradius.y'] = str(inradius) return getGeometryOutput(elementNode) def getHexagonalGrid(diameter, loopsComplex, maximumComplex, minimumComplex, zigzag): 'Get hexagonal grid.' diameter = complex(diameter.real, math.sqrt(0.75) * diameter.imag) demiradius = 0.25 * diameter xRadius = 0.5 * diameter.real xStart = minimumComplex.real - demiradius.real y = minimumComplex.imag - demiradius.imag gridPath = [] rowIndex = 0 while y < maximumComplex.imag: x = xStart if rowIndex % 2 == 1: x -= xRadius addGridRow(diameter, gridPath, loopsComplex, maximumComplex, rowIndex, x, y, zigzag) y += diameter.imag rowIndex += 1 return gridPath def getIsPointInsideZoneAwayOthers(diameterReciprocal, loopsComplex, point, pixelDictionary): 'Determine if the point is inside the loops zone and and away from the other points.' if not euclidean.getIsInFilledRegion(loopsComplex, point): return False pointOverDiameter = complex(point.real * diameterReciprocal.real, point.imag * diameterReciprocal.imag) squareValues = euclidean.getSquareValuesFromPoint(pixelDictionary, pointOverDiameter) for squareValue in squareValues: if abs(squareValue - pointOverDiameter) < 1.0: return False euclidean.addElementToPixelListFromPoint(pointOverDiameter, pixelDictionary, pointOverDiameter) return True def getNewDerivation(elementNode): 'Get new derivation.' return GridDerivation(elementNode) def getRandomGrid(derivation, diameter, elementNode, loopsComplex, maximumComplex, minimumComplex): 'Get rectangular grid.' gridPath = [] diameterReciprocal = complex(1.0 / diameter.real, 1.0 / diameter.imag) diameterSquared = diameter.real * diameter.real + diameter.imag * diameter.imag elements = int(math.ceil(derivation.density * euclidean.getAreaLoops(loopsComplex) / diameterSquared / math.sqrt(0.75))) elements = evaluate.getEvaluatedInt(elements, elementNode, 'elements') failedPlacementAttempts = 0 pixelDictionary = {} if derivation.seed is not None: random.seed(derivation.seed) successfulPlacementAttempts = 0 while failedPlacementAttempts < 100: point = euclidean.getRandomComplex(minimumComplex, maximumComplex) if getIsPointInsideZoneAwayOthers(diameterReciprocal, loopsComplex, point, pixelDictionary): gridPath.append(point) euclidean.addElementToPixelListFromPoint(point, pixelDictionary, point) successfulPlacementAttempts += 1 else: failedPlacementAttempts += 1 if successfulPlacementAttempts >= elements: return gridPath return gridPath def getRectangularGrid(diameter, loopsComplex, maximumComplex, minimumComplex, zigzag): 'Get rectangular grid.' demiradius = 0.25 * diameter xStart = minimumComplex.real - demiradius.real y = minimumComplex.imag - demiradius.imag gridPath = [] rowIndex = 0 while y < maximumComplex.imag: addGridRow(diameter, gridPath, loopsComplex, maximumComplex, rowIndex, xStart, y, zigzag) y += diameter.imag rowIndex += 1 return gridPath def processElementNode(elementNode): 'Process the xml element.' path.convertElementNode(elementNode, getGeometryOutput(elementNode)) class GridDerivation: 'Class to hold grid variables.' def __init__(self, elementNode): 'Set defaults.' self.inradius = lineation.getInradius(complex(10.0, 10.0), elementNode) self.demiwidth = lineation.getFloatByPrefixBeginEnd(elementNode, 'demiwidth', 'width', self.inradius.real) self.demiheight = lineation.getFloatByPrefixBeginEnd(elementNode, 'demiheight', 'height', self.inradius.imag) self.density = evaluate.getEvaluatedFloat(0.2, elementNode, 'density') self.radius = lineation.getComplexByPrefixBeginEnd(elementNode, 'elementRadius', 'elementDiameter', complex(1.0, 1.0)) self.radius = lineation.getComplexByPrefixBeginEnd(elementNode, 'radius', 'diameter', self.radius) self.seed = evaluate.getEvaluatedInt(None, elementNode, 'seed') self.target = evaluate.getTransformedPathsByKey([], elementNode, 'target') self.typeMenuRadioStrings = 'hexagonal random rectangular'.split() self.typeString = evaluate.getEvaluatedString('rectangular', elementNode, 'type') self.zigzag = evaluate.getEvaluatedBoolean(True, elementNode, 'zigzag') sfact-2011.12.18/fabmetheus_utilities/geometry/creation/heightmap.py000066400000000000000000000202101167321211700254000ustar00rootroot00000000000000""" Heightmap. http://www.cs.otago.ac.nz/graphics/Mirage/node59.html http://en.wikipedia.org/wiki/Heightmap http://en.wikipedia.org/wiki/Netpbm_format """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities.vector3index import Vector3Index from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean import math import random __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addHeightsByBitmap(heights, textLines): 'Add heights by bitmap.' for line in textLines[3:]: for integerWord in line.split(): heights.append(float(integerWord)) def addHeightsByGraymap(heights, textLines): 'Add heights by graymap.' divisor = float(textLines[3]) for line in textLines[4:]: for integerWord in line.split(): heights.append(float(integerWord) / divisor) def getAddIndexedHeightGrid(heightGrid, minimumXY, step, top, vertexes): 'Get and add an indexed heightGrid.' indexedHeightGrid = [] for rowIndex, row in enumerate(heightGrid): indexedRow = [] indexedHeightGrid.append(indexedRow) rowOffset = step.imag * float(rowIndex) + minimumXY.imag for columnIndex, element in enumerate(row): columnOffset = step.real * float(columnIndex) + minimumXY.real vector3index = Vector3Index(len(vertexes), columnOffset, rowOffset, top * element) indexedRow.append(vector3index) vertexes.append(vector3index) return indexedHeightGrid def getAddIndexedSegmentedPerimeter(heightGrid, maximumXY, minimumXY, step, vertexes, z=0.0): 'Get and add an indexed segmented perimeter.' indexedSegmentedPerimeter = [] firstRow = heightGrid[0] columnOffset = minimumXY.real numberOfRowsMinusTwo = len(heightGrid) - 2 for column in firstRow: vector3index = Vector3Index(len(vertexes), columnOffset, minimumXY.imag, z) vertexes.append(vector3index) indexedSegmentedPerimeter.append(vector3index) columnOffset += step.real rowOffset = minimumXY.imag for rowIndex in xrange(numberOfRowsMinusTwo): rowOffset += step.imag vector3index = Vector3Index(len(vertexes), maximumXY.real, rowOffset, z) vertexes.append(vector3index) indexedSegmentedPerimeter.append(vector3index) columnOffset = maximumXY.real for column in firstRow: vector3index = Vector3Index(len(vertexes), columnOffset, maximumXY.imag, z) vertexes.append(vector3index) indexedSegmentedPerimeter.append(vector3index) columnOffset -= step.real rowOffset = maximumXY.imag for rowIndex in xrange(numberOfRowsMinusTwo): rowOffset -= step.imag vector3index = Vector3Index(len(vertexes), minimumXY.real, rowOffset, z) vertexes.append(vector3index) indexedSegmentedPerimeter.append(vector3index) return indexedSegmentedPerimeter def getGeometryOutput(elementNode): 'Get vector3 vertexes from attribute dictionary.' derivation = HeightmapDerivation(elementNode) heightGrid = derivation.heightGrid if derivation.fileName != '': heightGrid = getHeightGrid(archive.getAbsoluteFolderPath(elementNode.getOwnerDocument().fileName, derivation.fileName)) return getGeometryOutputByHeightGrid(derivation, elementNode, heightGrid) def getGeometryOutputByArguments(arguments, elementNode): 'Get vector3 vertexes from attribute dictionary by arguments.' evaluate.setAttributesByArguments(['file', 'start'], arguments, elementNode) return getGeometryOutput(elementNode) def getGeometryOutputByHeightGrid(derivation, elementNode, heightGrid): 'Get vector3 vertexes from attribute dictionary.' numberOfColumns = len(heightGrid) if numberOfColumns < 2: print('Warning, in getGeometryOutputByHeightGrid in heightmap there are fewer than two rows for:') print(heightGrid) print(elementNode) return None numberOfRows = len(heightGrid[0]) if numberOfRows < 2: print('Warning, in getGeometryOutputByHeightGrid in heightmap there are fewer than two columns for:') print(heightGrid) print(elementNode) return None for row in heightGrid: if len(row) != numberOfRows: print('Warning, in getGeometryOutputByHeightGrid in heightmap the heightgrid is not rectangular for:') print(heightGrid) print(elementNode) return None inradiusComplex = derivation.inradius.dropAxis() minimumXY = -inradiusComplex step = complex(derivation.inradius.x / float(numberOfRows - 1), derivation.inradius.y / float(numberOfColumns - 1)) step += step faces = [] heightGrid = getRaisedHeightGrid(heightGrid, derivation.start) top = derivation.inradius.z + derivation.inradius.z vertexes = [] indexedBottomLoop = getAddIndexedSegmentedPerimeter(heightGrid, inradiusComplex, minimumXY, step, vertexes) indexedLoops = [indexedBottomLoop] indexedGridTop = getAddIndexedHeightGrid(heightGrid, minimumXY, step, top, vertexes) indexedLoops.append(triangle_mesh.getIndexedLoopFromIndexedGrid(indexedGridTop)) vertexes = triangle_mesh.getUniqueVertexes(indexedLoops + indexedGridTop) triangle_mesh.addPillarFromConvexLoopsGridTop(faces, indexedGridTop, indexedLoops) return triangle_mesh.getGeometryOutputByFacesVertexes(faces, vertexes) def getHeightGrid(fileName): 'Get heightGrid by fileName.' if 'models/' not in fileName: print('Warning, models/ was not in the absolute file path, so for security nothing will be done for:') print(fileName) print('The heightmap tool can only read a file which has models/ in the file path.') print('To import the file, move the file into a folder called model/ or a subfolder which is inside the model folder tree.') return pgmText = archive.getFileText(fileName) textLines = archive.getTextLines(pgmText) format = textLines[0].lower() sizeWords = textLines[2].split() numberOfColumns = int(sizeWords[0]) numberOfRows = int(sizeWords[1]) heights = [] if format == 'p1': addHeightsByBitmap(heights, textLines) elif format == 'p2': addHeightsByGraymap(heights, textLines) else: print('Warning, the file format was not recognized for:') print(fileName) print('Heightmap can only read the Netpbm Portable bitmap format and the Netpbm Portable graymap format.') print('The Netpbm formats are described at:') print('http://en.wikipedia.org/wiki/Netpbm_format') return [] heightGrid = [] heightIndex = 0 for rowIndex in xrange(numberOfRows): row = [] heightGrid.append(row) for columnIndex in xrange(numberOfColumns): row.append(heights[heightIndex]) heightIndex += 1 return heightGrid def getNewDerivation(elementNode): 'Get new derivation.' return HeightmapDerivation(elementNode) def getRaisedHeightGrid(heightGrid, start): 'Get heightGrid raised above start.' raisedHeightGrid = [] remainingHeight = 1.0 - start for row in heightGrid: raisedRow = [] raisedHeightGrid.append(raisedRow) for element in row: raisedElement = remainingHeight * element + start raisedRow.append(raisedElement) return raisedHeightGrid def processElementNode(elementNode): 'Process the xml element.' solid.processElementNodeByGeometry(elementNode, getGeometryOutput(elementNode)) class HeightmapDerivation: 'Class to hold heightmap variables.' def __init__(self, elementNode): 'Set defaults.' self.fileName = evaluate.getEvaluatedString('', elementNode, 'file') self.heightGrid = evaluate.getEvaluatedValue([], elementNode, 'heightGrid') self.inradius = evaluate.getVector3ByPrefixes(elementNode, ['demisize', 'inradius'], Vector3(10.0, 10.0, 5.0)) self.inradius = evaluate.getVector3ByMultiplierPrefix(elementNode, 2.0, 'size', self.inradius) self.start = evaluate.getEvaluatedFloat(0.0, elementNode, 'start') def __repr__(self): 'Get the string representation of this HeightmapDerivation.' return euclidean.getDictionaryString(self.__dict__) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/lathe.py000066400000000000000000000157731167321211700245510ustar00rootroot00000000000000""" Boolean geometry extrusion. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addLoopByComplex(derivation, endMultiplier, loopLists, path, pointComplex, vertexes): "Add an indexed loop to the vertexes." loops = loopLists[-1] loop = [] loops.append(loop) for point in path: pointMinusBegin = point - derivation.axisStart dotVector3 = derivation.axisProjectiveSpace.getDotVector3(pointMinusBegin) dotVector3Complex = dotVector3.dropAxis() dotPointComplex = pointComplex * dotVector3Complex dotPoint = Vector3(dotPointComplex.real, dotPointComplex.imag, dotVector3.z) projectedVector3 = derivation.axisProjectiveSpace.getVector3ByPoint(dotPoint) + derivation.axisStart loop.append(projectedVector3) def addNegatives(derivation, negatives, paths): "Add pillars output to negatives." for path in paths: loopListsByPath = getLoopListsByPath(derivation, 1.000001, path) geometryOutput = triangle_mesh.getPillarsOutput(loopListsByPath) negatives.append(geometryOutput) def addNegativesPositives(derivation, negatives, paths, positives): "Add pillars output to negatives and positives." for path in paths: endMultiplier = None normal = euclidean.getNormalByPath(path) if normal.dot(derivation.normal) < 0.0: endMultiplier = 1.000001 loopListsByPath = getLoopListsByPath(derivation, endMultiplier, path) geometryOutput = triangle_mesh.getPillarsOutput(loopListsByPath) if endMultiplier is None: positives.append(geometryOutput) else: negatives.append(geometryOutput) def addOffsetAddToLists( loop, offset, vector3Index, vertexes ): "Add an indexed loop to the vertexes." vector3Index += offset loop.append( vector3Index ) vertexes.append( vector3Index ) def addPositives(derivation, paths, positives): "Add pillars output to positives." for path in paths: loopListsByPath = getLoopListsByPath(derivation, None, path) geometryOutput = triangle_mesh.getPillarsOutput(loopListsByPath) positives.append(geometryOutput) def getGeometryOutput(derivation, elementNode): "Get triangle mesh from attribute dictionary." if derivation is None: derivation = LatheDerivation(elementNode) if len(euclidean.getConcatenatedList(derivation.target)) == 0: print('Warning, in lathe there are no paths.') print(elementNode.attributes) return None negatives = [] positives = [] addNegativesPositives(derivation, negatives, derivation.target, positives) return getGeometryOutputByNegativesPositives(derivation, elementNode, negatives, positives) def getGeometryOutputByArguments(arguments, elementNode): "Get triangle mesh from attribute dictionary by arguments." return getGeometryOutput(None, elementNode) def getGeometryOutputByNegativesPositives(derivation, elementNode, negatives, positives): "Get triangle mesh from derivation, elementNode, negatives and positives." positiveOutput = triangle_mesh.getUnifiedOutput(positives) if len(negatives) < 1: return solid.getGeometryOutputByManipulation(elementNode, positiveOutput) return solid.getGeometryOutputByManipulation(elementNode, {'difference' : {'shapes' : [positiveOutput] + negatives}}) def getLoopListsByPath(derivation, endMultiplier, path): "Get loop lists from path." vertexes = [] loopLists = [[]] if len(derivation.loop) < 2: return loopLists for pointIndex, pointComplex in enumerate(derivation.loop): if endMultiplier is not None and not derivation.isEndCloseToStart: if pointIndex == 0: nextPoint = derivation.loop[1] pointComplex = endMultiplier * (pointComplex - nextPoint) + nextPoint elif pointIndex == len(derivation.loop) - 1: previousPoint = derivation.loop[pointIndex - 1] pointComplex = endMultiplier * (pointComplex - previousPoint) + previousPoint addLoopByComplex(derivation, endMultiplier, loopLists, path, pointComplex, vertexes) if derivation.isEndCloseToStart: loopLists[-1].append([]) return loopLists def getNewDerivation(elementNode): 'Get new derivation.' return LatheDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." solid.processElementNodeByGeometry(elementNode, getGeometryOutput(None, elementNode)) class LatheDerivation: "Class to hold lathe variables." def __init__(self, elementNode): 'Set defaults.' self.axisEnd = evaluate.getVector3ByPrefix(None, elementNode, 'axisEnd') self.axisStart = evaluate.getVector3ByPrefix(None, elementNode, 'axisStart') self.end = evaluate.getEvaluatedFloat(360.0, elementNode, 'end') self.loop = evaluate.getTransformedPathByKey([], elementNode, 'loop') self.sides = evaluate.getEvaluatedInt(None, elementNode, 'sides') self.start = evaluate.getEvaluatedFloat(0.0, elementNode, 'start') self.target = evaluate.getTransformedPathsByKey([], elementNode, 'target') if len(self.target) < 1: print('Warning, no target in derive in lathe for:') print(elementNode) return firstPath = self.target[0] if len(firstPath) < 3: print('Warning, firstPath length is less than three in derive in lathe for:') print(elementNode) self.target = [] return if self.axisStart is None: if self.axisEnd is None: self.axisStart = firstPath[0] self.axisEnd = firstPath[-1] else: self.axisStart = Vector3() self.axis = self.axisEnd - self.axisStart axisLength = abs(self.axis) if axisLength <= 0.0: print('Warning, axisLength is zero in derive in lathe for:') print(elementNode) self.target = [] return self.axis /= axisLength firstVector3 = firstPath[1] - self.axisStart firstVector3Length = abs(firstVector3) if firstVector3Length <= 0.0: print('Warning, firstVector3Length is zero in derive in lathe for:') print(elementNode) self.target = [] return firstVector3 /= firstVector3Length self.axisProjectiveSpace = euclidean.ProjectiveSpace().getByBasisZFirst(self.axis, firstVector3) if self.sides is None: distanceToLine = euclidean.getDistanceToLineByPaths(self.axisStart, self.axisEnd, self.target) self.sides = evaluate.getSidesMinimumThreeBasedOnPrecisionSides(elementNode, distanceToLine) endRadian = math.radians(self.end) startRadian = math.radians(self.start) self.isEndCloseToStart = euclidean.getIsRadianClose(endRadian, startRadian) if len(self.loop) < 1: self.loop = euclidean.getComplexPolygonByStartEnd(endRadian, 1.0, self.sides, startRadian) self.normal = euclidean.getNormalByPath(firstPath) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/line.py000066400000000000000000000114721167321211700243730ustar00rootroot00000000000000""" Square path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = LineDerivation(elementNode) endMinusStart = derivation.end - derivation.start endMinusStartLength = abs(endMinusStart) if endMinusStartLength <= 0.0: print('Warning, end is the same as start in getGeometryOutput in line for:') print(derivation.start) print(derivation.end) print(elementNode) return None typeStringTwoCharacters = derivation.typeString.lower()[: 2] elementNode.attributes['closed'] = str(derivation.closed) if derivation.step is None and derivation.steps is None: return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop([derivation.start, derivation.end])) loop = [derivation.start] if derivation.step is not None and derivation.steps is not None: stepVector = derivation.step / endMinusStartLength * endMinusStart derivation.end = derivation.start + stepVector * derivation.steps return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector) if derivation.step is None: stepVector = endMinusStart / derivation.steps return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector) endMinusStartLengthOverStep = endMinusStartLength / derivation.step if typeStringTwoCharacters == 'av': derivation.steps = max(1.0, round(endMinusStartLengthOverStep)) stepVector = derivation.step / endMinusStartLength * endMinusStart derivation.end = derivation.start + stepVector * derivation.steps return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector) if typeStringTwoCharacters == 'ma': derivation.steps = math.ceil(endMinusStartLengthOverStep) if derivation.steps < 1.0: return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop([derivation.start, derivation.end])) stepVector = endMinusStart / derivation.steps return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector) if typeStringTwoCharacters == 'mi': derivation.steps = math.floor(endMinusStartLengthOverStep) if derivation.steps < 1.0: return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop)) stepVector = endMinusStart / derivation.steps return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector) print('Warning, the step type was not one of (average, maximum or minimum) in getGeometryOutput in line for:') print(derivation.typeString) print(elementNode) loop.append(derivation.end) return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop)) def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." evaluate.setAttributesByArguments(['start', 'end', 'step'], arguments, elementNode) return getGeometryOutput(None, elementNode) def getGeometryOutputByStep(elementNode, end, loop, steps, stepVector): "Get line geometry output by the end, loop, steps and stepVector." stepsFloor = int(math.floor(abs(steps))) for stepIndex in xrange(1, stepsFloor): loop.append(loop[stepIndex - 1] + stepVector) loop.append(end) return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop)) def getNewDerivation(elementNode): 'Get new derivation.' return LineDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class LineDerivation: "Class to hold line variables." def __init__(self, elementNode): 'Set defaults.' self.closed = evaluate.getEvaluatedBoolean(False, elementNode, 'closed') self.end = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'end') self.start = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'start') self.step = evaluate.getEvaluatedFloat(None, elementNode, 'step') self.steps = evaluate.getEvaluatedFloat(None, elementNode, 'steps') self.typeMenuRadioStrings = 'average maximum minimum'.split() self.typeString = evaluate.getEvaluatedString('minimum', elementNode, 'type') sfact-2011.12.18/fabmetheus_utilities/geometry/creation/linear_bearing_cage.py000066400000000000000000000310761167321211700273660ustar00rootroot00000000000000""" Linear bearing cage. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import extrude from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import peg from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.geometry.manipulation_matrix import translate from fabmetheus_utilities.geometry.solids import cylinder from fabmetheus_utilities.geometry.solids import sphere from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addAssemblyCage(derivation, negatives, positives): 'Add assembly linear bearing cage.' addCageGroove(derivation, negatives, positives) for pegCenterX in derivation.pegCenterXs: addPositivePeg(derivation, positives, pegCenterX, -derivation.pegY) addPositivePeg(derivation, positives, pegCenterX, derivation.pegY) translate.translateNegativesPositives(negatives, positives, Vector3(0.0, -derivation.halfSeparationWidth)) femaleNegatives = [] femalePositives = [] addCageGroove(derivation, femaleNegatives, femalePositives) for pegCenterX in derivation.pegCenterXs: addNegativePeg(derivation, femaleNegatives, pegCenterX, -derivation.pegY) addNegativePeg(derivation, femaleNegatives, pegCenterX, derivation.pegY) translate.translateNegativesPositives(femaleNegatives, femalePositives, Vector3(0.0, derivation.halfSeparationWidth)) negatives += femaleNegatives positives += femalePositives def addCage(derivation, height, negatives, positives): 'Add linear bearing cage.' copyShallow = derivation.elementNode.getCopyShallow() copyShallow.attributes['path'] = [Vector3(), Vector3(0.0, 0.0, height)] extrudeDerivation = extrude.ExtrudeDerivation(copyShallow) roundedExtendedRectangle = getRoundedExtendedRectangle(derivation.demiwidth, derivation.rectangleCenterX, 14) outsidePath = euclidean.getVector3Path(roundedExtendedRectangle) extrude.addPositives(extrudeDerivation, [outsidePath], positives) for bearingCenterX in derivation.bearingCenterXs: addNegativeSphere(derivation, negatives, bearingCenterX) def addCageGroove(derivation, negatives, positives): 'Add cage and groove.' addCage(derivation, derivation.demiheight, negatives, positives) addGroove(derivation, negatives) def addGroove(derivation, negatives): 'Add groove on each side of cage.' copyShallow = derivation.elementNode.getCopyShallow() extrude.setElementNodeToEndStart(copyShallow, Vector3(-derivation.demilength), Vector3(derivation.demilength)) extrudeDerivation = extrude.ExtrudeDerivation(copyShallow) bottom = derivation.demiheight - 0.5 * derivation.grooveWidth outside = derivation.demiwidth top = derivation.demiheight leftGroove = [ complex(-outside, bottom), complex(-derivation.innerDemiwidth, derivation.demiheight), complex(-outside, top)] rightGroove = [ complex(outside, top), complex(derivation.innerDemiwidth, derivation.demiheight), complex(outside, bottom)] extrude.addNegatives(extrudeDerivation, negatives, euclidean.getVector3Paths([leftGroove, rightGroove])) def addNegativePeg(derivation, negatives, x, y): 'Add negative cylinder at x and y.' negativePegRadius = derivation.pegRadiusArealized + derivation.halfPegClearance inradius = complex(negativePegRadius, negativePegRadius) copyShallow = derivation.elementNode.getCopyShallow() start = Vector3(x, y, derivation.height) sides = evaluate.getSidesMinimumThreeBasedOnPrecision(copyShallow, negativePegRadius) cylinder.addCylinderOutputByEndStart(0.0, inradius, negatives, sides, start, derivation.topOverBottom) def addNegativeSphere(derivation, negatives, x): 'Add negative sphere at x.' radius = Vector3(derivation.radiusPlusClearance, derivation.radiusPlusClearance, derivation.radiusPlusClearance) sphereOutput = sphere.getGeometryOutput(derivation.elementNode.getCopyShallow(), radius) euclidean.translateVector3Path(matrix.getVertexes(sphereOutput), Vector3(x, 0.0, derivation.demiheight)) negatives.append(sphereOutput) def addPositivePeg(derivation, positives, x, y): 'Add positive cylinder at x and y.' positivePegRadius = derivation.pegRadiusArealized - derivation.halfPegClearance radiusArealized = complex(positivePegRadius, positivePegRadius) copyShallow = derivation.elementNode.getCopyShallow() start = Vector3(x, y, derivation.demiheight) endZ = derivation.height peg.addPegOutput(derivation.pegBevel, endZ, positives, radiusArealized, derivation.sides, start, derivation.topOverBottom) def getBearingCenterXs(bearingCenterX, numberOfSteps, stepX): 'Get the bearing center x list.' bearingCenterXs = [] for stepIndex in xrange(numberOfSteps + 1): bearingCenterXs.append(bearingCenterX) bearingCenterX += stepX return bearingCenterXs def getGeometryOutput(elementNode): 'Get vector3 vertexes from attribute dictionary.' derivation = LinearBearingCageDerivation(elementNode) negatives = [] positives = [] if derivation.typeStringFirstCharacter == 'a': addAssemblyCage(derivation, negatives, positives) else: addCage(derivation, derivation.height, negatives, positives) return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives) def getGeometryOutputByArguments(arguments, elementNode): 'Get vector3 vertexes from attribute dictionary by arguments.' evaluate.setAttributesByArguments(['length', 'radius'], arguments, elementNode) return getGeometryOutput(elementNode) def getNewDerivation(elementNode): 'Get new derivation.' return LinearBearingCageDerivation(elementNode) def getPegCenterXs(numberOfSteps, pegCenterX, stepX): 'Get the peg center x list.' pegCenterXs = [] for stepIndex in xrange(numberOfSteps): pegCenterXs.append(pegCenterX) pegCenterX += stepX return pegCenterXs def getRoundedExtendedRectangle(radius, rectangleCenterX, sides): 'Get the rounded extended rectangle.' roundedExtendedRectangle = [] halfSides = int(sides / 2) halfSidesPlusOne = abs(halfSides + 1) sideAngle = math.pi / float(halfSides) extensionMultiplier = 1.0 / math.cos(0.5 * sideAngle) center = complex(rectangleCenterX, 0.0) startAngle = 0.5 * math.pi for halfSide in xrange(halfSidesPlusOne): unitPolar = euclidean.getWiddershinsUnitPolar(startAngle) unitPolarExtended = complex(unitPolar.real * extensionMultiplier, unitPolar.imag) roundedExtendedRectangle.append(unitPolarExtended * radius + center) startAngle += sideAngle center = complex(-rectangleCenterX, 0.0) startAngle = -0.5 * math.pi for halfSide in xrange(halfSidesPlusOne): unitPolar = euclidean.getWiddershinsUnitPolar(startAngle) unitPolarExtended = complex(unitPolar.real * extensionMultiplier, unitPolar.imag) roundedExtendedRectangle.append(unitPolarExtended * radius + center) startAngle += sideAngle return roundedExtendedRectangle def processElementNode(elementNode): 'Process the xml element.' solid.processElementNodeByGeometry(elementNode, getGeometryOutput(elementNode)) class LinearBearingCageDerivation: 'Class to hold linear bearing cage variables.' def __init__(self, elementNode): 'Set defaults.' self.length = evaluate.getEvaluatedFloat(50.0, elementNode, 'length') self.demilength = 0.5 * self.length self.elementNode = elementNode self.radius = lineation.getFloatByPrefixBeginEnd(elementNode, 'radius', 'diameter', 5.0) self.cageClearanceOverRadius = evaluate.getEvaluatedFloat(0.05, elementNode, 'cageClearanceOverRadius') self.cageClearance = self.cageClearanceOverRadius * self.radius self.cageClearance = evaluate.getEvaluatedFloat(self.cageClearance, elementNode, 'cageClearance') self.racewayClearanceOverRadius = evaluate.getEvaluatedFloat(0.1, elementNode, 'racewayClearanceOverRadius') self.racewayClearance = self.racewayClearanceOverRadius * self.radius self.racewayClearance = evaluate.getEvaluatedFloat(self.racewayClearance, elementNode, 'racewayClearance') self.typeMenuRadioStrings = 'assembly integral'.split() self.typeString = evaluate.getEvaluatedString('assembly', elementNode, 'type') self.typeStringFirstCharacter = self.typeString[: 1 ].lower() self.wallThicknessOverRadius = evaluate.getEvaluatedFloat(0.5, elementNode, 'wallThicknessOverRadius') self.wallThickness = self.wallThicknessOverRadius * self.radius self.wallThickness = evaluate.getEvaluatedFloat(self.wallThickness, elementNode, 'wallThickness') self.zenithAngle = evaluate.getEvaluatedFloat(45.0, elementNode, 'zenithAngle') self.zenithRadian = math.radians(self.zenithAngle) self.demiheight = self.radius * math.cos(self.zenithRadian) - self.racewayClearance self.height = self.demiheight + self.demiheight self.radiusPlusClearance = self.radius + self.cageClearance self.cageRadius = self.radiusPlusClearance + self.wallThickness self.demiwidth = self.cageRadius self.bearingCenterX = self.cageRadius - self.demilength separation = self.cageRadius + self.radiusPlusClearance bearingLength = -self.bearingCenterX - self.bearingCenterX self.numberOfSteps = int(math.floor(bearingLength / separation)) self.stepX = bearingLength / float(self.numberOfSteps) self.bearingCenterXs = getBearingCenterXs(self.bearingCenterX, self.numberOfSteps, self.stepX) if self.typeStringFirstCharacter == 'a': self.setAssemblyCage() self.rectangleCenterX = self.demiwidth - self.demilength def setAssemblyCage(self): 'Set two piece assembly parameters.' self.grooveDepthOverRadius = evaluate.getEvaluatedFloat(0.15, self.elementNode, 'grooveDepthOverRadius') self.grooveDepth = self.grooveDepthOverRadius * self.radius self.grooveDepth = evaluate.getEvaluatedFloat(self.grooveDepth, self.elementNode, 'grooveDepth') self.grooveWidthOverRadius = evaluate.getEvaluatedFloat(0.6, self.elementNode, 'grooveWidthOverRadius') self.grooveWidth = self.grooveWidthOverRadius * self.radius self.grooveWidth = evaluate.getEvaluatedFloat(self.grooveWidth, self.elementNode, 'grooveWidth') self.pegClearanceOverRadius = evaluate.getEvaluatedFloat(0.0, self.elementNode, 'pegClearanceOverRadius') self.pegClearance = self.pegClearanceOverRadius * self.radius self.pegClearance = evaluate.getEvaluatedFloat(self.pegClearance, self.elementNode, 'pegClearance') self.halfPegClearance = 0.5 * self.pegClearance self.pegRadiusOverRadius = evaluate.getEvaluatedFloat(0.5, self.elementNode, 'pegRadiusOverRadius') self.pegRadius = self.pegRadiusOverRadius * self.radius self.pegRadius = evaluate.getEvaluatedFloat(self.pegRadius, self.elementNode, 'pegRadius') self.sides = evaluate.getSidesMinimumThreeBasedOnPrecision(self.elementNode, self.pegRadius) self.pegRadiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(self.elementNode, self.pegRadius, self.sides) self.pegBevelOverPegRadius = evaluate.getEvaluatedFloat(0.25, self.elementNode, 'pegBevelOverPegRadius') self.pegBevel = self.pegBevelOverPegRadius * self.pegRadiusArealized self.pegBevel = evaluate.getEvaluatedFloat(self.pegBevel, self.elementNode, 'pegBevel') self.pegMaximumRadius = self.pegRadiusArealized + abs(self.halfPegClearance) self.separationOverRadius = evaluate.getEvaluatedFloat(0.5, self.elementNode, 'separationOverRadius') self.separation = self.separationOverRadius * self.radius self.separation = evaluate.getEvaluatedFloat(self.separation, self.elementNode, 'separation') self.topOverBottom = evaluate.getEvaluatedFloat(0.8, self.elementNode, 'topOverBottom') peg.setTopOverBottomByRadius(self, 0.0, self.pegRadiusArealized, self.height) self.quarterHeight = 0.5 * self.demiheight self.pegY = 0.5 * self.wallThickness + self.pegMaximumRadius cagePegRadius = self.cageRadius + self.pegMaximumRadius halfStepX = 0.5 * self.stepX pegHypotenuse = math.sqrt(self.pegY * self.pegY + halfStepX * halfStepX) if cagePegRadius > pegHypotenuse: self.pegY = math.sqrt(cagePegRadius * cagePegRadius - halfStepX * halfStepX) self.demiwidth = max(self.pegY + self.pegMaximumRadius + self.wallThickness, self.demiwidth) self.innerDemiwidth = self.demiwidth self.demiwidth += self.grooveDepth self.halfSeparationWidth = self.demiwidth + 0.5 * self.separation if self.pegRadiusArealized <= 0.0: self.pegCenterXs = [] else: self.pegCenterXs = getPegCenterXs(self.numberOfSteps, self.bearingCenterX + halfStepX, self.stepX) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/lineation.py000066400000000000000000000304731167321211700254300ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getComplexByDictionary(dictionary, valueComplex): 'Get complex by dictionary.' if 'x' in dictionary: valueComplex = complex(euclidean.getFloatFromValue(dictionary['x']),valueComplex.imag) if 'y' in dictionary: valueComplex = complex(valueComplex.real, euclidean.getFloatFromValue(dictionary['y'])) return valueComplex def getComplexByDictionaryListValue(value, valueComplex): 'Get complex by dictionary, list or value.' if value.__class__ == complex: return value if value.__class__ == dict: return getComplexByDictionary(value, valueComplex) if value.__class__ == list: return getComplexByFloatList(value, valueComplex) floatFromValue = euclidean.getFloatFromValue(value) if floatFromValue == None: return valueComplex return complex( floatFromValue, floatFromValue ) def getComplexByFloatList( floatList, valueComplex ): 'Get complex by float list.' if len(floatList) > 0: valueComplex = complex(euclidean.getFloatFromValue(floatList[0]), valueComplex.imag) if len(floatList) > 1: valueComplex = complex(valueComplex.real, euclidean.getFloatFromValue(floatList[1])) return valueComplex def getComplexByMultiplierPrefix(elementNode, multiplier, prefix, valueComplex): 'Get complex from multiplier, prefix and xml element.' if multiplier == 0.0: return valueComplex oldMultipliedValueComplex = valueComplex * multiplier complexByPrefix = getComplexByPrefix(elementNode, prefix, oldMultipliedValueComplex) if complexByPrefix == oldMultipliedValueComplex: return valueComplex return complexByPrefix / multiplier def getComplexByMultiplierPrefixes(elementNode, multiplier, prefixes, valueComplex): 'Get complex from multiplier, prefixes and xml element.' for prefix in prefixes: valueComplex = getComplexByMultiplierPrefix(elementNode, multiplier, prefix, valueComplex) return valueComplex def getComplexByPrefix(elementNode, prefix, valueComplex): 'Get complex from prefix and xml element.' value = evaluate.getEvaluatedValue(None, elementNode, prefix) if value is not None: valueComplex = getComplexByDictionaryListValue(value, valueComplex) x = evaluate.getEvaluatedFloat(None, elementNode, prefix + '.x') if x is not None: valueComplex = complex( x, getComplexIfNone( valueComplex ).imag ) y = evaluate.getEvaluatedFloat(None, elementNode, prefix + '.y') if y is not None: valueComplex = complex( getComplexIfNone( valueComplex ).real, y ) return valueComplex def getComplexByPrefixBeginEnd(elementNode, prefixBegin, prefixEnd, valueComplex): 'Get complex from element node, prefixBegin and prefixEnd.' valueComplex = getComplexByPrefix(elementNode, prefixBegin, valueComplex) if prefixEnd in elementNode.attributes: return 0.5 * getComplexByPrefix(elementNode, valueComplex + valueComplex, prefixEnd) else: return valueComplex def getComplexByPrefixes(elementNode, prefixes, valueComplex): 'Get complex from prefixes and xml element.' for prefix in prefixes: valueComplex = getComplexByPrefix(elementNode, prefix, valueComplex) return valueComplex def getComplexIfNone( valueComplex ): 'Get new complex if the original complex is none.' if valueComplex is None: return complex() return valueComplex def getFloatByPrefixBeginEnd(elementNode, prefixBegin, prefixEnd, valueFloat): 'Get float from prefixBegin, prefixEnd and xml element.' valueFloat = evaluate.getEvaluatedFloat(valueFloat, elementNode, prefixBegin) if prefixEnd in elementNode.attributes: return 0.5 * evaluate.getEvaluatedFloat(valueFloat + valueFloat, elementNode, prefixEnd) return valueFloat def getFloatByPrefixSide(defaultValue, elementNode, prefix, side): 'Get float by prefix and side.' if elementNode is None: return defaultValue if side != None: key = prefix + 'OverSide' if key in elementNode.attributes: defaultValue = euclidean.getFloatFromValue(evaluate.getEvaluatedValueObliviously(elementNode, key)) * side return evaluate.getEvaluatedFloat(defaultValue, elementNode, prefix) def getGeometryOutput(derivation, elementNode): 'Get geometry output from paths.' if derivation is None: derivation = LineationDerivation(elementNode) geometryOutput = [] for path in derivation.target: sideLoop = SideLoop(path) geometryOutput += getGeometryOutputByLoop(elementNode, sideLoop) return geometryOutput def getGeometryOutputByArguments(arguments, elementNode): 'Get vector3 vertexes from attribute dictionary by arguments.' return getGeometryOutput(None, elementNode) def getGeometryOutputByLoop(elementNode, sideLoop): 'Get geometry output by side loop.' sideLoop.rotate(elementNode) return getGeometryOutputByManipulation(elementNode, sideLoop) def getGeometryOutputByManipulation(elementNode, sideLoop): 'Get geometry output by manipulation.' sideLoop.loop = euclidean.getLoopWithoutCloseSequentialPoints( sideLoop.close, sideLoop.loop ) return sideLoop.getManipulationPluginLoops(elementNode) def getInradius(defaultInradius, elementNode): 'Get inradius.' defaultInradius = getComplexByPrefixes(elementNode, ['demisize', 'inradius'], defaultInradius) return getComplexByMultiplierPrefix(elementNode, 2.0, 'size', defaultInradius) def getMinimumRadius( beginComplexSegmentLength, endComplexSegmentLength, radius ): 'Get minimum radius.' return min( abs(radius), 0.5 * min( beginComplexSegmentLength, endComplexSegmentLength ) ) def getNewDerivation(elementNode): 'Get new derivation.' return LineationDerivation(elementNode) def getNumberOfBezierPoints(begin, elementNode, end): 'Get the numberOfBezierPoints.' numberOfBezierPoints = int(math.ceil(0.5 * evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, abs(end - begin)))) return evaluate.getEvaluatedInt(numberOfBezierPoints, elementNode, 'sides') def getPackedGeometryOutputByLoop(elementNode, sideLoop): 'Get packed geometry output by side loop.' sideLoop.rotate(elementNode) return getGeometryOutputByManipulation(elementNode, sideLoop) def getRadiusAverage(radiusComplex): 'Get average radius from radiusComplex.' return math.sqrt(radiusComplex.real * radiusComplex.imag) def getRadiusComplex(elementNode, radius): 'Get radius complex for elementNode.' radius = getComplexByPrefixes(elementNode, ['demisize', 'radius'], radius) return getComplexByMultiplierPrefixes(elementNode, 2.0, ['diameter', 'size'], radius) def getStrokeRadiusByPrefix(elementNode, prefix): 'Get strokeRadius by prefix.' strokeRadius = getFloatByPrefixBeginEnd(elementNode, prefix + 'strokeRadius', prefix + 'strokeWidth', 1.0) return getFloatByPrefixBeginEnd(elementNode, prefix + 'radius', prefix + 'diameter', strokeRadius) def processElementNode(elementNode): 'Process the xml element.' path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) def processElementNodeByFunction(elementNode, manipulationFunction): 'Process the xml element by the manipulationFunction.' elementAttributesCopy = elementNode.attributes.copy() targets = evaluate.getElementNodesByKey(elementNode, 'target') for target in targets: targetAttributesCopy = target.attributes.copy() target.attributes = elementAttributesCopy processTargetByFunction(manipulationFunction, target) target.attributes = targetAttributesCopy def processTargetByFunction(manipulationFunction, target): 'Process the target by the manipulationFunction.' if target.xmlObject is None: print('Warning, there is no object in processTargetByFunction in lineation for:') print(target) return geometryOutput = [] transformedPaths = target.xmlObject.getTransformedPaths() for transformedPath in transformedPaths: sideLoop = SideLoop(transformedPath) sideLoop.rotate(target) sideLoop.loop = euclidean.getLoopWithoutCloseSequentialPoints( sideLoop.close, sideLoop.loop ) geometryOutput += manipulationFunction(sideLoop.close, target, sideLoop.loop, '', sideLoop.sideLength) if len(geometryOutput) < 1: print('Warning, there is no geometryOutput in processTargetByFunction in lineation for:') print(target) return removeChildNodesFromElementObject(target) path.convertElementNode(target, geometryOutput) def removeChildNodesFromElementObject(elementNode): 'Process the xml element by manipulationFunction.' elementNode.removeChildNodesFromIDNameParent() if elementNode.xmlObject is not None: if elementNode.parentNode.xmlObject is not None: if elementNode.xmlObject in elementNode.parentNode.xmlObject.archivableObjects: elementNode.parentNode.xmlObject.archivableObjects.remove(elementNode.xmlObject) def setClosedAttribute(elementNode, revolutions): 'Set the closed attribute of the elementNode.' closedBoolean = evaluate.getEvaluatedBoolean(revolutions <= 1, elementNode, 'closed') elementNode.attributes['closed'] = str(closedBoolean).lower() class LineationDerivation: 'Class to hold lineation variables.' def __init__(self, elementNode): 'Set defaults.' self.target = evaluate.getTransformedPathsByKey([], elementNode, 'target') class SideLoop: 'Class to handle loop, side angle and side length.' def __init__(self, loop, sideAngle=None, sideLength=None): 'Initialize.' if sideAngle is None: if len(loop) > 0: sideAngle = 2.0 * math.pi / float(len(loop)) else: sideAngle = 1.0 print('Warning, loop has no sides in SideLoop in lineation.') if sideLength is None: if len(loop) > 0: sideLength = euclidean.getLoopLength(loop) / float(len(loop)) else: sideLength = 1.0 print('Warning, loop has no length in SideLoop in lineation.') self.loop = loop self.sideAngle = abs(sideAngle) self.sideLength = abs(sideLength) self.close = 0.001 * sideLength def getManipulationPluginLoops(self, elementNode): 'Get loop manipulated by the plugins in the manipulation paths folder.' xmlProcessor = elementNode.getXMLProcessor() matchingPlugins = evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationMatrixDictionary) matchingPlugins += evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationPathDictionary) matchingPlugins += evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationShapeDictionary) matchingPlugins.sort(evaluate.compareExecutionOrderAscending) loops = [self.loop] for matchingPlugin in matchingPlugins: matchingLoops = [] prefix = matchingPlugin.__name__.replace('_', '') + '.' for loop in loops: matchingLoops += matchingPlugin.getManipulatedPaths(self.close, elementNode, loop, prefix, self.sideLength) loops = matchingLoops return loops def rotate(self, elementNode): 'Rotate.' rotation = math.radians(evaluate.getEvaluatedFloat(0.0, elementNode, 'rotation')) rotation += evaluate.getEvaluatedFloat(0.0, elementNode, 'rotationOverSide') * self.sideAngle if rotation != 0.0: planeRotation = euclidean.getWiddershinsUnitPolar( rotation ) for vertex in self.loop: rotatedComplex = vertex.dropAxis() * planeRotation vertex.x = rotatedComplex.real vertex.y = rotatedComplex.imag if 'clockwise' in elementNode.attributes: isClockwise = euclidean.getBooleanFromValue(evaluate.getEvaluatedValueObliviously(elementNode, 'clockwise')) if isClockwise == euclidean.getIsWiddershinsByVector3( self.loop ): self.loop.reverse() class Spiral: 'Class to add a spiral.' def __init__(self, spiral, stepRatio): 'Initialize.' self.spiral = spiral if self.spiral is None: return self.spiralIncrement = self.spiral * stepRatio self.spiralTotal = Vector3() def __repr__(self): 'Get the string representation of this Spiral.' return self.spiral def getSpiralPoint(self, unitPolar, vector3): 'Add spiral to the vector.' if self.spiral is None: return vector3 vector3 += Vector3(unitPolar.real * self.spiralTotal.x, unitPolar.imag * self.spiralTotal.y, self.spiralTotal.z) self.spiralTotal += self.spiralIncrement return vector3 sfact-2011.12.18/fabmetheus_utilities/geometry/creation/mechaslab.py000066400000000000000000000277061167321211700253720ustar00rootroot00000000000000""" Mechaslab. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import extrude from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import peg from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.geometry.manipulation_matrix import translate from fabmetheus_utilities.geometry.solids import cylinder from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addAlongWay(begin, distance, end, loop): 'Get the beveled rectangle.' endMinusBegin = end - begin endMinusBeginLength = abs(endMinusBegin) if endMinusBeginLength <= 0.0: return alongWayMultiplier = distance / endMinusBeginLength loop.append(begin + alongWayMultiplier * endMinusBegin) def addGroove(derivation, negatives): 'Add groove on each side of cage.' copyShallow = derivation.elementNode.getCopyShallow() extrude.setElementNodeToEndStart(copyShallow, Vector3(-derivation.demilength), Vector3(derivation.demilength)) extrudeDerivation = extrude.ExtrudeDerivation(copyShallow) bottom = derivation.demiheight - 0.5 * derivation.grooveWidth outside = derivation.demiwidth top = derivation.demiheight leftGroove = [ complex(-outside, bottom), complex(-derivation.innerDemiwidth, derivation.demiheight), complex(-outside, top)] rightGroove = [ complex(outside, top), complex(derivation.innerDemiwidth, derivation.demiheight), complex(outside, bottom)] groovesComplex = [leftGroove, rightGroove] groovesVector3 = euclidean.getVector3Paths(groovesComplex) extrude.addPositives(extrudeDerivation, groovesVector3, negatives) def addHollowPegSocket(derivation, hollowPegSocket, negatives, positives): 'Add the socket and hollow peg.' pegHeight = derivation.pegHeight pegRadians = derivation.pegRadians pegRadiusComplex = complex(derivation.pegRadiusArealized, derivation.pegRadiusArealized) pegTip = 0.8 * derivation.pegRadiusArealized sides = derivation.pegSides start = Vector3(hollowPegSocket.center.real, hollowPegSocket.center.imag, derivation.height) tinyHeight = 0.0001 * pegHeight topRadians = 0.25 * math.pi boltTop = derivation.height if hollowPegSocket.shouldAddPeg: boltTop = peg.getTopAddBiconicOutput( pegRadians, pegHeight, positives, pegRadiusComplex, sides, start, pegTip, topRadians) sides = derivation.socketSides socketHeight = 1.05 * derivation.pegHeight socketRadiusComplex = complex(derivation.socketRadiusArealized, derivation.socketRadiusArealized) socketTip = 0.5 * derivation.overhangSpan start = Vector3(hollowPegSocket.center.real, hollowPegSocket.center.imag, -tinyHeight) topRadians = derivation.interiorOverhangRadians if hollowPegSocket.shouldAddSocket: peg.getTopAddBiconicOutput(pegRadians, socketHeight, negatives, socketRadiusComplex, sides, start, socketTip, topRadians) if derivation.boltRadius <= 0.0: return if (not hollowPegSocket.shouldAddPeg) and (not hollowPegSocket.shouldAddSocket): return boltRadiusComplex = complex(derivation.boltRadius, derivation.boltRadius) cylinder.addCylinderOutputByEndStart(boltTop + tinyHeight, boltRadiusComplex, negatives, derivation.boltSides, start) def addSlab(derivation, positives): 'Add slab.' copyShallow = derivation.elementNode.getCopyShallow() copyShallow.attributes['path'] = [Vector3(), Vector3(0.0, 0.0, derivation.height)] extrudeDerivation = extrude.ExtrudeDerivation(copyShallow) beveledRectangle = getBeveledRectangle(derivation.bevel, -derivation.topRight) outsidePath = euclidean.getVector3Path(beveledRectangle) extrude.addPositives(extrudeDerivation, [outsidePath], positives) def addXGroove(derivation, negatives, y): 'Add x groove.' if derivation.topBevel <= 0.0: return bottom = derivation.height - derivation.topBevel top = derivation.height groove = [complex(y, bottom), complex(y - derivation.topBevel, top), complex(y + derivation.topBevel, top)] triangle_mesh.addSymmetricXPath(negatives, groove, 1.0001 * derivation.topRight.real) def addYGroove(derivation, negatives, x): 'Add y groove' if derivation.topBevel <= 0.0: return bottom = derivation.height - derivation.topBevel top = derivation.height groove = [complex(x, bottom), complex(x - derivation.topBevel, top), complex(x + derivation.topBevel, top)] triangle_mesh.addSymmetricYPath(negatives, groove, 1.0001 * derivation.topRight.imag) def getBeveledRectangle(bevel, bottomLeft): 'Get the beveled rectangle.' bottomRight = complex(-bottomLeft.real, bottomLeft.imag) rectangle = [bottomLeft, bottomRight, -bottomLeft, -bottomRight] if bevel <= 0.0: return rectangle beveledRectangle = [] for pointIndex, point in enumerate(rectangle): begin = rectangle[(pointIndex + len(rectangle) - 1) % len(rectangle)] end = rectangle[(pointIndex + 1) % len(rectangle)] addAlongWay(point, bevel, begin, beveledRectangle) addAlongWay(point, bevel, end, beveledRectangle) return beveledRectangle def getGeometryOutput(elementNode): 'Get vector3 vertexes from attribute dictionary.' derivation = MechaslabDerivation(elementNode) negatives = [] positives = [] addSlab(derivation, positives) for hollowPegSocket in derivation.hollowPegSockets: addHollowPegSocket(derivation, hollowPegSocket, negatives, positives) if 's' in derivation.topBevelPositions: addXGroove(derivation, negatives, -derivation.topRight.imag) if 'n' in derivation.topBevelPositions: addXGroove(derivation, negatives, derivation.topRight.imag) if 'w' in derivation.topBevelPositions: addYGroove(derivation, negatives, -derivation.topRight.real) if 'e' in derivation.topBevelPositions: addYGroove(derivation, negatives, derivation.topRight.real) return extrude.getGeometryOutputByNegativesPositives(elementNode, negatives, positives) def getGeometryOutputByArguments(arguments, elementNode): 'Get vector3 vertexes from attribute dictionary by arguments.' evaluate.setAttributesByArguments(['length', 'radius'], arguments, elementNode) return getGeometryOutput(elementNode) def getNewDerivation(elementNode): 'Get new derivation.' return MechaslabDerivation(elementNode) def processElementNode(elementNode): 'Process the xml element.' solid.processElementNodeByGeometry(elementNode, getGeometryOutput(elementNode)) class CellExistence: 'Class to determine if a cell exists.' def __init__(self, columns, rows, value): 'Initialize.' self.existenceSet = None if value is None: return self.existenceSet = set() for element in value: if element.__class__ == int: columnIndex = (element + columns) % columns for rowIndex in xrange(rows): keyTuple = (columnIndex, rowIndex) self.existenceSet.add(keyTuple) else: keyTuple = (element[0], element[1]) self.existenceSet.add(keyTuple) def __repr__(self): 'Get the string representation of this CellExistence.' return euclidean.getDictionaryString(self.__dict__) def getIsInExistence(self, columnIndex, rowIndex): 'Detremine if the cell at the column and row exists.' if self.existenceSet is None: return True return (columnIndex, rowIndex) in self.existenceSet class HollowPegSocket: 'Class to hold hollow peg socket variables.' def __init__(self, center): 'Initialize.' self.center = center self.shouldAddPeg = True self.shouldAddSocket = True def __repr__(self): 'Get the string representation of this HollowPegSocket.' return euclidean.getDictionaryString(self.__dict__) class MechaslabDerivation: 'Class to hold mechaslab variables.' def __init__(self, elementNode): 'Set defaults.' self.bevelOverRadius = evaluate.getEvaluatedFloat(0.2, elementNode, 'bevelOverRadius') self.boltRadiusOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'boltRadiusOverRadius') self.columns = evaluate.getEvaluatedInt(2, elementNode, 'columns') self.elementNode = elementNode self.heightOverRadius = evaluate.getEvaluatedFloat(2.0, elementNode, 'heightOverRadius') self.interiorOverhangRadians = setting.getInteriorOverhangRadians(elementNode) self.overhangSpan = setting.getOverhangSpan(elementNode) self.pegClearanceOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'pegClearanceOverRadius') self.pegRadians = math.radians(evaluate.getEvaluatedFloat(2.0, elementNode, 'pegAngle')) self.pegHeightOverHeight = evaluate.getEvaluatedFloat(0.4, elementNode, 'pegHeightOverHeight') self.pegRadiusOverRadius = evaluate.getEvaluatedFloat(0.7, elementNode, 'pegRadiusOverRadius') self.radius = lineation.getFloatByPrefixBeginEnd(elementNode, 'radius', 'width', 5.0) self.rows = evaluate.getEvaluatedInt(1, elementNode, 'rows') self.topBevelOverRadius = evaluate.getEvaluatedFloat(0.2, elementNode, 'topBevelOverRadius') # Set derived values. self.bevel = evaluate.getEvaluatedFloat(self.bevelOverRadius * self.radius, elementNode, 'bevel') self.boltRadius = evaluate.getEvaluatedFloat(self.boltRadiusOverRadius * self.radius, elementNode, 'boltRadius') self.boltSides = evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, self.boltRadius) self.bottomLeftCenter = complex(-float(self.columns - 1), -float(self.rows - 1)) * self.radius self.height = evaluate.getEvaluatedFloat(self.heightOverRadius * self.radius, elementNode, 'height') self.hollowPegSockets = [] centerY = self.bottomLeftCenter.imag diameter = self.radius + self.radius self.pegExistence = CellExistence(self.columns, self.rows, evaluate.getEvaluatedValue(None, elementNode, 'pegs')) self.socketExistence = CellExistence(self.columns, self.rows, evaluate.getEvaluatedValue(None, elementNode, 'sockets')) for rowIndex in xrange(self.rows): centerX = self.bottomLeftCenter.real for columnIndex in xrange(self.columns): hollowPegSocket = HollowPegSocket(complex(centerX, centerY)) hollowPegSocket.shouldAddPeg = self.pegExistence.getIsInExistence(columnIndex, rowIndex) hollowPegSocket.shouldAddSocket = self.socketExistence.getIsInExistence(columnIndex, rowIndex) self.hollowPegSockets.append(hollowPegSocket) centerX += diameter centerY += diameter self.pegClearance = evaluate.getEvaluatedFloat(self.pegClearanceOverRadius * self.radius, elementNode, 'pegClearance') halfPegClearance = 0.5 * self.pegClearance self.pegHeight = evaluate.getEvaluatedFloat(self.pegHeightOverHeight * self.height, elementNode, 'pegHeight') self.pegRadius = evaluate.getEvaluatedFloat(self.pegRadiusOverRadius * self.radius, elementNode, 'pegRadius') sides = 24 * max(1, math.floor(evaluate.getSidesBasedOnPrecision(elementNode, self.pegRadius) / 24)) self.socketRadius = self.pegRadius + halfPegClearance self.pegSides = evaluate.getEvaluatedInt(sides, elementNode, 'pegSides') self.pegRadius -= halfPegClearance self.pegRadiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.pegRadius, self.pegSides) self.socketSides = evaluate.getEvaluatedInt(sides, elementNode, 'socketSides') self.socketRadiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.socketRadius, self.socketSides) self.topBevel = evaluate.getEvaluatedFloat(self.topBevelOverRadius * self.radius, elementNode, 'topBevel') self.topBevelPositions = evaluate.getEvaluatedString('nwse', elementNode, 'topBevelPositions').lower() self.topRight = complex(float(self.columns), float(self.rows)) * self.radius def __repr__(self): 'Get the string representation of this MechaslabDerivation.' return euclidean.getDictionaryString(self.__dict__) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/peg.py000066400000000000000000000123001167321211700242060ustar00rootroot00000000000000""" Peg. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import extrude from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import cylinder from fabmetheus_utilities.vector3 import Vector3 import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addPegOutput(bevel, endZ, outputs, radiusArealized, sides, start, topOverBottom): 'Add beveled cylinder to outputs given bevel, endZ, radiusArealized and start.' height = abs(start.z - endZ) bevelStartRatio = max(1.0 - bevel / height, 0.5) oneMinusBevelStartRatio = 1.0 - bevelStartRatio trunkEndZ = bevelStartRatio * endZ + oneMinusBevelStartRatio * start.z trunkTopOverBottom = bevelStartRatio * topOverBottom + oneMinusBevelStartRatio cylinder.addCylinderOutputByEndStart(trunkEndZ, radiusArealized, outputs, sides, start, trunkTopOverBottom) capRadius = radiusArealized * trunkTopOverBottom capStart = bevelStartRatio * Vector3(start.x, start.y, endZ) + oneMinusBevelStartRatio * start radiusMaximum = max(radiusArealized.real, radiusArealized.imag) endRadiusMaximum = radiusMaximum * topOverBottom - bevel trunkRadiusMaximum = radiusMaximum * trunkTopOverBottom capTopOverBottom = endRadiusMaximum / trunkRadiusMaximum cylinder.addCylinderOutputByEndStart(endZ, capRadius, outputs, sides, capStart, capTopOverBottom) def getGeometryOutput(derivation, elementNode): 'Get vector3 vertexes from attribute dictionary.' if derivation is None: derivation = PegDerivation(elementNode) positives = [] radiusArealized = complex(derivation.radiusArealized, derivation.radiusArealized) addPegOutput(derivation.bevel, derivation.endZ, positives, radiusArealized, derivation.sides, derivation.start, derivation.topOverBottom) return extrude.getGeometryOutputByNegativesPositives(elementNode, [], positives) def getGeometryOutputByArguments(arguments, elementNode): 'Get vector3 vertexes from attribute dictionary by arguments.' evaluate.setAttributesByArguments(['radius', 'endZ', 'start'], arguments, elementNode) return getGeometryOutput(None, elementNode) def getNewDerivation(elementNode): 'Get new derivation.' return PegDerivation(elementNode) def getTopAddBiconicOutput(bottomRadians, height, outputs, radius, sides, start, tipRadius, topRadians): 'Get top and add biconic cylinder to outputs.' radiusMaximum = max(radius.real, radius.imag) topRadiusMaximum = radiusMaximum - height * math.tan(bottomRadians) trunkEndZ = start.z + height trunkTopOverBottom = topRadiusMaximum / radiusMaximum topRadiusComplex = trunkTopOverBottom * radius cylinder.addCylinderOutputByEndStart(trunkEndZ, radius, outputs, sides, start, trunkTopOverBottom) tipOverTop = tipRadius / topRadiusMaximum if tipOverTop >= 1.0: return trunkEndZ capStart = Vector3(start.x, start.y, trunkEndZ) capEndZ = trunkEndZ + (topRadiusMaximum - tipRadius) / math.tan(topRadians) cylinder.addCylinderOutputByEndStart(capEndZ, topRadiusComplex, outputs, sides, capStart, tipOverTop) return capEndZ def processElementNode(elementNode): 'Process the xml element.' solid.processElementNodeByGeometry(elementNode, getGeometryOutput(None, elementNode)) def setTopOverBottomByRadius(derivation, endZ, radius, startZ): 'Set the derivation topOverBottom by the angle of the elementNode, the endZ, float radius and startZ.' angleDegrees = evaluate.getEvaluatedFloat(None, derivation.elementNode, 'angle') if angleDegrees is not None: derivation.topOverBottom = cylinder.getTopOverBottom(math.radians(angleDegrees), endZ, complex(radius, radius), startZ) class PegDerivation: 'Class to hold peg variables.' def __init__(self, elementNode): 'Set defaults.' self.bevelOverRadius = evaluate.getEvaluatedFloat(0.25, elementNode, 'bevelOverRadius') self.clearanceOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'clearanceOverRadius') self.elementNode = elementNode self.endZ = evaluate.getEvaluatedFloat(10.0, elementNode, 'endZ') self.start = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'start') self.radius = lineation.getFloatByPrefixBeginEnd(elementNode, 'radius', 'diameter', 2.0) self.sides = evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, max(self.radius.real, self.radius.imag)) self.radiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.radius, self.sides) self.topOverBottom = evaluate.getEvaluatedFloat(0.8, elementNode, 'topOverBottom') setTopOverBottomByRadius(self, self.endZ, self.radiusArealized, self.start.z) # Set derived variables. self.bevel = evaluate.getEvaluatedFloat(self.bevelOverRadius * self.radiusArealized, elementNode, 'bevel') self.clearance = evaluate.getEvaluatedFloat(self.clearanceOverRadius * self.radiusArealized, elementNode, 'clearance') sfact-2011.12.18/fabmetheus_utilities/geometry/creation/polygon.py000066400000000000000000000062451167321211700251350ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = PolygonDerivation(elementNode) loop = [] spiral = lineation.Spiral(derivation.spiral, 0.5 * derivation.sideAngle / math.pi) for side in xrange(derivation.start, derivation.start + derivation.extent + 1): angle = float(side) * derivation.sideAngle unitPolar = euclidean.getWiddershinsUnitPolar(angle) vertex = spiral.getSpiralPoint(unitPolar, Vector3(unitPolar.real * derivation.radius.real, unitPolar.imag * derivation.radius.imag)) loop.append(vertex) loop = euclidean.getLoopWithoutCloseEnds(0.000001 * max(derivation.radius.real, derivation.radius.imag), loop) lineation.setClosedAttribute(elementNode, derivation.revolutions) return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop, derivation.sideAngle)) def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." evaluate.setAttributesByArguments(['sides', 'radius'], arguments, elementNode) return getGeometryOutput(None, elementNode) def getNewDerivation(elementNode): 'Get new derivation.' return PolygonDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class PolygonDerivation: "Class to hold polygon variables." def __init__(self, elementNode): 'Set defaults.' self.sides = evaluate.getEvaluatedFloat(4.0, elementNode, 'sides') self.sideAngle = 2.0 * math.pi / self.sides cosSide = math.cos(0.5 * self.sideAngle) self.radius = lineation.getComplexByMultiplierPrefixes(elementNode, cosSide, ['apothem', 'inradius'], complex(1.0, 1.0)) self.radius = lineation.getComplexByPrefixes(elementNode, ['demisize', 'radius'], self.radius) self.radius = lineation.getComplexByMultiplierPrefixes(elementNode, 2.0, ['diameter', 'size'], self.radius) self.sidesCeiling = int(math.ceil(abs(self.sides))) self.start = evaluate.getEvaluatedInt(0, elementNode, 'start') end = evaluate.getEvaluatedInt(self.sidesCeiling, elementNode, 'end') self.revolutions = evaluate.getEvaluatedInt(1, elementNode, 'revolutions') self.extent = evaluate.getEvaluatedInt(end - self.start, elementNode, 'extent') self.extent += self.sidesCeiling * (self.revolutions - 1) self.spiral = evaluate.getVector3ByPrefix(None, elementNode, 'spiral') sfact-2011.12.18/fabmetheus_utilities/geometry/creation/shaft.py000066400000000000000000000066171167321211700245560ustar00rootroot00000000000000""" Shaft path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = ShaftDerivation(elementNode) shaftPath = getShaftPath(derivation.depthBottom, derivation.depthTop, derivation.radius, derivation.sides) return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(shaftPath)) def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." evaluate.setAttributesByArguments(['radius', 'sides'], arguments, elementNode) return getGeometryOutput(None, elementNode) def getNewDerivation(elementNode): 'Get new derivation.' return ShaftDerivation(elementNode) def getShaftPath(depthBottom, depthTop, radius, sides): 'Get shaft with the option of a flat on the top and/or bottom.' if radius <= 0.0: return [] sideAngle = 2.0 * math.pi / float(abs(sides)) startAngle = 0.5 * sideAngle endAngle = math.pi - 0.1 * sideAngle shaftProfile = [] while startAngle < endAngle: unitPolar = euclidean.getWiddershinsUnitPolar(startAngle) shaftProfile.append(unitPolar * radius) startAngle += sideAngle if abs(sides) % 2 == 1: shaftProfile.append(complex(-radius, 0.0)) horizontalBegin = radius - depthTop horizontalEnd = depthBottom - radius shaftProfile = euclidean.getHorizontallyBoundedPath(horizontalBegin, horizontalEnd, shaftProfile) for shaftPointIndex, shaftPoint in enumerate(shaftProfile): shaftProfile[shaftPointIndex] = complex(shaftPoint.imag, shaftPoint.real) shaftPath = euclidean.getVector3Path(euclidean.getMirrorPath(shaftProfile)) if sides > 0: shaftPath.reverse() return shaftPath def processElementNode(elementNode): "Process the xml element." path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class ShaftDerivation: "Class to hold shaft variables." def __init__(self, elementNode): 'Set defaults.' self.depthBottomOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'depthBottomOverRadius') self.depthTopOverRadius = evaluate.getEvaluatedFloat(0.0, elementNode, 'depthOverRadius') self.depthTopOverRadius = evaluate.getEvaluatedFloat( self.depthTopOverRadius, elementNode, 'depthTopOverRadius') self.radius = evaluate.getEvaluatedFloat(1.0, elementNode, 'radius') self.sides = evaluate.getEvaluatedInt(4, elementNode, 'sides') self.depthBottom = self.radius * self.depthBottomOverRadius self.depthBottom = evaluate.getEvaluatedFloat(self.depthBottom, elementNode, 'depthBottom') self.depthTop = self.radius * self.depthTopOverRadius self.depthTop = evaluate.getEvaluatedFloat(self.depthTop, elementNode, 'depth') self.depthTop = evaluate.getEvaluatedFloat(self.depthTop, elementNode, 'depthTop') sfact-2011.12.18/fabmetheus_utilities/geometry/creation/solid.py000066400000000000000000000144261167321211700245600ustar00rootroot00000000000000""" Solid. Solid has some of the same functions as lineation, however you can not define geometry by dictionary string in the target because there is no getGeometryOutputByArguments function. You would have to define a shape by making the shape element. Also, you can not define geometry by 'get, because the target only gets element. Instead you would have the shape element, and set the target in solid to that element. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutputByFunction(elementNode, geometryFunction): 'Get geometry output by manipulationFunction.' if elementNode.xmlObject is None: print('Warning, there is no object in getGeometryOutputByFunction in solid for:') print(elementNode) return None geometryOutput = elementNode.xmlObject.getGeometryOutput() if geometryOutput is None: print('Warning, there is no geometryOutput in getGeometryOutputByFunction in solid for:') print(elementNode) return None return geometryFunction(elementNode, geometryOutput, '') def getGeometryOutputByManipulation(elementNode, geometryOutput): 'Get geometryOutput manipulated by the plugins in the manipulation shapes & solids folders.' xmlProcessor = elementNode.getXMLProcessor() matchingPlugins = getSolidMatchingPlugins(elementNode) matchingPlugins.sort(evaluate.compareExecutionOrderAscending) for matchingPlugin in matchingPlugins: prefix = matchingPlugin.__name__.replace('_', '') + '.' geometryOutput = matchingPlugin.getManipulatedGeometryOutput(elementNode, geometryOutput, prefix) return geometryOutput def getNewDerivation(elementNode): 'Get new derivation.' return SolidDerivation(elementNode) def getSolidMatchingPlugins(elementNode): 'Get solid plugins in the manipulation matrix, shapes & solids folders.' xmlProcessor = elementNode.getXMLProcessor() matchingPlugins = evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationMatrixDictionary) return matchingPlugins + evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationShapeDictionary) def processArchiveRemoveSolid(elementNode, geometryOutput): 'Process the target by the manipulationFunction.' solidMatchingPlugins = getSolidMatchingPlugins(elementNode) if len(solidMatchingPlugins) == 0: elementNode.parentNode.xmlObject.archivableObjects.append(elementNode.xmlObject) matrix.getBranchMatrixSetElementNode(elementNode) return processElementNodeByGeometry(elementNode, getGeometryOutputByManipulation(elementNode, geometryOutput)) def processElementNode(elementNode): 'Process the xml element.' processElementNodeByDerivation(None, elementNode) def processElementNodeByDerivation(derivation, elementNode): 'Process the xml element by derivation.' if derivation == None: derivation = SolidDerivation(elementNode) elementAttributesCopy = elementNode.attributes.copy() for target in derivation.targets: targetAttributesCopy = target.attributes.copy() target.attributes = elementAttributesCopy processTarget(target) target.attributes = targetAttributesCopy def processElementNodeByFunction(elementNode, manipulationFunction): 'Process the xml element.' if 'target' not in elementNode.attributes: print('Warning, there was no target in processElementNodeByFunction in solid for:') print(elementNode) return target = evaluate.getEvaluatedLinkValue(elementNode, str(elementNode.attributes['target']).strip()) if target.__class__.__name__ == 'ElementNode': manipulationFunction(elementNode, target) return path.convertElementNode(elementNode, target) manipulationFunction(elementNode, elementNode) def processElementNodeByFunctionPair(elementNode, geometryFunction, pathFunction): 'Process the xml element by the appropriate manipulationFunction.' elementAttributesCopy = elementNode.attributes.copy() targets = evaluate.getElementNodesByKey(elementNode, 'target') for target in targets: targetAttributesCopy = target.attributes.copy() target.attributes = elementAttributesCopy processTargetByFunctionPair(geometryFunction, pathFunction, target) target.attributes = targetAttributesCopy def processElementNodeByGeometry(elementNode, geometryOutput): 'Process the xml element by geometryOutput.' if geometryOutput != None: elementNode.getXMLProcessor().convertElementNode(elementNode, geometryOutput) def processTarget(target): 'Process the target.' if target.xmlObject == None: print('Warning, there is no object in processElementNode in solid for:') print(target) return geometryOutput = target.xmlObject.getGeometryOutput() if geometryOutput == None: print('Warning, there is no geometryOutput in processElementNode in solid for:') print(target.xmlObject) return geometryOutput = getGeometryOutputByManipulation(target, geometryOutput) lineation.removeChildNodesFromElementObject(target) target.getXMLProcessor().convertElementNode(target, geometryOutput) def processTargetByFunctionPair(geometryFunction, pathFunction, target): 'Process the target by the manipulationFunction.' if target.xmlObject is None: print('Warning, there is no object in processTargetByFunctions in solid for:') print(target) return if len(target.xmlObject.getPaths()) > 0: lineation.processTargetByFunction(pathFunction, target) return geometryOutput = getGeometryOutputByFunction(target, geometryFunction) lineation.removeChildNodesFromElementObject(target) target.getXMLProcessor().convertElementNode(target, geometryOutput) class SolidDerivation: 'Class to hold solid variables.' def __init__(self, elementNode): 'Set defaults.' self.targets = evaluate.getElementNodesByKey(elementNode, 'target') sfact-2011.12.18/fabmetheus_utilities/geometry/creation/sponge.py000066400000000000000000000172431167321211700247410ustar00rootroot00000000000000""" Sponge cross section. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math import random import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = SpongeDerivation(elementNode) awayPoints = [] vector3Path = euclidean.getVector3Path(euclidean.getSquareLoopWiddershins(-derivation.inradius, derivation.inradius)) geometryOutput = lineation.SideLoop(vector3Path).getManipulationPluginLoops(elementNode) minimumDistanceFromOther = derivation.wallThickness + derivation.minimumRadius + derivation.minimumRadius if derivation.inradiusMinusRadiusThickness.real <= 0.0 or derivation.inradiusMinusRadiusThickness.imag <= 0.0: return geometryOutput for point in derivation.path: if abs(point.x) <= derivation.inradiusMinusRadiusThickness.real and abs(point.y) <= derivation.inradiusMinusRadiusThickness.imag: awayPoints.append(point) awayCircles = [] for point in awayPoints: if getIsPointAway(minimumDistanceFromOther, point, awayCircles): awayCircles.append(SpongeCircle(point, derivation.minimumRadius)) averagePotentialBubbleArea = derivation.potentialBubbleArea / float(len(awayCircles)) averageBubbleRadius = math.sqrt(averagePotentialBubbleArea / math.pi) - 0.5 * derivation.wallThickness sides = -4 * (max(evaluate.getSidesBasedOnPrecision(elementNode, averageBubbleRadius), 4) / 4) sideAngle = math.pi / sides cosSide = math.cos(sideAngle) arealOverlapRatio = (1 - cosSide) / cosSide for circleIndex, circle in enumerate(awayCircles): otherCircles = awayCircles[: circleIndex] + awayCircles[circleIndex + 1 :] circle.radius = circle.getRadius(arealOverlapRatio, circle.center, derivation, otherCircles) if derivation.searchAttempts > 0: for circleIndex, circle in enumerate(awayCircles): otherCircles = awayCircles[: circleIndex] + awayCircles[circleIndex + 1 :] circle.moveCircle(arealOverlapRatio, derivation, otherCircles) for circle in awayCircles: vector3Path = euclidean.getVector3Path(euclidean.getComplexPolygon(circle.center.dropAxis(), circle.radius, sides, sideAngle)) geometryOutput += lineation.SideLoop(vector3Path).getManipulationPluginLoops(elementNode) return geometryOutput def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." return getGeometryOutput(None, elementNode) def getIsPointAway(minimumDistance, point, spongeCircles): 'Determine if the point is at least the minimumDistance away from other points.' for otherSpongeCircle in spongeCircles: if abs(otherSpongeCircle.center - point) < minimumDistance: return False return True def getNewDerivation(elementNode): 'Get new derivation.' return SpongeDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class SpongeCircle: "Class to hold sponge circle." def __init__(self, center, radius=0.0): 'Initialize.' self.center = center self.radius = radius def getRadius(self, arealOverlapRatio, center, derivation, otherCircles): 'Set sponge bubble radius.' spongeRadius = 987654321.0 for otherSpongeCircle in otherCircles: distance = abs(otherSpongeCircle.center.dropAxis() - center.dropAxis()) spongeRadius = min(distance - derivation.wallThickness - otherSpongeCircle.radius, spongeRadius) arealOverlap = arealOverlapRatio * spongeRadius spongeRadius = min(derivation.inradiusMinusThickness.real + arealOverlap - abs(center.x), spongeRadius) return min(derivation.inradiusMinusThickness.imag + arealOverlap - abs(center.y), spongeRadius) def moveCircle(self, arealOverlapRatio, derivation, otherCircles): 'Move circle into an open spot.' angle = (abs(self.center) + self.radius) % euclidean.globalTau movedCenter = self.center searchRadius = derivation.searchRadiusOverRadius * self.radius distanceIncrement = searchRadius / float(derivation.searchAttempts) distance = 0.0 greatestRadius = self.radius searchCircles = [] searchCircleDistance = searchRadius + searchRadius + self.radius + derivation.wallThickness for otherCircle in otherCircles: if abs(self.center - otherCircle.center) <= searchCircleDistance + otherCircle.radius: searchCircles.append(otherCircle) for attemptIndex in xrange(derivation.searchAttempts): angle += euclidean.globalGoldenAngle distance += distanceIncrement offset = distance * euclidean.getWiddershinsUnitPolar(angle) attemptCenter = self.center + Vector3(offset.real, offset.imag) radius = self.getRadius(arealOverlapRatio, attemptCenter, derivation, searchCircles) if radius > greatestRadius: greatestRadius = radius movedCenter = attemptCenter self.center = movedCenter self.radius = greatestRadius class SpongeDerivation: "Class to hold sponge variables." def __init__(self, elementNode): 'Initialize.' elementNode.attributes['closed'] = 'true' self.density = evaluate.getEvaluatedFloat(1.0, elementNode, 'density') self.minimumRadiusOverThickness = evaluate.getEvaluatedFloat(1.0, elementNode, 'minimumRadiusOverThickness') self.mobile = evaluate.getEvaluatedBoolean(False, elementNode, 'mobile') self.inradius = lineation.getInradius(complex(10.0, 10.0), elementNode) self.path = None if 'path' in elementNode.attributes: self.path = evaluate.getPathByKey([], elementNode, 'path') self.searchAttempts = evaluate.getEvaluatedInt(0, elementNode, 'searchAttempts') self.searchRadiusOverRadius = evaluate.getEvaluatedFloat(1.0, elementNode, 'searchRadiusOverRadius') self.seed = evaluate.getEvaluatedInt(None, elementNode, 'seed') self.wallThickness = evaluate.getEvaluatedFloat(2.0 * setting.getPerimeterWidth(elementNode), elementNode, 'wallThickness') # Set derived variables. self.halfWallThickness = 0.5 * self.wallThickness self.inradiusMinusThickness = self.inradius - complex(self.wallThickness, self.wallThickness) self.minimumRadius = evaluate.getEvaluatedFloat(self.minimumRadiusOverThickness * self.wallThickness, elementNode, 'minimumRadius') self.inradiusMinusRadiusThickness = self.inradiusMinusThickness - complex(self.minimumRadius, self.minimumRadius) self.potentialBubbleArea = 4.0 * self.inradiusMinusThickness.real * self.inradiusMinusThickness.imag if self.path is None: radiusPlusHalfThickness = self.minimumRadius + self.halfWallThickness numberOfPoints = int(math.ceil(self.density * self.potentialBubbleArea / math.pi / radiusPlusHalfThickness / radiusPlusHalfThickness)) self.path = [] if self.seed is None: self.seed = time.time() print('Sponge seed used was: %s' % self.seed) random.seed(self.seed) for pointIndex in xrange(numberOfPoints): point = euclidean.getRandomComplex(-self.inradiusMinusRadiusThickness, self.inradiusMinusRadiusThickness) self.path.append(Vector3(point.real, point.imag)) def __repr__(self): "Get the string representation of this SpongeDerivation." return str(self.__dict__) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/sponge_slice.py000066400000000000000000000170361167321211700261200ustar00rootroot00000000000000""" Sponge slice. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math import random import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = SpongeSliceDerivation(elementNode) awayPoints = [] vector3Path = euclidean.getVector3Path(euclidean.getSquareLoopWiddershins(-derivation.inradius, derivation.inradius)) geometryOutput = lineation.SideLoop(vector3Path).getManipulationPluginLoops(elementNode) minimumDistanceFromOther = derivation.wallThickness + derivation.minimumRadius + derivation.minimumRadius if derivation.inradiusMinusRadiusThickness.real <= 0.0 or derivation.inradiusMinusRadiusThickness.imag <= 0.0: return geometryOutput for point in derivation.path: if abs(point.x) <= derivation.inradiusMinusRadiusThickness.real and abs(point.y) <= derivation.inradiusMinusRadiusThickness.imag: awayPoints.append(point) awayCircles = [] for point in awayPoints: if getIsPointAway(minimumDistanceFromOther, point, awayCircles): awayCircles.append(SpongeCircle(point, derivation.minimumRadius)) averagePotentialBubbleArea = derivation.potentialBubbleArea / float(len(awayCircles)) averageBubbleRadius = math.sqrt(averagePotentialBubbleArea / math.pi) - 0.5 * derivation.wallThickness sides = -4 * (max(evaluate.getSidesBasedOnPrecision(elementNode, averageBubbleRadius), 4) / 4) sideAngle = math.pi / sides cosSide = math.cos(sideAngle) overlapArealRatio = (1 - cosSide) / cosSide for circleIndex, circle in enumerate(awayCircles): otherCircles = awayCircles[: circleIndex] + awayCircles[circleIndex + 1 :] circle.radius = circle.getRadius(circle.center, derivation, otherCircles, overlapArealRatio) if derivation.searchAttempts > 0: for circleIndex, circle in enumerate(awayCircles): otherCircles = awayCircles[: circleIndex] + awayCircles[circleIndex + 1 :] circle.moveCircle(derivation, otherCircles, overlapArealRatio) for circle in awayCircles: vector3Path = euclidean.getVector3Path(euclidean.getComplexPolygon(circle.center.dropAxis(), circle.radius, sides, sideAngle)) geometryOutput += lineation.SideLoop(vector3Path).getManipulationPluginLoops(elementNode) return geometryOutput def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." return getGeometryOutput(None, elementNode) def getIsPointAway(minimumDistance, point, spongeCircles): 'Determine if the point is at least the minimumDistance away from other points.' for otherSpongeCircle in spongeCircles: if abs(otherSpongeCircle.center - point) < minimumDistance: return False return True def getNewDerivation(elementNode): 'Get new derivation.' return SpongeSliceDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class SpongeCircle: "Class to hold sponge circle." def __init__(self, center, radius=0.0): 'Initialize.' self.center = center self.radius = radius def getRadius(self, center, derivation, otherCircles, overlapArealRatio): 'Get sponge bubble radius.' radius = 987654321.0 for otherSpongeCircle in otherCircles: distance = abs(otherSpongeCircle.center.dropAxis() - center.dropAxis()) radius = min(distance - derivation.wallThickness - otherSpongeCircle.radius, radius) overlapAreal = overlapArealRatio * radius radius = min(derivation.inradiusMinusThickness.real + overlapAreal - abs(center.x), radius) return min(derivation.inradiusMinusThickness.imag + overlapAreal - abs(center.y), radius) def moveCircle(self, derivation, otherCircles, overlapArealRatio): 'Move circle into an open spot.' angle = (abs(self.center) + self.radius) % euclidean.globalTau movedCenter = self.center searchRadius = derivation.searchRadiusOverRadius * self.radius distanceIncrement = searchRadius / float(derivation.searchAttempts) distance = 0.0 greatestRadius = self.radius searchCircles = [] searchCircleDistance = searchRadius + searchRadius + self.radius + derivation.wallThickness for otherCircle in otherCircles: if abs(self.center - otherCircle.center) <= searchCircleDistance + otherCircle.radius: searchCircles.append(otherCircle) for attemptIndex in xrange(derivation.searchAttempts): angle += euclidean.globalGoldenAngle distance += distanceIncrement offset = distance * euclidean.getWiddershinsUnitPolar(angle) attemptCenter = self.center + Vector3(offset.real, offset.imag) radius = self.getRadius(attemptCenter, derivation, searchCircles, overlapArealRatio) if radius > greatestRadius: greatestRadius = radius movedCenter = attemptCenter self.center = movedCenter self.radius = greatestRadius class SpongeSliceDerivation: "Class to hold sponge slice variables." def __init__(self, elementNode): 'Initialize.' elementNode.attributes['closed'] = 'true' self.density = evaluate.getEvaluatedFloat(1.0, elementNode, 'density') self.minimumRadiusOverThickness = evaluate.getEvaluatedFloat(1.0, elementNode, 'minimumRadiusOverThickness') self.mobile = evaluate.getEvaluatedBoolean(False, elementNode, 'mobile') self.inradius = lineation.getInradius(complex(10.0, 10.0), elementNode) self.path = None if 'path' in elementNode.attributes: self.path = evaluate.getPathByKey([], elementNode, 'path') self.searchAttempts = evaluate.getEvaluatedInt(0, elementNode, 'searchAttempts') self.searchRadiusOverRadius = evaluate.getEvaluatedFloat(1.0, elementNode, 'searchRadiusOverRadius') self.seed = evaluate.getEvaluatedInt(None, elementNode, 'seed') self.wallThickness = evaluate.getEvaluatedFloat(2.0 * setting.getPerimeterWidth(elementNode), elementNode, 'wallThickness') # Set derived variables. self.halfWallThickness = 0.5 * self.wallThickness self.inradiusMinusThickness = self.inradius - complex(self.wallThickness, self.wallThickness) self.minimumRadius = evaluate.getEvaluatedFloat(self.minimumRadiusOverThickness * self.wallThickness, elementNode, 'minimumRadius') self.inradiusMinusRadiusThickness = self.inradiusMinusThickness - complex(self.minimumRadius, self.minimumRadius) self.potentialBubbleArea = 4.0 * self.inradiusMinusThickness.real * self.inradiusMinusThickness.imag if self.path is None: radiusPlusHalfThickness = self.minimumRadius + self.halfWallThickness numberOfPoints = int(math.ceil(self.density * self.potentialBubbleArea / math.pi / radiusPlusHalfThickness / radiusPlusHalfThickness)) self.path = [] if self.seed is None: self.seed = time.time() print('Sponge slice seed used was: %s' % self.seed) random.seed(self.seed) for pointIndex in xrange(numberOfPoints): point = euclidean.getRandomComplex(-self.inradiusMinusRadiusThickness, self.inradiusMinusRadiusThickness) self.path.append(Vector3(point.real, point.imag)) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/square.py000066400000000000000000000072461167321211700247500ustar00rootroot00000000000000""" Square path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = SquareDerivation(elementNode) topRight = complex(derivation.topDemiwidth, derivation.demiheight) topLeft = complex(-derivation.topDemiwidth, derivation.demiheight) bottomLeft = complex(-derivation.bottomDemiwidth, -derivation.demiheight) bottomRight = complex(derivation.bottomDemiwidth, -derivation.demiheight) if derivation.interiorAngle != 90.0: interiorPlaneAngle = euclidean.getWiddershinsUnitPolar(math.radians(derivation.interiorAngle - 90.0)) topRight = (topRight - bottomRight) * interiorPlaneAngle + bottomRight topLeft = (topLeft - bottomLeft) * interiorPlaneAngle + bottomLeft lineation.setClosedAttribute(elementNode, derivation.revolutions) complexLoop = [topRight, topLeft, bottomLeft, bottomRight] originalLoop = complexLoop[:] for revolution in xrange(1, derivation.revolutions): complexLoop += originalLoop spiral = lineation.Spiral(derivation.spiral, 0.25) loop = [] loopCentroid = euclidean.getLoopCentroid(originalLoop) for point in complexLoop: unitPolar = euclidean.getNormalized(point - loopCentroid) loop.append(spiral.getSpiralPoint(unitPolar, Vector3(point.real, point.imag))) return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop, 0.5 * math.pi)) def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." if len(arguments) < 1: return getGeometryOutput(None, elementNode) inradius = 0.5 * euclidean.getFloatFromValue(arguments[0]) elementNode.attributes['inradius.x'] = str(inradius) if len(arguments) > 1: inradius = 0.5 * euclidean.getFloatFromValue(arguments[1]) elementNode.attributes['inradius.y'] = str(inradius) return getGeometryOutput(None, elementNode) def getNewDerivation(elementNode): 'Get new derivation.' return SquareDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class SquareDerivation: "Class to hold square variables." def __init__(self, elementNode): 'Set defaults.' self.inradius = lineation.getInradius(complex(1.0, 1.0), elementNode) self.demiwidth = lineation.getFloatByPrefixBeginEnd(elementNode, 'demiwidth', 'width', self.inradius.real) self.demiheight = lineation.getFloatByPrefixBeginEnd(elementNode, 'demiheight', 'height', self.inradius.imag) self.bottomDemiwidth = lineation.getFloatByPrefixBeginEnd(elementNode, 'bottomdemiwidth', 'bottomwidth', self.demiwidth) self.topDemiwidth = lineation.getFloatByPrefixBeginEnd(elementNode, 'topdemiwidth', 'topwidth', self.demiwidth) self.interiorAngle = evaluate.getEvaluatedFloat(90.0, elementNode, 'interiorangle') self.revolutions = evaluate.getEvaluatedInt(1, elementNode, 'revolutions') self.spiral = evaluate.getVector3ByPrefix(None, elementNode, 'spiral') sfact-2011.12.18/fabmetheus_utilities/geometry/creation/teardrop.py000066400000000000000000000124221167321211700252600ustar00rootroot00000000000000""" Teardrop path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import extrude from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addNegativesByRadius(elementNode, end, negatives, radius, start): "Add teardrop drill hole to negatives." if radius <= 0.0: return copyShallow = elementNode.getCopyShallow() extrude.setElementNodeToEndStart(copyShallow, end, start) extrudeDerivation = extrude.ExtrudeDerivation(copyShallow) extrude.addNegatives(extrudeDerivation, negatives, [getTeardropPathByEndStart(elementNode, end, radius, start)]) def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attribute dictionary." if derivation is None: derivation = TeardropDerivation(elementNode) teardropPath = getTeardropPath( derivation.inclination, derivation.overhangRadians, derivation.overhangSpan, derivation.radiusArealized, derivation.sides) return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(teardropPath)) def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." evaluate.setAttributesByArguments(['radius', 'inclination'], arguments, elementNode) return getGeometryOutput(None, elementNode) def getInclination(end, start): "Get inclination." if end is None or start is None: return 0.0 endMinusStart = end - start return math.atan2(endMinusStart.z, abs(endMinusStart.dropAxis())) def getNewDerivation(elementNode): 'Get new derivation.' return TeardropDerivation(elementNode) def getTeardropPath(inclination, overhangRadians, overhangSpan, radiusArealized, sides): "Get vector3 teardrop path." sideAngle = 2.0 * math.pi / float(sides) overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(overhangRadians) overhangRadians = math.atan2(overhangPlaneAngle.imag, overhangPlaneAngle.real * math.cos(inclination)) tanOverhangAngle = math.tan(overhangRadians) beginAngle = overhangRadians beginMinusEndAngle = math.pi + overhangRadians + overhangRadians withinSides = int(math.ceil(beginMinusEndAngle / sideAngle)) withinSideAngle = -beginMinusEndAngle / float(withinSides) teardropPath = [] for side in xrange(withinSides + 1): unitPolar = euclidean.getWiddershinsUnitPolar(beginAngle) teardropPath.append(unitPolar * radiusArealized) beginAngle += withinSideAngle firstPoint = teardropPath[0] if overhangSpan <= 0.0: teardropPath.append(complex(0.0, firstPoint.imag + firstPoint.real / tanOverhangAngle)) else: deltaX = (radiusArealized - firstPoint.imag) * tanOverhangAngle overhangPoint = complex(firstPoint.real - deltaX, radiusArealized) remainingDeltaX = max(0.0, overhangPoint.real - 0.5 * overhangSpan ) overhangPoint += complex(-remainingDeltaX, remainingDeltaX / tanOverhangAngle) teardropPath.append(complex(-overhangPoint.real, overhangPoint.imag)) teardropPath.append(overhangPoint) return euclidean.getVector3Path(teardropPath) def getTeardropPathByEndStart(elementNode, end, radius, start): "Get vector3 teardrop path by end and start." inclination = getInclination(end, start) sides = evaluate.getSidesMinimumThreeBasedOnPrecisionSides(elementNode, radius) radiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNoderadius, sides) return getTeardropPath(inclination, setting.getOverhangRadians(elementNode), setting.getOverhangSpan(elementNode), radiusArealized, sides) def processElementNode(elementNode): "Process the xml element." path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class TeardropDerivation: "Class to hold teardrop variables." def __init__(self, elementNode): 'Set defaults.' end = evaluate.getVector3ByPrefix(None, elementNode, 'end') start = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'start') inclinationDegree = math.degrees(getInclination(end, start)) self.elementNode = elementNode self.inclination = math.radians(evaluate.getEvaluatedFloat(inclinationDegree, elementNode, 'inclination')) self.overhangRadians = setting.getOverhangRadians(elementNode) self.overhangSpan = setting.getOverhangSpan(elementNode) self.radius = lineation.getFloatByPrefixBeginEnd(elementNode, 'radius', 'diameter', 1.0) size = evaluate.getEvaluatedFloat(None, elementNode, 'size') if size is not None: self.radius = 0.5 * size self.sides = evaluate.getEvaluatedFloat(None, elementNode, 'sides') if self.sides is None: self.sides = evaluate.getSidesMinimumThreeBasedOnPrecisionSides(elementNode, self.radius) self.radiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.radius, self.sides) sfact-2011.12.18/fabmetheus_utilities/geometry/creation/text.py000066400000000000000000000050141167321211700244230ustar00rootroot00000000000000""" Text vertexes. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities import euclidean from fabmetheus_utilities import svg_reader __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometryOutput(derivation, elementNode): "Get vector3 vertexes from attributes." if derivation is None: derivation = TextDerivation(elementNode) if derivation.textString == '': print('Warning, textString is empty in getGeometryOutput in text for:') print(elementNode) return [] geometryOutput = [] for textComplexLoop in svg_reader.getTextComplexLoops(derivation.fontFamily, derivation.fontSize, derivation.textString): textComplexLoop.reverse() vector3Path = euclidean.getVector3Path(textComplexLoop) sideLoop = lineation.SideLoop(vector3Path) sideLoop.rotate(elementNode) geometryOutput += lineation.getGeometryOutputByManipulation(elementNode, sideLoop) return geometryOutput def getGeometryOutputByArguments(arguments, elementNode): "Get vector3 vertexes from attribute dictionary by arguments." evaluate.setAttributesByArguments(['text', 'fontSize', 'fontFamily'], arguments, elementNode) return getGeometryOutput(None, elementNode) def getNewDerivation(elementNode): 'Get new derivation.' return TextDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." path.convertElementNode(elementNode, getGeometryOutput(None, elementNode)) class TextDerivation: "Class to hold text variables." def __init__(self, elementNode): 'Set defaults.' self.fontFamily = evaluate.getEvaluatedString('Gentium Basic Regular', elementNode, 'font-family') self.fontFamily = evaluate.getEvaluatedString(self.fontFamily, elementNode, 'fontFamily') self.fontSize = evaluate.getEvaluatedFloat(12.0, elementNode, 'font-size') self.fontSize = evaluate.getEvaluatedFloat(self.fontSize, elementNode, 'fontSize') self.textString = elementNode.getTextContent() self.textString = evaluate.getEvaluatedString(self.textString, elementNode, 'text') sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/000077500000000000000000000000001167321211700243345ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/__init__.py000066400000000000000000000006571167321211700264550ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/dictionary.py000066400000000000000000000130021167321211700270470ustar00rootroot00000000000000""" Boolean geometry dictionary object. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities import euclidean from fabmetheus_utilities import xml_simple_writer import cStringIO __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getAllPaths(paths, xmlObject): 'Get all paths.' for archivableObject in xmlObject.archivableObjects: paths += archivableObject.getPaths() return paths def getAllTransformedPaths(transformedPaths, xmlObject): 'Get all transformed paths.' for archivableObject in xmlObject.archivableObjects: transformedPaths += archivableObject.getTransformedPaths() return transformedPaths def getAllTransformedVertexes(transformedVertexes, xmlObject): 'Get all transformed vertexes.' for archivableObject in xmlObject.archivableObjects: transformedVertexes += archivableObject.getTransformedVertexes() return transformedVertexes def getAllVertexes(vertexes, xmlObject): 'Get all vertexes.' for archivableObject in xmlObject.archivableObjects: vertexes += archivableObject.getVertexes() return vertexes def processElementNode(elementNode): 'Process the xml element.' evaluate.processArchivable( Dictionary, elementNode) class Dictionary: 'A dictionary object.' def __init__(self): 'Add empty lists.' self.archivableObjects = [] self.elementNode = None def __repr__(self): 'Get the string representation of this object info.' output = xml_simple_writer.getBeginGeometryXMLOutput(self.elementNode) self.addXML( 1, output ) return xml_simple_writer.getEndGeometryXMLString(output) def addXML(self, depth, output): 'Add xml for this object.' attributeCopy = {} if self.elementNode is not None: attributeCopy = evaluate.getEvaluatedDictionaryByCopyKeys(['paths', 'target', 'vertexes'], self.elementNode) euclidean.removeElementsFromDictionary(attributeCopy, matrix.getKeysM()) euclidean.removeTrueFromDictionary(attributeCopy, 'visible') innerOutput = cStringIO.StringIO() self.addXMLInnerSection(depth + 1, innerOutput) self.addXMLArchivableObjects(depth + 1, innerOutput) xml_simple_writer.addBeginEndInnerXMLTag(attributeCopy, depth, innerOutput.getvalue(), self.getXMLLocalName(), output) def addXMLArchivableObjects(self, depth, output): 'Add xml for this object.' xml_simple_writer.addXMLFromObjects( depth, self.archivableObjects, output ) def addXMLInnerSection(self, depth, output): 'Add xml section for this object.' pass def createShape(self): 'Create the shape.' pass def getAttributes(self): 'Get attribute table.' if self.elementNode is None: return {} return self.elementNode.attributes def getComplexTransformedPathLists(self): 'Get complex transformed path lists.' complexTransformedPathLists = [] for archivableObject in self.archivableObjects: complexTransformedPathLists.append(euclidean.getComplexPaths(archivableObject.getTransformedPaths())) return complexTransformedPathLists def getFabricationExtension(self): 'Get fabrication extension.' return 'xml' def getFabricationText(self, addLayerTemplate): 'Get fabrication text.' return self.__repr__() def getGeometryOutput(self): 'Get geometry output dictionary.' shapeOutput = [] for visibleObject in evaluate.getVisibleObjects(self.archivableObjects): geometryOutput = visibleObject.getGeometryOutput() if geometryOutput != None: visibleObject.transformGeometryOutput(geometryOutput) shapeOutput.append(geometryOutput) if len(shapeOutput) < 1: return None return {self.getXMLLocalName() : {'shapes' : shapeOutput}} def getMatrix4X4(self): "Get the matrix4X4." return None def getMatrixChainTetragrid(self): 'Get the matrix chain tetragrid.' return self.elementNode.parentNode.xmlObject.getMatrixChainTetragrid() def getMinimumZ(self): 'Get the minimum z.' return None def getPaths(self): 'Get all paths.' return getAllPaths([], self) def getTransformedPaths(self): 'Get all transformed paths.' return getAllTransformedPaths([], self) def getTransformedVertexes(self): 'Get all transformed vertexes.' return getAllTransformedVertexes([], self) def getTriangleMeshes(self): 'Get all triangleMeshes.' triangleMeshes = [] for archivableObject in self.archivableObjects: triangleMeshes += archivableObject.getTriangleMeshes() return triangleMeshes def getType(self): 'Get type.' return self.__class__.__name__ def getVertexes(self): 'Get all vertexes.' return getAllVertexes([], self) def getVisible(self): 'Get visible.' return False def getXMLLocalName(self): 'Get xml local name.' return self.__class__.__name__.lower() def setToElementNode(self, elementNode): 'Set the shape of this carvable object info.' self.elementNode = elementNode elementNode.parentNode.xmlObject.archivableObjects.append(self) def transformGeometryOutput(self, geometryOutput): 'Transform the geometry output by the local matrix4x4.' if self.getMatrix4X4() != None: matrix.transformVector3sByMatrix(self.getMatrix4X4().tetragrid, matrix.getVertexes(geometryOutput)) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/face.py000066400000000000000000000130571167321211700256120ustar00rootroot00000000000000""" Face of a triangle mesh. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities.vector3index import Vector3Index from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import xml_simple_reader from fabmetheus_utilities import xml_simple_writer import cStringIO import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addFaces(geometryOutput, faces): 'Add the faces.' if geometryOutput.__class__ == list: for element in geometryOutput: addFaces(element, faces) return if geometryOutput.__class__ != dict: return for geometryOutputKey in geometryOutput.keys(): geometryOutputValue = geometryOutput[geometryOutputKey] if geometryOutputKey == 'face': for face in geometryOutputValue: faces.append(face) else: addFaces(geometryOutputValue, faces) def addGeometryList(elementNode, faces): "Add vertex elements to an xml element." for face in faces: faceElement = xml_simple_reader.ElementNode() face.addToAttributes( faceElement.attributes ) faceElement.localName = 'face' faceElement.parentNode = elementNode elementNode.childNodes.append( faceElement ) def getCommonVertexIndex( edgeFirst, edgeSecond ): "Get the vertex index that both edges have in common." for edgeFirstVertexIndex in edgeFirst.vertexIndexes: if edgeFirstVertexIndex == edgeSecond.vertexIndexes[0] or edgeFirstVertexIndex == edgeSecond.vertexIndexes[1]: return edgeFirstVertexIndex print( "Inconsistent GNU Triangulated Surface" ) print( edgeFirst ) print( edgeSecond ) return 0 def getFaces(geometryOutput): 'Get the faces.' faces = [] addFaces(geometryOutput, faces) return faces def processElementNode(elementNode): "Process the xml element." face = Face() face.index = len(elementNode.parentNode.xmlObject.faces) for vertexIndexIndex in xrange(3): face.vertexIndexes.append(evaluate.getEvaluatedInt(None, elementNode, 'vertex' + str(vertexIndexIndex))) elementNode.parentNode.xmlObject.faces.append(face) class Edge: "An edge of a triangle mesh." def __init__(self): "Set the face indexes to None." self.faceIndexes = [] self.vertexIndexes = [] self.zMaximum = None self.zMinimum = None def __repr__(self): "Get the string representation of this Edge." return str( self.index ) + ' ' + str( self.faceIndexes ) + ' ' + str(self.vertexIndexes) def addFaceIndex( self, faceIndex ): "Add first None face index to input face index." self.faceIndexes.append( faceIndex ) def getFromVertexIndexes( self, edgeIndex, vertexIndexes ): "Initialize from two vertex indices." self.index = edgeIndex self.vertexIndexes = vertexIndexes[:] self.vertexIndexes.sort() return self class Face: "A face of a triangle mesh." def __init__(self): "Initialize." self.edgeIndexes = [] self.index = None self.vertexIndexes = [] def __repr__(self): "Get the string representation of this object info." output = cStringIO.StringIO() self.addXML( 2, output ) return output.getvalue() def addToAttributes(self, attributes): "Add to the attribute dictionary." for vertexIndexIndex in xrange(len(self.vertexIndexes)): vertexIndex = self.vertexIndexes[vertexIndexIndex] attributes['vertex' + str(vertexIndexIndex)] = str(vertexIndex) def addXML(self, depth, output): "Add the xml for this object." attributes = {} self.addToAttributes(attributes) xml_simple_writer.addClosedXMLTag( attributes, depth, 'face', output ) def copy(self): 'Get the copy of this face.' faceCopy = Face() faceCopy.edgeIndexes = self.edgeIndexes[:] faceCopy.index = self.index faceCopy.vertexIndexes = self.vertexIndexes[:] return faceCopy def getFromEdgeIndexes( self, edgeIndexes, edges, faceIndex ): "Initialize from edge indices." if len(self.vertexIndexes) > 0: return self.index = faceIndex self.edgeIndexes = edgeIndexes for edgeIndex in edgeIndexes: edges[ edgeIndex ].addFaceIndex( faceIndex ) for triangleIndex in xrange(3): indexFirst = ( 3 - triangleIndex ) % 3 indexSecond = ( 4 - triangleIndex ) % 3 self.vertexIndexes.append( getCommonVertexIndex( edges[ edgeIndexes[ indexFirst ] ], edges[ edgeIndexes[ indexSecond ] ] ) ) return self def setEdgeIndexesToVertexIndexes( self, edges, edgeTable ): "Set the edge indexes to the vertex indexes." if len(self.edgeIndexes) > 0: return for triangleIndex in xrange(3): indexFirst = ( 3 - triangleIndex ) % 3 indexSecond = ( 4 - triangleIndex ) % 3 vertexIndexFirst = self.vertexIndexes[ indexFirst ] vertexIndexSecond = self.vertexIndexes[ indexSecond ] vertexIndexPair = [ vertexIndexFirst, vertexIndexSecond ] vertexIndexPair.sort() edgeIndex = len( edges ) if str( vertexIndexPair ) in edgeTable: edgeIndex = edgeTable[ str( vertexIndexPair ) ] else: edgeTable[ str( vertexIndexPair ) ] = edgeIndex edge = Edge().getFromVertexIndexes( edgeIndex, vertexIndexPair ) edges.append( edge ) edges[ edgeIndex ].addFaceIndex( self.index ) self.edgeIndexes.append( edgeIndex ) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/path.py000066400000000000000000000151341167321211700256460ustar00rootroot00000000000000""" Path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import dictionary from fabmetheus_utilities.geometry.geometry_tools import vertex from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean from fabmetheus_utilities import svg_writer from fabmetheus_utilities import xml_simple_reader from fabmetheus_utilities import xml_simple_writer __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def convertElementNode(elementNode, geometryOutput): 'Convert the xml element by geometryOutput.' if geometryOutput is None: return if len(geometryOutput) < 1: return if len(geometryOutput) == 1: firstLoop = geometryOutput[0] if firstLoop.__class__ == list: geometryOutput = firstLoop firstElement = geometryOutput[0] if firstElement.__class__ == list: if len(firstElement) > 1: convertElementNodeRenameByPaths(elementNode, geometryOutput) else: convertElementNodeByPath(elementNode, firstElement) else: convertElementNodeByPath(elementNode, geometryOutput) def convertElementNodeByPath(elementNode, geometryOutput): 'Convert the xml element to a path xml element.' createLinkPath(elementNode) elementNode.xmlObject.vertexes = geometryOutput vertex.addGeometryList(elementNode, geometryOutput) def convertElementNodeRenameByPaths(elementNode, geometryOutput): 'Convert the xml element to a path xml element and add paths.' createLinkPath(elementNode) for geometryOutputChild in geometryOutput: pathElement = xml_simple_reader.ElementNode() pathElement.setParentAddToChildNodes(elementNode) convertElementNodeByPath(pathElement, geometryOutputChild) def createLinkPath(elementNode): 'Create and link a path object.' elementNode.localName = 'path' elementNode.linkObject(Path()) def processElementNode(elementNode): 'Process the xml element.' evaluate.processArchivable(Path, elementNode) class Path(dictionary.Dictionary): 'A path.' def __init__(self): 'Add empty lists.' dictionary.Dictionary.__init__(self) self.matrix4X4 = matrix.Matrix() self.oldChainTetragrid = None self.transformedPath = None self.vertexes = [] def addXMLInnerSection(self, depth, output): 'Add the xml section for this object.' if self.matrix4X4 is not None: self.matrix4X4.addXML(depth, output) xml_simple_writer.addXMLFromVertexes(depth, output, self.vertexes) def getFabricationExtension(self): 'Get fabrication extension.' return 'svg' def getFabricationText(self, addLayerTemplate): 'Get fabrication text.' carving = SVGFabricationCarving(addLayerTemplate, self.elementNode) carving.setCarveLayerThickness(setting.getSheetThickness(self.elementNode)) carving.processSVGElement(self.elementNode.getOwnerDocument().fileName) return str(carving) def getMatrix4X4(self): "Get the matrix4X4." return self.matrix4X4 def getMatrixChainTetragrid(self): 'Get the matrix chain tetragrid.' return matrix.getTetragridTimesOther(self.elementNode.parentNode.xmlObject.getMatrixChainTetragrid(), self.matrix4X4.tetragrid) def getPaths(self): 'Get all paths.' self.transformedPath = None if len(self.vertexes) > 0: return dictionary.getAllPaths([self.vertexes], self) return dictionary.getAllPaths([], self) def getTransformedPaths(self): 'Get all transformed paths.' if self.elementNode is None: return dictionary.getAllPaths([self.vertexes], self) chainTetragrid = self.getMatrixChainTetragrid() if self.oldChainTetragrid != chainTetragrid: self.oldChainTetragrid = chainTetragrid self.transformedPath = None if self.transformedPath is None: self.transformedPath = matrix.getTransformedVector3s(chainTetragrid, self.vertexes) if len(self.transformedPath) > 0: return dictionary.getAllTransformedPaths([self.transformedPath], self) return dictionary.getAllTransformedPaths([], self) class SVGFabricationCarving: 'An svg carving.' def __init__(self, addLayerTemplate, elementNode): 'Add empty lists.' self.addLayerTemplate = addLayerTemplate self.elementNode = elementNode self.layerThickness = 1.0 self.loopLayers = [] def __repr__(self): 'Get the string representation of this carving.' return self.getCarvedSVG() def addXML(self, depth, output): 'Add xml for this object.' xml_simple_writer.addXMLFromObjects(depth, self.loopLayers, output) def getCarveBoundaryLayers(self): 'Get the boundary layers.' return self.loopLayers def getCarveCornerMaximum(self): 'Get the corner maximum of the vertexes.' return self.cornerMaximum def getCarveCornerMinimum(self): 'Get the corner minimum of the vertexes.' return self.cornerMinimum def getCarvedSVG(self): 'Get the carved svg text.' return svg_writer.getSVGByLoopLayers(self.addLayerTemplate, self, self.loopLayers) def getCarveLayerThickness(self): 'Get the layer thickness.' return self.layerThickness def getFabmetheusXML(self): 'Return the fabmetheus XML.' return self.elementNode.getOwnerDocument().getOriginalRoot() def getInterpretationSuffix(self): 'Return the suffix for a carving.' return 'svg' def processSVGElement(self, fileName): 'Parse SVG element and store the layers.' self.fileName = fileName paths = self.elementNode.xmlObject.getPaths() oldZ = None self.loopLayers = [] loopLayer = None for path in paths: if len(path) > 0: z = path[0].z if z != oldZ: loopLayer = euclidean.LoopLayer(z) self.loopLayers.append(loopLayer) oldZ = z loopLayer.loops.append(euclidean.getComplexPath(path)) if len(self.loopLayers) < 1: return self.cornerMaximum = Vector3(-987654321.0, -987654321.0, -987654321.0) self.cornerMinimum = Vector3(987654321.0, 987654321.0, 987654321.0) svg_writer.setSVGCarvingCorners(self.cornerMaximum, self.cornerMinimum, self.layerThickness, self.loopLayers) def setCarveImportRadius( self, importRadius ): 'Set the import radius.' pass def setCarveIsCorrectMesh( self, isCorrectMesh ): 'Set the is correct mesh flag.' pass def setCarveLayerThickness( self, layerThickness ): 'Set the layer thickness.' self.layerThickness = layerThickness sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/path_elements/000077500000000000000000000000001167321211700271645ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/path_elements/__init__.py000066400000000000000000000006571167321211700313050ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 4 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/path_elements/arc.py000066400000000000000000000036561167321211700303150ustar00rootroot00000000000000""" Arc vertexes. From: http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean from fabmetheus_utilities import svg_reader import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getArcPath(elementNode): "Get the arc path.rx ry x-axis-rotation large-arc-flag sweep-flag" begin = elementNode.getPreviousVertex(Vector3()) end = evaluate.getVector3FromElementNode(elementNode) largeArcFlag = evaluate.getEvaluatedBoolean(True, elementNode, 'largeArcFlag') radius = lineation.getComplexByPrefix(elementNode, 'radius', complex(1.0, 1.0)) sweepFlag = evaluate.getEvaluatedBoolean(True, elementNode, 'sweepFlag') xAxisRotation = math.radians(evaluate.getEvaluatedFloat(0.0, elementNode, 'xAxisRotation')) arcComplexes = svg_reader.getArcComplexes(begin.dropAxis(), end.dropAxis(), largeArcFlag, radius, sweepFlag, xAxisRotation) path = [] if len(arcComplexes) < 1: return [] incrementZ = (end.z - begin.z) / float(len(arcComplexes)) z = begin.z for pointIndex in xrange(len(arcComplexes)): pointComplex = arcComplexes[pointIndex] z += incrementZ path.append(Vector3(pointComplex.real, pointComplex.imag, z)) if len(path) > 0: path[-1] = end return path def processElementNode(elementNode): "Process the xml element." elementNode.parentNode.xmlObject.vertexes += getArcPath(elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/path_elements/cubic.py000066400000000000000000000047121167321211700306270ustar00rootroot00000000000000""" Cubic vertexes. From: http://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import svg_reader __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCubicPath(elementNode): "Get the cubic path." end = evaluate.getVector3FromElementNode(elementNode) previousElementNode = elementNode.getPreviousElementNode() if previousElementNode is None: print('Warning, can not get previousElementNode in getCubicPath in cubic for:') print(elementNode) return [end] begin = elementNode.getPreviousVertex(Vector3()) evaluatedControlPoints = evaluate.getTransformedPathByKey([], elementNode, 'controlPoints') if len(evaluatedControlPoints) > 1: return getCubicPathByBeginEnd(begin, evaluatedControlPoints, elementNode, end) controlPoint0 = evaluate.getVector3ByPrefix(None, elementNode, 'controlPoint0') controlPoint1 = evaluate.getVector3ByPrefix(None, elementNode, 'controlPoint1') if len(evaluatedControlPoints) == 1: controlPoint1 = evaluatedControlPoints[0] if controlPoint0 is None: oldControlPoint = evaluate.getVector3ByPrefixes(previousElementNode, ['controlPoint','controlPoint1'], None) if oldControlPoint is None: oldControlPoints = evaluate.getTransformedPathByKey([], previousElementNode, 'controlPoints') if len(oldControlPoints) > 0: oldControlPoint = oldControlPoints[-1] if oldControlPoint is None: oldControlPoint = end controlPoint0 = begin + begin - oldControlPoint return getCubicPathByBeginEnd(begin, [controlPoint0, controlPoint1], elementNode, end) def getCubicPathByBeginEnd(begin, controlPoints, elementNode, end): "Get the cubic path by begin and end." return svg_reader.getCubicPoints(begin, controlPoints, end, lineation.getNumberOfBezierPoints(begin, elementNode, end)) def processElementNode(elementNode): "Process the xml element." elementNode.parentNode.xmlObject.vertexes += getCubicPath(elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/path_elements/quadratic.py000066400000000000000000000034551167321211700315220ustar00rootroot00000000000000""" Quadratic vertexes. From: http://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import svg_reader __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getQuadraticPath(elementNode): "Get the quadratic path." end = evaluate.getVector3FromElementNode(elementNode) previousElementNode = elementNode.getPreviousElementNode() if previousElementNode is None: print('Warning, can not get previousElementNode in getQuadraticPath in quadratic for:') print(elementNode) return [end] begin = elementNode.getPreviousVertex(Vector3()) controlPoint = evaluate.getVector3ByPrefix(None, elementNode, 'controlPoint') if controlPoint is None: oldControlPoint = evaluate.getVector3ByPrefixes(previousElementNode, ['controlPoint','controlPoint1'], None) if oldControlPoint is None: oldControlPoint = end controlPoint = begin + begin - oldControlPoint evaluate.addVector3ToElementNode(elementNode, 'controlPoint', controlPoint) return svg_reader.getQuadraticPoints(begin, controlPoint, end, lineation.getNumberOfBezierPoints(begin, elementNode, end)) def processElementNode(elementNode): "Process the xml element." elementNode.parentNode.xmlObject.vertexes += getQuadraticPath(elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_tools/vertex.py000066400000000000000000000027641167321211700262340ustar00rootroot00000000000000""" Vertex of a triangle mesh. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities import xml_simple_reader __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addGeometryList(elementNode, vertexes): "Add vertex elements to an xml element." for vertex in vertexes: vertexElement = getUnboundVertexElement(vertex) vertexElement.parentNode = elementNode elementNode.childNodes.append( vertexElement ) def addVertexToAttributes(attributes, vertex): "Add to the attribute dictionary." if vertex.x != 0.0: attributes['x'] = str(vertex.x) if vertex.y != 0.0: attributes['y'] = str(vertex.y) if vertex.z != 0.0: attributes['z'] = str(vertex.z) def getUnboundVertexElement(vertex): "Add vertex element to an xml element." vertexElement = xml_simple_reader.ElementNode() addVertexToAttributes(vertexElement.attributes, vertex) vertexElement.localName = 'vertex' return vertexElement def processElementNode(elementNode): "Process the xml element." elementNode.parentNode.xmlObject.vertexes.append(evaluate.getVector3FromElementNode(elementNode)) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/000077500000000000000000000000001167321211700252075ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/__init__.py000066400000000000000000000007351167321211700273250ustar00rootroot00000000000000""" This page is in the table of contents. This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. """ import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/boolean_geometry.py000066400000000000000000000200701167321211700311120ustar00rootroot00000000000000""" This page is in the table of contents. The xml.py script is an import translator plugin to get a carving from an Art of Illusion xml file. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an xml file and returns the carving. An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice. This will bring up the XML file chooser window, choose a place to save the file then click "OK". Leave the "compressFile" checkbox unchecked. All the objects from the scene will be exported, this plugin will ignore the light and camera. If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import boolean_solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean from fabmetheus_utilities import settings from fabmetheus_utilities import xml_simple_writer import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getEmptyZLoops(archivableObjects, importRadius, shouldPrintWarning, z, zoneArrangement): 'Get loops at empty z level.' emptyZ = zoneArrangement.getEmptyZ(z) visibleObjects = evaluate.getVisibleObjects(archivableObjects) visibleObjectLoopsList = boolean_solid.getVisibleObjectLoopsList(importRadius, visibleObjects, emptyZ) loops = euclidean.getConcatenatedList(visibleObjectLoopsList) if euclidean.isLoopListIntersecting(loops): loops = boolean_solid.getLoopsUnified(importRadius, visibleObjectLoopsList) if shouldPrintWarning: print('Warning, the triangle mesh slice intersects itself in getExtruderPaths in boolean_geometry.') print( 'Something will still be printed, but there is no guarantee that it will be the correct shape.' ) print('Once the gcode is saved, you should check over the layer with a z of:') print(z) return loops def getLoopLayers(archivableObjects, importRadius, layerThickness, maximumZ, shouldPrintWarning, z, zoneArrangement): 'Get loop layers.' loopLayers = [] while z < maximumZ: triangle_mesh.getLoopLayerAppend(loopLayers, z).loops = getEmptyZLoops(archivableObjects, importRadius, True, z, zoneArrangement) z += layerThickness return loopLayers def getMinimumZ(geometryObject): 'Get the minimum of the minimum z of the archivableObjects and the object.' booleanGeometry = BooleanGeometry() booleanGeometry.archivableObjects = geometryObject.archivableObjects booleanGeometry.importRadius = setting.getImportRadius(geometryObject.elementNode) booleanGeometry.layerThickness = setting.getLayerThickness(geometryObject.elementNode) archivableMinimumZ = booleanGeometry.getMinimumZ() geometryMinimumZ = geometryObject.getMinimumZ() if archivableMinimumZ == None: return geometryMinimumZ if geometryMinimumZ is None: return archivableMinimumZ return min(archivableMinimumZ, geometryMinimumZ) class BooleanGeometry: 'A boolean geometry scene.' def __init__(self): 'Add empty lists.' self.archivableObjects = [] self.belowLoops = [] self.importRadius = 0.6 self.layerThickness = 0.4 self.loopLayers = [] def __repr__(self): 'Get the string representation of this carving.' elementNode = None if len(self.archivableObjects) > 0: elementNode = self.archivableObjects[0].elementNode output = xml_simple_writer.getBeginGeometryXMLOutput(elementNode) self.addXML( 1, output ) return xml_simple_writer.getEndGeometryXMLString(output) def addXML(self, depth, output): 'Add xml for this object.' xml_simple_writer.addXMLFromObjects( depth, self.archivableObjects, output ) def getCarveBoundaryLayers(self): 'Get the boundary layers.' if self.getMinimumZ() is None: return [] z = self.minimumZ + 0.5 * self.layerThickness self.loopLayers = getLoopLayers(self.archivableObjects, self.importRadius, self.layerThickness, self.maximumZ, True, z, self.zoneArrangement) self.cornerMaximum = Vector3(-912345678.0, -912345678.0, -912345678.0) self.cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0) for loopLayer in self.loopLayers: for loop in loopLayer.loops: for point in loop: pointVector3 = Vector3(point.real, point.imag, loopLayer.z) self.cornerMaximum.maximize(pointVector3) self.cornerMinimum.minimize(pointVector3) self.cornerMaximum.z += self.halfHeight self.cornerMinimum.z -= self.halfHeight for loopLayerIndex in xrange(len(self.loopLayers) -1, -1, -1): loopLayer = self.loopLayers[loopLayerIndex] if len(loopLayer.loops) > 0: return self.loopLayers[: loopLayerIndex + 1] return [] def getCarveCornerMaximum(self): 'Get the corner maximum of the vertexes.' return self.cornerMaximum def getCarveCornerMinimum(self): 'Get the corner minimum of the vertexes.' return self.cornerMinimum def getCarveLayerThickness(self): 'Get the layer thickness.' return self.layerThickness def getFabmetheusXML(self): 'Return the fabmetheus XML.' if len(self.archivableObjects) > 0: return self.archivableObjects[0].elementNode.getOwnerDocument().getOriginalRoot() return None def getInterpretationSuffix(self): 'Return the suffix for a boolean carving.' return 'xml' def getMatrix4X4(self): 'Get the matrix4X4.' return None def getMatrixChainTetragrid(self): 'Get the matrix chain tetragrid.' return None def getMinimumZ(self): 'Get the minimum z.' vertexes = [] for visibleObject in evaluate.getVisibleObjects(self.archivableObjects): vertexes += visibleObject.getTransformedVertexes() if len(vertexes) < 1: return None self.maximumZ = -912345678.0 self.minimumZ = 912345678.0 for vertex in vertexes: self.maximumZ = max(self.maximumZ, vertex.z) self.minimumZ = min(self.minimumZ, vertex.z) self.zoneArrangement = triangle_mesh.ZoneArrangement(self.layerThickness, vertexes) self.halfHeight = 0.5 * self.layerThickness self.setActualMinimumZ() return self.minimumZ def getNumberOfEmptyZLoops(self, z): 'Get number of empty z loops.' return len(getEmptyZLoops(self.archivableObjects, self.importRadius, False, z, self.zoneArrangement)) def setActualMinimumZ(self): 'Get the actual minimum z at the lowest rotated boundary layer.' halfHeightOverMyriad = 0.0001 * self.halfHeight while self.minimumZ < self.maximumZ: if self.getNumberOfEmptyZLoops(self.minimumZ + halfHeightOverMyriad) > 0: if self.getNumberOfEmptyZLoops(self.minimumZ - halfHeightOverMyriad) < 1: return increment = -self.halfHeight while abs(increment) > halfHeightOverMyriad: self.minimumZ += increment increment = 0.5 * abs(increment) if self.getNumberOfEmptyZLoops(self.minimumZ) > 0: increment = -increment self.minimumZ = round(self.minimumZ, -int(round(math.log10(halfHeightOverMyriad) + 1.5))) return self.minimumZ += self.layerThickness def setCarveImportRadius( self, importRadius ): 'Set the import radius.' self.importRadius = importRadius def setCarveIsCorrectMesh( self, isCorrectMesh ): 'Set the is correct mesh flag.' self.isCorrectMesh = isCorrectMesh def setCarveLayerThickness( self, layerThickness ): 'Set the layer thickness.' self.layerThickness = layerThickness sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/boolean_solid.py000066400000000000000000000273751167321211700304100ustar00rootroot00000000000000""" This page is in the table of contents. The xml.py script is an import translator plugin to get a carving from an Art of Illusion xml file. An import plugin is a script in the interpret_plugins folder which has the function getCarving. It is meant to be run from the interpret tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getCarving function takes the file name of an xml file and returns the carving. An xml file can be exported from Art of Illusion by going to the "File" menu, then going into the "Export" menu item, then picking the XML choice. This will bring up the XML file chooser window, choose a place to save the file then click "OK". Leave the "compressFile" checkbox unchecked. All the objects from the scene will be exported, this plugin will ignore the light and camera. If you want to fabricate more than one object at a time, you can have multiple objects in the Art of Illusion scene and they will all be carved, then fabricated together. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import group from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addLineLoopsIntersections( loopLoopsIntersections, loops, pointBegin, pointEnd ): 'Add intersections of the line with the loops.' normalizedSegment = pointEnd - pointBegin normalizedSegmentLength = abs( normalizedSegment ) if normalizedSegmentLength <= 0.0: return lineLoopsIntersections = [] normalizedSegment /= normalizedSegmentLength segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd addLoopsXSegmentIntersections( lineLoopsIntersections, loops, pointBeginRotated.real, pointEndRotated.real, segmentYMirror, pointBeginRotated.imag ) for lineLoopsIntersection in lineLoopsIntersections: point = complex( lineLoopsIntersection, pointBeginRotated.imag ) * normalizedSegment loopLoopsIntersections.append(point) def addLineXSegmentIntersection( lineLoopsIntersections, segmentFirstX, segmentSecondX, vector3First, vector3Second, y ): 'Add intersections of the line with the x segment.' xIntersection = euclidean.getXIntersectionIfExists( vector3First, vector3Second, y ) if xIntersection is None: return if xIntersection < min( segmentFirstX, segmentSecondX ): return if xIntersection <= max( segmentFirstX, segmentSecondX ): lineLoopsIntersections.append( xIntersection ) def addLoopLoopsIntersections( loop, loopsLoopsIntersections, otherLoops ): 'Add intersections of the loop with the other loops.' for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] addLineLoopsIntersections( loopsLoopsIntersections, otherLoops, pointBegin, pointEnd ) def addLoopsXSegmentIntersections( lineLoopsIntersections, loops, segmentFirstX, segmentSecondX, segmentYMirror, y ): 'Add intersections of the loops with the x segment.' for loop in loops: addLoopXSegmentIntersections( lineLoopsIntersections, loop, segmentFirstX, segmentSecondX, segmentYMirror, y ) def addLoopXSegmentIntersections( lineLoopsIntersections, loop, segmentFirstX, segmentSecondX, segmentYMirror, y ): 'Add intersections of the loop with the x segment.' rotatedLoop = euclidean.getRotatedComplexes( segmentYMirror, loop ) for pointIndex in xrange( len( rotatedLoop ) ): pointFirst = rotatedLoop[pointIndex] pointSecond = rotatedLoop[ (pointIndex + 1) % len( rotatedLoop ) ] addLineXSegmentIntersection( lineLoopsIntersections, segmentFirstX, segmentSecondX, pointFirst, pointSecond, y ) def getInBetweenLoopsFromLoops(loops, radius): 'Get the in between loops from loops.' inBetweenLoops = [] for loop in loops: inBetweenLoop = [] for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] intercircle.addPointsFromSegment(pointBegin, pointEnd, inBetweenLoop, radius) inBetweenLoops.append(inBetweenLoop) return inBetweenLoops def getInsetPointsByInsetLoop( insetLoop, inside, loops, radius ): 'Get the inset points of the inset loop inside the loops.' insetPointsByInsetLoop = [] for pointIndex in xrange( len( insetLoop ) ): pointBegin = insetLoop[ ( pointIndex + len( insetLoop ) - 1 ) % len( insetLoop ) ] pointCenter = insetLoop[pointIndex] pointEnd = insetLoop[ (pointIndex + 1) % len( insetLoop ) ] if getIsInsetPointInsideLoops( inside, loops, pointBegin, pointCenter, pointEnd, radius ): insetPointsByInsetLoop.append( pointCenter ) return insetPointsByInsetLoop def getInsetPointsByInsetLoops( insetLoops, inside, loops, radius ): 'Get the inset points of the inset loops inside the loops.' insetPointsByInsetLoops = [] for insetLoop in insetLoops: insetPointsByInsetLoops += getInsetPointsByInsetLoop( insetLoop, inside, loops, radius ) return insetPointsByInsetLoops def getIsInsetPointInsideLoops( inside, loops, pointBegin, pointCenter, pointEnd, radius ): 'Determine if the inset point is inside the loops.' centerMinusBegin = euclidean.getNormalized( pointCenter - pointBegin ) centerMinusBeginWiddershins = complex( - centerMinusBegin.imag, centerMinusBegin.real ) endMinusCenter = euclidean.getNormalized( pointEnd - pointCenter ) endMinusCenterWiddershins = complex( - endMinusCenter.imag, endMinusCenter.real ) widdershinsNormalized = euclidean.getNormalized( centerMinusBeginWiddershins + endMinusCenterWiddershins ) * radius return euclidean.getIsInFilledRegion( loops, pointCenter + widdershinsNormalized ) == inside def getLoopsDifference(importRadius, loopLists): 'Get difference loops.' halfImportRadius = 0.5 * importRadius # so that there are no misses on shallow angles radiusSide = 0.01 * importRadius negativeLoops = getLoopsUnified(importRadius, loopLists[1 :]) intercircle.directLoops(False, negativeLoops) positiveLoops = loopLists[0] intercircle.directLoops(True, positiveLoops) corners = getInsetPointsByInsetLoops(negativeLoops, True, positiveLoops, radiusSide) corners += getInsetPointsByInsetLoops(positiveLoops, False, negativeLoops, radiusSide) allPoints = corners[:] allPoints += getInsetPointsByInsetLoops(getInBetweenLoopsFromLoops(negativeLoops, halfImportRadius), True, positiveLoops, radiusSide) allPoints += getInsetPointsByInsetLoops(getInBetweenLoopsFromLoops(positiveLoops, halfImportRadius), False, negativeLoops, radiusSide) return triangle_mesh.getDescendingAreaOrientedLoops(allPoints, corners, importRadius) def getLoopsIntersection(importRadius, loopLists): 'Get intersection loops.' intercircle.directLoopLists( True, loopLists ) if len(loopLists) < 1: return [] if len(loopLists) < 2: return loopLists[0] intercircle.directLoopLists(True, loopLists) loopsIntersection = loopLists[0] for loopList in loopLists[1 :]: loopsIntersection = getLoopsIntersectionByPair( importRadius, loopsIntersection, loopList ) return loopsIntersection def getLoopsIntersectionByPair(importRadius, loopsFirst, loopsLast): 'Get intersection loops for a pair of loop lists.' halfImportRadius = 0.5 * importRadius # so that there are no misses on shallow angles radiusSide = 0.01 * importRadius corners = [] corners += getInsetPointsByInsetLoops(loopsFirst, True, loopsLast, radiusSide) corners += getInsetPointsByInsetLoops(loopsLast, True, loopsFirst, radiusSide) allPoints = corners[:] allPoints += getInsetPointsByInsetLoops(getInBetweenLoopsFromLoops(loopsFirst, halfImportRadius), True, loopsLast, radiusSide) allPoints += getInsetPointsByInsetLoops(getInBetweenLoopsFromLoops(loopsLast, halfImportRadius), True, loopsFirst, radiusSide) return triangle_mesh.getDescendingAreaOrientedLoops(allPoints, corners, importRadius) def getLoopsListsIntersections( loopsList ): 'Get intersections betweens the loops lists.' loopsListsIntersections = [] for loopsIndex in xrange( len( loopsList ) ): loops = loopsList[ loopsIndex ] for otherLoops in loopsList[ : loopsIndex ]: loopsListsIntersections += getLoopsLoopsIntersections( loops, otherLoops ) return loopsListsIntersections def getLoopsLoopsIntersections( loops, otherLoops ): 'Get all the intersections of the loops with the other loops.' loopsLoopsIntersections = [] for loop in loops: addLoopLoopsIntersections( loop, loopsLoopsIntersections, otherLoops ) return loopsLoopsIntersections def getLoopsUnified(importRadius, loopLists): 'Get joined loops sliced through shape.' allPoints = [] corners = getLoopsListsIntersections(loopLists) radiusSideNegative = -0.01 * importRadius intercircle.directLoopLists(True, loopLists) for loopListIndex in xrange(len(loopLists)): insetLoops = loopLists[ loopListIndex ] inBetweenInsetLoops = getInBetweenLoopsFromLoops(insetLoops, importRadius) otherLoops = euclidean.getConcatenatedList(loopLists[: loopListIndex] + loopLists[loopListIndex + 1 :]) corners += getInsetPointsByInsetLoops(insetLoops, False, otherLoops, radiusSideNegative) allPoints += getInsetPointsByInsetLoops(inBetweenInsetLoops, False, otherLoops, radiusSideNegative) allPoints += corners[:] return triangle_mesh.getDescendingAreaOrientedLoops(allPoints, corners, importRadius) def getVisibleObjectLoopsList( importRadius, visibleObjects, z ): 'Get visible object loops list.' visibleObjectLoopsList = [] for visibleObject in visibleObjects: visibleObjectLoops = visibleObject.getLoops(importRadius, z) visibleObjectLoopsList.append( visibleObjectLoops ) return visibleObjectLoopsList class BooleanSolid( group.Group ): 'A boolean solid object.' def getDifference(self, importRadius, visibleObjectLoopsList): 'Get subtracted loops sliced through shape.' return getLoopsDifference(importRadius, visibleObjectLoopsList) def getIntersection(self, importRadius, visibleObjectLoopsList): 'Get intersected loops sliced through shape.' return getLoopsIntersection(importRadius, visibleObjectLoopsList) def getLoops(self, importRadius, z): 'Get loops sliced through shape.' visibleObjects = evaluate.getVisibleObjects(self.archivableObjects) if len( visibleObjects ) < 1: return [] visibleObjectLoopsList = getVisibleObjectLoopsList( importRadius, visibleObjects, z ) loops = self.getLoopsFromObjectLoopsList(importRadius, visibleObjectLoopsList) return euclidean.getSimplifiedLoops( loops, importRadius ) def getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList): 'Get loops from visible object loops list.' return self.operationFunction(importRadius, visibleObjectLoopsList) def getTransformedPaths(self): 'Get all transformed paths.' importRadius = setting.getImportRadius(self.elementNode) loopsFromObjectLoopsList = self.getLoopsFromObjectLoopsList(importRadius, self.getComplexTransformedPathLists()) return euclidean.getVector3Paths(loopsFromObjectLoopsList) def getUnion(self, importRadius, visibleObjectLoopsList): 'Get joined loops sliced through shape.' return getLoopsUnified(importRadius, visibleObjectLoopsList) def getXMLLocalName(self): 'Get xml class name.' return self.operationFunction.__name__.lower()[ len('get') : ] sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate.py000066400000000000000000002063341167321211700273770ustar00rootroot00000000000000""" Evaluate expressions. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings import math import os import sys import traceback __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalModuleFunctionsDictionary = {} def addPrefixDictionary(dictionary, keys, value): 'Add prefixed key values to dictionary.' for key in keys: dictionary[key.lstrip('_')] = value def addQuoteWord(evaluatorWords, word): 'Add quote word and remainder if the word starts with a quote character or dollar sign, otherwise add the word.' if len(word) < 2: evaluatorWords.append(word) return firstCharacter = word[0] if firstCharacter == '$': dotIndex = word.find('.', 1) if dotIndex > -1: evaluatorWords.append(word[: dotIndex]) evaluatorWords.append(word[dotIndex :]) return if firstCharacter != '"' and firstCharacter != "'": evaluatorWords.append(word) return nextQuoteIndex = word.find(firstCharacter, 1) if nextQuoteIndex < 0 or nextQuoteIndex == len(word) - 1: evaluatorWords.append(word) return nextQuoteIndex += 1 evaluatorWords.append(word[: nextQuoteIndex]) evaluatorWords.append(word[nextQuoteIndex :]) def addToPathsRecursively(paths, vector3Lists): 'Add to vector3 paths recursively.' if vector3Lists.__class__ == Vector3 or vector3Lists.__class__ .__name__ == 'Vector3Index': paths.append([ vector3Lists ]) return path = [] for vector3List in vector3Lists: if vector3List.__class__ == list: addToPathsRecursively(paths, vector3List) elif vector3List.__class__ == Vector3: path.append(vector3List) if len(path) > 0: paths.append(path) def addValueToEvaluatedDictionary(elementNode, evaluatedDictionary, key): 'Get the evaluated dictionary.' value = getEvaluatedValueObliviously(elementNode, key) if value is None: valueString = str(elementNode.attributes[key]) print('Warning, addValueToEvaluatedDictionary in evaluate can not get a value for:') print(valueString) evaluatedDictionary[key + '__Warning__'] = 'Can not evaluate: ' + valueString.replace('"', ' ').replace( "'", ' ') else: evaluatedDictionary[key] = value def addVector3ToElementNode(elementNode, key, vector3): 'Add vector3 to xml element.' elementNode.attributes[key] = '[%s,%s,%s]' % (vector3.x, vector3.y, vector3.z) def compareExecutionOrderAscending(module, otherModule): 'Get comparison in order to sort modules in ascending execution order.' if module.globalExecutionOrder < otherModule.globalExecutionOrder: return -1 if module.globalExecutionOrder > otherModule.globalExecutionOrder: return 1 if module.__name__ < otherModule.__name__: return -1 return int(module.__name__ > otherModule.__name__) def convertToPaths(dictionary): 'Recursively convert any ElementNodes to paths.' if dictionary.__class__ == Vector3 or dictionary.__class__.__name__ == 'Vector3Index': return keys = getKeys(dictionary) if keys is None: return for key in keys: value = dictionary[key] if value.__class__.__name__ == 'ElementNode': if value.xmlObject is not None: dictionary[key] = getFloatListListsByPaths(value.xmlObject.getPaths()) else: convertToPaths(dictionary[key]) def convertToTransformedPaths(dictionary): 'Recursively convert any ElementNodes to paths.' if dictionary.__class__ == Vector3 or dictionary.__class__.__name__ == 'Vector3Index': return keys = getKeys(dictionary) if keys is None: return for key in keys: value = dictionary[key] if value.__class__.__name__ == 'ElementNode': if value.xmlObject is not None: dictionary[key] = value.xmlObject.getTransformedPaths() else: convertToTransformedPaths(dictionary[key]) def executeLeftOperations( evaluators, operationLevel ): 'Evaluate the expression value from the numeric and operation evaluators.' for negativeIndex in xrange( - len(evaluators), - 1 ): evaluatorIndex = negativeIndex + len(evaluators) evaluators[evaluatorIndex].executeLeftOperation( evaluators, evaluatorIndex, operationLevel ) def executeNextEvaluatorArguments(evaluator, evaluators, evaluatorIndex, nextEvaluator): 'Execute the nextEvaluator arguments.' if evaluator.value is None: print('Warning, executeNextEvaluatorArguments in evaluate can not get a evaluator.value for:') print(evaluatorIndex) print(evaluators) print(evaluator) return nextEvaluator.value = evaluator.value(*nextEvaluator.arguments) del evaluators[evaluatorIndex] def executePairOperations(evaluators, operationLevel): 'Evaluate the expression value from the numeric and operation evaluators.' for negativeIndex in xrange(1 - len(evaluators), - 1): evaluatorIndex = negativeIndex + len(evaluators) evaluators[evaluatorIndex].executePairOperation(evaluators, evaluatorIndex, operationLevel) def getBracketEvaluators(bracketBeginIndex, bracketEndIndex, evaluators): 'Get the bracket evaluators.' return getEvaluatedExpressionValueEvaluators(evaluators[bracketBeginIndex + 1 : bracketEndIndex]) def getBracketsExist(evaluators): 'Evaluate the expression value.' bracketBeginIndex = None for negativeIndex in xrange( - len(evaluators), 0 ): bracketEndIndex = negativeIndex + len(evaluators) evaluatorEnd = evaluators[ bracketEndIndex ] evaluatorWord = evaluatorEnd.word if evaluatorWord in ['(', '[', '{']: bracketBeginIndex = bracketEndIndex elif evaluatorWord in [')', ']', '}']: if bracketBeginIndex is None: print('Warning, bracketBeginIndex in evaluateBrackets in evaluate is None.') print('This may be because the brackets are not balanced.') print(evaluators) del evaluators[ bracketEndIndex ] return evaluators[ bracketBeginIndex ].executeBracket(bracketBeginIndex, bracketEndIndex, evaluators) evaluators[ bracketBeginIndex ].word = None return True return False def getBracketValuesDeleteEvaluator(bracketBeginIndex, bracketEndIndex, evaluators): 'Get the bracket values and delete the evaluator.' evaluatedExpressionValueEvaluators = getBracketEvaluators(bracketBeginIndex, bracketEndIndex, evaluators) bracketValues = [] for evaluatedExpressionValueEvaluator in evaluatedExpressionValueEvaluators: bracketValues.append( evaluatedExpressionValueEvaluator.value ) del evaluators[ bracketBeginIndex + 1: bracketEndIndex + 1 ] return bracketValues def getCapitalizedSuffixKey(prefix, suffix): 'Get key with capitalized suffix.' if prefix == '' or prefix.endswith('.'): return prefix + suffix return prefix + suffix[:1].upper()+suffix[1:] def getDictionarySplitWords(dictionary, value): 'Get split line for evaluators.' if getIsQuoted(value): return [value] for dictionaryKey in dictionary.keys(): value = value.replace(dictionaryKey, ' ' + dictionaryKey + ' ') dictionarySplitWords = [] for word in value.split(): dictionarySplitWords.append(word) return dictionarySplitWords def getElementNodeByKey(elementNode, key): 'Get the xml element by key.' if key not in elementNode.attributes: return None word = str(elementNode.attributes[key]).strip() evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word) if evaluatedLinkValue.__class__.__name__ == 'ElementNode': return evaluatedLinkValue print('Warning, could not get ElementNode in getElementNodeByKey in evaluate for:') print(key) print(evaluatedLinkValue) print(elementNode) return None def getElementNodeObject(evaluatedLinkValue): 'Get ElementNodeObject.' if evaluatedLinkValue.__class__.__name__ != 'ElementNode': print('Warning, could not get ElementNode in getElementNodeObject in evaluate for:') print(evaluatedLinkValue.__class__.__name__) print(evaluatedLinkValue) return None if evaluatedLinkValue.xmlObject is None: print('Warning, evaluatedLinkValue.xmlObject is None in getElementNodeObject in evaluate for:') print(evaluatedLinkValue) return None return evaluatedLinkValue.xmlObject def getElementNodesByKey(elementNode, key): 'Get the xml elements by key.' if key not in elementNode.attributes: return [] word = str(elementNode.attributes[key]).strip() evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word) if evaluatedLinkValue.__class__.__name__ == 'ElementNode': return [evaluatedLinkValue] if evaluatedLinkValue.__class__ == list: return evaluatedLinkValue print('Warning, could not get ElementNodes in getElementNodesByKey in evaluate for:') print(key) print(evaluatedLinkValue) print(elementNode) return [] def getEndIndexConvertEquationValue( bracketEndIndex, evaluatorIndex, evaluators ): 'Get the bracket end index and convert the equation value evaluators into a string.' evaluator = evaluators[evaluatorIndex] if evaluator.__class__ != EvaluatorValue: return bracketEndIndex if not evaluator.word.startswith('equation.'): return bracketEndIndex if evaluators[ evaluatorIndex + 1 ].word != ':': return bracketEndIndex valueBeginIndex = evaluatorIndex + 2 equationValueString = '' for valueEvaluatorIndex in xrange( valueBeginIndex, len(evaluators) ): valueEvaluator = evaluators[ valueEvaluatorIndex ] if valueEvaluator.word == ',' or valueEvaluator.word == '}': if equationValueString == '': return bracketEndIndex else: evaluators[ valueBeginIndex ] = EvaluatorValue( equationValueString ) valueDeleteIndex = valueBeginIndex + 1 del evaluators[ valueDeleteIndex : valueEvaluatorIndex ] return bracketEndIndex - valueEvaluatorIndex + valueDeleteIndex equationValueString += valueEvaluator.word return bracketEndIndex def getEvaluatedBoolean(defaultValue, elementNode, key): 'Get the evaluated boolean.' if elementNode is None: return defaultValue if key in elementNode.attributes: return euclidean.getBooleanFromValue(getEvaluatedValueObliviously(elementNode, key)) return defaultValue def getEvaluatedDictionaryByCopyKeys(copyKeys, elementNode): 'Get the evaluated dictionary by copyKeys.' evaluatedDictionary = {} for key in elementNode.attributes.keys(): if key in copyKeys: evaluatedDictionary[key] = elementNode.attributes[key] else: addValueToEvaluatedDictionary(elementNode, evaluatedDictionary, key) return evaluatedDictionary def getEvaluatedDictionaryByEvaluationKeys(elementNode, evaluationKeys): 'Get the evaluated dictionary.' evaluatedDictionary = {} for key in elementNode.attributes.keys(): if key in evaluationKeys: addValueToEvaluatedDictionary(elementNode, evaluatedDictionary, key) return evaluatedDictionary def getEvaluatedExpressionValue(elementNode, value): 'Evaluate the expression value.' try: return getEvaluatedExpressionValueBySplitLine(elementNode, getEvaluatorSplitWords(value)) except: print('Warning, in getEvaluatedExpressionValue in evaluate could not get a value for:') print(value) traceback.print_exc(file=sys.stdout) return None def getEvaluatedExpressionValueBySplitLine(elementNode, words): 'Evaluate the expression value.' evaluators = [] for wordIndex, word in enumerate(words): nextWord = '' nextWordIndex = wordIndex + 1 if nextWordIndex < len(words): nextWord = words[nextWordIndex] evaluator = getEvaluator(elementNode, evaluators, nextWord, word) if evaluator is not None: evaluators.append(evaluator) while getBracketsExist(evaluators): pass evaluatedExpressionValueEvaluators = getEvaluatedExpressionValueEvaluators(evaluators) if len( evaluatedExpressionValueEvaluators ) > 0: return evaluatedExpressionValueEvaluators[0].value return None def getEvaluatedExpressionValueEvaluators(evaluators): 'Evaluate the expression value from the numeric and operation evaluators.' for evaluatorIndex, evaluator in enumerate(evaluators): evaluator.executeCenterOperation(evaluators, evaluatorIndex) for negativeIndex in xrange(1 - len(evaluators), 0): evaluatorIndex = negativeIndex + len(evaluators) evaluators[evaluatorIndex].executeRightOperation(evaluators, evaluatorIndex) executeLeftOperations(evaluators, 200) for operationLevel in [80, 60, 40, 20, 15]: executePairOperations(evaluators, operationLevel) executeLeftOperations(evaluators, 13) executePairOperations(evaluators, 12) for negativeIndex in xrange(-len(evaluators), 0): evaluatorIndex = negativeIndex + len(evaluators) evaluators[evaluatorIndex].executePairOperation(evaluators, evaluatorIndex, 10) for evaluatorIndex in xrange(len(evaluators) - 1, -1, -1): evaluators[evaluatorIndex].executePairOperation(evaluators, evaluatorIndex, 0) return evaluators def getEvaluatedFloat(defaultValue, elementNode, key): 'Get the evaluated float.' if elementNode is None: return defaultValue if key in elementNode.attributes: return euclidean.getFloatFromValue(getEvaluatedValueObliviously(elementNode, key)) return defaultValue def getEvaluatedInt(defaultValue, elementNode, key): 'Get the evaluated int.' if elementNode is None: return None if key in elementNode.attributes: try: return getIntFromFloatString(getEvaluatedValueObliviously(elementNode, key)) except: print('Warning, could not evaluate the int.') print(key) print(elementNode.attributes[key]) return defaultValue def getEvaluatedIntByKeys(defaultValue, elementNode, keys): 'Get the evaluated int by keys.' for key in keys: defaultValue = getEvaluatedInt(defaultValue, elementNode, key) return defaultValue def getEvaluatedLinkValue(elementNode, word): 'Get the evaluated link value.' if word == '': return '' if getStartsWithCurlyEqualRoundSquare(word): return getEvaluatedExpressionValue(elementNode, word) return word def getEvaluatedString(defaultValue, elementNode, key): 'Get the evaluated string.' if elementNode is None: return defaultValue if key in elementNode.attributes: return str(getEvaluatedValueObliviously(elementNode, key)) return defaultValue def getEvaluatedValue(defaultValue, elementNode, key): 'Get the evaluated value.' if elementNode is None: return defaultValue if key in elementNode.attributes: return getEvaluatedValueObliviously(elementNode, key) return defaultValue def getEvaluatedValueObliviously(elementNode, key): 'Get the evaluated value.' value = str(elementNode.attributes[key]).strip() if key == 'id' or key == 'name' or key == 'tags': return value return getEvaluatedLinkValue(elementNode, value) def getEvaluator(elementNode, evaluators, nextWord, word): 'Get the evaluator.' if word in globalSplitDictionary: return globalSplitDictionary[word](elementNode, word) firstCharacter = word[: 1] if firstCharacter == "'" or firstCharacter == '"': if len(word) > 1: if firstCharacter == word[-1]: return EvaluatorValue(word[1 : -1]) if firstCharacter == '$': return EvaluatorValue(word[1 :]) dotIndex = word.find('.') functions = elementNode.getXMLProcessor().functions if dotIndex > -1 and len(word) > 1: if dotIndex == 0 and word[1].isalpha(): return EvaluatorAttribute(elementNode, word) if dotIndex > 0: untilDot = word[: dotIndex] if untilDot in globalModuleEvaluatorDictionary: return globalModuleEvaluatorDictionary[untilDot](elementNode, word) if len(functions) > 0: if untilDot in functions[-1].localDictionary: return EvaluatorLocal(elementNode, word) if firstCharacter.isalpha() or firstCharacter == '_': if len(functions) > 0: if word in functions[-1].localDictionary: return EvaluatorLocal(elementNode, word) wordElement = elementNode.getElementNodeByID(word) if wordElement is not None: if wordElement.getNodeName() == 'class': return EvaluatorClass(wordElement, word) if wordElement.getNodeName() == 'function': return EvaluatorFunction(wordElement, word) return EvaluatorValue(word) return EvaluatorNumeric(elementNode, word) def getEvaluatorSplitWords(value): 'Get split words for evaluators.' if value.startswith('='): value = value[len('=') :] if len(value) < 1: return [] global globalDictionaryOperatorBegin uniqueQuoteIndex = 0 word = '' quoteString = None quoteDictionary = {} for characterIndex in xrange(len(value)): character = value[characterIndex] if character == '"' or character == "'": if quoteString is None: quoteString = '' elif quoteString is not None: if character == quoteString[: 1]: uniqueQuoteIndex = getUniqueQuoteIndex(uniqueQuoteIndex, value) uniqueToken = getTokenByNumber(uniqueQuoteIndex) quoteDictionary[uniqueToken] = quoteString + character character = uniqueToken quoteString = None if quoteString is None: word += character else: quoteString += character beginSplitWords = getDictionarySplitWords(globalDictionaryOperatorBegin, word) global globalSplitDictionaryOperator evaluatorSplitWords = [] for beginSplitWord in beginSplitWords: if beginSplitWord in globalDictionaryOperatorBegin: evaluatorSplitWords.append(beginSplitWord) else: evaluatorSplitWords += getDictionarySplitWords(globalSplitDictionaryOperator, beginSplitWord) for evaluatorSplitWordIndex, evaluatorSplitWord in enumerate(evaluatorSplitWords): for quoteDictionaryKey in quoteDictionary.keys(): if quoteDictionaryKey in evaluatorSplitWord: evaluatorSplitWords[evaluatorSplitWordIndex] = evaluatorSplitWord.replace(quoteDictionaryKey, quoteDictionary[quoteDictionaryKey]) evaluatorTransitionWords = [] for evaluatorSplitWord in evaluatorSplitWords: addQuoteWord(evaluatorTransitionWords, evaluatorSplitWord) return evaluatorTransitionWords def getFloatListFromBracketedString( bracketedString ): 'Get list from a bracketed string.' if not getIsBracketed( bracketedString ): return None bracketedString = bracketedString.strip().replace('[', '').replace(']', '').replace('(', '').replace(')', '') if len( bracketedString ) < 1: return [] splitLine = bracketedString.split(',') floatList = [] for word in splitLine: evaluatedFloat = euclidean.getFloatFromValue(word) if evaluatedFloat is not None: floatList.append( evaluatedFloat ) return floatList def getFloatListListsByPaths(paths): 'Get float lists by paths.' floatListLists = [] for path in paths: floatListList = [] for point in path: floatListList.append( point.getFloatList() ) return floatListLists def getIntFromFloatString(value): 'Get the int from the string.' floatString = str(value).strip() if floatString == '': return None dotIndex = floatString.find('.') if dotIndex < 0: return int(value) return int( round( float(floatString) ) ) def getIsBracketed(word): 'Determine if the word is bracketed.' if len(word) < 2: return False firstCharacter = word[0] lastCharacter = word[-1] if firstCharacter == '(' and lastCharacter == ')': return True return firstCharacter == '[' and lastCharacter == ']' def getIsQuoted(word): 'Determine if the word is quoted.' if len(word) < 2: return False firstCharacter = word[0] lastCharacter = word[-1] if firstCharacter == '"' and lastCharacter == '"': return True return firstCharacter == "'" and lastCharacter == "'" def getKeys(repository): 'Get keys for repository.' repositoryClass = repository.__class__ if repositoryClass == list or repositoryClass == tuple: return range(len(repository)) if repositoryClass == dict: return repository.keys() return None def getLocalAttributeValueString(key, valueString): 'Get the local attribute value string with augmented assignment.' augmentedStatements = '+= -= *= /= %= **='.split() for augmentedStatement in augmentedStatements: if valueString.startswith(augmentedStatement): return key + augmentedStatement[: -1] + valueString[len(augmentedStatement) :] return valueString def getMatchingPlugins(elementNode, namePathDictionary): 'Get the plugins whose names are in the attribute dictionary.' matchingPlugins = [] namePathDictionaryCopy = namePathDictionary.copy() for key in elementNode.attributes: dotIndex = key.find('.') if dotIndex > - 1: keyUntilDot = key[: dotIndex] if keyUntilDot in namePathDictionaryCopy: pluginModule = archive.getModuleWithPath( namePathDictionaryCopy[ keyUntilDot ] ) del namePathDictionaryCopy[ keyUntilDot ] if pluginModule is not None: matchingPlugins.append( pluginModule ) return matchingPlugins def getNextChildIndex(elementNode): 'Get the next childNode index.' for childNodeIndex, childNode in enumerate( elementNode.parentNode.childNodes ): if childNode == elementNode: return childNodeIndex + 1 return len( elementNode.parentNode.childNodes ) def getPathByKey(defaultPath, elementNode, key): 'Get path from prefix and xml element.' if key not in elementNode.attributes: return defaultPath word = str(elementNode.attributes[key]).strip() evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word) if evaluatedLinkValue.__class__ == list: return getPathByList(evaluatedLinkValue) elementNodeObject = getElementNodeObject(evaluatedLinkValue) if elementNodeObject is None: return defaultPath return elementNodeObject.getPaths()[0] def getPathByList(vertexList): 'Get the paths by list.' if len(vertexList) < 1: return Vector3() if vertexList[0].__class__ != list: vertexList = [vertexList] path = [] for floatList in vertexList: vector3 = getVector3ByFloatList(floatList, Vector3()) path.append(vector3) return path def getPathByPrefix(elementNode, path, prefix): 'Get path from prefix and xml element.' if len(path) < 2: print('Warning, bug, path is too small in evaluate in setPathByPrefix.') return pathByKey = getPathByKey([], elementNode, getCapitalizedSuffixKey(prefix, 'path')) if len( pathByKey ) < len(path): for pointIndex in xrange( len( pathByKey ) ): path[pointIndex] = pathByKey[pointIndex] else: path = pathByKey path[0] = getVector3ByPrefix(path[0], elementNode, getCapitalizedSuffixKey(prefix, 'pathStart')) path[-1] = getVector3ByPrefix(path[-1], elementNode, getCapitalizedSuffixKey(prefix, 'pathEnd')) return path def getPathsByKey(defaultPaths, elementNode, key): 'Get paths by key.' if key not in elementNode.attributes: return defaultPaths word = str(elementNode.attributes[key]).strip() evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word) if evaluatedLinkValue.__class__ == dict or evaluatedLinkValue.__class__ == list: convertToPaths(evaluatedLinkValue) return getPathsByLists(evaluatedLinkValue) elementNodeObject = getElementNodeObject(evaluatedLinkValue) if elementNodeObject is None: return defaultPaths return elementNodeObject.getPaths() def getPathsByLists(vertexLists): 'Get paths by lists.' vector3Lists = getVector3ListsRecursively(vertexLists) paths = [] addToPathsRecursively(paths, vector3Lists) return paths def getRadiusArealizedBasedOnAreaRadius(elementNode, radius, sides): 'Get the areal radius from the radius, number of sides and cascade radiusAreal.' if elementNode.getCascadeBoolean(False, 'radiusAreal'): return radius return radius * euclidean.getRadiusArealizedMultiplier(sides) def getSidesBasedOnPrecision(elementNode, radius): 'Get the number of polygon sides.' return int(math.ceil(math.sqrt(0.5 * radius / setting.getPrecision(elementNode)) * math.pi)) def getSidesMinimumThreeBasedOnPrecision(elementNode, radius): 'Get the number of polygon sides, with a minimum of three.' return max(getSidesBasedOnPrecision(elementNode, radius), 3) def getSidesMinimumThreeBasedOnPrecisionSides(elementNode, radius): 'Get the number of polygon sides, with a minimum of three.' sides = getSidesMinimumThreeBasedOnPrecision(elementNode, radius) return getEvaluatedFloat(sides, elementNode, 'sides') def getSplitDictionary(): 'Get split dictionary.' global globalSplitDictionaryOperator splitDictionary = globalSplitDictionaryOperator.copy() global globalDictionaryOperatorBegin splitDictionary.update( globalDictionaryOperatorBegin ) splitDictionary['and'] = EvaluatorAnd splitDictionary['false'] = EvaluatorFalse splitDictionary['False'] = EvaluatorFalse splitDictionary['or'] = EvaluatorOr splitDictionary['not'] = EvaluatorNot splitDictionary['true'] = EvaluatorTrue splitDictionary['True'] = EvaluatorTrue splitDictionary['none'] = EvaluatorNone splitDictionary['None'] = EvaluatorNone return splitDictionary def getStartsWithCurlyEqualRoundSquare(word): 'Determine if the word starts with round or square brackets.' return word.startswith('{') or word.startswith('=') or word.startswith('(') or word.startswith('[') def getTokenByNumber(number): 'Get token by number.' return '_%s_' % number def getTransformedPathByKey(defaultTransformedPath, elementNode, key): 'Get transformed path from prefix and xml element.' if key not in elementNode.attributes: return defaultTransformedPath value = elementNode.attributes[key] if value.__class__ == list: return value word = str(value).strip() evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word) if evaluatedLinkValue.__class__ == list: return getPathByList(evaluatedLinkValue) elementNodeObject = getElementNodeObject(evaluatedLinkValueClass) if elementNodeObject is None: return defaultTransformedPath return elementNodeObject.getTransformedPaths()[0] def getTransformedPathByPrefix(elementNode, path, prefix): 'Get path from prefix and xml element.' if len(path) < 2: print('Warning, bug, path is too small in evaluate in setPathByPrefix.') return pathByKey = getTransformedPathByKey([], elementNode, getCapitalizedSuffixKey(prefix, 'path')) if len( pathByKey ) < len(path): for pointIndex in xrange( len( pathByKey ) ): path[pointIndex] = pathByKey[pointIndex] else: path = pathByKey path[0] = getVector3ByPrefix(path[0], elementNode, getCapitalizedSuffixKey(prefix, 'pathStart')) path[-1] = getVector3ByPrefix(path[-1], elementNode, getCapitalizedSuffixKey(prefix, 'pathEnd')) return path def getTransformedPathsByKey(defaultTransformedPaths, elementNode, key): 'Get transformed paths by key.' if key not in elementNode.attributes: return defaultTransformedPaths value = elementNode.attributes[key] if value.__class__ == list: return getPathsByLists(value) word = str(value).strip() evaluatedLinkValue = getEvaluatedLinkValue(elementNode, word) if evaluatedLinkValue.__class__ == dict or evaluatedLinkValue.__class__ == list: convertToTransformedPaths(evaluatedLinkValue) return getPathsByLists(evaluatedLinkValue) elementNodeObject = getElementNodeObject(evaluatedLinkValue) if elementNodeObject is None: return defaultTransformedPaths return elementNodeObject.getTransformedPaths() def getUniqueQuoteIndex( uniqueQuoteIndex, word ): 'Get uniqueQuoteIndex.' uniqueQuoteIndex += 1 while getTokenByNumber(uniqueQuoteIndex) in word: uniqueQuoteIndex += 1 return uniqueQuoteIndex def getUniqueToken(word): 'Get unique token.' uniqueString = '@#!' for character in uniqueString: if character not in word: return character uniqueNumber = 0 while True: for character in uniqueString: uniqueToken = character + str(uniqueNumber) if uniqueToken not in word: return uniqueToken uniqueNumber += 1 def getVector3ByDictionary( dictionary, vector3 ): 'Get vector3 by dictionary.' if 'x' in dictionary: vector3 = getVector3IfNone(vector3) vector3.x = euclidean.getFloatFromValue(dictionary['x']) if 'y' in dictionary: vector3 = getVector3IfNone(vector3) vector3.y = euclidean.getFloatFromValue(dictionary['y']) if 'z' in dictionary: vector3 = getVector3IfNone(vector3) vector3.z = euclidean.getFloatFromValue( dictionary['z'] ) return vector3 def getVector3ByDictionaryListValue(value, vector3): 'Get vector3 by dictionary, list or value.' if value.__class__ == Vector3 or value.__class__.__name__ == 'Vector3Index': return value if value.__class__ == dict: return getVector3ByDictionary(value, vector3) if value.__class__ == list: return getVector3ByFloatList(value, vector3) floatFromValue = euclidean.getFloatFromValue(value) if floatFromValue == None: return vector3 vector3.setToXYZ(floatFromValue, floatFromValue, floatFromValue) return vector3 def getVector3ByFloatList(floatList, vector3): 'Get vector3 by float list.' if len(floatList) > 0: vector3 = getVector3IfNone(vector3) vector3.x = euclidean.getFloatFromValue(floatList[0]) if len(floatList) > 1: vector3 = getVector3IfNone(vector3) vector3.y = euclidean.getFloatFromValue(floatList[1]) if len(floatList) > 2: vector3 = getVector3IfNone(vector3) vector3.z = euclidean.getFloatFromValue(floatList[2]) return vector3 def getVector3ByMultiplierPrefix( elementNode, multiplier, prefix, vector3 ): 'Get vector3 from multiplier, prefix and xml element.' if multiplier == 0.0: return vector3 oldMultipliedValueVector3 = vector3 * multiplier vector3ByPrefix = getVector3ByPrefix(oldMultipliedValueVector3.copy(), elementNode, prefix) if vector3ByPrefix == oldMultipliedValueVector3: return vector3 return vector3ByPrefix / multiplier def getVector3ByMultiplierPrefixes( elementNode, multiplier, prefixes, vector3 ): 'Get vector3 from multiplier, prefixes and xml element.' for prefix in prefixes: vector3 = getVector3ByMultiplierPrefix( elementNode, multiplier, prefix, vector3 ) return vector3 def getVector3ByPrefix(defaultVector3, elementNode, prefix): 'Get vector3 from prefix and xml element.' value = getEvaluatedValue(None, elementNode, prefix) if value is not None: defaultVector3 = getVector3ByDictionaryListValue(value, defaultVector3) prefix = archive.getUntilDot(prefix) x = getEvaluatedFloat(None, elementNode, prefix + '.x') if x is not None: defaultVector3 = getVector3IfNone(defaultVector3) defaultVector3.x = x y = getEvaluatedFloat(None, elementNode, prefix + '.y') if y is not None: defaultVector3 = getVector3IfNone(defaultVector3) defaultVector3.y = y z = getEvaluatedFloat(None, elementNode, prefix + '.z') if z is not None: defaultVector3 = getVector3IfNone(defaultVector3) defaultVector3.z = z return defaultVector3 def getVector3ByPrefixes( elementNode, prefixes, vector3 ): 'Get vector3 from prefixes and xml element.' for prefix in prefixes: vector3 = getVector3ByPrefix(vector3, elementNode, prefix) return vector3 def getVector3FromElementNode(elementNode): 'Get vector3 from xml element.' vector3 = Vector3( getEvaluatedFloat(0.0, elementNode, 'x'), getEvaluatedFloat(0.0, elementNode, 'y'), getEvaluatedFloat(0.0, elementNode, 'z')) return getVector3ByPrefix(vector3, elementNode, 'cartesian') def getVector3IfNone(vector3): 'Get new vector3 if the original vector3 is none.' if vector3 is None: return Vector3() return vector3 def getVector3ListsRecursively(floatLists): 'Get vector3 lists recursively.' if len(floatLists) < 1: return Vector3() firstElement = floatLists[0] if firstElement.__class__ == Vector3: return floatLists if firstElement.__class__ != list: return getVector3ByFloatList(floatLists, Vector3()) vector3ListsRecursively = [] for floatList in floatLists: vector3ListsRecursively.append(getVector3ListsRecursively(floatList)) return vector3ListsRecursively def getVisibleObjects(archivableObjects): 'Get the visible objects.' visibleObjects = [] for archivableObject in archivableObjects: if archivableObject.getVisible(): visibleObjects.append(archivableObject) return visibleObjects def processArchivable(archivableClass, elementNode): 'Get any new elements and process the archivable.' if elementNode is None: return elementNode.xmlObject = archivableClass() elementNode.xmlObject.setToElementNode(elementNode) elementNode.getXMLProcessor().processChildNodes(elementNode) def processCondition(elementNode): 'Process the xml element condition.' xmlProcessor = elementNode.getXMLProcessor() if elementNode.xmlObject is None: elementNode.xmlObject = ModuleElementNode(elementNode) if elementNode.xmlObject.conditionSplitWords is None: return if len(xmlProcessor.functions ) < 1: print('Warning, the (in) element is not in a function in processCondition in evaluate for:') print(elementNode) return if int(getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject.conditionSplitWords)) > 0: xmlProcessor.functions[-1].processChildNodes(elementNode) else: elementNode.xmlObject.processElse(elementNode) def removeIdentifiersFromDictionary(dictionary): 'Remove the identifier elements from a dictionary.' euclidean.removeElementsFromDictionary(dictionary, ['id', 'name', 'tags']) return dictionary def setAttributesByArguments(argumentNames, arguments, elementNode): 'Set the attribute dictionary to the arguments.' for argumentIndex, argument in enumerate(arguments): elementNode.attributes[argumentNames[argumentIndex]] = argument def setFunctionLocalDictionary(arguments, function): 'Evaluate the function statement and delete the evaluators.' function.localDictionary = {'_arguments' : arguments} if len(arguments) > 0: firstArgument = arguments[0] if firstArgument.__class__ == dict: function.localDictionary = firstArgument return if 'parameters' not in function.elementNode.attributes: return parameters = function.elementNode.attributes['parameters'].strip() if parameters == '': return parameterWords = parameters.split(',') for parameterWordIndex, parameterWord in enumerate(parameterWords): strippedWord = parameterWord.strip() keyValue = KeyValue().getByEqual(strippedWord) if parameterWordIndex < len(arguments): function.localDictionary[keyValue.key] = arguments[parameterWordIndex] else: strippedValue = keyValue.value if strippedValue is None: print('Warning there is no default parameter in getParameterValue for:') print(strippedWord) print(parameterWords) print(arguments) print( function.elementNode.attributes ) else: strippedValue = strippedValue.strip() function.localDictionary[keyValue.key.strip()] = strippedValue if len(arguments) > len(parameterWords): print('Warning there are too many initializeFunction parameters for:') print( function.elementNode.attributes ) print(parameterWords) print(arguments) def setLocalAttribute(elementNode): 'Set the local attribute if any.' if elementNode.xmlObject is not None: return for key in elementNode.attributes: if key[: 1].isalpha(): value = getEvaluatorSplitWords(getLocalAttributeValueString(key, elementNode.attributes[key].strip())) elementNode.xmlObject = KeyValue(key, value) return elementNode.xmlObject = KeyValue() class BaseFunction: 'Class to get equation results.' def __init__(self, elementNode): 'Initialize.' self.elementNode = elementNode self.localDictionary = {} self.xmlProcessor = elementNode.getXMLProcessor() def __repr__(self): 'Get the string representation of this Class.' return str(self.__dict__) def getReturnValue(self): 'Get return value.' self.getReturnValueWithoutDeletion() del self.xmlProcessor.functions[-1] return self.returnValue def processChildNodes(self, elementNode): 'Process childNodes if shouldReturn is false.' for childNode in elementNode.childNodes: if self.shouldReturn: return self.xmlProcessor.processElementNode(childNode) class ClassFunction(BaseFunction): 'Class to get class results.' def getReturnValueByArguments(self, *arguments): 'Get return value by arguments.' setFunctionLocalDictionary(arguments, self) return self.getReturnValue() def getReturnValueWithoutDeletion(self): 'Get return value without deleting last function.' self.returnValue = None self.shouldReturn = False self.xmlProcessor.functions.append(self) self.processChildNodes(self.elementNode) return self.returnValue class ClassObject: 'Class to hold class attributes and functions.' def __init__(self, elementNode): 'Initialize.' self.functionDictionary = elementNode.xmlObject.functionDictionary self.selfDictionary = {} for variable in elementNode.xmlObject.variables: self.selfDictionary[variable] = None def __repr__(self): 'Get the string representation of this Class.' return str(self.__dict__) def _getAccessibleAttribute(self, attributeName): 'Get the accessible attribute.' if attributeName in self.selfDictionary: return self.selfDictionary[attributeName] if attributeName in self.functionDictionary: function = self.functionDictionary[attributeName] function.classObject = self return function.getReturnValueByArguments return None def _setAccessibleAttribute(self, attributeName, value): 'Set the accessible attribute.' if attributeName in self.selfDictionary: self.selfDictionary[attributeName] = value class EmptyObject: 'An empty object.' def __init__(self): 'Do nothing.' pass class Evaluator: 'Base evaluator class.' def __init__(self, elementNode, word): 'Set value to none.' self.value = None self.word = word def __repr__(self): 'Get the string representation of this Class.' return str(self.__dict__) def executeBracket( self, bracketBeginIndex, bracketEndIndex, evaluators ): 'Execute the bracket.' pass def executeCenterOperation(self, evaluators, evaluatorIndex): 'Execute operator which acts on the center.' pass def executeDictionary(self, dictionary, evaluators, keys, evaluatorIndex, nextEvaluator): 'Execute the dictionary.' del evaluators[evaluatorIndex] enumeratorKeys = euclidean.getEnumeratorKeys(dictionary, keys) if enumeratorKeys.__class__ == list: nextEvaluator.value = [] for enumeratorKey in enumeratorKeys: if enumeratorKey in dictionary: nextEvaluator.value.append(dictionary[enumeratorKey]) else: print('Warning, key in executeKey in Evaluator in evaluate is not in for:') print(enumeratorKey) print(dictionary) return if enumeratorKeys in dictionary: nextEvaluator.value = dictionary[enumeratorKeys] else: print('Warning, key in executeKey in Evaluator in evaluate is not in for:') print(enumeratorKeys) print(dictionary) def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator): 'Execute the function.' pass def executeKey(self, evaluators, keys, evaluatorIndex, nextEvaluator): 'Execute the key index.' if self.value.__class__ == str: self.executeString(evaluators, keys, evaluatorIndex, nextEvaluator) return if self.value.__class__ == list: self.executeList(evaluators, keys, evaluatorIndex, nextEvaluator) return if self.value.__class__ == dict: self.executeDictionary(self.value, evaluators, keys, evaluatorIndex, nextEvaluator) return getAccessibleDictionaryFunction = getattr(self.value, '_getAccessibleDictionary', None) if getAccessibleDictionaryFunction is not None: self.executeDictionary(getAccessibleDictionaryFunction(), evaluators, keys, evaluatorIndex, nextEvaluator) return if self.value.__class__.__name__ != 'ElementNode': return del evaluators[evaluatorIndex] enumeratorKeys = euclidean.getEnumeratorKeys(self.value.attributes, keys) if enumeratorKeys.__class__ == list: nextEvaluator.value = [] for enumeratorKey in enumeratorKeys: if enumeratorKey in self.value.attributes: nextEvaluator.value.append(getEvaluatedExpressionValue(self.value, self.value.attributes[enumeratorKey])) else: print('Warning, key in executeKey in Evaluator in evaluate is not in for:') print(enumeratorKey) print(self.value.attributes) return if enumeratorKeys in self.value.attributes: nextEvaluator.value = getEvaluatedExpressionValue(self.value, self.value.attributes[enumeratorKeys]) else: print('Warning, key in executeKey in Evaluator in evaluate is not in for:') print(enumeratorKeys) print(self.value.attributes) def executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel): 'Execute operator which acts from the left.' pass def executeList(self, evaluators, keys, evaluatorIndex, nextEvaluator): 'Execute the key index.' del evaluators[evaluatorIndex] enumeratorKeys = euclidean.getEnumeratorKeys(self.value, keys) if enumeratorKeys.__class__ == list: nextEvaluator.value = [] for enumeratorKey in enumeratorKeys: intKey = euclidean.getIntFromValue(enumeratorKey) if self.getIsInRange(intKey): nextEvaluator.value.append(self.value[intKey]) else: print('Warning, key in executeList in Evaluator in evaluate is not in for:') print(enumeratorKey) print(self.value) return intKey = euclidean.getIntFromValue(enumeratorKeys) if self.getIsInRange(intKey): nextEvaluator.value = self.value[intKey] else: print('Warning, key in executeList in Evaluator in evaluate is not in for:') print(enumeratorKeys) print(self.value) def executePairOperation(self, evaluators, evaluatorIndex, operationLevel): 'Operate on two evaluators.' pass def executeRightOperation( self, evaluators, evaluatorIndex ): 'Execute operator which acts from the right.' pass def executeString(self, evaluators, keys, evaluatorIndex, nextEvaluator): 'Execute the string.' del evaluators[evaluatorIndex] enumeratorKeys = euclidean.getEnumeratorKeys(self.value, keys) if enumeratorKeys.__class__ == list: nextEvaluator.value = '' for enumeratorKey in enumeratorKeys: intKey = euclidean.getIntFromValue(enumeratorKey) if self.getIsInRange(intKey): nextEvaluator.value += self.value[intKey] else: print('Warning, key in executeString in Evaluator in evaluate is not in for:') print(enumeratorKey) print(self.value) return intKey = euclidean.getIntFromValue(enumeratorKeys) if self.getIsInRange(intKey): nextEvaluator.value = self.value[intKey] else: print('Warning, key in executeString in Evaluator in evaluate is not in for:') print(enumeratorKeys) print(self.value) def getIsInRange(self, keyIndex): 'Determine if the keyIndex is in range.' if keyIndex is None: return False return keyIndex >= -len(self.value) and keyIndex < len(self.value) class EvaluatorAddition(Evaluator): 'Class to add two evaluators.' def executePair( self, evaluators, evaluatorIndex ): 'Add two evaluators.' leftIndex = evaluatorIndex - 1 rightIndex = evaluatorIndex + 1 if leftIndex < 0: print('Warning, no leftKey in executePair in EvaluatorAddition for:') print(evaluators) print(evaluatorIndex) print(self) del evaluators[evaluatorIndex] return if rightIndex >= len(evaluators): print('Warning, no rightKey in executePair in EvaluatorAddition for:') print(evaluators) print(evaluatorIndex) print(self) del evaluators[evaluatorIndex] return rightValue = evaluators[rightIndex].value evaluators[leftIndex].value = self.getOperationValue(evaluators[leftIndex].value, evaluators[rightIndex].value) del evaluators[ evaluatorIndex : evaluatorIndex + 2 ] def executePairOperation(self, evaluators, evaluatorIndex, operationLevel): 'Operate on two evaluators.' if operationLevel == 20: self.executePair(evaluators, evaluatorIndex) def getEvaluatedValues(self, enumerable, keys, value): 'Get evaluatedValues.' if enumerable.__class__ == dict: evaluatedValues = {} for key in keys: evaluatedValues[key] = self.getOperationValue(value, enumerable[key]) return evaluatedValues evaluatedValues = [] for key in keys: evaluatedValues.append(self.getOperationValue(value, enumerable[key])) return evaluatedValues def getOperationValue(self, leftValue, rightValue): 'Get operation value.' leftKeys = getKeys(leftValue) rightKeys = getKeys(rightValue) if leftKeys is None and rightKeys is None: return self.getValueFromValuePair(leftValue, rightValue) if leftKeys is None: return self.getEvaluatedValues(rightValue, rightKeys, leftValue) if rightKeys is None: return self.getEvaluatedValues(leftValue, leftKeys, rightValue) leftKeys.sort(reverse=True) rightKeys.sort(reverse=True) if leftKeys != rightKeys: print('Warning, the leftKeys are different from the rightKeys in getOperationValue in EvaluatorAddition for:') print('leftValue') print(leftValue) print(leftKeys) print('rightValue') print(rightValue) print(rightKeys) print(self) return None if leftValue.__class__ == dict or rightValue.__class__ == dict: evaluatedValues = {} for leftKey in leftKeys: evaluatedValues[leftKey] = self.getOperationValue(leftValue[leftKey], rightValue[leftKey]) return evaluatedValues evaluatedValues = [] for leftKey in leftKeys: evaluatedValues.append(self.getOperationValue(leftValue[leftKey], rightValue[leftKey])) return evaluatedValues def getValueFromValuePair(self, leftValue, rightValue): 'Add two values.' return leftValue + rightValue class EvaluatorEqual(EvaluatorAddition): 'Class to compare two evaluators.' def executePairOperation(self, evaluators, evaluatorIndex, operationLevel): 'Operate on two evaluators.' if operationLevel == 15: self.executePair(evaluators, evaluatorIndex) def getBooleanFromValuePair(self, leftValue, rightValue): 'Compare two values.' return leftValue == rightValue def getValueFromValuePair(self, leftValue, rightValue): 'Get value from comparison.' return self.getBooleanFromValuePair(leftValue, rightValue) class EvaluatorSubtraction(EvaluatorAddition): 'Class to subtract two evaluators.' def executeLeft( self, evaluators, evaluatorIndex ): 'Minus the value to the right.' leftIndex = evaluatorIndex - 1 rightIndex = evaluatorIndex + 1 leftValue = None if leftIndex >= 0: leftValue = evaluators[leftIndex].value if leftValue is not None: return rightValue = evaluators[rightIndex].value if rightValue is None: print('Warning, can not minus.') print( evaluators[rightIndex].word ) else: evaluators[rightIndex].value = self.getNegativeValue(rightValue) del evaluators[evaluatorIndex] def executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel): 'Minus the value to the right.' if operationLevel == 200: self.executeLeft(evaluators, evaluatorIndex) def getNegativeValue( self, value ): 'Get the negative value.' keys = getKeys(value) if keys is None: return self.getValueFromSingleValue(value) for key in keys: value[key] = self.getNegativeValue(value[key]) return value def getValueFromSingleValue( self, value ): 'Minus value.' return -value def getValueFromValuePair(self, leftValue, rightValue): 'Subtract two values.' return leftValue - rightValue class EvaluatorAnd(EvaluatorAddition): 'Class to compare two evaluators.' def executePairOperation(self, evaluators, evaluatorIndex, operationLevel): 'Operate on two evaluators.' if operationLevel == 12: self.executePair(evaluators, evaluatorIndex) def getBooleanFromValuePair(self, leftValue, rightValue): 'And two values.' return leftValue and rightValue def getValueFromValuePair(self, leftValue, rightValue): 'Get value from comparison.' return self.getBooleanFromValuePair(leftValue, rightValue) class EvaluatorAttribute(Evaluator): 'Class to handle an attribute.' def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator): 'Execute the function.' executeNextEvaluatorArguments(self, evaluators, evaluatorIndex, nextEvaluator) def executeRightOperation( self, evaluators, evaluatorIndex ): 'Execute operator which acts from the right.' attributeName = self.word[1 :] previousIndex = evaluatorIndex - 1 previousEvaluator = evaluators[previousIndex] if previousEvaluator.value.__class__ == dict: from fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables import dictionary_attribute self.value = dictionary_attribute._getAccessibleAttribute(attributeName, previousEvaluator.value) elif previousEvaluator.value.__class__ == list: from fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables import list_attribute self.value = list_attribute._getAccessibleAttribute(attributeName, previousEvaluator.value) elif previousEvaluator.value.__class__ == str: from fabmetheus_utilities.geometry.geometry_utilities.evaluate_enumerables import string_attribute self.value = string_attribute._getAccessibleAttribute(attributeName, previousEvaluator.value) else: attributeKeywords = attributeName.split('.') self.value = previousEvaluator.value for attributeKeyword in attributeKeywords: self.value = getattr(self.value, '_getAccessibleAttribute', None)(attributeKeyword) if self.value is None: print('Warning, EvaluatorAttribute in evaluate can not get a getAccessibleAttributeFunction for:') print(attributeName) print(previousEvaluator.value) print(self) return del evaluators[previousIndex] class EvaluatorBracketCurly(Evaluator): 'Class to evaluate a string.' def executeBracket(self, bracketBeginIndex, bracketEndIndex, evaluators): 'Execute the bracket.' for evaluatorIndex in xrange(bracketEndIndex - 3, bracketBeginIndex, - 1): bracketEndIndex = getEndIndexConvertEquationValue(bracketEndIndex, evaluatorIndex, evaluators) evaluatedExpressionValueEvaluators = getBracketEvaluators(bracketBeginIndex, bracketEndIndex, evaluators) self.value = {} for evaluatedExpressionValueEvaluator in evaluatedExpressionValueEvaluators: keyValue = evaluatedExpressionValueEvaluator.value self.value[keyValue.key] = keyValue.value del evaluators[bracketBeginIndex + 1: bracketEndIndex + 1] class EvaluatorBracketRound(Evaluator): 'Class to evaluate a string.' def __init__(self, elementNode, word): 'Set value to none.' self.arguments = [] self.value = None self.word = word def executeBracket( self, bracketBeginIndex, bracketEndIndex, evaluators ): 'Execute the bracket.' self.arguments = getBracketValuesDeleteEvaluator(bracketBeginIndex, bracketEndIndex, evaluators) if len( self.arguments ) < 1: return if len( self.arguments ) > 1: self.value = self.arguments else: self.value = self.arguments[0] def executeRightOperation( self, evaluators, evaluatorIndex ): 'Evaluate the statement and delete the evaluators.' previousIndex = evaluatorIndex - 1 if previousIndex < 0: return evaluators[ previousIndex ].executeFunction( evaluators, previousIndex, self ) class EvaluatorBracketSquare(Evaluator): 'Class to evaluate a string.' def executeBracket( self, bracketBeginIndex, bracketEndIndex, evaluators ): 'Execute the bracket.' self.value = getBracketValuesDeleteEvaluator(bracketBeginIndex, bracketEndIndex, evaluators) def executeRightOperation( self, evaluators, evaluatorIndex ): 'Evaluate the statement and delete the evaluators.' previousIndex = evaluatorIndex - 1 if previousIndex < 0: return if self.value.__class__ != list: return evaluators[ previousIndex ].executeKey( evaluators, self.value, previousIndex, self ) class EvaluatorClass(Evaluator): 'Class evaluator class.' def __init__(self, elementNode, word): 'Set value to none.' self.elementNode = elementNode self.value = None self.word = word def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator): 'Execute the function.' if self.elementNode.xmlObject is None: self.elementNode.xmlObject = FunctionVariable(self.elementNode) nextEvaluator.value = ClassObject(self.elementNode) initializeFunction = None if '_init' in self.elementNode.xmlObject.functionDictionary: function = self.elementNode.xmlObject.functionDictionary['_init'] function.classObject = nextEvaluator.value setFunctionLocalDictionary(nextEvaluator.arguments, function) function.getReturnValue() del evaluators[evaluatorIndex] class EvaluatorComma(Evaluator): 'Class to join two evaluators.' def executePairOperation(self, evaluators, evaluatorIndex, operationLevel): 'Operate on two evaluators.' if operationLevel != 0: return previousIndex = evaluatorIndex - 1 if previousIndex < 0: evaluators[evaluatorIndex].value = None return if evaluators[previousIndex].word == ',': evaluators[evaluatorIndex].value = None return del evaluators[evaluatorIndex] class EvaluatorConcatenate(Evaluator): 'Class to join two evaluators.' def executePairOperation(self, evaluators, evaluatorIndex, operationLevel): 'Operate on two evaluators.' if operationLevel != 80: return leftIndex = evaluatorIndex - 1 if leftIndex < 0: del evaluators[evaluatorIndex] return rightIndex = evaluatorIndex + 1 if rightIndex >= len(evaluators): del evaluators[ leftIndex : rightIndex ] return leftValue = evaluators[leftIndex].value rightValue = evaluators[rightIndex].value if leftValue.__class__ == rightValue.__class__ and (leftValue.__class__ == list or rightValue.__class__ == str): evaluators[leftIndex].value = leftValue + rightValue del evaluators[ evaluatorIndex : evaluatorIndex + 2 ] return if leftValue.__class__ == list and rightValue.__class__ == int: if rightValue > 0: originalList = leftValue[:] for copyIndex in xrange( rightValue - 1 ): leftValue += originalList evaluators[leftIndex].value = leftValue del evaluators[ evaluatorIndex : evaluatorIndex + 2 ] return if leftValue.__class__ == dict and rightValue.__class__ == dict: leftValue.update(rightValue) evaluators[leftIndex].value = leftValue del evaluators[ evaluatorIndex : evaluatorIndex + 2 ] return del evaluators[ leftIndex : evaluatorIndex + 2 ] class EvaluatorDictionary(Evaluator): 'Class to join two evaluators.' def executePairOperation(self, evaluators, evaluatorIndex, operationLevel): 'Operate on two evaluators.' if operationLevel != 10: return leftEvaluatorIndex = evaluatorIndex - 1 if leftEvaluatorIndex < 0: print('Warning, leftEvaluatorIndex is less than zero in EvaluatorDictionary for:') print(self) print(evaluators) return rightEvaluatorIndex = evaluatorIndex + 1 if rightEvaluatorIndex >= len(evaluators): print('Warning, rightEvaluatorIndex too high in EvaluatorDictionary for:') print(rightEvaluatorIndex) print(self) print(evaluators) return evaluators[rightEvaluatorIndex].value = KeyValue(evaluators[leftEvaluatorIndex].value, evaluators[rightEvaluatorIndex].value) del evaluators[ leftEvaluatorIndex : rightEvaluatorIndex ] class EvaluatorDivision(EvaluatorAddition): 'Class to divide two evaluators.' def executePairOperation(self, evaluators, evaluatorIndex, operationLevel): 'Operate on two evaluators.' if operationLevel == 40: self.executePair(evaluators, evaluatorIndex) def getValueFromValuePair(self, leftValue, rightValue): 'Divide two values.' return leftValue / rightValue class EvaluatorElement(Evaluator): 'Element evaluator class.' def __init__(self, elementNode, word): 'Set value to none.' self.elementNode = elementNode self.value = None self.word = word def executeCenterOperation(self, evaluators, evaluatorIndex): 'Execute operator which acts on the center.' dotIndex = self.word.find('.') if dotIndex < 0: print('Warning, EvaluatorElement in evaluate can not find the dot for:') print(functionName) print(self) return attributeName = self.word[dotIndex + 1 :] moduleName = self.word[: dotIndex] if moduleName in globalModuleFunctionsDictionary: self.value = globalModuleFunctionsDictionary[moduleName](attributeName, self.elementNode) return pluginModule = None if moduleName in globalElementNameSet: pluginModule = archive.getModuleWithPath(archive.getElementsPath(moduleName)) if pluginModule is None: print('Warning, EvaluatorElement in evaluate can not get a pluginModule for:') print(moduleName) print(self) return getAccessibleAttributeFunction = pluginModule._getAccessibleAttribute globalModuleFunctionsDictionary[moduleName] = getAccessibleAttributeFunction self.value = getAccessibleAttributeFunction(attributeName, self.elementNode) def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator): 'Execute the function.' executeNextEvaluatorArguments(self, evaluators, evaluatorIndex, nextEvaluator) class EvaluatorFalse(Evaluator): 'Class to evaluate a string.' def __init__(self, elementNode, word): 'Set value to zero.' self.value = False self.word = word class EvaluatorFunction(Evaluator): 'Function evaluator class.' def __init__(self, elementNode, word): 'Set value to none.' self.elementNode = elementNode self.value = None self.word = word def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator): 'Execute the function.' if self.elementNode.xmlObject is None: if 'return' in self.elementNode.attributes: value = self.elementNode.attributes['return'] self.elementNode.xmlObject = getEvaluatorSplitWords(value) else: self.elementNode.xmlObject = [] self.function = Function(self.elementNode ) setFunctionLocalDictionary(nextEvaluator.arguments, self.function) nextEvaluator.value = self.function.getReturnValue() del evaluators[evaluatorIndex] class EvaluatorFundamental(Evaluator): 'Fundamental evaluator class.' def executeCenterOperation(self, evaluators, evaluatorIndex): 'Execute operator which acts on the center.' dotIndex = self.word.find('.') if dotIndex < 0: print('Warning, EvaluatorFundamental in evaluate can not find the dot for:') print(functionName) print(self) return attributeName = self.word[dotIndex + 1 :] moduleName = self.word[: dotIndex] if moduleName in globalModuleFunctionsDictionary: self.value = globalModuleFunctionsDictionary[moduleName](attributeName) return pluginModule = None if moduleName in globalFundamentalNameSet: pluginModule = archive.getModuleWithPath(archive.getFundamentalsPath(moduleName)) else: underscoredName = '_' + moduleName if underscoredName in globalFundamentalNameSet: pluginModule = archive.getModuleWithPath(archive.getFundamentalsPath(underscoredName)) if pluginModule is None: print('Warning, EvaluatorFundamental in evaluate can not get a pluginModule for:') print(moduleName) print(self) return getAccessibleAttributeFunction = pluginModule._getAccessibleAttribute globalModuleFunctionsDictionary[moduleName] = getAccessibleAttributeFunction self.value = getAccessibleAttributeFunction(attributeName) def executeFunction(self, evaluators, evaluatorIndex, nextEvaluator): 'Execute the function.' executeNextEvaluatorArguments(self, evaluators, evaluatorIndex, nextEvaluator) class EvaluatorGreaterEqual( EvaluatorEqual ): 'Class to compare two evaluators.' def getBooleanFromValuePair(self, leftValue, rightValue): 'Compare two values.' return leftValue >= rightValue class EvaluatorGreater( EvaluatorEqual ): 'Class to compare two evaluators.' def getBooleanFromValuePair(self, leftValue, rightValue): 'Compare two values.' return leftValue > rightValue class EvaluatorLessEqual( EvaluatorEqual ): 'Class to compare two evaluators.' def getBooleanFromValuePair(self, leftValue, rightValue): 'Compare two values.' return leftValue <= rightValue class EvaluatorLess( EvaluatorEqual ): 'Class to compare two evaluators.' def getBooleanFromValuePair(self, leftValue, rightValue): 'Compare two values.' return leftValue < rightValue class EvaluatorLocal(EvaluatorElement): 'Class to get a local variable.' def executeCenterOperation(self, evaluators, evaluatorIndex): 'Execute operator which acts on the center.' functions = self.elementNode.getXMLProcessor().functions if len(functions) < 1: print('Warning, there are no functions in EvaluatorLocal in evaluate for:') print(self.word) return attributeKeywords = self.word.split('.') self.value = functions[-1].localDictionary[attributeKeywords[0]] for attributeKeyword in attributeKeywords[1 :]: self.value = self.value._getAccessibleAttribute(attributeKeyword) class EvaluatorModulo( EvaluatorDivision ): 'Class to modulo two evaluators.' def getValueFromValuePair(self, leftValue, rightValue): 'Modulo two values.' return leftValue % rightValue class EvaluatorMultiplication( EvaluatorDivision ): 'Class to multiply two evaluators.' def getValueFromValuePair(self, leftValue, rightValue): 'Multiply two values.' return leftValue * rightValue class EvaluatorNone(Evaluator): 'Class to evaluate None.' def __init__(self, elementNode, word): 'Set value to none.' self.value = None self.word = str(word) class EvaluatorNot(EvaluatorSubtraction): 'Class to compare two evaluators.' def executeLeftOperation(self, evaluators, evaluatorIndex, operationLevel): 'Minus the value to the right.' if operationLevel == 13: self.executeLeft(evaluators, evaluatorIndex) def getValueFromSingleValue( self, value ): 'Minus value.' return not value class EvaluatorNotEqual( EvaluatorEqual ): 'Class to compare two evaluators.' def getBooleanFromValuePair(self, leftValue, rightValue): 'Compare two values.' return leftValue != rightValue class EvaluatorNumeric(Evaluator): 'Class to evaluate a string.' def __init__(self, elementNode, word): 'Set value.' self.value = None self.word = word try: if '.' in word: self.value = float(word) else: self.value = int(word) except: print('Warning, EvaluatorNumeric in evaluate could not get a numeric value for:') print(word) print(elementNode) class EvaluatorOr( EvaluatorAnd ): 'Class to compare two evaluators.' def getBooleanFromValuePair(self, leftValue, rightValue): 'Or two values.' return leftValue or rightValue class EvaluatorPower(EvaluatorAddition): 'Class to power two evaluators.' def executePairOperation(self, evaluators, evaluatorIndex, operationLevel): 'Operate on two evaluators.' if operationLevel == 60: self.executePair(evaluators, evaluatorIndex) def getValueFromValuePair(self, leftValue, rightValue): 'Power of two values.' return leftValue ** rightValue class EvaluatorSelf(EvaluatorElement): 'Class to handle self.' def executeCenterOperation(self, evaluators, evaluatorIndex): 'Execute operator which acts on the center.' functions = self.elementNode.getXMLProcessor().functions if len(functions) < 1: print('Warning, there are no functions in executeCenterOperation in EvaluatorSelf in evaluate for:') print(self.elementNode) return function = functions[-1] attributeKeywords = self.word.split('.') self.value = function.classObject for attributeKeyword in attributeKeywords[1 :]: self.value = self.value._getAccessibleAttribute(attributeKeyword) class EvaluatorTrue(Evaluator): 'Class to evaluate a string.' def __init__(self, elementNode, word): 'Set value to true.' self.value = True self.word = word class EvaluatorValue(Evaluator): 'Class to evaluate a string.' def __init__(self, word): 'Set value to none.' self.value = word self.word = str(word) class Function(BaseFunction): 'Class to get equation results.' def __init__(self, elementNode): 'Initialize.' self.elementNode = elementNode self.evaluatorSplitLine = elementNode.xmlObject self.localDictionary = {} self.xmlProcessor = elementNode.getXMLProcessor() def getReturnValueWithoutDeletion(self): 'Get return value without deleting last function.' self.returnValue = None self.xmlProcessor.functions.append(self) if len(self.evaluatorSplitLine) < 1: self.shouldReturn = False self.processChildNodes(self.elementNode) else: self.returnValue = getEvaluatedExpressionValueBySplitLine(self.elementNode, self.evaluatorSplitLine) return self.returnValue class FunctionVariable: 'Class to hold class functions and variable set.' def __init__(self, elementNode): 'Initialize.' self.functionDictionary = {} self.variables = [] self.processClass(elementNode) def addToVariableSet(self, elementNode): 'Add to variables.' setLocalAttribute(elementNode) keySplitLine = elementNode.xmlObject.key.split('.') if len(keySplitLine) == 2: if keySplitLine[0] == 'self': variable = keySplitLine[1] if variable not in self.variables: self.variables.append(variable) def processClass(self, elementNode): 'Add class to FunctionVariable.' for childNode in elementNode.childNodes: self.processFunction(childNode) if 'parentNode' in elementNode.attributes: self.processClass(elementNode.getElementNodeByID(elementNode.attributes['parentNode'])) def processFunction(self, elementNode): 'Add function to function dictionary.' if elementNode.getNodeName() != 'function': return idKey = elementNode.attributes['id'] if idKey in self.functionDictionary: return self.functionDictionary[idKey] = ClassFunction(elementNode) for childNode in elementNode.childNodes: self.processStatement(childNode) def processStatement(self, elementNode): 'Add self statement to variables.' if elementNode.getNodeName() == 'statement': self.addToVariableSet(elementNode) for childNode in elementNode.childNodes: self.processStatement(childNode) class KeyValue: 'Class to hold a key value.' def __init__(self, key=None, value=None): 'Get key value.' self.key = key self.value = value def __repr__(self): 'Get the string representation of this KeyValue.' return str(self.__dict__) def getByCharacter( self, character, line ): 'Get by character.' dotIndex = line.find( character ) if dotIndex < 0: self.key = line self.value = None return self self.key = line[: dotIndex] self.value = line[dotIndex + 1 :] return self def getByDot(self, line): 'Get by dot.' return self.getByCharacter('.', line ) def getByEqual(self, line): 'Get by dot.' return self.getByCharacter('=', line ) class ModuleElementNode: 'Class to get the in attribute, the index name and the value name.' def __init__( self, elementNode): 'Initialize.' self.conditionSplitWords = None self.elseElement = None if 'condition' in elementNode.attributes: self.conditionSplitWords = getEvaluatorSplitWords( elementNode.attributes['condition'] ) else: print('Warning, could not find the condition attribute in ModuleElementNode in evaluate for:') print(elementNode) return if len( self.conditionSplitWords ) < 1: self.conditionSplitWords = None print('Warning, could not get split words for the condition attribute in ModuleElementNode in evaluate for:') print(elementNode) nextIndex = getNextChildIndex(elementNode) if nextIndex >= len( elementNode.parentNode.childNodes ): return nextElementNode = elementNode.parentNode.childNodes[ nextIndex ] lowerLocalName = nextElementNode.getNodeName().lower() if lowerLocalName != 'else' and lowerLocalName != 'elif': return xmlProcessor = elementNode.getXMLProcessor() if lowerLocalName not in xmlProcessor.namePathDictionary: return self.pluginModule = archive.getModuleWithPath( xmlProcessor.namePathDictionary[ lowerLocalName ] ) if self.pluginModule is None: return self.elseElement = nextElementNode def processElse(self, elementNode): 'Process the else statement.' if self.elseElement is not None: self.pluginModule.processElse( self.elseElement) globalCreationDictionary = archive.getGeometryDictionary('creation') globalDictionaryOperatorBegin = { '||' : EvaluatorConcatenate, '==' : EvaluatorEqual, '>=' : EvaluatorGreaterEqual, '<=' : EvaluatorLessEqual, '!=' : EvaluatorNotEqual, '**' : EvaluatorPower } globalModuleEvaluatorDictionary = {} globalFundamentalNameSet = set(archive.getPluginFileNamesFromDirectoryPath(archive.getFundamentalsPath())) addPrefixDictionary(globalModuleEvaluatorDictionary, globalFundamentalNameSet, EvaluatorFundamental) globalElementNameSet = set(archive.getPluginFileNamesFromDirectoryPath(archive.getElementsPath())) addPrefixDictionary(globalModuleEvaluatorDictionary, globalElementNameSet, EvaluatorElement) globalModuleEvaluatorDictionary['self'] = EvaluatorSelf globalSplitDictionaryOperator = { '+' : EvaluatorAddition, '{' : EvaluatorBracketCurly, '}' : Evaluator, '(' : EvaluatorBracketRound, ')' : Evaluator, '[' : EvaluatorBracketSquare, ']' : Evaluator, ',' : EvaluatorComma, ':' : EvaluatorDictionary, '/' : EvaluatorDivision, '>' : EvaluatorGreater, '<' : EvaluatorLess, '%' : EvaluatorModulo, '*' : EvaluatorMultiplication, '-' : EvaluatorSubtraction } globalSplitDictionary = getSplitDictionary() # must be after globalSplitDictionaryOperator sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/000077500000000000000000000000001167321211700307115ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/__init__.py000066400000000000000000000006571167321211700330320ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 4 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/creation.py000066400000000000000000000040761167321211700330760ustar00rootroot00000000000000""" Boolean geometry utilities. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def _getAccessibleAttribute(attributeName, elementNode): 'Get the accessible attribute.' functionName = attributeName[len('get') :].lower() if functionName not in evaluate.globalCreationDictionary: print('Warning, functionName not in globalCreationDictionary in _getAccessibleAttribute in creation for:') print(functionName) print(elementNode) return None pluginModule = archive.getModuleWithPath(evaluate.globalCreationDictionary[functionName]) if pluginModule is None: print('Warning, _getAccessibleAttribute in creation can not get a pluginModule for:') print(functionName) print(elementNode) return None return Creation(elementNode, pluginModule).getCreation class Creation: 'Class to handle a creation.' def __init__(self, elementNode, pluginModule): 'Initialize.' self.elementNode = elementNode self.pluginModule = pluginModule def __repr__(self): "Get the string representation of this creation." return self.elementNode def getCreation(self, *arguments): "Get creation." dictionary = {'_fromCreationEvaluator': 'true'} firstArgument = None if len(arguments) > 0: firstArgument = arguments[0] if firstArgument.__class__ == dict: dictionary.update(firstArgument) return self.pluginModule.getGeometryOutput(None, self.elementNode.getCopyShallow(dictionary)) copyShallow = self.elementNode.getCopyShallow(dictionary) return self.pluginModule.getGeometryOutputByArguments(arguments, copyShallow) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/document.py000066400000000000000000000060741167321211700331100ustar00rootroot00000000000000""" Boolean geometry utilities. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def _getAccessibleAttribute(attributeName, elementNode): 'Get the accessible attribute.' if attributeName in globalGetAccessibleAttributeSet: return getattr(Document(elementNode), attributeName, None) return None class Document: 'Class to handle elementNodes in a document.' def __init__(self, elementNode): 'Initialize.' self.elementNode = elementNode def __repr__(self): 'Get the string representation of this Document.' return self.elementNode def getCascadeBoolean(self, defaultBoolean, key): 'Get cascade boolean.' return self.elementNode.getCascadeBoolean(defaultBoolean, key) def getCascadeFloat(self, defaultFloat, key): 'Get cascade float.' return self.elementNode.getCascadeFloat(defaultFloat, key) def getDocumentElement(self): 'Get document element element.' return self.elementNode.getDocumentElement() def getElementByID(self, idKey): 'Get element by id.' elementByID = self.elementNode.getElementNodeByID(idKey) if elementByID is None: print('Warning, could not get elementByID in getElementByID in document for:') print(idKey) print(self.elementNode) return elementByID def getElementsByName(self, nameKey): 'Get element by name.' elementsByName = self.elementNode.getElementNodesByName(nameKey) if elementsByName is None: print('Warning, could not get elementsByName in getElementsByName in document for:') print(nameKey) print(self.elementNode) return elementsByName def getElementsByTag(self, tagKey): 'Get element by tag.' elementsByTag = self.elementNode.getElementNodesByTag(tagKey) if elementsByTag is None: print('Warning, could not get elementsByTag in getElementsByTag in document for:') print(tagKey) print(self.elementNode) return elementsByTag def getParentNode(self): 'Get parentNode element.' return self.elementNode.parentNode def getPrevious(self): 'Get previous element.' return self.getPreviousElement() def getPreviousElement(self): 'Get previous element.' return self.elementNode.getPreviousElementNode() def getPreviousVertex(self): 'Get previous element.' return self.elementNode.getPreviousVertex() def getSelfElement(self): 'Get self element.' return self.elementNode globalAccessibleAttributeDictionary = 'getCascadeBoolean getCascadeFloat getDocumentElement getElementByID getElementsByName'.split() globalAccessibleAttributeDictionary += 'getElementsByTag getParentNode getPrevious getPreviousElement getPreviousVertex'.split() globalAccessibleAttributeDictionary += 'getSelfElement'.split() globalGetAccessibleAttributeSet = set(globalAccessibleAttributeDictionary) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_elements/setting.py000066400000000000000000000146101167321211700327420ustar00rootroot00000000000000""" Boolean geometry utilities. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from skeinforge_application.skeinforge_utilities import skeinforge_craft import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def _getAccessibleAttribute(attributeName, elementNode): 'Get the accessible attribute.' if attributeName in globalGetAccessibleAttributeSet: return getattr(Setting(elementNode), attributeName, None) return None def getCascadeFloatWithoutSelf(defaultFloat, elementNode, key): 'Get the cascade float.' if key in elementNode.attributes: value = elementNode.attributes[key] functionName = 'get' + key[0].upper() + key[1 :] if functionName in value: if elementNode.parentNode is None: return defaultFloat else: elementNode = elementNode.parentNode return elementNode.getCascadeFloat(defaultFloat, key) def getImportRadius(elementNode): 'Get the importRadius.' if elementNode is None: return 0.36 preferences = skeinforge_craft.getCraftPreferences('carve') importCoarseness = skeinforge_craft.getCraftValue('Import Coarseness', preferences) importCoarseness = getCascadeFloatWithoutSelf(importCoarseness, elementNode, 'importCoarseness') layerThickness = skeinforge_craft.getCraftValue('Layer Thickness', preferences) layerThickness = getCascadeFloatWithoutSelf(layerThickness, elementNode, 'layerThickness') perimeterWidthOverThickness = skeinforge_craft.getCraftValue('Perimeter Width over Thickness', preferences) perimeterWidthOverThickness = getCascadeFloatWithoutSelf(perimeterWidthOverThickness, elementNode, 'perimeterWidthOverThickness') return getCascadeFloatWithoutSelf(0.5 * importCoarseness * layerThickness * perimeterWidthOverThickness, elementNode, 'importRadius') def getInteriorOverhangAngle(elementNode): 'Get the interior overhang support angle in degrees.' return getCascadeFloatWithoutSelf(30.0, elementNode, 'interiorOverhangAngle') def getInteriorOverhangRadians(elementNode): 'Get the interior overhang support angle in radians.' return math.radians(getInteriorOverhangAngle(elementNode)) def getLayerThickness(elementNode): 'Get the layer thickness.' if elementNode is None: return 0.4 preferences = skeinforge_craft.getCraftPreferences('carve') return getCascadeFloatWithoutSelf(skeinforge_craft.getCraftValue('Layer Thickness', preferences), elementNode, 'layerThickness') def getOverhangAngle(elementNode): 'Get the overhang support angle in degrees.' return getCascadeFloatWithoutSelf(45.0, elementNode, 'overhangAngle') def getOverhangRadians(elementNode): 'Get the overhang support angle in radians.' return math.radians(getOverhangAngle(elementNode)) def getOverhangSpan(elementNode): 'Get the overhang span.' return getCascadeFloatWithoutSelf(2.0 * getLayerThickness(elementNode), elementNode, 'overhangSpan') def getPerimeterWidth(elementNode): 'Get the perimeter width.' if elementNode is None: return 0.72 preferences = skeinforge_craft.getCraftPreferences('carve') layerThickness = skeinforge_craft.getCraftValue('Layer Thickness', preferences) layerThickness = getCascadeFloatWithoutSelf(layerThickness, elementNode, 'layerThickness') perimeterWidthOverThickness = skeinforge_craft.getCraftValue('Perimeter Width over Thickness', preferences) perimeterWidthOverThickness = getCascadeFloatWithoutSelf(perimeterWidthOverThickness, elementNode, 'perimeterWidthOverThickness') return getCascadeFloatWithoutSelf(perimeterWidthOverThickness, elementNode, 'perimeterWidth') def getPrecision(elementNode): 'Get the cascade precision.' return getCascadeFloatWithoutSelf(0.2 * getLayerThickness(elementNode), elementNode, 'precision') def getSheetThickness(elementNode): 'Get the sheet thickness.' return getCascadeFloatWithoutSelf(3.0, elementNode, 'sheetThickness') def getTwistPrecision(elementNode): 'Get the twist precision in degrees.' return getCascadeFloatWithoutSelf(5.0, elementNode, 'twistPrecision') def getTwistPrecisionRadians(elementNode): 'Get the twist precision in radians.' return math.radians(getTwistPrecision(elementNode)) class Setting: 'Class to get handle elementNodes in a setting.' def __init__(self, elementNode): 'Initialize.' self.elementNode = elementNode def __repr__(self): 'Get the string representation of this Setting.' return self.elementNode def getImportRadius(self): 'Get the importRadius.' return getImportRadius(self.elementNode) def getInteriorOverhangAngle(self): 'Get the interior overhang support angle in degrees.' return getInteriorOverhangAngle(self.elementNode) def getInteriorOverhangRadians(self): 'Get the interior overhang support angle in radians.' return getInteriorOverhangRadians(self.elementNode) def getLayerThickness(self): 'Get the layer thickness.' return getLayerThickness(self.elementNode) def getOverhangAngle(self): 'Get the overhang support angle in degrees.' return getOverhangAngle(self.elementNode) def getOverhangRadians(self): 'Get the overhang support angle in radians.' return getOverhangRadians(self.elementNode) def getOverhangSpan(self): 'Get the overhang span.' return getOverhangSpan(self.elementNode) def getPerimeterWidth(self): 'Get the perimeter width.' return getPerimeterWidth(self.elementNode) def getPrecision(self): 'Get the cascade precision.' return getPrecision(self.elementNode) def getSheetThickness(self): 'Get the sheet thickness.' return getSheetThickness(self.elementNode) def getTwistPrecision(self): 'Get the twist precision in degrees.' return getTwistPrecision(self.elementNode) def getTwistPrecisionRadians(self): 'Get the twist precision in radians.' return getTwistPrecisionRadians(self.elementNode) globalAccessibleAttributeDictionary = 'getImportRadius getInteriorOverhangAngle getInteriorOverhangRadians'.split() globalAccessibleAttributeDictionary += 'getLayerThickness getOverhangSpan getOverhangAngle getOverhangRadians'.split() globalAccessibleAttributeDictionary += 'getPerimeterWidth getPrecision getSheetThickness getTwistPrecision getTwistPrecisionRadians'.split() globalGetAccessibleAttributeSet = set(globalAccessibleAttributeDictionary) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/000077500000000000000000000000001167321211700313775ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables/__init__.py000066400000000000000000000006571167321211700335200ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 4 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) dictionary_attribute.py000066400000000000000000000062111167321211700361220ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables""" Dictionary object attributes. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def _getAccessibleAttribute(attributeName, dictionaryObject): 'Get the accessible attribute.' if attributeName in globalNativeFunctionSet: return getattr(dictionaryObject, attributeName, None) if attributeName in globalGetAccessibleAttributeSet: stringAttribute = DictionaryAttribute(dictionaryObject) return getattr(stringAttribute, attributeName, None) return None class DictionaryAttribute: 'Class to handle a dictionary.' def __init__(self, dictionaryObject): 'Initialize.' self.dictionaryObject = dictionaryObject def __repr__(self): "Get the dictionary representation of this DictionaryAttribute." return str(self.dictionaryObject) def count(self, value): 'Get the count.' countTotal = 0 for key, iteratorValue in self.dictionaryObject.iteritems(): if iteratorValue == value: countTotal += 1 return countTotal def delete(self, arguments): 'Get the delete dictionary.' if arguments.__class__ != list: del self.dictionaryObject[arguments] return self.dictionaryObject if len(arguments) == 0: self.dictionaryObject.clear() return self.dictionaryObject if len(arguments) == 1: del self.dictionaryObject[arguments[0]] return self.dictionaryObject for enumeratorKey in euclidean.getEnumeratorKeysAlwaysList(self.dictionaryObject, arguments): del self.dictionaryObject[enumeratorKey] return self.dictionaryObject def getIsIn(self, value): 'Determine if the value is in.' return value in self.dictionaryObject def getIsNotIn(self, value): 'Determine if the value is in.' return not(value in self.dictionaryObject) def getLength(self): 'Get the length.' return len(self.dictionaryObject) def getMax(self): 'Get the max.' return max(self.dictionaryObject) def getMin(self): 'Get the min.' return min(self.dictionaryObject) def index(self, value): 'Get the index element.' for key, iteratorValue in self.dictionaryObject.iteritems(): if iteratorValue == value: return key raise ValueError('Value (%s) not found in index in DictionaryAttribute for (%s).' % (value, self.dictionaryObject)) def length(self): 'Get the length.' return len(self.dictionaryObject) def set(self, itemIndex, value): 'Set value.' self.dictionaryObject[itemIndex] = value return self.dictionaryObject globalAccessibleAttributeDictionary = 'count delete getIsIn getIsNotIn getLength getMax getMin index length set'.split() globalGetAccessibleAttributeSet = set(globalAccessibleAttributeDictionary) globalNativeFunctions = 'clear copy fromkeys get items keys pop popitem remove setdefault update values'.split() globalNativeFunctionSet = set(globalNativeFunctions) list_attribute.py000066400000000000000000000067301167321211700347360ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables""" List object attributes. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def _getAccessibleAttribute(attributeName, listObject): 'Get the accessible attribute.' if attributeName in globalNativeFunctionSet: return getattr(listObject, attributeName, None) if attributeName in globalGetAccessibleAttributeSet: stringAttribute = ListAttribute(listObject) return getattr(stringAttribute, attributeName, None) return None class ListAttribute: 'Class to handle a list.' def __init__(self, listObject): 'Initialize.' self.listObject = listObject def __repr__(self): "Get the list representation of this ListAttribute." return str(self.listObject) def add(self, value): 'Get the concatenation, same as append.' return self.listObject + [value] def copy(self): 'Get the copy.' return self.listObject[:] def delete(self, arguments): 'Get the delete list.' deleteList = [] enumeratorSet = set(euclidean.getEnumeratorKeysAlwaysList(self.listObject, arguments)) for elementIndex, element in enumerate(self.listObject): if elementIndex not in enumeratorSet: deleteList.append(element) return deleteList def get(self, itemIndex): 'Get value by index' return self.listObject[itemIndex] def getExpansion(self, items): 'Get the concatenated copies.' expansion = [] for itemIndex in xrange(items): expansion += self.listObject[:] return expansion def getIsIn(self, value): 'Determine if the value is in.' return value in self.listObject def getIsNotIn(self, value): 'Determine if the value is in.' return not(value in self.listObject) def getLength(self): 'Get the length.' return len(self.listObject) def getMax(self): 'Get the max.' return max(self.listObject) def getMin(self): 'Get the min.' return min(self.listObject) def insert(self, insertIndex, value): 'Get the insert list.' if insertIndex < 0: insertIndex += len(self.listObject) insertIndex = max(0, insertIndex) return self.listObject[: insertIndex] + [value] + self.listObject[insertIndex :] def keys(self): 'Get the keys.' return range(len(self.listObject)) def length(self): 'Get the length.' return len(self.listObject) def rindex(self, value): 'Get the rindex element.' for elementIndex, element in enumerate(self.listObject): if element == value: return elementIndex raise ValueError('Value (%s) not found in rindex in ListAttribute for (%s).' % (value, self.listObject)) def set(self, itemIndex, value): 'Set value.' self.listObject[itemIndex] = value return self.listObject def values(self, arguments=None): 'Get the values.' return self.listObject globalAccessibleAttributeDictionary = 'add copy count delete get getExpansion getIsIn getIsNotIn getLength getMax getMin'.split() globalAccessibleAttributeDictionary += 'insert keys length rindex set values'.split() globalGetAccessibleAttributeSet = set(globalAccessibleAttributeDictionary) globalNativeFunctions = 'append extend index pop remove reverse sort'.split() globalNativeFunctionSet = set(globalNativeFunctions) string_attribute.py000066400000000000000000000100751167321211700352660ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_enumerables""" String object attributes. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def _getAccessibleAttribute(attributeName, stringObject): 'Get the accessible attribute.' if attributeName in globalNativeFunctionSet: return getattr(stringObject, attributeName, None) if attributeName in globalGetAccessibleAttributeSet: stringAttribute = StringAttribute(stringObject) return getattr(stringAttribute, attributeName, None) return None class StringAttribute: 'Class to handle a string.' def __init__(self, stringObject): 'Initialize.' self.stringObject = stringObject def __repr__(self): "Get the string representation of this StringAttribute." return self.stringObject def add(self, nextString): 'Get the add string, same as append.' return self.stringObject + nextString def append(self, nextString): 'Get the append string.' return self.stringObject + nextString def copy(self): 'Get the copy.' return self.stringObject[:] def delete(self, arguments): 'Get the delete string.' deleteString = '' enumeratorSet = set(euclidean.getEnumeratorKeysAlwaysList(self.stringObject, arguments)) for characterIndex, character in enumerate(self.stringObject): if characterIndex not in enumeratorSet: deleteString += character return deleteString def get(self, itemIndex): 'Get value by characterIndex' return self.stringObject[itemIndex] def getExpansion(self, items): 'Get the concatenated copies.' expansion = '' for itemIndex in xrange(items): expansion += self.stringObject return expansion def getIsIn(self, value): 'Determine if the value is in.' return value in self.stringObject def getIsNotIn(self, value): 'Determine if the value is in.' return not(value in self.stringObject) def getLength(self): 'Get the length.' return len(self.stringObject) def getMax(self): 'Get the max.' return max(self.stringObject) def getMin(self): 'Get the min.' return min(self.stringObject) def insert(self, insertIndex, value): 'Get the insert string.' if insertIndex < 0: insertIndex += len(self.stringObject) insertIndex = max(0, insertIndex) return self.stringObject[: insertIndex] + value + self.stringObject[insertIndex :] def keys(self): 'Get the keys.' return range(len(self.stringObject)) def length(self): 'Get the length.' return len(self.stringObject) def remove(self, value): 'Get the remove string.' removeIndex = self.stringObject.find(value) if removeIndex > -1: return self.stringObject[: removeIndex] + self.stringObject[removeIndex + len(value) :] return self.stringObject def reverse(self): 'Get the reverse string.' return self.stringObject[: : -1] def set(self, itemIndex, value): 'Set value.' self.stringObject[itemIndex] = value return self.stringObject def values(self): 'Get the values.' values = [] for character in self.stringObject: values.append(character) return values globalAccessibleAttributeDictionary = 'add append copy delete get getExpansion getIsIn getIsNotIn getLength getMax getMin'.split() globalAccessibleAttributeDictionary += 'insert keys length remove reverse set values'.split() globalGetAccessibleAttributeSet = set(globalAccessibleAttributeDictionary) globalNativeFunctions = 'capitalize center count decode encode endswith expandtabs find format index isalnum join'.split() globalNativeFunctions += 'isalpha isdigit islower isspace istitle isupper ljust lower lstrip partition replace rfind rindex'.split() globalNativeFunctions += 'rjust rpartition rsplit rstrip split splitlines startswith strip swapcase title translate upper zfill'.split() globalNativeFunctionSet = set(globalNativeFunctions) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/000077500000000000000000000000001167321211700315565ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/__init__.py000066400000000000000000000006571167321211700336770ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 4 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/_math.py000066400000000000000000000050361167321211700332240ustar00rootroot00000000000000""" Boolean geometry utilities. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalNativeFunctions = 'acos asin atan atan2 ceil cos cosh degrees e exp fabs floor fmod frexp hypot'.split() globalNativeFunctions += 'ldexp log log10 modf pi pow radians sin sinh sqrt tan tanh trunc'.split() globalNativeFunctionSet = set(globalNativeFunctions) #Constants from: http://www.physlink.com/reference/MathConstants.cfm #Tau is from: http://tauday.com/ #If anyone wants to add stuff, more constants are at: http://en.wikipedia.org/wiki/Mathematical_constant globalMathConstantDictionary = { 'euler' : 0.5772156649015328606065120, 'golden' : euclidean.globalGoldenRatio, 'goldenAngle' : euclidean.globalGoldenAngle, 'goldenRatio' : euclidean.globalGoldenRatio, 'tau' : euclidean.globalTau} def _getAccessibleAttribute(attributeName): 'Get the accessible attribute.' if attributeName in globalMathConstantDictionary: return globalMathConstantDictionary[attributeName] if attributeName in globalNativeFunctionSet: return math.__dict__[attributeName] if attributeName in globalAccessibleAttributeDictionary: return globalAccessibleAttributeDictionary[attributeName] return None def getAbs(value): 'Get the abs.' return abs(value) def getBoolean(value): 'Get the boolean.' return bool(value) def getDivmod(x, y): 'Get the divmod.' return divmod(x, y) def getFloat(value): 'Get the float.' return float(value) def getHex(value): 'Get the hex.' return hex(value) def getInt(value): 'Get the int.' return int(value) def getLong(value): 'Get the long.' return long(value) def getMax(first, second): 'Get the max.' return max(first, second) def getMin(first, second): 'Get the min.' return min(first, second) def getRound(value): 'Get the round.' return round(value) def getString(value): 'Get the string.' return str(value) globalAccessibleAttributeDictionary = { 'abs' : getAbs, 'boolean' : getBoolean, 'divmod' : getDivmod, 'float' : getFloat, 'hex' : getHex, 'int' : getInt, 'long' : getLong, 'max' : getMax, 'min' : getMin, 'round' : getRound, 'string' : getString} sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/euclid.py000066400000000000000000000063611167321211700334030ustar00rootroot00000000000000""" Boolean geometry utilities. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities.vector3index import Vector3Index from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def _getAccessibleAttribute(attributeName): 'Get the accessible attribute.' if attributeName in globalAccessibleAttributeDictionary: return globalAccessibleAttributeDictionary[attributeName] return None def getComplex(x=0.0, y=0.0): 'Get the complex.' return complex(x, y) def getCylindrical(azimuthDegrees, radius=1.0, z=0.0): 'Get the cylindrical vector3 by degrees.' return getCylindricalByRadians(math.radians(azimuthDegrees), radius, z) def getCylindricalByRadians(azimuthRadians, radius=1.0, z=0.0): 'Get the cylindrical vector3 by radians.' polar = radius * euclidean.getWiddershinsUnitPolar(azimuthRadians) return Vector3(polar.real, polar.imag, z) def getNestedVectorTestExample(x=0.0, y=0.0, z=0.0): 'Get the NestedVectorTestExample.' return NestedVectorTestExample(Vector3(x, y, z)) def getPolar(angleDegrees, radius=1.0): 'Get the complex polar by degrees.' return radius * euclidean.getWiddershinsUnitPolar(math.radians(angleDegrees)) def getPolarByRadians(angleRadians, radius=1.0): 'Get the complex polar by radians.' return radius * euclidean.getWiddershinsUnitPolar(angleRadians) def getSpherical(azimuthDegrees, elevationDegrees, radius=1.0): 'Get the spherical vector3 unit by degrees.' return getSphericalByRadians(math.radians(azimuthDegrees), math.radians(elevationDegrees), radius) def getSphericalByRadians(azimuthRadians, elevationRadians, radius=1.0): 'Get the spherical vector3 unit by radians.' elevationComplex = euclidean.getWiddershinsUnitPolar(elevationRadians) azimuthComplex = euclidean.getWiddershinsUnitPolar(azimuthRadians) * elevationComplex.real return Vector3(azimuthComplex.real, azimuthComplex.imag, elevationComplex.imag) * radius def getVector3(x=0.0, y=0.0, z=0.0): 'Get the vector3.' return Vector3(x, y, z) def getVector3Index(index=0, x=0.0, y=0.0, z=0.0): 'Get the vector3.' return Vector3Index(index, x, y, z) class NestedVectorTestExample: 'Class to test local attribute.' def __init__(self, vector3): 'Get the accessible attribute.' self.vector3 = vector3 def _getAccessibleAttribute(self, attributeName): "Get the accessible attribute." if attributeName == 'vector3': return getattr(self, attributeName, None) return None globalAccessibleAttributeDictionary = { 'complex' : getComplex, 'getCylindrical' : getCylindrical, 'getCylindricalByRadians' : getCylindricalByRadians, 'getPolar' : getPolar, 'getPolarByRadians' : getPolarByRadians, 'getSpherical' : getSpherical, 'getSphericalByRadians' : getSphericalByRadians, 'NestedVectorTestExample' : getNestedVectorTestExample, 'Vector3' : getVector3, 'Vector3Index' : getVector3Index} sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/measure.py000066400000000000000000000050571167321211700336000ustar00rootroot00000000000000""" Boolean geometry utilities. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def _getAccessibleAttribute(attributeName): 'Get the accessible attribute.' if attributeName in globalAccessibleAttributeDictionary: return globalAccessibleAttributeDictionary[attributeName] return None def getBoundingBoxByPaths(elementNode): 'Get bounding box of the transformed paths of the xmlObject of the elementNode.' transformedPaths = elementNode.xmlObject.getTransformedPaths() maximum = euclidean.getMaximumByVector3Paths(transformedPaths) minimum = euclidean.getMinimumByVector3Paths(transformedPaths) return [minimum, maximum] def getCenterByPaths(elementNode): 'Get center of the transformed paths of the xmlObject of the elementNode.' transformedPaths = elementNode.xmlObject.getTransformedPaths() return 0.5 * (euclidean.getMaximumByVector3Paths(transformedPaths) + euclidean.getMinimumByVector3Paths(transformedPaths)) def getExtentByPaths(elementNode): 'Get extent of the transformed paths of the xmlObject of the elementNode.' transformedPaths = elementNode.xmlObject.getTransformedPaths() return euclidean.getMaximumByVector3Paths(transformedPaths) - euclidean.getMinimumByVector3Paths(transformedPaths) def getInradiusByPaths(elementNode): 'Get inradius of the transformed paths of the xmlObject of the elementNode.' return 0.5 * getExtentByPaths(elementNode) def getMinimumByPaths(elementNode): 'Get minimum of the transformed paths of the xmlObject of the elementNode.' return euclidean.getMinimumByVector3Paths(elementNode.xmlObject.getTransformedPaths()) def getMaximumByPaths(elementNode): 'Get maximum of the transformed paths of the xmlObject of the elementNode.' return euclidean.getMaximumByVector3Paths(elementNode.xmlObject.getTransformedPaths()) globalAccessibleAttributeDictionary = { 'getBoundingBoxByPaths' : getBoundingBoxByPaths, 'getCenterByPaths' : getCenterByPaths, 'getExtentByPaths' : getExtentByPaths, 'getInradiusByPaths' : getInradiusByPaths, 'getMaximumByPaths' : getMaximumByPaths, 'getMinimumByPaths' : getMinimumByPaths} sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/evaluate_fundamentals/print.py000066400000000000000000000017301167321211700332650ustar00rootroot00000000000000""" Boolean geometry utilities. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def _getAccessibleAttribute(attributeName): 'Get the accessible attribute.' if attributeName in globalAccessibleAttributeDictionary: return globalAccessibleAttributeDictionary[attributeName] return None def continuous(valueString): 'Print continuous.' sys.stdout.write(str(valueString)) return valueString def line(valueString): 'Print line.' print(valueString) return valueString globalAccessibleAttributeDictionary = {'continuous' : continuous, 'line' : line} sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/example.csv000066400000000000000000000001251167321211700273550ustar00rootroot00000000000000"A" 0 0 2 8 4 0 1 4 3 4 "B" 0 4 2 4 4 5 4 7 3 8 0 8 0 0 3 0 4 1 4 3 2 4 "C" sfact-2011.12.18/fabmetheus_utilities/geometry/geometry_utilities/matrix.py000066400000000000000000000467511167321211700271020ustar00rootroot00000000000000""" Boolean geometry four by four matrix. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import xml_simple_writer import cStringIO import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 300 def addVertexes(geometryOutput, vertexes): 'Add the vertexes.' if geometryOutput.__class__ == list: for element in geometryOutput: addVertexes(element, vertexes) return if geometryOutput.__class__ == dict: for geometryOutputKey in geometryOutput.keys(): if geometryOutputKey == 'vertex': vertexes += geometryOutput[geometryOutputKey] else: addVertexes(geometryOutput[geometryOutputKey], vertexes) def getBranchMatrix(elementNode): 'Get matrix starting from the object if it exists, otherwise get a matrix starting from stratch.' branchMatrix = Matrix() matrixChildElement = elementNode.getFirstChildByLocalName('matrix') if matrixChildElement is not None: branchMatrix = branchMatrix.getFromElementNode(matrixChildElement, '') branchMatrix = branchMatrix.getFromElementNode(elementNode, 'matrix.') if elementNode.xmlObject is None: return branchMatrix elementNodeMatrix = elementNode.xmlObject.getMatrix4X4() if elementNodeMatrix is None: return branchMatrix return elementNodeMatrix.getOtherTimesSelf(branchMatrix.tetragrid) def getBranchMatrixSetElementNode(elementNode): 'Get matrix starting from the object if it exists, otherwise get a matrix starting from stratch.' branchMatrix = getBranchMatrix(elementNode) setElementNodeDictionaryMatrix(elementNode, branchMatrix) return branchMatrix def getCumulativeVector3Remove(defaultVector3, elementNode, prefix): 'Get cumulative vector3 and delete the prefixed attributes.' if prefix == '': defaultVector3.x = evaluate.getEvaluatedFloat(defaultVector3.x, elementNode, 'x') defaultVector3.y = evaluate.getEvaluatedFloat(defaultVector3.y, elementNode, 'y') defaultVector3.z = evaluate.getEvaluatedFloat(defaultVector3.z, elementNode, 'z') euclidean.removeElementsFromDictionary(elementNode.attributes, ['x', 'y', 'z']) prefix = 'cartesian' defaultVector3 = evaluate.getVector3ByPrefix(defaultVector3, elementNode, prefix) euclidean.removePrefixFromDictionary(elementNode.attributes, prefix) return defaultVector3 def getDiagonalSwitchedTetragrid(angleDegrees, diagonals): 'Get the diagonals and switched matrix by degrees.' return getDiagonalSwitchedTetragridByRadians(math.radians(angleDegrees), diagonals) def getDiagonalSwitchedTetragridByPolar(diagonals, unitPolar): 'Get the diagonals and switched matrix by unitPolar.' diagonalSwitchedTetragrid = getIdentityTetragrid() for diagonal in diagonals: diagonalSwitchedTetragrid[diagonal][diagonal] = unitPolar.real diagonalSwitchedTetragrid[diagonals[0]][diagonals[1]] = -unitPolar.imag diagonalSwitchedTetragrid[diagonals[1]][diagonals[0]] = unitPolar.imag return diagonalSwitchedTetragrid def getDiagonalSwitchedTetragridByRadians(angleRadians, diagonals): 'Get the diagonals and switched matrix by radians.' return getDiagonalSwitchedTetragridByPolar(diagonals, euclidean.getWiddershinsUnitPolar(angleRadians)) def getIdentityTetragrid(tetragrid=None): 'Get four by four matrix with diagonal elements set to one.' if tetragrid is None: return [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]] return tetragrid def getIsIdentityTetragrid(tetragrid): 'Determine if the tetragrid is the identity tetragrid.' for column in xrange(4): for row in xrange(4): if column == row: if tetragrid[column][row] != 1.0: return False elif tetragrid[column][row] != 0.0: return False return True def getIsIdentityTetragridOrNone(tetragrid): 'Determine if the tetragrid is None or if it is the identity tetragrid.' if tetragrid == None: return True return getIsIdentityTetragrid(tetragrid) def getKeyA(row, column, prefix=''): 'Get the a format key string from row & column, counting from zero.' return '%sa%s%s' % (prefix, row, column) def getKeyM(row, column, prefix=''): 'Get the m format key string from row & column, counting from one.' return '%sm%s%s' % (prefix, row + 1, column + 1) def getKeysA(prefix=''): 'Get the matrix keys, counting from zero.' keysA = [] for row in xrange(4): for column in xrange(4): key = getKeyA(row, column, prefix) keysA.append(key) return keysA def getKeysM(prefix=''): 'Get the matrix keys, counting from one.' keysM = [] for row in xrange(4): for column in xrange(4): key = getKeyM(row, column, prefix) keysM.append(key) return keysM def getRemovedFloat(defaultFloat, elementNode, key, prefix): 'Get the float by the key and the prefix.' prefixKey = prefix + key if prefixKey in elementNode.attributes: floatValue = evaluate.getEvaluatedFloat(None, elementNode, prefixKey) if floatValue is None: print('Warning, evaluated value in getRemovedFloatByKeys in matrix is None for key:') print(prefixKey) print('for elementNode dictionary value:') print(elementNode.attributes[prefixKey]) print('for elementNode dictionary:') print(elementNode.attributes) else: defaultFloat = floatValue del elementNode.attributes[prefixKey] return defaultFloat def getRemovedFloatByKeys(defaultFloat, elementNode, keys, prefix): 'Get the float by the keys and the prefix.' for key in keys: defaultFloat = getRemovedFloat(defaultFloat, elementNode, key, prefix) return defaultFloat def getRotateAroundAxisTetragrid(elementNode, prefix): 'Get rotate around axis tetragrid and delete the axis and angle attributes.' angle = getRemovedFloatByKeys(0.0, elementNode, ['angle', 'counterclockwise'], prefix) angle -= getRemovedFloat(0.0, elementNode, 'clockwise', prefix) if angle == 0.0: return None angleRadians = math.radians(angle) axis = getCumulativeVector3Remove(Vector3(), elementNode, prefix + 'axis') axisLength = abs(axis) if axisLength <= 0.0: print('Warning, axisLength was zero in getRotateAroundAxisTetragrid in matrix so nothing will be done for:') print(elementNode) return None axis /= axisLength tetragrid = getIdentityTetragrid() cosAngle = math.cos(angleRadians) sinAngle = math.sin(angleRadians) oneMinusCos = 1.0 - math.cos(angleRadians) xx = axis.x * axis.x xy = axis.x * axis.y xz = axis.x * axis.z yy = axis.y * axis.y yz = axis.y * axis.z zz = axis.z * axis.z tetragrid[0] = [cosAngle + xx * oneMinusCos, xy * oneMinusCos - axis.z * sinAngle, xz * oneMinusCos + axis.y * sinAngle, 0.0] tetragrid[1] = [xy * oneMinusCos + axis.z * sinAngle, cosAngle + yy * oneMinusCos, yz * oneMinusCos - axis.x * sinAngle, 0.0] tetragrid[2] = [xz * oneMinusCos - axis.y * sinAngle, yz * oneMinusCos + axis.x * sinAngle, cosAngle + zz * oneMinusCos, 0.0] return tetragrid def getRotateTetragrid(elementNode, prefix): 'Get rotate tetragrid and delete the rotate attributes.' # http://en.wikipedia.org/wiki/Rotation_matrix rotateMatrix = Matrix() rotateMatrix.tetragrid = getRotateAroundAxisTetragrid(elementNode, prefix) zAngle = getRemovedFloatByKeys(0.0, elementNode, ['axisclockwisez', 'observerclockwisez', 'z'], prefix) zAngle -= getRemovedFloatByKeys(0.0, elementNode, ['axiscounterclockwisez', 'observercounterclockwisez'], prefix) if zAngle != 0.0: rotateMatrix.tetragrid = getTetragridTimesOther(getDiagonalSwitchedTetragrid(-zAngle, [0, 1]), rotateMatrix.tetragrid) xAngle = getRemovedFloatByKeys(0.0, elementNode, ['axisclockwisex', 'observerclockwisex', 'x'], prefix) xAngle -= getRemovedFloatByKeys(0.0, elementNode, ['axiscounterclockwisex', 'observercounterclockwisex'], prefix) if xAngle != 0.0: rotateMatrix.tetragrid = getTetragridTimesOther(getDiagonalSwitchedTetragrid(-xAngle, [1, 2]), rotateMatrix.tetragrid) yAngle = getRemovedFloatByKeys(0.0, elementNode, ['axiscounterclockwisey', 'observerclockwisey', 'y'], prefix) yAngle -= getRemovedFloatByKeys(0.0, elementNode, ['axisclockwisey', 'observercounterclockwisey'], prefix) if yAngle != 0.0: rotateMatrix.tetragrid = getTetragridTimesOther(getDiagonalSwitchedTetragrid(yAngle, [0, 2]), rotateMatrix.tetragrid) return rotateMatrix.tetragrid def getScaleTetragrid(elementNode, prefix): 'Get scale matrix and delete the scale attributes.' scaleDefaultVector3 = Vector3(1.0, 1.0, 1.0) scale = getCumulativeVector3Remove(scaleDefaultVector3.copy(), elementNode, prefix) if scale == scaleDefaultVector3: return None return [[scale.x, 0.0, 0.0, 0.0], [0.0, scale.y, 0.0, 0.0], [0.0, 0.0, scale.z, 0.0], [0.0, 0.0, 0.0, 1.0]] def getTetragridA(elementNode, prefix, tetragrid): 'Get the tetragrid from the elementNode letter a values.' keysA = getKeysA(prefix) evaluatedDictionary = evaluate.getEvaluatedDictionaryByEvaluationKeys(elementNode, keysA) if len(evaluatedDictionary.keys()) < 1: return tetragrid for row in xrange(4): for column in xrange(4): key = getKeyA(row, column, prefix) if key in evaluatedDictionary: value = evaluatedDictionary[key] if value is None or value == 'None': print('Warning, value in getTetragridA in matrix is None for key for dictionary:') print(key) print(evaluatedDictionary) else: tetragrid = getIdentityTetragrid(tetragrid) tetragrid[row][column] = float(value) euclidean.removeElementsFromDictionary(elementNode.attributes, keysA) return tetragrid def getTetragridC(elementNode, prefix, tetragrid): 'Get the matrix Tetragrid from the elementNode letter c values.' columnKeys = 'Pc1 Pc2 Pc3 Pc4'.replace('P', prefix).split() evaluatedDictionary = evaluate.getEvaluatedDictionaryByEvaluationKeys(elementNode, columnKeys) if len(evaluatedDictionary.keys()) < 1: return tetragrid for columnKeyIndex, columnKey in enumerate(columnKeys): if columnKey in evaluatedDictionary: value = evaluatedDictionary[columnKey] if value is None or value == 'None': print('Warning, value in getTetragridC in matrix is None for columnKey for dictionary:') print(columnKey) print(evaluatedDictionary) else: tetragrid = getIdentityTetragrid(tetragrid) for elementIndex, element in enumerate(value): tetragrid[elementIndex][columnKeyIndex] = element euclidean.removeElementsFromDictionary(elementNode.attributes, columnKeys) return tetragrid def getTetragridCopy(tetragrid): 'Get tetragrid copy.' if tetragrid == None: return None tetragridCopy = [] for tetragridRow in tetragrid: tetragridCopy.append(tetragridRow[:]) return tetragridCopy def getTetragridM(elementNode, prefix, tetragrid): 'Get the tetragrid from the elementNode letter m values.' keysM = getKeysM(prefix) evaluatedDictionary = evaluate.getEvaluatedDictionaryByEvaluationKeys(elementNode, keysM) if len(evaluatedDictionary.keys()) < 1: return tetragrid for row in xrange(4): for column in xrange(4): key = getKeyM(row, column, prefix) if key in evaluatedDictionary: value = evaluatedDictionary[key] if value is None or value == 'None': print('Warning, value in getTetragridM in matrix is None for key for dictionary:') print(key) print(evaluatedDictionary) else: tetragrid = getIdentityTetragrid(tetragrid) tetragrid[row][column] = float(value) euclidean.removeElementsFromDictionary(elementNode.attributes, keysM) return tetragrid def getTetragridMatrix(elementNode, prefix, tetragrid): 'Get the tetragrid from the elementNode matrix value.' matrixKey = prefix + 'matrix' evaluatedDictionary = evaluate.getEvaluatedDictionaryByEvaluationKeys(elementNode, [matrixKey]) if len(evaluatedDictionary.keys()) < 1: return tetragrid value = evaluatedDictionary[matrixKey] if value is None or value == 'None': print('Warning, value in getTetragridMatrix in matrix is None for matrixKey for dictionary:') print(matrixKey) print(evaluatedDictionary) else: tetragrid = getIdentityTetragrid(tetragrid) for rowIndex, row in enumerate(value): for elementIndex, element in enumerate(row): tetragrid[rowIndex][elementIndex] = element euclidean.removeElementsFromDictionary(elementNode.attributes, [matrixKey]) return tetragrid def getTetragridR(elementNode, prefix, tetragrid): 'Get the tetragrid from the elementNode letter r values.' rowKeys = 'Pr1 Pr2 Pr3 Pr4'.replace('P', prefix).split() evaluatedDictionary = evaluate.getEvaluatedDictionaryByEvaluationKeys(elementNode, rowKeys) if len(evaluatedDictionary.keys()) < 1: return tetragrid for rowKeyIndex, rowKey in enumerate(rowKeys): if rowKey in evaluatedDictionary: value = evaluatedDictionary[rowKey] if value is None or value == 'None': print('Warning, value in getTetragridR in matrix is None for rowKey for dictionary:') print(rowKey) print(evaluatedDictionary) else: tetragrid = getIdentityTetragrid(tetragrid) for elementIndex, element in enumerate(value): tetragrid[rowKeyIndex][elementIndex] = element euclidean.removeElementsFromDictionary(elementNode.attributes, rowKeys) return tetragrid def getTetragridTimesOther(firstTetragrid, otherTetragrid ): 'Get this matrix multiplied by the other matrix.' #A down, B right from http://en.wikipedia.org/wiki/Matrix_multiplication if firstTetragrid is None: return otherTetragrid if otherTetragrid is None: return firstTetragrid tetragridTimesOther = [] for row in xrange(4): matrixRow = firstTetragrid[row] tetragridTimesOtherRow = [] tetragridTimesOther.append(tetragridTimesOtherRow) for column in xrange(4): dotProduct = 0 for elementIndex in xrange(4): dotProduct += matrixRow[elementIndex] * otherTetragrid[elementIndex][column] tetragridTimesOtherRow.append(dotProduct) return tetragridTimesOther def getTransformedByList(floatList, point): 'Get the point transformed by the array.' return floatList[0] * point.x + floatList[1] * point.y + floatList[2] * point.z + floatList[3] def getTransformedVector3(tetragrid, vector3): 'Get the vector3 multiplied by a matrix.' if getIsIdentityTetragridOrNone(tetragrid): return vector3.copy() return getTransformedVector3Blindly(tetragrid, vector3) def getTransformedVector3Blindly(tetragrid, vector3): 'Get the vector3 multiplied by a tetragrid without checking if the tetragrid exists.' return Vector3( getTransformedByList(tetragrid[0], vector3), getTransformedByList(tetragrid[1], vector3), getTransformedByList(tetragrid[2], vector3)) def getTransformedVector3s(tetragrid, vector3s): 'Get the vector3s multiplied by a matrix.' if getIsIdentityTetragridOrNone(tetragrid): return euclidean.getPathCopy(vector3s) transformedVector3s = [] for vector3 in vector3s: transformedVector3s.append(getTransformedVector3Blindly(tetragrid, vector3)) return transformedVector3s def getTransformTetragrid(elementNode, prefix): 'Get the tetragrid from the elementNode.' tetragrid = getTetragridA(elementNode, prefix, None) tetragrid = getTetragridC(elementNode, prefix, tetragrid) tetragrid = getTetragridM(elementNode, prefix, tetragrid) tetragrid = getTetragridMatrix(elementNode, prefix, tetragrid) tetragrid = getTetragridR(elementNode, prefix, tetragrid) return tetragrid def getTranslateTetragrid(elementNode, prefix): 'Get translate matrix and delete the translate attributes.' translation = getCumulativeVector3Remove(Vector3(), elementNode, prefix) if translation.getIsDefault(): return None return getTranslateTetragridByTranslation(translation) def getTranslateTetragridByTranslation(translation): 'Get translate tetragrid by translation.' return [[1.0, 0.0, 0.0, translation.x], [0.0, 1.0, 0.0, translation.y], [0.0, 0.0, 1.0, translation.z], [0.0, 0.0, 0.0, 1.0]] def getVertexes(geometryOutput): 'Get the vertexes.' vertexes = [] addVertexes(geometryOutput, vertexes) return vertexes def setAttributesToMultipliedTetragrid(elementNode, tetragrid): 'Set the element attribute dictionary and element matrix to the matrix times the tetragrid.' setElementNodeDictionaryMatrix(elementNode, getBranchMatrix(elementNode).getOtherTimesSelf(tetragrid)) def setElementNodeDictionaryMatrix(elementNode, matrix4X4): 'Set the element attribute dictionary or element matrix to the matrix.' if elementNode.xmlObject is None: elementNode.attributes.update(matrix4X4.getAttributes('matrix.')) else: elementNode.xmlObject.matrix4X4 = matrix4X4 def transformVector3Blindly(tetragrid, vector3): 'Transform the vector3 by a tetragrid without checking to see if it exists.' x = getTransformedByList(tetragrid[0], vector3) y = getTransformedByList(tetragrid[1], vector3) z = getTransformedByList(tetragrid[2], vector3) vector3.x = x vector3.y = y vector3.z = z def transformVector3ByMatrix(tetragrid, vector3): 'Transform the vector3 by a matrix.' if getIsIdentityTetragridOrNone(tetragrid): return transformVector3Blindly(tetragrid, vector3) def transformVector3sByMatrix(tetragrid, vector3s): 'Transform the vector3s by a matrix.' if getIsIdentityTetragridOrNone(tetragrid): return for vector3 in vector3s: transformVector3Blindly(tetragrid, vector3) class Matrix: 'A four by four matrix.' def __init__(self, tetragrid=None): 'Add empty lists.' self.tetragrid = getTetragridCopy(tetragrid) def __eq__(self, other): 'Determine whether this matrix is identical to other one.' if other is None: return False if other.__class__ != self.__class__: return False return other.tetragrid == self.tetragrid def __ne__(self, other): 'Determine whether this vector is not identical to other one.' return not self.__eq__(other) def __repr__(self): 'Get the string representation of this four by four matrix.' output = cStringIO.StringIO() self.addXML(0, output) return output.getvalue() def addXML(self, depth, output): 'Add xml for this object.' attributes = self.getAttributes() if len(attributes) > 0: xml_simple_writer.addClosedXMLTag(attributes, depth, self.__class__.__name__.lower(), output) def getAttributes(self, prefix=''): 'Get the attributes from row column attribute strings, counting from one.' attributes = {} if self.tetragrid is None: return attributes for row in xrange(4): for column in xrange(4): default = float(column == row) value = self.tetragrid[row][column] if abs( value - default ) > 0.00000000000001: if abs(value) < 0.00000000000001: value = 0.0 attributes[prefix + getKeyM(row, column)] = value return attributes def getFromElementNode(self, elementNode, prefix): 'Get the values from row column attribute strings, counting from one.' attributes = elementNode.attributes if attributes is None: return self self.tetragrid = getTetragridTimesOther(getTransformTetragrid(elementNode, prefix), self.tetragrid) self.tetragrid = getTetragridTimesOther(getScaleTetragrid(elementNode, 'scale.'), self.tetragrid) self.tetragrid = getTetragridTimesOther(getRotateTetragrid(elementNode, 'rotate.'), self.tetragrid) self.tetragrid = getTetragridTimesOther(getTranslateTetragrid(elementNode, 'translate.'), self.tetragrid) return self def getOtherTimesSelf(self, otherTetragrid): 'Get this matrix reverse multiplied by the other matrix.' return Matrix(getTetragridTimesOther(otherTetragrid, self.tetragrid)) def getSelfTimesOther(self, otherTetragrid): 'Get this matrix multiplied by the other matrix.' return Matrix(getTetragridTimesOther(self.tetragrid, otherTetragrid)) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_matrix/000077500000000000000000000000001167321211700253455ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_matrix/__init__.py000066400000000000000000000006571167321211700274660ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_matrix/_scale.py000066400000000000000000000042761167321211700271560ustar00rootroot00000000000000""" Boolean geometry scale. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 340 def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): "Get equated geometryOutput." scalePoints( elementNode, matrix.getVertexes(geometryOutput), prefix ) return geometryOutput def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get equated paths." scalePoints( elementNode, loop, prefix ) return [loop] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return ScaleDerivation(elementNode) def manipulateElementNode(elementNode, target): "Manipulate the xml element." derivation = ScaleDerivation(elementNode) if derivation.scaleTetragrid == None: print('Warning, scaleTetragrid was None in scale so nothing will be done for:') print(elementNode) return matrix.setAttributesToMultipliedTetragrid(target, derivation.scaleTetragrid) def processElementNode(elementNode): "Process the xml element." solid.processElementNodeByFunction(elementNode, manipulateElementNode) def scalePoints(elementNode, points, prefix): "Scale the points." scaleVector3Default = Vector3(1.0, 1.0, 1.0) scaleVector3 = matrix.getCumulativeVector3Remove(scaleVector3Default.copy(), elementNode, prefix) if scaleVector3 == scaleVector3Default: return for point in points: point.x *= scaleVector3.x point.y *= scaleVector3.y point.z *= scaleVector3.z class ScaleDerivation: "Class to hold scale variables." def __init__(self, elementNode): 'Set defaults.' self.scaleTetragrid = matrix.getScaleTetragrid(elementNode, '') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_matrix/rotate.py000066400000000000000000000044161167321211700272220ustar00rootroot00000000000000""" Boolean geometry rotate. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 360 def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): 'Get equated geometryOutput.' rotatePoints(elementNode, matrix.getVertexes(geometryOutput), prefix) return geometryOutput def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): 'Get equated paths.' rotatePoints(elementNode, loop, prefix) return [loop] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return RotateDerivation(elementNode, prefix) def manipulateElementNode(elementNode, target): 'Manipulate the xml element.' derivation = RotateDerivation(elementNode, '') if derivation.rotateTetragrid == None: print('Warning, rotateTetragrid was None in rotate so nothing will be done for:') print(elementNode) return matrix.setAttributesToMultipliedTetragrid(target, derivation.rotateTetragrid) def processElementNode(elementNode): 'Process the xml element.' solid.processElementNodeByFunction(elementNode, manipulateElementNode) def rotatePoints(elementNode, points, prefix): 'Rotate the points.' derivation = RotateDerivation(elementNode, prefix) if derivation.rotateTetragrid == None: print('Warning, rotateTetragrid was None in rotate so nothing will be done for:') print(elementNode) return matrix.transformVector3sByMatrix(derivation.rotateTetragrid, points) class RotateDerivation: "Class to hold rotate variables." def __init__(self, elementNode, prefix): 'Set defaults.' self.rotateTetragrid = matrix.getRotateTetragrid(elementNode, prefix) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_matrix/transform.py000066400000000000000000000045121167321211700277340ustar00rootroot00000000000000""" Boolean geometry transform. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 320 def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): 'Get equated geometryOutput.' transformPoints(elementNode, matrix.getVertexes(geometryOutput), prefix) return geometryOutput def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): 'Get equated paths.' transformPoints(elementNode, loop, prefix) return [loop] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return TransformDerivation(elementNode, prefix) def manipulateElementNode(elementNode, target): 'Manipulate the xml element.' derivation = TransformDerivation(elementNode, '') if derivation.transformTetragrid == None: print('Warning, transformTetragrid was None in transform so nothing will be done for:') print(elementNode) return matrix.setAttributesToMultipliedTetragrid(target, derivation.transformTetragrid) def processElementNode(elementNode): 'Process the xml element.' solid.processElementNodeByFunction(elementNode, manipulateElementNode) def transformPoints(elementNode, points, prefix): 'Transform the points.' derivation = TransformDerivation(elementNode, prefix) if derivation.transformTetragrid == None: print('Warning, transformTetragrid was None in transform so nothing will be done for:') print(elementNode) return matrix.transformVector3sByMatrix(derivation.transformTetragrid, points) class TransformDerivation: "Class to hold transform variables." def __init__(self, elementNode, prefix): 'Set defaults.' self.transformTetragrid = matrix.getTransformTetragrid(elementNode, prefix) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_matrix/translate.py000066400000000000000000000046031167321211700277170ustar00rootroot00000000000000""" Boolean geometry translation. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 380 def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): "Get equated geometryOutput." translatePoints(elementNode, matrix.getVertexes(geometryOutput), prefix) return geometryOutput def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get equated paths." translatePoints(elementNode, loop, prefix) return [loop] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return TranslateDerivation(elementNode) def manipulateElementNode(elementNode, target): "Manipulate the xml element." derivation = TranslateDerivation(elementNode) if derivation.translateTetragrid == None: print('Warning, translateTetragrid was None in translate so nothing will be done for:') print(elementNode) return matrix.setAttributesToMultipliedTetragrid(target, derivation.translateTetragrid) def processElementNode(elementNode): "Process the xml element." solid.processElementNodeByFunction(elementNode, manipulateElementNode) def translateNegativesPositives(negatives, positives, translation): 'Translate the negatives and postives.' euclidean.translateVector3Path(matrix.getVertexes(negatives), translation) euclidean.translateVector3Path(matrix.getVertexes(positives), translation) def translatePoints(elementNode, points, prefix): "Translate the points." translateVector3 = matrix.getCumulativeVector3Remove(Vector3(), elementNode, prefix) if abs(translateVector3) > 0.0: euclidean.translateVector3Path(points, translateVector3) class TranslateDerivation: "Class to hold translate variables." def __init__(self, elementNode): 'Set defaults.' self.translateTetragrid = matrix.getTranslateTetragrid(elementNode, '') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_meta/000077500000000000000000000000001167321211700247675ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_meta/__init__.py000066400000000000000000000006571167321211700271100ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_meta/_array.py000066400000000000000000000126031167321211700266200ustar00rootroot00000000000000""" Boolean geometry array. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import vertex from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addPathToGroup(derivation, groupDictionaryCopy, path, targetMatrix, totalIndex): 'Add path to the array group.' for pointIndex, point in enumerate(path): arrayElement = derivation.target.getCopy(derivation.elementNode.getIDSuffix(totalIndex), derivation.elementNode) arrayDictionary = arrayElement.attributes arrayDictionary['visible'] = str(derivation.visible).lower() arrayDictionary.update(groupDictionaryCopy) euclidean.removeTrueFromDictionary(arrayDictionary, 'visible') vertexMatrix = matrix.Matrix(matrix.getTranslateTetragridByTranslation(point)) zAngle = totalIndex * 50.0 rotationMatrix = getRotationMatrix(arrayDictionary, derivation, path, point, pointIndex) arrayElementMatrix = vertexMatrix.getSelfTimesOther(rotationMatrix.getSelfTimesOther(targetMatrix.tetragrid).tetragrid) arrayDictionary.update(arrayElementMatrix.getAttributes('matrix.')) arrayDictionary['_arrayIndex'] = totalIndex arrayDictionary['_arrayPoint'] = point totalIndex += 1 def getNewDerivation(elementNode): 'Get new derivation.' return ArrayDerivation(elementNode) def getRotationMatrix(arrayDictionary, derivation, path, point, pointIndex): 'Get rotationMatrix.' if len(path) < 2 or not derivation.track: return matrix.Matrix() point = point.dropAxis() begin = path[(pointIndex + len(path) - 1) % len(path)].dropAxis() end = path[(pointIndex + 1) % len(path)].dropAxis() pointMinusBegin = point - begin pointMinusBeginLength = abs(pointMinusBegin) endMinusPoint = end - point endMinusPointLength = abs(endMinusPoint) if not derivation.closed: if pointIndex == 0 and endMinusPointLength > 0.0: return getRotationMatrixByPolar(arrayDictionary, endMinusPoint, endMinusPointLength) elif pointIndex == len(path) - 1 and pointMinusBeginLength > 0.0: return getRotationMatrixByPolar(arrayDictionary, pointMinusBegin, pointMinusBeginLength) if pointMinusBeginLength <= 0.0: print('Warning, point equals previous point in getRotationMatrix in array for:') print(path) print(pointIndex) print(derivation.elementNode) return matrix.Matrix() pointMinusBegin /= pointMinusBeginLength if endMinusPointLength <= 0.0: print('Warning, point equals next point in getRotationMatrix in array for:') print(path) print(pointIndex) print(derivation.elementNode) return matrix.Matrix() endMinusPoint /= endMinusPointLength averagePolar = pointMinusBegin + endMinusPoint averagePolarLength = abs(averagePolar) if averagePolarLength <= 0.0: print('Warning, averagePolarLength is zero in getRotationMatrix in array for:') print(path) print(pointIndex) print(derivation.elementNode) return matrix.Matrix() return getRotationMatrixByPolar(arrayDictionary, averagePolar, averagePolarLength) def getRotationMatrixByPolar(arrayDictionary, polar, polarLength): 'Get rotationMatrix by polar and polarLength.' polar /= polarLength arrayDictionary['_arrayRotation'] = math.degrees(math.atan2(polar.imag, polar.real)) return matrix.Matrix(matrix.getDiagonalSwitchedTetragridByPolar([0, 1], polar)) def processElementNode(elementNode): "Process the xml element." processElementNodeByDerivation(None, elementNode) def processElementNodeByDerivation(derivation, elementNode): 'Process the xml element by derivation.' if derivation is None: derivation = ArrayDerivation(elementNode) if derivation.target is None: print('Warning, array could not get target for:') print(elementNode) return if len(derivation.paths) < 1: print('Warning, array could not get paths for:') print(elementNode) return groupDictionaryCopy = elementNode.attributes.copy() euclidean.removeElementsFromDictionary(groupDictionaryCopy, ['closed', 'paths', 'target', 'track', 'vertexes']) evaluate.removeIdentifiersFromDictionary(groupDictionaryCopy) targetMatrix = matrix.getBranchMatrixSetElementNode(derivation.target) elementNode.localName = 'group' totalIndex = 0 for path in derivation.paths: addPathToGroup(derivation, groupDictionaryCopy, path, targetMatrix, totalIndex) elementNode.getXMLProcessor().processElementNode(elementNode) class ArrayDerivation: "Class to hold array variables." def __init__(self, elementNode): 'Set defaults.' self.closed = evaluate.getEvaluatedBoolean(True, elementNode, 'closed') self.elementNode = elementNode self.paths = evaluate.getTransformedPathsByKey([], elementNode, 'paths') vertexTargets = evaluate.getElementNodesByKey(elementNode, 'vertexes') for vertexTarget in vertexTargets: self.paths.append(vertexTarget.getVertexes()) self.target = evaluate.getElementNodeByKey(elementNode, 'target') self.track = evaluate.getEvaluatedBoolean(True, elementNode, 'track') self.visible = evaluate.getEvaluatedBoolean(True, elementNode, 'visible') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_meta/_carve.py000066400000000000000000000076711167321211700266130ustar00rootroot00000000000000""" Boolean geometry carve. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities import euclidean from fabmetheus_utilities import xml_simple_reader __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getLinkedElementNode(idSuffix, parentNode, target): 'Get elementNode with identifiers and parentNode.' linkedElementNode = xml_simple_reader.ElementNode() euclidean.overwriteDictionary(target.attributes, ['id', 'name', 'quantity'], linkedElementNode.attributes) linkedElementNode.addSuffixToID(idSuffix) tagKeys = target.getTagKeys() tagKeys.append('carve') tagKeys.sort() tags = ', '.join(tagKeys) linkedElementNode.attributes['tags'] = tags linkedElementNode.setParentAddToChildNodes(parentNode) linkedElementNode.addToIdentifierDictionaries() return linkedElementNode def getNewDerivation(elementNode): 'Get new derivation.' return CarveDerivation(elementNode) def processElementNode(elementNode): 'Process the xml element.' processElementNodeByDerivation(None, elementNode) def processElementNodeByDerivation(derivation, elementNode): 'Process the xml element by derivation.' if derivation is None: derivation = CarveDerivation(elementNode) targetElementNode = derivation.targetElementNode if targetElementNode is None: print('Warning, carve could not get target for:') print(elementNode) return xmlObject = targetElementNode.xmlObject if xmlObject is None: print('Warning, processElementNodeByDerivation in carve could not get xmlObject for:') print(targetElementNode) print(derivation.elementNode) return matrix.getBranchMatrixSetElementNode(targetElementNode) transformedVertexes = xmlObject.getTransformedVertexes() if len(transformedVertexes) < 1: print('Warning, transformedVertexes is zero in processElementNodeByDerivation in carve for:') print(xmlObject) print(targetElementNode) print(derivation.elementNode) return elementNode.localName = 'group' elementNode.getXMLProcessor().processElementNode(elementNode) minimumZ = boolean_geometry.getMinimumZ(xmlObject) maximumZ = euclidean.getTopPath(transformedVertexes) zoneArrangement = triangle_mesh.ZoneArrangement(derivation.layerThickness, transformedVertexes) oldVisibleString = targetElementNode.attributes['visible'] targetElementNode.attributes['visible'] = True z = minimumZ + 0.5 * derivation.layerThickness loopLayers = boolean_geometry.getLoopLayers([xmlObject], derivation.importRadius, derivation.layerThickness, maximumZ, False, z, zoneArrangement) targetElementNode.attributes['visible'] = oldVisibleString for loopLayerIndex, loopLayer in enumerate(loopLayers): if len(loopLayer.loops) > 0: pathElement = getLinkedElementNode('_carve_%s' % loopLayerIndex, elementNode, targetElementNode) vector3Loops = euclidean.getVector3Paths(loopLayer.loops, loopLayer.z) path.convertElementNode(pathElement, vector3Loops) class CarveDerivation: "Class to hold carve variables." def __init__(self, elementNode): 'Set defaults.' self.elementNode = elementNode self.importRadius = setting.getImportRadius(elementNode) self.layerThickness = setting.getLayerThickness(elementNode) self.targetElementNode = evaluate.getElementNodeByKey(elementNode, 'target') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_meta/_copy.py000066400000000000000000000055051167321211700264570ustar00rootroot00000000000000""" Boolean geometry copy. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewDerivation(elementNode): 'Get new derivation.' return CopyDerivation(elementNode) def processElementNode(elementNode): 'Process the xml element.' processElementNodeByDerivation(None, elementNode) def processElementNodeByDerivation(derivation, elementNode): 'Process the xml element by derivation.' if derivation is None: derivation = CopyDerivation(elementNode) if derivation.target is None: print('Warning, copy could not get target for:') print(elementNode) return del elementNode.attributes['target'] copyMatrix = matrix.getBranchMatrixSetElementNode(elementNode) targetMatrix = matrix.getBranchMatrixSetElementNode(derivation.target) targetDictionaryCopy = evaluate.removeIdentifiersFromDictionary(derivation.target.attributes.copy()) targetDictionaryCopy.update(elementNode.attributes) elementNode.attributes = targetDictionaryCopy euclidean.removeTrueFromDictionary(elementNode.attributes, 'visible') elementNode.localName = derivation.target.localName derivation.target.copyXMLChildNodes(elementNode.getIDSuffix(), elementNode) elementNode.getXMLProcessor().processElementNode(elementNode) if copyMatrix is not None and targetMatrix is not None: elementNode.xmlObject.matrix4X4 = copyMatrix.getSelfTimesOther(targetMatrix.tetragrid) if elementNode.xmlObject == None: return if len(elementNode.xmlObject.getPaths()) > 0: lineation.processElementNode(elementNode) return geometryOutput = elementNode.xmlObject.getGeometryOutput() if geometryOutput == None: return solidMatchingPlugins = solid.getSolidMatchingPlugins(elementNode) if len(solidMatchingPlugins) == 0: return geometryOutput = solid.getGeometryOutputByManipulation(elementNode, geometryOutput) elementNode.xmlObject.transformGeometryOutput(geometryOutput) lineation.removeChildNodesFromElementObject(elementNode) elementNode.getXMLProcessor().convertElementNode(elementNode, geometryOutput) class CopyDerivation: "Class to hold copy variables." def __init__(self, elementNode): 'Set defaults.' self.target = evaluate.getElementNodeByKey(elementNode, 'target') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_meta/disjoin.py000066400000000000000000000121411167321211700267770ustar00rootroot00000000000000""" Boolean geometry disjoin. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import path from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.geometry.solids import difference from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities import euclidean from fabmetheus_utilities import xml_simple_reader from fabmetheus_utilities.vector3 import Vector3 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getLinkedElementNode(idSuffix, parentNode, target): 'Get elementNode with identifiers and parentNode.' linkedElementNode = xml_simple_reader.ElementNode() euclidean.overwriteDictionary(target.attributes, ['id', 'name', 'quantity'], linkedElementNode.attributes) linkedElementNode.addSuffixToID(idSuffix) tagKeys = target.getTagKeys() tagKeys.append('disjoin') tagKeys.sort() tags = ', '.join(tagKeys) linkedElementNode.attributes['tags'] = tags linkedElementNode.setParentAddToChildNodes(parentNode) linkedElementNode.addToIdentifierDictionaries() return linkedElementNode def getNewDerivation(elementNode): 'Get new derivation.' return DisjoinDerivation(elementNode) def processElementNode(elementNode): 'Process the xml element.' processElementNodeByDerivation(None, elementNode) def processElementNodeByDerivation(derivation, elementNode): 'Process the xml element by derivation.' if derivation is None: derivation = DisjoinDerivation(elementNode) targetElementNode = derivation.targetElementNode if targetElementNode is None: print('Warning, disjoin could not get target for:') print(elementNode) return xmlObject = targetElementNode.xmlObject if xmlObject is None: print('Warning, processElementNodeByDerivation in disjoin could not get xmlObject for:') print(targetElementNode) print(derivation.elementNode) return matrix.getBranchMatrixSetElementNode(targetElementNode) transformedVertexes = xmlObject.getTransformedVertexes() if len(transformedVertexes) < 1: print('Warning, transformedVertexes is zero in processElementNodeByDerivation in disjoin for:') print(xmlObject) print(targetElementNode) print(derivation.elementNode) return elementNode.localName = 'group' elementNode.getXMLProcessor().processElementNode(elementNode) targetChainMatrix = matrix.Matrix(xmlObject.getMatrixChainTetragrid()) minimumZ = boolean_geometry.getMinimumZ(xmlObject) z = minimumZ + 0.5 * derivation.sheetThickness zoneArrangement = triangle_mesh.ZoneArrangement(derivation.layerThickness, transformedVertexes) oldVisibleString = targetElementNode.attributes['visible'] targetElementNode.attributes['visible'] = True loops = boolean_geometry.getEmptyZLoops([xmlObject], derivation.importRadius, False, z, zoneArrangement) targetElementNode.attributes['visible'] = oldVisibleString vector3Loops = euclidean.getVector3Paths(loops, z) pathElement = getLinkedElementNode('_sheet', elementNode, targetElementNode) path.convertElementNode(pathElement, vector3Loops) targetOutput = xmlObject.getGeometryOutput() differenceElement = getLinkedElementNode('_solid', elementNode, targetElementNode) targetElementCopy = targetElementNode.getCopy('_positive', differenceElement) targetElementCopy.attributes['visible'] = True targetElementCopy.attributes.update(targetChainMatrix.getAttributes('matrix.')) complexMaximum = euclidean.getMaximumByVector3Path(transformedVertexes).dropAxis() complexMinimum = euclidean.getMinimumByVector3Path(transformedVertexes).dropAxis() centerComplex = 0.5 * (complexMaximum + complexMinimum) centerVector3 = Vector3(centerComplex.real, centerComplex.imag, minimumZ) slightlyMoreThanHalfExtent = 0.501 * (complexMaximum - complexMinimum) inradius = Vector3(slightlyMoreThanHalfExtent.real, slightlyMoreThanHalfExtent.imag, derivation.sheetThickness) cubeElement = xml_simple_reader.ElementNode() cubeElement.attributes['inradius'] = str(inradius) if not centerVector3.getIsDefault(): cubeElement.attributes['translate.'] = str(centerVector3) cubeElement.localName = 'cube' cubeElement.setParentAddToChildNodes(differenceElement) difference.processElementNode(differenceElement) class DisjoinDerivation: "Class to hold disjoin variables." def __init__(self, elementNode): 'Set defaults.' self.elementNode = elementNode self.importRadius = setting.getImportRadius(elementNode) self.layerThickness = setting.getLayerThickness(elementNode) self.sheetThickness = setting.getSheetThickness(elementNode) self.targetElementNode = evaluate.getElementNodeByKey(elementNode, 'target') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_meta/import.py000066400000000000000000000100521167321211700266510ustar00rootroot00000000000000""" Boolean geometry group of solids. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import group from fabmetheus_utilities import xml_simple_reader from fabmetheus_utilities import xml_simple_writer from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings import cStringIO import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def appendAttributes(fromElementNode, toElementNode): 'Append the attributes from the child nodes of fromElementNode to the attributes of toElementNode.' for childNode in fromElementNode.childNodes: toElementNode.attributes.update(evaluate.removeIdentifiersFromDictionary(childNode.attributes.copy())) def getNewDerivation(elementNode): 'Get new derivation.' return ImportDerivation(elementNode) def getXMLFromCarvingFileName(fileName): 'Get xml text from xml text.' carving = fabmetheus_interpret.getCarving(fileName) if carving is None: return '' output = xml_simple_writer.getBeginGeometryXMLOutput() carving.addXML(0, output) return xml_simple_writer.getEndGeometryXMLString(output) def processElementNode(elementNode): "Process the xml element." processElementNodeByDerivation(None, elementNode) def processElementNodeByDerivation(derivation, elementNode): 'Process the xml element by derivation.' if derivation is None: derivation = ImportDerivation(elementNode) if derivation.fileName is None: return parserFileName = elementNode.getOwnerDocument().fileName absoluteFileName = archive.getAbsoluteFolderPath(parserFileName, derivation.fileName) if 'models/' not in absoluteFileName: print('Warning, models/ was not in the absolute file path, so for security nothing will be done for:') print(elementNode) print('For which the absolute file path is:') print(absoluteFileName) print('The import tool can only read a file which has models/ in the file path.') print('To import the file, move the file into a folder called model/ or a subfolder which is inside the model folder tree.') return xmlText = '' if derivation.fileName.endswith('.xml'): xmlText = archive.getFileText(absoluteFileName) else: xmlText = getXMLFromCarvingFileName(absoluteFileName) print('The import tool is opening the file:') print(absoluteFileName) if xmlText == '': print('The file %s could not be found by processElementNode in import.' % derivation.fileName) return if derivation.importName is None: elementNode.attributes['_importName'] = archive.getUntilDot(derivation.fileName) if derivation.basename: elementNode.attributes['_importName'] = os.path.basename(elementNode.attributes['_importName']) xml_simple_reader.createAppendByText(elementNode, xmlText) if derivation.appendDocumentElement: appendAttributes(elementNode, elementNode.getDocumentElement()) if derivation.appendElement: appendAttributes(elementNode, elementNode) elementNode.localName = 'group' evaluate.processArchivable(group.Group, elementNode) class ImportDerivation: "Class to hold import variables." def __init__(self, elementNode): 'Set defaults.' self.appendDocumentElement = evaluate.getEvaluatedBoolean(False, elementNode, 'appendDocumentElement') self.appendElement = evaluate.getEvaluatedBoolean(False, elementNode, 'appendElement') self.basename = evaluate.getEvaluatedBoolean(True, elementNode, 'basename') self.elementNode = elementNode self.fileName = evaluate.getEvaluatedString('', elementNode, 'file') self.importName = evaluate.getEvaluatedString(None, elementNode, '_importName') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_meta/write.py000066400000000000000000000100741167321211700264750ustar00rootroot00000000000000""" Boolean geometry write. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewDerivation(elementNode): 'Get new derivation.' return WriteDerivation(elementNode) def processElementNode(elementNode): "Process the xml element." processElementNodeByDerivation(None, elementNode) def processElementNodeByDerivation(derivation, elementNode): 'Process the xml element by derivation.' if derivation is None: derivation = WriteDerivation(elementNode) if len(derivation.targets) < 1: print('Warning, processElementNode in write could not get targets for:') print(elementNode) return fileNames = [] for target in derivation.targets: writeElementNode(derivation, fileNames, target) def writeElementNode(derivation, fileNames, target): "Write a quantity of the target." xmlObject = target.xmlObject if xmlObject is None: print('Warning, writeTarget in write could not get xmlObject for:') print(target) print(derivation.elementNode) return parserDirectory = os.path.dirname(derivation.elementNode.getOwnerDocument().fileName) absoluteFolderDirectory = os.path.abspath(os.path.join(parserDirectory, derivation.folderName)) if '/models' not in absoluteFolderDirectory: print('Warning, models/ was not in the absolute file path, so for security nothing will be done for:') print(derivation.elementNode) print('For which the absolute folder path is:') print(absoluteFolderDirectory) print('The write tool can only write a file which has models/ in the file path.') print('To write the file, move the file into a folder called model/ or a subfolder which is inside the model folder tree.') return quantity = evaluate.getEvaluatedInt(1, target, 'quantity') for itemIndex in xrange(quantity): writeXMLObject(absoluteFolderDirectory, derivation, fileNames, target, xmlObject) def writeXMLObject(absoluteFolderDirectory, derivation, fileNames, target, xmlObject): "Write one instance of the xmlObject." extension = evaluate.getEvaluatedString(xmlObject.getFabricationExtension(), derivation.elementNode, 'extension') fileNameRoot = derivation.fileName if fileNameRoot == '': fileNameRoot = evaluate.getEvaluatedString('', target, 'name') fileNameRoot = evaluate.getEvaluatedString(fileNameRoot, target, 'id') fileNameRoot += derivation.suffix fileName = '%s.%s' % (fileNameRoot, extension) suffixIndex = 2 while fileName in fileNames: fileName = '%s_%s.%s' % (fileNameRoot, suffixIndex, extension) suffixIndex += 1 absoluteFileName = os.path.join(absoluteFolderDirectory, fileName) fileNames.append(fileName) archive.makeDirectory(absoluteFolderDirectory) if not derivation.writeMatrix: xmlObject.matrix4X4 = matrix.Matrix() print('The write tool generated the file:') print(absoluteFileName) archive.writeFileText(absoluteFileName, xmlObject.getFabricationText(derivation.addLayerTemplate)) class WriteDerivation: "Class to hold write variables." def __init__(self, elementNode): 'Set defaults.' self.addLayerTemplate = evaluate.getEvaluatedBoolean(False, elementNode, 'addLayerTemplate') self.elementNode = elementNode self.fileName = evaluate.getEvaluatedString('', elementNode, 'file') self.folderName = evaluate.getEvaluatedString('', elementNode, 'folder') self.suffix = evaluate.getEvaluatedString('', elementNode, 'suffix') self.targets = evaluate.getElementNodesByKey(elementNode, 'target') self.writeMatrix = evaluate.getEvaluatedBoolean(True, elementNode, 'writeMatrix') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/000077500000000000000000000000001167321211700251605ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/__init__.py000066400000000000000000000006571167321211700273010ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/_inset.py000066400000000000000000000020241167321211700270110ustar00rootroot00000000000000""" Create inset. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities import intercircle __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 80 def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get inset path." radius = lineation.getStrokeRadiusByPrefix(elementNode, prefix) return intercircle.getInsetLoopsFromVector3Loop(loop, radius) def processElementNode(elementNode): "Process the xml element." lineation.processElementNodeByFunction(elementNode, getManipulatedPaths) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/_outset.py000066400000000000000000000027321167321211700272200ustar00rootroot00000000000000""" Create inset. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities import intercircle __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 80 def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get outset path." derivation = OutsetDerivation(elementNode, prefix) return intercircle.getInsetLoopsFromVector3Loop(loop, -derivation.radius) def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return OutsetDerivation(elementNode, prefix) def processElementNode(elementNode): "Process the xml element." lineation.processElementNodeByFunction(elementNode, getManipulatedPaths) class OutsetDerivation: "Class to hold outset variables." def __init__(self, elementNode, prefix): 'Set defaults.' self.radius = evaluate.getEvaluatedFloat(2.0 * setting.getPerimeterWidth(elementNode), elementNode, prefix + 'radius') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/bevel.py000066400000000000000000000053061167321211700266330ustar00rootroot00000000000000""" Add material to support overhang or remove material at the overhang angle. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 20 def getBevelPath( begin, center, close, end, radius ): "Get bevel path." beginComplex = begin.dropAxis() centerComplex = center.dropAxis() endComplex = end.dropAxis() beginComplexSegmentLength = abs( centerComplex - beginComplex ) endComplexSegmentLength = abs( centerComplex - endComplex ) minimumRadius = lineation.getMinimumRadius( beginComplexSegmentLength, endComplexSegmentLength, radius ) if minimumRadius <= close: return [ center ] beginBevel = center + minimumRadius / beginComplexSegmentLength * ( begin - center ) endBevel = center + minimumRadius / endComplexSegmentLength * ( end - center ) if radius > 0.0: return [ beginBevel, endBevel ] midpointComplex = 0.5 * ( beginBevel.dropAxis() + endBevel.dropAxis() ) spikeComplex = centerComplex + centerComplex - midpointComplex return [ beginBevel, Vector3( spikeComplex.real, spikeComplex.imag, center.z ), endBevel ] def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get bevel loop." if len(loop) < 3: return [loop] derivation = BevelDerivation(elementNode, prefix, sideLength) if derivation.radius == 0.0: return loop bevelLoop = [] for pointIndex in xrange(len(loop)): begin = loop[(pointIndex + len(loop) - 1) % len(loop)] center = loop[pointIndex] end = loop[(pointIndex + 1) % len(loop)] bevelLoop += getBevelPath(begin, center, close, end, derivation.radius) return [euclidean.getLoopWithoutCloseSequentialPoints(close, bevelLoop)] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return BevelDerivation(elementNode, prefix, sideLength) def processElementNode(elementNode): "Process the xml element." lineation.processElementNodeByFunction(elementNode, getManipulatedPaths) class BevelDerivation: "Class to hold bevel variables." def __init__(self, elementNode, prefix, sideLength): 'Set defaults.' self.radius = lineation.getFloatByPrefixSide(0.0, elementNode, prefix + 'radius', sideLength) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/convex.py000066400000000000000000000023061167321211700270350ustar00rootroot00000000000000""" Create outline. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 80 def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get path with overhangs removed or filled in." if len(loop) < 4: return [loop] loopComplex = euclidean.getComplexPath(loop) return euclidean.getVector3Paths([euclidean.getLoopConvex(loopComplex)], loop[0].z) def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return evaluate.EmptyObject() def processElementNode(elementNode): "Process the xml element." lineation.processElementNodeByFunction(elementNode, getManipulatedPaths) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/outline.py000066400000000000000000000036721167321211700272210ustar00rootroot00000000000000""" Create outline. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean from fabmetheus_utilities import intercircle __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 80 def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get path with outline." if len(loop) < 2: return [loop] derivation = OutlineDerivation(elementNode, prefix, sideLength) loopComplex = euclidean.getComplexPath(loop) if derivation.isClosed: loopComplexes = intercircle.getAroundsFromLoop(loopComplex, derivation.radius) else: loopComplexes = intercircle.getAroundsFromPath(loopComplex, derivation.radius) return euclidean.getVector3Paths(loopComplexes, loop[0].z) def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return OutlineDerivation(elementNode, prefix, sideLength) def processElementNode(elementNode): "Process the xml element." lineation.processElementNodeByFunction(elementNode, getManipulatedPaths) class OutlineDerivation: "Class to hold outline variables." def __init__(self, elementNode, prefix, sideLength): 'Set defaults.' self.isClosed = evaluate.getEvaluatedBoolean(False, elementNode, prefix + 'closed') self.radius = evaluate.getEvaluatedFloat(setting.getPerimeterWidth(elementNode), elementNode, prefix + 'radius') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/overhang.py000066400000000000000000000412571167321211700273540ustar00rootroot00000000000000""" Add material to support overhang or remove material at the overhang angle. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 100 def addUnsupportedPointIndexes( alongAway ): "Add the indexes of the unsupported points." addedUnsupportedPointIndexes = [] for pointIndex in xrange( len( alongAway.loop ) ): point = alongAway.loop[pointIndex] if pointIndex not in alongAway.unsupportedPointIndexes: if not alongAway.getIsClockwisePointSupported(point): alongAway.unsupportedPointIndexes.append( pointIndex ) addedUnsupportedPointIndexes.append( pointIndex ) for pointIndex in addedUnsupportedPointIndexes: point = alongAway.loop[pointIndex] point.y += alongAway.maximumYPlus def alterClockwiseSupportedPath( alongAway, elementNode ): "Get clockwise path with overhangs carved out." alongAway.bottomPoints = [] alongAway.overhangSpan = setting.getOverhangSpan(elementNode) maximumY = - 987654321.0 minimumYPointIndex = 0 for pointIndex in xrange( len( alongAway.loop ) ): point = alongAway.loop[pointIndex] if point.y < alongAway.loop[ minimumYPointIndex ].y: minimumYPointIndex = pointIndex maximumY = max( maximumY, point.y ) alongAway.maximumYPlus = 2.0 * ( maximumY - alongAway.loop[ minimumYPointIndex ].y ) alongAway.loop = euclidean.getAroundLoop( minimumYPointIndex, minimumYPointIndex, alongAway.loop ) overhangClockwise = OverhangClockwise( alongAway ) alongAway.unsupportedPointIndexes = [] oldUnsupportedPointIndexesLength = - 987654321.0 while len( alongAway.unsupportedPointIndexes ) > oldUnsupportedPointIndexesLength: oldUnsupportedPointIndexesLength = len( alongAway.unsupportedPointIndexes ) addUnsupportedPointIndexes( alongAway ) for pointIndex in alongAway.unsupportedPointIndexes: point = alongAway.loop[pointIndex] point.y -= alongAway.maximumYPlus alongAway.unsupportedPointIndexes.sort() alongAway.unsupportedPointIndexLists = [] oldUnsupportedPointIndex = - 987654321.0 unsupportedPointIndexList = None for unsupportedPointIndex in alongAway.unsupportedPointIndexes: if unsupportedPointIndex > oldUnsupportedPointIndex + 1: unsupportedPointIndexList = [] alongAway.unsupportedPointIndexLists.append( unsupportedPointIndexList ) oldUnsupportedPointIndex = unsupportedPointIndex unsupportedPointIndexList.append( unsupportedPointIndex ) alongAway.unsupportedPointIndexLists.reverse() for unsupportedPointIndexList in alongAway.unsupportedPointIndexLists: overhangClockwise.alterLoop( unsupportedPointIndexList ) def alterWiddershinsSupportedPath( alongAway, close ): "Get widdershins path with overhangs filled in." alongAway.bottomPoints = [] alongAway.minimumY = getMinimumYByPath( alongAway.loop ) for point in alongAway.loop: if point.y - alongAway.minimumY < close: alongAway.addToBottomPoints(point) ascendingYPoints = alongAway.loop[:] ascendingYPoints.sort( compareYAscending ) overhangWiddershinsLeft = OverhangWiddershinsLeft( alongAway ) overhangWiddershinsRight = OverhangWiddershinsRight( alongAway ) for point in ascendingYPoints: alterWiddershinsSupportedPathByPoint( alongAway, overhangWiddershinsLeft, overhangWiddershinsRight, point ) def alterWiddershinsSupportedPathByPoint( alongAway, overhangWiddershinsLeft, overhangWiddershinsRight, point ): "Get widdershins path with overhangs filled in for point." if alongAway.getIsWiddershinsPointSupported(point): return overhangWiddershins = overhangWiddershinsLeft if overhangWiddershinsRight.getDistance() < overhangWiddershinsLeft.getDistance(): overhangWiddershins = overhangWiddershinsRight overhangWiddershins.alterLoop() def compareYAscending( point, pointOther ): "Get comparison in order to sort points in ascending y." if point.y < pointOther.y: return - 1 return int( point.y > pointOther.y ) def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get path with overhangs removed or filled in." if len(loop) < 3: print('Warning, loop has less than three sides in getManipulatedPaths in overhang for:') print(elementNode) return [loop] derivation = OverhangDerivation(elementNode, prefix) overhangPlaneAngle = euclidean.getWiddershinsUnitPolar(0.5 * math.pi - derivation.overhangRadians) if derivation.overhangInclinationRadians != 0.0: overhangInclinationCosine = abs(math.cos(derivation.overhangInclinationRadians)) if overhangInclinationCosine == 0.0: return [loop] imaginaryTimesCosine = overhangPlaneAngle.imag * overhangInclinationCosine overhangPlaneAngle = euclidean.getNormalized(complex(overhangPlaneAngle.real, imaginaryTimesCosine)) alongAway = AlongAway(loop, overhangPlaneAngle) if euclidean.getIsWiddershinsByVector3(loop): alterWiddershinsSupportedPath(alongAway, close) else: alterClockwiseSupportedPath(alongAway, elementNode) return [euclidean.getLoopWithoutCloseSequentialPoints(close, alongAway.loop)] def getMinimumYByPath(path): "Get path with overhangs removed or filled in." minimumYByPath = path[0].y for point in path: minimumYByPath = min( minimumYByPath, point.y ) return minimumYByPath def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return OverhangDerivation(elementNode, prefix) def processElementNode(elementNode): "Process the xml element." lineation.processElementNodeByFunction(elementNode, getManipulatedPaths) class AlongAway: "Class to derive the path along the point and away from the point." def __init__( self, loop, overhangPlaneAngle ): "Initialize." self.loop = loop self.overhangPlaneAngle = overhangPlaneAngle self.ySupport = - self.overhangPlaneAngle.imag def __repr__(self): "Get the string representation of AlongAway." return '%s' % ( self.overhangPlaneAngle ) def addToBottomPoints(self, point): "Add point to bottom points and set y to minimumY." self.bottomPoints.append(point) point.y = self.minimumY def getIsClockwisePointSupported(self, point): "Determine if the point on the clockwise loop is supported." self.point = point self.pointIndex = None self.awayIndexes = [] numberOfIntersectionsBelow = 0 for pointIndex in xrange( len( self.loop ) ): begin = self.loop[pointIndex] end = self.loop[ (pointIndex + 1) % len( self.loop ) ] if begin != point and end != point: self.awayIndexes.append( pointIndex ) yIntersection = euclidean.getYIntersectionIfExists( begin.dropAxis(), end.dropAxis(), point.x ) if yIntersection is not None: numberOfIntersectionsBelow += ( yIntersection < point.y ) if begin == point: self.pointIndex = pointIndex if numberOfIntersectionsBelow % 2 == 0: return True if self.pointIndex is None: return True if self.getIsPointSupportedBySegment( self.pointIndex - 1 + len( self.loop ) ): return True return self.getIsPointSupportedBySegment( self.pointIndex + 1 ) def getIsPointSupportedBySegment( self, endIndex ): "Determine if the point on the widdershins loop is supported." endComplex = self.loop[ ( endIndex % len( self.loop ) ) ].dropAxis() endMinusPointComplex = euclidean.getNormalized( endComplex - self.point.dropAxis() ) return endMinusPointComplex.imag < self.ySupport def getIsWiddershinsPointSupported(self, point): "Determine if the point on the widdershins loop is supported." if point.y <= self.minimumY: return True self.point = point self.pointIndex = None self.awayIndexes = [] numberOfIntersectionsBelow = 0 for pointIndex in xrange( len( self.loop ) ): begin = self.loop[pointIndex] end = self.loop[ (pointIndex + 1) % len( self.loop ) ] if begin != point and end != point: self.awayIndexes.append( pointIndex ) yIntersection = euclidean.getYIntersectionIfExists( begin.dropAxis(), end.dropAxis(), point.x ) if yIntersection is not None: numberOfIntersectionsBelow += ( yIntersection < point.y ) if begin == point: self.pointIndex = pointIndex if numberOfIntersectionsBelow % 2 == 1: return True if self.pointIndex is None: return True if self.getIsPointSupportedBySegment( self.pointIndex - 1 + len( self.loop ) ): return True return self.getIsPointSupportedBySegment( self.pointIndex + 1 ) class OverhangClockwise: "Class to get the intersection up from the point." def __init__( self, alongAway ): "Initialize." self.alongAway = alongAway self.halfRiseOverWidth = 0.5 * alongAway.overhangPlaneAngle.imag / alongAway.overhangPlaneAngle.real self.widthOverRise = alongAway.overhangPlaneAngle.real / alongAway.overhangPlaneAngle.imag def __repr__(self): "Get the string representation of OverhangClockwise." return '%s' % ( self.intersectionPlaneAngle ) def alterLoop( self, unsupportedPointIndexes ): "Alter alongAway loop." unsupportedBeginIndex = unsupportedPointIndexes[0] unsupportedEndIndex = unsupportedPointIndexes[-1] beginIndex = unsupportedBeginIndex - 1 endIndex = unsupportedEndIndex + 1 begin = self.alongAway.loop[ beginIndex ] end = self.alongAway.loop[ endIndex ] truncatedOverhangSpan = self.alongAway.overhangSpan width = end.x - begin.x heightDifference = abs( end.y - begin.y ) remainingWidth = width - self.widthOverRise * heightDifference if remainingWidth <= 0.0: del self.alongAway.loop[ unsupportedBeginIndex : endIndex ] return highest = begin supportX = begin.x + remainingWidth if end.y > begin.y: highest = end supportX = end.x - remainingWidth tipY = highest.y + self.halfRiseOverWidth * remainingWidth highestBetween = - 987654321.0 for unsupportedPointIndex in unsupportedPointIndexes: highestBetween = max( highestBetween, self.alongAway.loop[ unsupportedPointIndex ].y ) if highestBetween > highest.y: truncatedOverhangSpan = 0.0 if highestBetween < tipY: below = tipY - highestBetween truncatedOverhangSpan = min( self.alongAway.overhangSpan, below / self.halfRiseOverWidth ) truncatedOverhangSpanRadius = 0.5 * truncatedOverhangSpan if remainingWidth <= truncatedOverhangSpan: supportPoint = Vector3( supportX, highest.y, highest.z ) self.alongAway.loop[ unsupportedBeginIndex : endIndex ] = [ supportPoint ] return midSupportX = 0.5 * ( supportX + highest.x ) if truncatedOverhangSpan <= 0.0: supportPoint = Vector3( midSupportX, tipY, highest.z ) self.alongAway.loop[ unsupportedBeginIndex : endIndex ] = [ supportPoint ] return supportXLeft = midSupportX - truncatedOverhangSpanRadius supportXRight = midSupportX + truncatedOverhangSpanRadius supportY = tipY - self.halfRiseOverWidth * truncatedOverhangSpan supportPoints = [ Vector3( supportXLeft, supportY, highest.z ), Vector3( supportXRight, supportY, highest.z ) ] self.alongAway.loop[ unsupportedBeginIndex : endIndex ] = supportPoints class OverhangDerivation: "Class to hold overhang variables." def __init__(self, elementNode, prefix): 'Set defaults.' self.overhangRadians = setting.getOverhangRadians(elementNode) self.overhangInclinationRadians = math.radians(evaluate.getEvaluatedFloat(0.0, elementNode, prefix + 'inclination')) class OverhangWiddershinsLeft: "Class to get the intersection from the point down to the left." def __init__( self, alongAway ): "Initialize." self.alongAway = alongAway self.intersectionPlaneAngle = - alongAway.overhangPlaneAngle self.setRatios() def __repr__(self): "Get the string representation of OverhangWiddershins." return '%s' % ( self.intersectionPlaneAngle ) def alterLoop(self): "Alter alongAway loop." insertedPoint = self.alongAway.point.copy() if self.closestXIntersectionIndex is not None: self.alongAway.loop = self.getIntersectLoop() intersectionRelativeComplex = self.closestXDistance * self.intersectionPlaneAngle intersectionPoint = insertedPoint + Vector3( intersectionRelativeComplex.real, intersectionRelativeComplex.imag ) self.alongAway.loop.append( intersectionPoint ) return if self.closestBottomPoint is None: return if self.closestBottomPoint not in self.alongAway.loop: return insertedPoint.x = self.bottomX closestBottomIndex = self.alongAway.loop.index( self.closestBottomPoint ) self.alongAway.addToBottomPoints( insertedPoint ) self.alongAway.loop = self.getBottomLoop( closestBottomIndex, insertedPoint ) self.alongAway.loop.append( insertedPoint ) def getBottomLoop( self, closestBottomIndex, insertedPoint ): "Get loop around bottom." endIndex = closestBottomIndex + len( self.alongAway.loop ) + 1 return euclidean.getAroundLoop( self.alongAway.pointIndex, endIndex, self.alongAway.loop ) def getDistance(self): "Get distance between point and closest intersection or bottom point along line." self.pointMinusBottomY = self.alongAway.point.y - self.alongAway.minimumY self.diagonalDistance = self.pointMinusBottomY * self.diagonalRatio if self.alongAway.pointIndex is None: return self.getDistanceToBottom() rotatedLoop = euclidean.getRotatedComplexes( self.intersectionYMirror, euclidean.getComplexPath( self.alongAway.loop ) ) rotatedPointComplex = rotatedLoop[ self.alongAway.pointIndex ] beginX = rotatedPointComplex.real endX = beginX + self.diagonalDistance + self.diagonalDistance xIntersectionIndexList = [] for pointIndex in self.alongAway.awayIndexes: beginComplex = rotatedLoop[pointIndex] endComplex = rotatedLoop[ (pointIndex + 1) % len( rotatedLoop ) ] xIntersection = euclidean.getXIntersectionIfExists( beginComplex, endComplex, rotatedPointComplex.imag ) if xIntersection is not None: if xIntersection >= beginX and xIntersection < endX: xIntersectionIndexList.append( euclidean.XIntersectionIndex( pointIndex, xIntersection ) ) self.closestXDistance = 987654321.0 self.closestXIntersectionIndex = None for xIntersectionIndex in xIntersectionIndexList: xDistance = abs( xIntersectionIndex.x - beginX ) if xDistance < self.closestXDistance: self.closestXIntersectionIndex = xIntersectionIndex self.closestXDistance = xDistance if self.closestXIntersectionIndex is not None: return self.closestXDistance return self.getDistanceToBottom() def getDistanceToBottom(self): "Get distance between point and closest bottom point along line." self.bottomX = self.alongAway.point.x + self.pointMinusBottomY * self.xRatio self.closestBottomPoint = None closestDistanceX = 987654321.0 for point in self.alongAway.bottomPoints: distanceX = abs( point.x - self.bottomX ) if self.getIsOnside(point.x): if distanceX < closestDistanceX: closestDistanceX = distanceX self.closestBottomPoint = point return closestDistanceX + self.diagonalDistance def getIntersectLoop(self): "Get intersection loop." endIndex = self.closestXIntersectionIndex.index + len( self.alongAway.loop ) + 1 return euclidean.getAroundLoop( self.alongAway.pointIndex, endIndex, self.alongAway.loop ) def getIsOnside( self, x ): "Determine if x is on the side along the direction of the intersection line." return x <= self.alongAway.point.x def setRatios(self): "Set ratios." self.diagonalRatio = 1.0 / abs( self.intersectionPlaneAngle.imag ) self.intersectionYMirror = complex( self.intersectionPlaneAngle.real, - self.intersectionPlaneAngle.imag ) self.xRatio = self.intersectionPlaneAngle.real / abs( self.intersectionPlaneAngle.imag ) class OverhangWiddershinsRight( OverhangWiddershinsLeft ): "Class to get the intersection from the point down to the right." def __init__( self, alongAway ): "Initialize." self.alongAway = alongAway self.intersectionPlaneAngle = complex( alongAway.overhangPlaneAngle.real, - alongAway.overhangPlaneAngle.imag ) self.setRatios() def getBottomLoop( self, closestBottomIndex, insertedPoint ): "Get loop around bottom." endIndex = self.alongAway.pointIndex + len( self.alongAway.loop ) + 1 return euclidean.getAroundLoop( closestBottomIndex, endIndex, self.alongAway.loop ) def getIntersectLoop(self): "Get intersection loop." beginIndex = self.closestXIntersectionIndex.index + len( self.alongAway.loop ) + 1 endIndex = self.alongAway.pointIndex + len( self.alongAway.loop ) + 1 return euclidean.getAroundLoop( beginIndex, endIndex, self.alongAway.loop ) def getIsOnside( self, x ): "Determine if x is on the side along the direction of the intersection line." return x >= self.alongAway.point.x sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/round.py000066400000000000000000000104021167321211700266560ustar00rootroot00000000000000""" Add material to support overhang or remove material at the overhang angle. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 40 def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get round loop." if len(loop) < 3: return [loop] derivation = RoundDerivation(elementNode, prefix, sideLength) if derivation.radius == 0.0: return loop roundLoop = [] sidesPerRadian = 0.5 / math.pi * evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, sideLength) for pointIndex in xrange(len(loop)): begin = loop[(pointIndex + len(loop) - 1) % len(loop)] center = loop[pointIndex] end = loop[(pointIndex + 1) % len(loop)] roundLoop += getRoundPath(begin, center, close, end, derivation.radius, sidesPerRadian) return [euclidean.getLoopWithoutCloseSequentialPoints(close, roundLoop)] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return RoundDerivation(elementNode, prefix, sideLength) def getRoundPath( begin, center, close, end, radius, sidesPerRadian ): "Get round path." beginComplex = begin.dropAxis() centerComplex = center.dropAxis() endComplex = end.dropAxis() beginComplexSegmentLength = abs( centerComplex - beginComplex ) endComplexSegmentLength = abs( centerComplex - endComplex ) minimumRadius = lineation.getMinimumRadius( beginComplexSegmentLength, endComplexSegmentLength, radius ) if minimumRadius <= close: return [ center ] beginBevel = center + minimumRadius / beginComplexSegmentLength * ( begin - center ) endBevel = center + minimumRadius / endComplexSegmentLength * ( end - center ) beginBevelComplex = beginBevel.dropAxis() endBevelComplex = endBevel.dropAxis() midpointComplex = 0.5 * ( beginBevelComplex + endBevelComplex ) if radius < 0.0: centerComplex = midpointComplex + midpointComplex - centerComplex midpointMinusCenterComplex = midpointComplex - centerComplex midpointCenterLength = abs( midpointMinusCenterComplex ) midpointEndLength = abs( midpointComplex - endBevelComplex ) midpointCircleCenterLength = midpointEndLength * midpointEndLength / midpointCenterLength circleRadius = math.sqrt( midpointCircleCenterLength * midpointCircleCenterLength + midpointEndLength * midpointEndLength ) circleCenterComplex = midpointComplex + midpointMinusCenterComplex * midpointCircleCenterLength / midpointCenterLength circleCenter = Vector3( circleCenterComplex.real, circleCenterComplex.imag, center.z ) endMinusCircleCenterComplex = endBevelComplex - circleCenterComplex beginMinusCircleCenter = beginBevel - circleCenter beginMinusCircleCenterComplex = beginMinusCircleCenter.dropAxis() angleDifference = euclidean.getAngleDifferenceByComplex( endMinusCircleCenterComplex, beginMinusCircleCenterComplex ) steps = int( math.ceil( abs( angleDifference ) * sidesPerRadian ) ) stepPlaneAngle = euclidean.getWiddershinsUnitPolar( angleDifference / float( steps ) ) deltaZStep = ( end.z - begin.z ) / float( steps ) roundPath = [ beginBevel ] for step in xrange( 1, steps ): beginMinusCircleCenterComplex = beginMinusCircleCenterComplex * stepPlaneAngle arcPointComplex = circleCenterComplex + beginMinusCircleCenterComplex arcPoint = Vector3( arcPointComplex.real, arcPointComplex.imag, begin.z + deltaZStep * step ) roundPath.append( arcPoint ) return roundPath + [ endBevel ] def processElementNode(elementNode): "Process the xml element." lineation.processElementNodeByFunction(elementNode, getManipulatedPaths) class RoundDerivation: "Class to hold round variables." def __init__(self, elementNode, prefix, sideLength): 'Set defaults.' self.radius = lineation.getFloatByPrefixSide(0.0, elementNode, prefix + 'radius', sideLength) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/segment.py000066400000000000000000000154461167321211700272060ustar00rootroot00000000000000""" Add material to support overhang or remove material at the overhang angle. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 60 def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get segment loop." if len(loop) < 3: return [loop] derivation = SegmentDerivation(elementNode, prefix) if derivation.path == getSegmentPathDefault(): return [loop] path = getXNormalizedVector3Path(derivation.path) if euclidean.getIsWiddershinsByVector3(loop): path = path[: : -1] for point in path: point.x = 1.0 - point.x if derivation.center == None: point.y = - point.y segmentLoop = [] startEnd = StartEnd(elementNode, len(loop), prefix) for pointIndex in xrange(len(loop)): if pointIndex >= startEnd.start and pointIndex < startEnd.end: segmentLoop += getSegmentPath(derivation.center, loop, path, pointIndex) else: segmentLoop.append(loop[pointIndex]) return [euclidean.getLoopWithoutCloseSequentialPoints( close, segmentLoop)] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return SegmentDerivation(elementNode, prefix) def getRadialPath(begin, center, end, path): "Get radial path." beginComplex = begin.dropAxis() endComplex = end.dropAxis() centerComplex = center.dropAxis() beginMinusCenterComplex = beginComplex - centerComplex endMinusCenterComplex = endComplex - centerComplex beginMinusCenterComplexRadius = abs( beginMinusCenterComplex ) endMinusCenterComplexRadius = abs( endMinusCenterComplex ) if beginMinusCenterComplexRadius == 0.0 or endMinusCenterComplexRadius == 0.0: return [ begin ] beginMinusCenterComplex /= beginMinusCenterComplexRadius endMinusCenterComplex /= endMinusCenterComplexRadius angleDifference = euclidean.getAngleDifferenceByComplex( endMinusCenterComplex, beginMinusCenterComplex ) radialPath = [] for point in path: weightEnd = point.x weightBegin = 1.0 - weightEnd weightedRadius = beginMinusCenterComplexRadius * weightBegin + endMinusCenterComplexRadius * weightEnd * ( 1.0 + point.y ) radialComplex = weightedRadius * euclidean.getWiddershinsUnitPolar( angleDifference * point.x ) * beginMinusCenterComplex polygonPoint = center + Vector3( radialComplex.real, radialComplex.imag, point.z ) radialPath.append( polygonPoint ) return radialPath def getSegmentPath(center, loop, path, pointIndex): "Get segment path." centerBegin = loop[pointIndex] centerEnd = loop[(pointIndex + 1) % len(loop)] centerEndMinusBegin = centerEnd - centerBegin if abs( centerEndMinusBegin ) <= 0.0: return [ centerBegin ] if center != None: return getRadialPath(centerBegin, center, centerEnd, path) begin = loop[(pointIndex + len(loop) - 1) % len(loop)] end = loop[ ( pointIndex + 2 ) % len(loop) ] return getWedgePath( begin, centerBegin, centerEnd, centerEndMinusBegin, end, path ) def getSegmentPathDefault(): "Get segment path default." return [ Vector3(), Vector3( 0.0, 1.0 ) ] def getWedgePath( begin, centerBegin, centerEnd, centerEndMinusBegin, end, path ): "Get segment path." beginComplex = begin.dropAxis() centerBeginComplex = centerBegin.dropAxis() centerEndComplex = centerEnd.dropAxis() endComplex = end.dropAxis() wedgePath = [] centerBeginMinusBeginComplex = euclidean.getNormalized( centerBeginComplex - beginComplex ) centerEndMinusCenterBeginComplexOriginal = centerEndComplex - centerBeginComplex centerEndMinusCenterBeginComplexLength = abs( centerEndMinusCenterBeginComplexOriginal ) if centerEndMinusCenterBeginComplexLength <= 0.0: return [ centerBegin ] centerEndMinusCenterBeginComplex = centerEndMinusCenterBeginComplexOriginal / centerEndMinusCenterBeginComplexLength endMinusCenterEndComplex = euclidean.getNormalized( endComplex - centerEndComplex ) widdershinsBegin = getWiddershinsAverageByVector3( centerBeginMinusBeginComplex, centerEndMinusCenterBeginComplex ) widdershinsEnd = getWiddershinsAverageByVector3( centerEndMinusCenterBeginComplex, endMinusCenterEndComplex ) for point in path: weightEnd = point.x weightBegin = 1.0 - weightEnd polygonPoint = centerBegin + centerEndMinusBegin * point.x weightedWiddershins = widdershinsBegin * weightBegin + widdershinsEnd * weightEnd polygonPoint += weightedWiddershins * point.y * centerEndMinusCenterBeginComplexLength polygonPoint.z += point.z wedgePath.append( polygonPoint ) return wedgePath def getWiddershinsAverageByVector3( centerMinusBeginComplex, endMinusCenterComplex ): "Get the normalized average of the widdershins vectors." centerMinusBeginWiddershins = Vector3( - centerMinusBeginComplex.imag, centerMinusBeginComplex.real ) endMinusCenterWiddershins = Vector3( - endMinusCenterComplex.imag, endMinusCenterComplex.real ) return ( centerMinusBeginWiddershins + endMinusCenterWiddershins ).getNormalized() def getXNormalizedVector3Path(path): "Get path where the x ranges from 0 to 1." if len(path) < 1: return path minimumX = path[0].x for point in path[1 :]: minimumX = min( minimumX, point.x ) for point in path: point.x -= minimumX maximumX = path[0].x for point in path[1 :]: maximumX = max( maximumX, point.x ) for point in path: point.x /= maximumX return path def processElementNode(elementNode): "Process the xml element." lineation.processElementNodeByFunction(elementNode, getManipulatedPaths) class SegmentDerivation: "Class to hold segment variables." def __init__(self, elementNode, prefix): 'Set defaults.' self.center = evaluate.getVector3ByPrefix(None, elementNode, prefix + 'center') self.path = evaluate.getPathByPrefix(elementNode, getSegmentPathDefault(), prefix) class StartEnd: 'Class to get a start through end range.' def __init__(self, elementNode, modulo, prefix): "Initialize." self.start = evaluate.getEvaluatedInt(0, elementNode, prefix + 'start') self.extent = evaluate.getEvaluatedInt(modulo - self.start, elementNode, prefix + 'extent') self.end = evaluate.getEvaluatedInt(self.start + self.extent, elementNode, prefix + 'end') self.revolutions = evaluate.getEvaluatedInt(1, elementNode, prefix + 'revolutions') if self.revolutions > 1: self.end += modulo * (self.revolutions - 1) def __repr__(self): "Get the string representation of this StartEnd." return '%s, %s, %s' % (self.start, self.end, self.revolutions) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_paths/wedge.py000066400000000000000000000026031167321211700266260ustar00rootroot00000000000000""" Add material to support overhang or remove material at the overhang angle. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.vector3 import Vector3 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = -200 def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get wedge loop." derivation = WedgeDerivation(elementNode, prefix) loop.append(derivation.center) return [loop] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return WedgeDerivation(elementNode, prefix) def processElementNode(elementNode): "Process the xml element." lineation.processElementNodeByFunction(elementNode, getManipulatedPaths) class WedgeDerivation: "Class to hold wedge variables." def __init__(self, elementNode, prefix): 'Set defaults.' self.center = evaluate.getVector3ByPrefix(Vector3(), elementNode, prefix + 'center') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_shapes/000077500000000000000000000000001167321211700253245ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_shapes/__init__.py000066400000000000000000000006571167321211700274450ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_shapes/_bottom.py000066400000000000000000000076521167321211700273530ustar00rootroot00000000000000""" Boolean geometry bottom. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 400 def bottomElementNode(derivation, target): "Bottom target." xmlObject = target.xmlObject if xmlObject is None: print('Warning, bottomTarget in bottom could not get xmlObject for:') print(target) print(derivation.elementNode) return targetMatrix = matrix.getBranchMatrixSetElementNode(target) lift = derivation.altitude transformedPaths = xmlObject.getTransformedPaths() if len(transformedPaths) > 0: lift += derivation.getAdditionalPathLift() - euclidean.getBottomByPaths(transformedPaths) else: lift -= boolean_geometry.getMinimumZ(xmlObject) targetMatrix.tetragrid = matrix.getIdentityTetragrid(targetMatrix.tetragrid) targetMatrix.tetragrid[2][3] += lift matrix.setElementNodeDictionaryMatrix(target, targetMatrix) def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): 'Get bottomed geometryOutput.' derivation = BottomDerivation(elementNode, prefix) copyShallow = elementNode.getCopyShallow() solid.processElementNodeByGeometry(copyShallow, geometryOutput) targetMatrix = matrix.getBranchMatrixSetElementNode(elementNode) matrix.setElementNodeDictionaryMatrix(copyShallow, targetMatrix) minimumZ = boolean_geometry.getMinimumZ(copyShallow.xmlObject) copyShallow.parentNode.xmlObject.archivableObjects.remove(copyShallow.xmlObject) lift = derivation.altitude - minimumZ vertexes = matrix.getVertexes(geometryOutput) for vertex in vertexes: vertex.z += lift return geometryOutput def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): 'Get flipped paths.' if len(loop) < 1: return [[]] derivation = BottomDerivation(elementNode, prefix) targetMatrix = matrix.getBranchMatrixSetElementNode(elementNode) transformedLoop = matrix.getTransformedVector3s(matrix.getIdentityTetragrid(targetMatrix.tetragrid), loop) lift = derivation.altitude + derivation.getAdditionalPathLift() - euclidean.getBottomByPath(transformedLoop) for point in loop: point.z += lift return [loop] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return BottomDerivation(elementNode, '') def processElementNode(elementNode): "Process the xml element." processElementNodeByDerivation(None, elementNode) def processElementNodeByDerivation(derivation, elementNode): 'Process the xml element by derivation.' if derivation is None: derivation = BottomDerivation(elementNode, '') targets = evaluate.getElementNodesByKey(elementNode, 'target') if len(targets) < 1: print('Warning, processElementNode in bottom could not get targets for:') print(elementNode) return for target in targets: bottomElementNode(derivation, target) class BottomDerivation: "Class to hold bottom variables." def __init__(self, elementNode, prefix): 'Set defaults.' self.altitude = evaluate.getEvaluatedFloat(0.0, elementNode, prefix + 'altitude') self.elementNode = elementNode self.liftPath = evaluate.getEvaluatedBoolean(True, elementNode, prefix + 'liftPath') def getAdditionalPathLift(self): "Get path lift." return 0.5 * setting.getLayerThickness(self.elementNode) * float(self.liftPath) sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_shapes/_inset.py000066400000000000000000000120301167321211700271530ustar00rootroot00000000000000""" Create inset. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities.evaluate_elements import setting from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry from fabmetheus_utilities.geometry.geometry_utilities import boolean_solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3index import Vector3Index from fabmetheus_utilities import euclidean from fabmetheus_utilities import intercircle import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 80 def getLoopOrEmpty(loopIndex, loops): 'Get the loop, or if the loopIndex is out of range, get an empty list.' if loopIndex < 0 or loopIndex >= len(loops): return [] return loops[loopIndex] def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get inset path." radius = lineation.getStrokeRadiusByPrefix(elementNode, prefix) return intercircle.getInsetLoopsFromVector3Loop(loop, radius) def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): 'Get inset geometryOutput.' derivation = InsetDerivation(elementNode, prefix) if derivation.radius == 0.0: return geometryOutput copyShallow = elementNode.getCopyShallow() solid.processElementNodeByGeometry(copyShallow, geometryOutput) targetMatrix = matrix.getBranchMatrixSetElementNode(elementNode) matrix.setElementNodeDictionaryMatrix(copyShallow, targetMatrix) transformedVertexes = copyShallow.xmlObject.getTransformedVertexes() minimumZ = boolean_geometry.getMinimumZ(copyShallow.xmlObject) maximumZ = euclidean.getTopPath(transformedVertexes) layerThickness = setting.getLayerThickness(elementNode) importRadius = setting.getImportRadius(elementNode) zoneArrangement = triangle_mesh.ZoneArrangement(layerThickness, transformedVertexes) copyShallow.attributes['visible'] = True copyShallowObjects = [copyShallow.xmlObject] bottomLoopLayer = euclidean.LoopLayer(minimumZ) z = minimumZ + 0.1 * layerThickness bottomLoopLayer.loops = boolean_geometry.getEmptyZLoops(copyShallowObjects, importRadius, False, z, zoneArrangement) loopLayers = [bottomLoopLayer] z = minimumZ + layerThickness loopLayers += boolean_geometry.getLoopLayers(copyShallowObjects, importRadius, layerThickness, maximumZ, False, z, zoneArrangement) copyShallow.parentNode.xmlObject.archivableObjects.remove(copyShallow.xmlObject) belowLoop = [] diagonalRadius = math.sqrt(0.5) * derivation.radius insetDiagonalLoops = [] loops = [] vertexes = [] for loopLayer in loopLayers: insetDiagonalLoops.append(intercircle.getLargestInsetLoopFromLoop(loopLayer.loops[0], diagonalRadius)) for loopLayerIndex, loopLayer in enumerate(loopLayers): vector3Loop = [] insetLoop = intercircle.getLargestInsetLoopFromLoop(loopLayer.loops[0], derivation.radius) loopLists = [[getLoopOrEmpty(loopLayerIndex - 1, insetDiagonalLoops)], [insetLoop]] largestLoop = euclidean.getLargestLoop(boolean_solid.getLoopsIntersection(importRadius, loopLists)) if evaluate.getEvaluatedBoolean(True, elementNode, prefix + 'insetTop'): loopLists = [[getLoopOrEmpty(loopLayerIndex + 1, insetDiagonalLoops)], [largestLoop]] largestLoop = euclidean.getLargestLoop(boolean_solid.getLoopsIntersection(importRadius, loopLists)) for point in largestLoop: vector3Index = Vector3Index(len(vertexes), point.real, point.imag, loopLayer.z) vector3Loop.append(vector3Index) vertexes.append(vector3Index) if len(vector3Loop) > 0: loops.append(vector3Loop) if evaluate.getEvaluatedBoolean(False, elementNode, prefix + 'addExtraTopLayer') and len(loops) > 0: topLoop = loops[-1] vector3Loop = [] loops.append(vector3Loop) z = topLoop[0].z + layerThickness for point in topLoop: vector3Index = Vector3Index(len(vertexes), point.x, point.y, z) vector3Loop.append(vector3Index) vertexes.append(vector3Index) geometryOutput = triangle_mesh.getMeldedPillarOutput(loops) return geometryOutput def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return OutsetDerivation(elementNode, prefix) def processElementNode(elementNode): "Process the xml element." solid.processElementNodeByFunctionPair(elementNode, getManipulatedGeometryOutput, getManipulatedPaths) class InsetDerivation: "Class to hold inset variables." def __init__(self, elementNode, prefix): 'Set defaults.' self.radius = evaluate.getEvaluatedFloat(2.0 * setting.getPerimeterWidth(elementNode), elementNode, prefix + 'radius') sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_shapes/equation.py000066400000000000000000000102121167321211700275170ustar00rootroot00000000000000""" Equation for vertexes. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = -100 def equate(point, returnValue): "Get equation for rectangular." point.setToVector3(evaluate.getVector3ByDictionaryListValue(returnValue, point)) def equatePoints(elementNode, points, prefix, revolutions): "Equate the points." derivation = EquationDerivation(elementNode, prefix) for equationResult in derivation.equationResults: for point in points: returnValue = equationResult.getReturnValue(point, revolutions) if returnValue == None: print('Warning, returnValue in alterVertexesByEquation in equation is None for:') print(point) print(elementNode) else: equationResult.equationFunction(point, returnValue) def equateX(point, returnValue): "Get equation for rectangular x." point.x = returnValue def equateY(point, returnValue): "Get equation for rectangular y." point.y = returnValue def equateZ(point, returnValue): "Get equation for rectangular z." point.z = returnValue def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): "Get equated geometryOutput." equatePoints(elementNode, matrix.getVertexes(geometryOutput), prefix, None) return geometryOutput def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): "Get equated paths." equatePoints(elementNode, loop, prefix, 0.0) return [loop] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return EquationDerivation(elementNode, prefix) class EquationDerivation: "Class to hold equation variables." def __init__(self, elementNode, prefix): 'Set defaults.' self.equationResults = [] self.addEquationResult(elementNode, equate, prefix) self.addEquationResult(elementNode, equateX, prefix) self.addEquationResult(elementNode, equateY, prefix) self.addEquationResult(elementNode, equateZ, prefix) def addEquationResult(self, elementNode, equationFunction, prefix): 'Add equation result to equationResults.' prefixedEquationName = prefix + equationFunction.__name__[ len('equate') : ].replace('Dot', '.').lower() if prefixedEquationName in elementNode.attributes: self.equationResults.append(EquationResult(elementNode, equationFunction, prefixedEquationName)) class EquationResult: "Class to get equation results." def __init__(self, elementNode, equationFunction, key): "Initialize." self.distance = 0.0 elementNode.xmlObject = evaluate.getEvaluatorSplitWords(elementNode.attributes[key]) self.equationFunction = equationFunction self.function = evaluate.Function(elementNode) self.points = [] def getReturnValue(self, point, revolutions): "Get return value." if self.function is None: return point self.function.localDictionary['azimuth'] = math.degrees(math.atan2(point.y, point.x)) if len(self.points) > 0: self.distance += abs(point - self.points[-1]) self.function.localDictionary['distance'] = self.distance self.function.localDictionary['radius'] = abs(point.dropAxis()) if revolutions != None: if len( self.points ) > 0: revolutions += 0.5 / math.pi * euclidean.getAngleAroundZAxisDifference(point, self.points[-1]) self.function.localDictionary['revolutions'] = revolutions self.function.localDictionary['vertex'] = point self.function.localDictionary['vertexes'] = self.points self.function.localDictionary['vertexindex'] = len(self.points) self.function.localDictionary['x'] = point.x self.function.localDictionary['y'] = point.y self.function.localDictionary['z'] = point.z self.points.append(point) return self.function.getReturnValueWithoutDeletion() sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_shapes/flip.py000066400000000000000000000060741167321211700266370ustar00rootroot00000000000000""" Add material to support overhang or remove material at the overhang angle. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.vector3 import Vector3 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 200 # http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=269576 # http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node159.html # m.a00 = -2 * norm.x * norm.x + 1; # m.a10 = -2 * norm.y * norm.x; # m.a20 = -2 * norm.z * norm.x; # m.a30 = 0; # m.a01 = -2 * norm.x * norm.y; # m.a11 = -2 * norm.y * norm.y + 1; # m.a21 = -2 * norm.z * norm.y; # m.a31 = 0; # m.a02 = -2 * norm.x * norm.z; # m.a12 = -2 * norm.y * norm.z; # m.a22 = -2 * norm.z * norm.z + 1; # m.a32 = 0; # m.a03 = -2 * norm.x * d; # m.a13 = -2 * norm.y * d; # m.a23 = -2 * norm.z * d; # m.a33 = 1; # normal = unit_vector(normal[:3]) # M = numpy.identity(4) # M[:3, :3] -= 2.0 * numpy.outer(normal, normal) # M[:3, 3] = (2.0 * numpy.dot(point[:3], normal)) * normal # return M def flipPoints(elementNode, points, prefix): 'Flip the points.' derivation = FlipDerivation(elementNode, prefix) for point in points: point.setToVector3(point - 2.0 * derivation.axis.dot(point - derivation.origin) * derivation.axis) def getFlippedLoop(elementNode, loop, prefix): 'Get flipped loop.' flipPoints(elementNode, loop, prefix) if getShouldReverse(elementNode, prefix): loop.reverse() return loop def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): 'Get equated geometryOutput.' flipPoints(elementNode, matrix.getVertexes(geometryOutput), prefix) return geometryOutput def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): 'Get flipped paths.' return [getFlippedLoop(elementNode, loop, prefix)] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return FlipDerivation(elementNode, prefix) def getShouldReverse(elementNode, prefix): 'Determine if the loop should be reversed.' return evaluate.getEvaluatedBoolean(True, elementNode, prefix + 'reverse') def processElementNode(elementNode): 'Process the xml element.' solid.processElementNodeByFunctionPair(elementNode, getManipulatedGeometryOutput, getManipulatedPaths) class FlipDerivation: "Class to hold flip variables." def __init__(self, elementNode, prefix): 'Set defaults.' self.origin = evaluate.getVector3ByPrefix(Vector3(), elementNode, prefix + 'origin') self.axis = evaluate.getVector3ByPrefix(Vector3(1.0, 0.0, 0.0), elementNode, prefix + 'axis').getNormalized() sfact-2011.12.18/fabmetheus_utilities/geometry/manipulation_shapes/mirror.py000066400000000000000000000037451167321211700272210ustar00rootroot00000000000000""" Add material to support overhang or remove material at the overhang angle. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_tools import face from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.geometry.manipulation_shapes import flip from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalExecutionOrder = 200 def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): 'Get equated geometryOutput.' flippedGeometryOutput = triangle_mesh.getGeometryOutputCopy(geometryOutput) flip.flipPoints(elementNode, matrix.getVertexes(flippedGeometryOutput), prefix) if flip.getShouldReverse(elementNode, prefix): flippedFaces = face.getFaces(flippedGeometryOutput) for flippedFace in flippedFaces: flippedFace.vertexIndexes.reverse() return {'union' : {'shapes' : [flippedGeometryOutput, geometryOutput]}} def getManipulatedPaths(close, elementNode, loop, prefix, sideLength): 'Get flipped paths.' return [loop + flip.getFlippedLoop(elementNode, euclidean.getPathCopy(loop), prefix)] def getNewDerivation(elementNode, prefix, sideLength): 'Get new derivation.' return evaluate.EmptyObject() def processElementNode(elementNode): 'Process the xml element.' solid.processElementNodeByFunctionPair(elementNode, getManipulatedGeometryOutput, getManipulatedPaths) sfact-2011.12.18/fabmetheus_utilities/geometry/solids/000077500000000000000000000000001167321211700225565ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/solids/__init__.py000066400000000000000000000007351167321211700246740ustar00rootroot00000000000000""" This page is in the table of contents. This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. """ import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/solids/cube.py000066400000000000000000000051471167321211700240550ustar00rootroot00000000000000""" Boolean geometry cube. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addCube(elementNode, faces, inradius, vertexes): 'Add cube by inradius.' square = [ complex(-inradius.x, -inradius.y), complex(inradius.x, -inradius.y), complex(inradius.x, inradius.y), complex(-inradius.x, inradius.y)] bottomTopSquare = triangle_mesh.getAddIndexedLoops(square, vertexes, [-inradius.z, inradius.z]) triangle_mesh.addPillarByLoops(faces, bottomTopSquare) def getGeometryOutput(elementNode, inradius): 'Get cube triangle mesh by inradius.' faces = [] vertexes = [] addCube(elementNode, faces, inradius, vertexes) return {'trianglemesh' : {'vertex' : vertexes, 'face' : faces}} def getNewDerivation(elementNode): 'Get new derivation.' return CubeDerivation(elementNode) def processElementNode(elementNode): 'Process the xml element.' evaluate.processArchivable(Cube, elementNode) class Cube(triangle_mesh.TriangleMesh): 'A cube object.' def addXMLSection(self, depth, output): 'Add the xml section for this object.' pass def createShape(self): 'Create the shape.' addCube(self.elementNode, self.faces, self.inradius, self.vertexes) def setToElementNode(self, elementNode): 'Set to elementNode.' attributes = elementNode.attributes self.elementNode = elementNode self.inradius = CubeDerivation(elementNode).inradius attributes['inradius.x'] = self.inradius.x attributes['inradius.y'] = self.inradius.y attributes['inradius.z'] = self.inradius.z if 'inradius' in attributes: del attributes['inradius'] self.createShape() solid.processArchiveRemoveSolid(elementNode, self.getGeometryOutput()) class CubeDerivation: "Class to hold cube variables." def __init__(self, elementNode): 'Set defaults.' self.inradius = evaluate.getVector3ByPrefixes(elementNode, ['demisize', 'inradius'], Vector3(1.0, 1.0, 1.0)) self.inradius = evaluate.getVector3ByMultiplierPrefix(elementNode, 2.0, 'size', self.inradius) sfact-2011.12.18/fabmetheus_utilities/geometry/solids/cylinder.py000066400000000000000000000111221167321211700247360ustar00rootroot00000000000000""" Boolean geometry cylinder. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import lineation from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.geometry.solids import cube from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addCylinder(faces, inradius, sides, topOverBottom, vertexes): 'Add cylinder by inradius.' polygonBottom = euclidean.getComplexPolygonByComplexRadius(complex(inradius.x, inradius.y), sides) polygonTop = polygonBottom if topOverBottom <= 0.0: polygonTop = [complex()] elif topOverBottom != 1.0: polygonTop = euclidean.getComplexPathByMultiplier(topOverBottom, polygonTop) bottomTopPolygon = [ triangle_mesh.getAddIndexedLoop(polygonBottom, vertexes, -inradius.z), triangle_mesh.getAddIndexedLoop(polygonTop, vertexes, inradius.z)] triangle_mesh.addPillarByLoops(faces, bottomTopPolygon) def addCylinderOutputByEndStart(endZ, inradiusComplex, outputs, sides, start, topOverBottom=1.0): 'Add cylinder triangle mesh by endZ, inradius and start.' inradius = Vector3(inradiusComplex.real, inradiusComplex.imag, 0.5 * abs(endZ - start.z)) cylinderOutput = getGeometryOutput(inradius, sides, topOverBottom) vertexes = matrix.getVertexes(cylinderOutput) if endZ < start.z: for vertex in vertexes: vertex.z = -vertex.z translation = Vector3(start.x, start.y, inradius.z + min(start.z, endZ)) euclidean.translateVector3Path(vertexes, translation) outputs.append(cylinderOutput) def getGeometryOutput(inradius, sides, topOverBottom): 'Get cylinder triangle mesh by inradius.' faces = [] vertexes = [] addCylinder(faces, inradius, sides, topOverBottom, vertexes) return {'trianglemesh' : {'vertex' : vertexes, 'face' : faces}} def getNewDerivation(elementNode): 'Get new derivation.' return CylinderDerivation(elementNode) def getTopOverBottom(angle, endZ, inradiusComplex, startZ): 'Get topOverBottom by angle in radians, endZ, inradius and start.' return max(1.0 - abs(endZ - startZ) * math.tan(angle) / lineation.getRadiusAverage(inradiusComplex), 0.0) def processElementNode(elementNode): 'Process the xml element.' evaluate.processArchivable(Cylinder, elementNode) class Cylinder( cube.Cube ): 'A cylinder object.' def __init__(self): 'Add empty lists.' cube.Cube.__init__(self) def createShape(self): 'Create the shape.' sides = evaluate.getSidesMinimumThreeBasedOnPrecision(self.elementNode, max(self.inradius.x, self.inradius.y)) if self.elementNode.getCascadeBoolean(False, 'radiusAreal'): radiusArealizedMultiplier = euclidean.getRadiusArealizedMultiplier(sides) self.inradius.x *= radiusArealizedMultiplier self.inradius.y *= radiusArealizedMultiplier addCylinder(self.faces, self.inradius, sides, self.topOverBottom, self.vertexes) def setToElementNode(self, elementNode): 'Set to elementNode.' attributes = elementNode.attributes self.elementNode = elementNode derivation = CylinderDerivation(elementNode) self.inradius = derivation.inradius self.topOverBottom = derivation.topOverBottom if 'inradius' in attributes: del attributes['inradius'] attributes['height'] = self.inradius.z + self.inradius.z attributes['radius.x'] = self.inradius.x attributes['radius.y'] = self.inradius.y attributes['topOverBottom'] = self.topOverBottom self.createShape() solid.processArchiveRemoveSolid(elementNode, self.getGeometryOutput()) class CylinderDerivation: "Class to hold cylinder variables." def __init__(self, elementNode): 'Set defaults.' self.inradius = evaluate.getVector3ByPrefixes(elementNode, ['demisize', 'inradius', 'radius'], Vector3(1.0, 1.0, 1.0)) self.inradius = evaluate.getVector3ByMultiplierPrefixes(elementNode, 2.0, ['diameter', 'size'], self.inradius) self.inradius.z = 0.5 * evaluate.getEvaluatedFloat(self.inradius.z + self.inradius.z, elementNode, 'height') self.topOverBottom = evaluate.getEvaluatedFloat(1.0, elementNode, 'topOverBottom') sfact-2011.12.18/fabmetheus_utilities/geometry/solids/difference.py000066400000000000000000000027551167321211700252330ustar00rootroot00000000000000""" Boolean geometry difference of solids. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import boolean_solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import group __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def convertElementNode(elementNode, geometryOutput): "Convert the xml element to a difference xml element." group.convertContainerElementNode(elementNode, geometryOutput, Difference()) def getNewDerivation(elementNode): 'Get new derivation.' return evaluate.EmptyObject(elementNode) def processElementNode(elementNode): "Process the xml element." evaluate.processArchivable(Difference, elementNode) class Difference( boolean_solid.BooleanSolid ): "A difference object." def getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList): "Get loops from visible object loops list." return self.getDifference(importRadius, visibleObjectLoopsList) def getXMLLocalName(self): "Get xml class name." return self.__class__.__name__.lower() sfact-2011.12.18/fabmetheus_utilities/geometry/solids/group.py000066400000000000000000000053201167321211700242640ustar00rootroot00000000000000""" Boolean geometry group of solids. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import dictionary from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities import euclidean __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def convertContainerElementNode(elementNode, geometryOutput, xmlObject): "Convert the xml element to a group xml element." elementNode.linkObject(xmlObject) matrix.getBranchMatrixSetElementNode(elementNode) elementNode.getXMLProcessor().createChildNodes(geometryOutput['shapes'], elementNode) def convertElementNode(elementNode, geometryOutput): "Convert the xml element to a group xml element." convertContainerElementNode(elementNode, geometryOutput, Group()) def getNewDerivation(elementNode): 'Get new derivation.' return evaluate.EmptyObject(elementNode) def processElementNode(elementNode): "Process the xml element." evaluate.processArchivable(Group, elementNode) class Group(dictionary.Dictionary): "A group." def __init__(self): "Add empty lists." dictionary.Dictionary.__init__(self) self.matrix4X4 = matrix.Matrix() def addXMLInnerSection(self, depth, output): "Add xml inner section for this object." if self.matrix4X4 != None: self.matrix4X4.addXML(depth, output) self.addXMLSection(depth, output) def addXMLSection(self, depth, output): "Add the xml section for this object." pass def getLoops(self, importRadius, z): "Get loops sliced through shape." visibleObjects = evaluate.getVisibleObjects(self.archivableObjects) loops = [] for visibleObject in visibleObjects: loops += visibleObject.getLoops(importRadius, z) return loops def getMatrix4X4(self): "Get the matrix4X4." return self.matrix4X4 def getMatrixChainTetragrid(self): "Get the matrix chain tetragrid." return matrix.getTetragridTimesOther(self.elementNode.parentNode.xmlObject.getMatrixChainTetragrid(), self.matrix4X4.tetragrid) def getVisible(self): "Get visible." return euclidean.getBooleanFromDictionary(True, self.getAttributes(), 'visible') def setToElementNode(self, elementNode): 'Set to elementNode.' self.elementNode = elementNode elementNode.parentNode.xmlObject.archivableObjects.append(self) matrix.getBranchMatrixSetElementNode(elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry/solids/intersection.py000066400000000000000000000026111167321211700256360ustar00rootroot00000000000000""" Boolean geometry intersection of solids. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import difference from fabmetheus_utilities.geometry.solids import group __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def convertElementNode(elementNode, geometryOutput): "Convert the xml element to an intersection xml element." group.convertContainerElementNode(elementNode, geometryOutput, Intersection()) def getNewDerivation(elementNode): 'Get new derivation.' return evaluate.EmptyObject(elementNode) def processElementNode(elementNode): "Process the xml element." evaluate.processArchivable(Intersection, elementNode) class Intersection(difference.Difference): "An intersection object." def getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList): "Get loops from visible object loops list." return self.getIntersection(importRadius, visibleObjectLoopsList) sfact-2011.12.18/fabmetheus_utilities/geometry/solids/sphere.py000066400000000000000000000061411167321211700244200ustar00rootroot00000000000000""" Boolean geometry sphere. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.creation import solid from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import cube from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addSphere(elementNode, faces, radius, vertexes): 'Add sphere by radius.' bottom = -radius.z sides = evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, max(radius.x, radius.y, radius.z)) sphereSlices = max(sides / 2, 2) equator = euclidean.getComplexPolygonByComplexRadius(complex(radius.x, radius.y), sides) polygons = [triangle_mesh.getAddIndexedLoop([complex()], vertexes, bottom)] zIncrement = (radius.z + radius.z) / float(sphereSlices) z = bottom for sphereSlice in xrange(1, sphereSlices): z += zIncrement zPortion = abs(z) / radius.z multipliedPath = euclidean.getComplexPathByMultiplier(math.sqrt(1.0 - zPortion * zPortion), equator) polygons.append(triangle_mesh.getAddIndexedLoop(multipliedPath, vertexes, z)) polygons.append(triangle_mesh.getAddIndexedLoop([complex()], vertexes, radius.z)) triangle_mesh.addPillarByLoops(faces, polygons) def getGeometryOutput(elementNode, radius): 'Get triangle mesh from attribute dictionary.' faces = [] vertexes = [] addSphere(elementNode, faces, radius, vertexes) return {'trianglemesh' : {'vertex' : vertexes, 'face' : faces}} def getNewDerivation(elementNode): 'Get new derivation.' return SphereDerivation(elementNode) def processElementNode(elementNode): 'Process the xml element.' evaluate.processArchivable(Sphere, elementNode) class Sphere(cube.Cube): 'A sphere object.' def createShape(self): 'Create the shape.' addSphere(self.elementNode, self.faces, self.radius, self.vertexes) def setToElementNode(self, elementNode): 'Set to elementNode.' attributes = elementNode.attributes self.elementNode = elementNode self.radius = SphereDerivation(elementNode).radius if 'radius' in attributes: del attributes['radius'] attributes['radius.x'] = self.radius.x attributes['radius.y'] = self.radius.y attributes['radius.z'] = self.radius.z self.createShape() solid.processArchiveRemoveSolid(elementNode, self.getGeometryOutput()) class SphereDerivation: "Class to hold sphere variables." def __init__(self, elementNode): 'Set defaults.' self.radius = evaluate.getVector3ByPrefixes(elementNode, ['demisize', 'radius'], Vector3(1.0, 1.0, 1.0)) self.radius = evaluate.getVector3ByMultiplierPrefixes(elementNode, 2.0, ['diameter', 'size'], self.radius) sfact-2011.12.18/fabmetheus_utilities/geometry/solids/triangle_mesh.py000066400000000000000000001072171167321211700257610ustar00rootroot00000000000000""" Triangle Mesh holds the faces and edges of a triangular mesh. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_tools import face from fabmetheus_utilities.geometry.geometry_tools import dictionary from fabmetheus_utilities.geometry.geometry_tools import vertex from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities.geometry.solids import group from fabmetheus_utilities import xml_simple_writer from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities.vector3index import Vector3Index from fabmetheus_utilities import euclidean from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addEdgePair( edgePairTable, edges, faceEdgeIndex, remainingEdgeIndex, remainingEdgeTable ): 'Add edge pair to the edge pair table.' if faceEdgeIndex == remainingEdgeIndex: return if not faceEdgeIndex in remainingEdgeTable: return edgePair = EdgePair().getFromIndexesEdges( [ remainingEdgeIndex, faceEdgeIndex ], edges ) edgePairTable[ str( edgePair ) ] = edgePair def addFacesByConcaveLoop(faces, indexedLoop): 'Add faces from a polygon which is concave.' if len(indexedLoop) < 3: return remainingLoop = indexedLoop[:] while len(remainingLoop) > 2: remainingLoop = getRemainingLoopAddFace(faces, remainingLoop) def addFacesByConvex(faces, indexedLoop): 'Add faces from a convex polygon.' if len(indexedLoop) < 3: return indexBegin = indexedLoop[0].index for indexedPointIndex in xrange(1, len(indexedLoop) - 1): indexCenter = indexedLoop[indexedPointIndex].index indexEnd = indexedLoop[(indexedPointIndex + 1) % len(indexedLoop) ].index if indexBegin != indexCenter and indexCenter != indexEnd and indexEnd != indexBegin: faceFromConvex = face.Face() faceFromConvex.index = len(faces) faceFromConvex.vertexIndexes.append(indexBegin) faceFromConvex.vertexIndexes.append(indexCenter) faceFromConvex.vertexIndexes.append(indexEnd) faces.append(faceFromConvex) def addFacesByConvexBottomTopLoop(faces, indexedLoopBottom, indexedLoopTop): 'Add faces from loops.' if len(indexedLoopBottom) == 0 or len(indexedLoopTop) == 0: return for indexedPointIndex in xrange(max(len(indexedLoopBottom), len(indexedLoopTop))): indexedConvex = [] if len(indexedLoopBottom) > 1: indexedConvex.append(indexedLoopBottom[indexedPointIndex]) indexedConvex.append(indexedLoopBottom[(indexedPointIndex + 1) % len(indexedLoopBottom)]) else: indexedConvex.append(indexedLoopBottom[0]) if len(indexedLoopTop) > 1: indexedConvex.append(indexedLoopTop[(indexedPointIndex + 1) % len(indexedLoopTop)]) indexedConvex.append(indexedLoopTop[indexedPointIndex]) else: indexedConvex.append(indexedLoopTop[0]) addFacesByConvex(faces, indexedConvex) def addFacesByConvexLoops(faces, indexedLoops): 'Add faces from loops.' if len(indexedLoops) < 2: return for indexedLoopsIndex in xrange(len(indexedLoops) - 2): addFacesByConvexBottomTopLoop(faces, indexedLoops[indexedLoopsIndex], indexedLoops[indexedLoopsIndex + 1]) indexedLoopBottom = indexedLoops[-2] indexedLoopTop = indexedLoops[-1] if len(indexedLoopTop) < 1: indexedLoopTop = indexedLoops[0] addFacesByConvexBottomTopLoop(faces, indexedLoopBottom, indexedLoopTop) def addFacesByConvexReversed(faces, indexedLoop): 'Add faces from a reversed convex polygon.' addFacesByConvex(faces, indexedLoop[: : -1]) def addFacesByGrid(faces, grid): 'Add faces from grid.' cellTopLoops = getIndexedCellLoopsFromIndexedGrid(grid) for cellTopLoop in cellTopLoops: addFacesByConvex(faces, cellTopLoop) def addFacesByLoop(faces, indexedLoop): 'Add faces from a polygon which may be concave.' if len(indexedLoop) < 3: return lastNormal = None for pointIndex, point in enumerate(indexedLoop): center = indexedLoop[(pointIndex + 1) % len(indexedLoop)] end = indexedLoop[(pointIndex + 2) % len(indexedLoop)] normal = euclidean.getNormalWeighted(point, center, end) if abs(normal) > 0.0: if lastNormal != None: if lastNormal.dot(normal) < 0.0: addFacesByConcaveLoop(faces, indexedLoop) return lastNormal = normal # totalNormal = Vector3() # for pointIndex, point in enumerate(indexedLoop): # center = indexedLoop[(pointIndex + 1) % len(indexedLoop)] # end = indexedLoop[(pointIndex + 2) % len(indexedLoop)] # totalNormal += euclidean.getNormalWeighted(point, center, end) # totalNormal.normalize() addFacesByConvex(faces, indexedLoop) def addFacesByLoopReversed(faces, indexedLoop): 'Add faces from a reversed convex polygon.' addFacesByLoop(faces, indexedLoop[: : -1]) def addFacesByMeldedConvexLoops(faces, indexedLoops): 'Add faces from melded loops.' if len(indexedLoops) < 2: return for indexedLoopsIndex in xrange(len(indexedLoops) - 2): FaceGenerator(faces, indexedLoops[indexedLoopsIndex], indexedLoops[indexedLoopsIndex + 1]) indexedLoopBottom = indexedLoops[-2] indexedLoopTop = indexedLoops[-1] if len(indexedLoopTop) < 1: indexedLoopTop = indexedLoops[0] FaceGenerator(faces, indexedLoopBottom, indexedLoopTop) def addLoopToPointTable(loop, pointTable): 'Add the points in the loop to the point table.' for point in loop: pointTable[point] = None def addMeldedPillarByLoops(faces, indexedLoops): 'Add melded pillar by loops which may be concave.' if len(indexedLoops) < 1: return if len(indexedLoops[-1]) < 1: addFacesByMeldedConvexLoops(faces, indexedLoops) return addFacesByLoopReversed(faces, indexedLoops[0]) addFacesByMeldedConvexLoops(faces, indexedLoops) addFacesByLoop(faces, indexedLoops[-1]) def addPillarByLoops(faces, indexedLoops): 'Add pillar by loops which may be concave.' if len(indexedLoops) < 1: return if len(indexedLoops[-1]) < 1: addFacesByConvexLoops(faces, indexedLoops) return addFacesByLoopReversed(faces, indexedLoops[0]) addFacesByConvexLoops(faces, indexedLoops) addFacesByLoop(faces, indexedLoops[-1]) def addPillarFromConvexLoopsGrids(faces, indexedGrids, indexedLoops): 'Add pillar from convex loops and grids.' cellBottomLoops = getIndexedCellLoopsFromIndexedGrid(indexedGrids[0]) for cellBottomLoop in cellBottomLoops: addFacesByConvexReversed(faces, cellBottomLoop) addFacesByConvexLoops(faces, indexedLoops) addFacesByGrid(faces, indexedGrids[-1]) def addPillarFromConvexLoopsGridTop(faces, indexedGridTop, indexedLoops): 'Add pillar from convex loops and grid top.' addFacesByLoopReversed(faces, indexedLoops[0]) addFacesByConvexLoops(faces, indexedLoops) addFacesByGrid(faces, indexedGridTop) def addPointsAtZ(edgePair, points, radius, vertexes, z): 'Add point complexes on the segment between the edge intersections with z.' carveIntersectionFirst = getCarveIntersectionFromEdge(edgePair.edges[0], vertexes, z) carveIntersectionSecond = getCarveIntersectionFromEdge(edgePair.edges[1], vertexes, z) # threshold radius above 0.8 can create extra holes on Screw Holder, 0.7 should be safe for everything intercircle.addPointsFromSegment(carveIntersectionFirst, carveIntersectionSecond, points, radius, 0.7) def addSymmetricXPath(outputs, path, x): 'Add x path output to outputs.' vertexes = [] loops = [getSymmetricXLoop(path, vertexes, -x), getSymmetricXLoop(path, vertexes, x)] outputs.append(getPillarOutput(loops)) def addSymmetricXPaths(outputs, paths, x): 'Add x paths outputs to outputs.' for path in paths: addSymmetricXPath(outputs, path, x) def addSymmetricYPath(outputs, path, y): 'Add y path output to outputs.' vertexes = [] loops = [getSymmetricYLoop(path, vertexes, -y), getSymmetricYLoop(path, vertexes, y)] outputs.append(getPillarOutput(loops)) def addSymmetricYPaths(outputs, paths, y): 'Add y paths outputs to outputs.' for path in paths: addSymmetricYPath(outputs, path, y) def addWithLeastLength(importRadius, loops, point): 'Insert a point into a loop, at the index at which the loop would be shortest.' close = 1.65 * importRadius # a bit over the experimental minimum additional loop length to restore a right angle shortestAdditionalLength = close shortestLoop = None shortestPointIndex = None for loop in loops: if len(loop) > 3: for pointIndex in xrange(len(loop)): additionalLoopLength = getAdditionalLoopLength(loop, point, pointIndex) if additionalLoopLength < shortestAdditionalLength: if getIsPointCloseInline(close, loop, point, pointIndex): shortestAdditionalLength = additionalLoopLength shortestLoop = loop shortestPointIndex = pointIndex if shortestPointIndex != None: shortestLoop.insert( shortestPointIndex, point ) def convertElementNode(elementNode, geometryOutput): 'Convert the xml element to a TriangleMesh xml element.' elementNode.linkObject(TriangleMesh()) matrix.getBranchMatrixSetElementNode(elementNode) vertex.addGeometryList(elementNode, geometryOutput['vertex']) face.addGeometryList(elementNode, geometryOutput['face']) elementNode.getXMLProcessor().processChildNodes(elementNode) def getAddIndexedGrid( grid, vertexes, z ): 'Get and add an indexed grid.' indexedGrid = [] for row in grid: indexedRow = [] indexedGrid.append( indexedRow ) for pointComplex in row: vector3index = Vector3Index( len(vertexes), pointComplex.real, pointComplex.imag, z ) indexedRow.append(vector3index) vertexes.append(vector3index) return indexedGrid def getAddIndexedLoop(loop, vertexes, z): 'Get and add an indexed loop.' indexedLoop = [] for index in xrange(len(loop)): pointComplex = loop[index] vector3index = Vector3Index(len(vertexes), pointComplex.real, pointComplex.imag, z) indexedLoop.append(vector3index) vertexes.append(vector3index) return indexedLoop def getAddIndexedLoops( loop, vertexes, zList ): 'Get and add indexed loops.' indexedLoops = [] for z in zList: indexedLoop = getAddIndexedLoop( loop, vertexes, z ) indexedLoops.append(indexedLoop) return indexedLoops def getAdditionalLoopLength(loop, point, pointIndex): 'Get the additional length added by inserting a point into a loop.' afterPoint = loop[pointIndex] beforePoint = loop[(pointIndex + len(loop) - 1) % len(loop)] return abs(point - beforePoint) + abs(point - afterPoint) - abs(afterPoint - beforePoint) def getCarveIntersectionFromEdge(edge, vertexes, z): 'Get the complex where the carve intersects the edge.' firstVertex = vertexes[ edge.vertexIndexes[0] ] firstVertexComplex = firstVertex.dropAxis() secondVertex = vertexes[ edge.vertexIndexes[1] ] secondVertexComplex = secondVertex.dropAxis() zMinusFirst = z - firstVertex.z up = secondVertex.z - firstVertex.z return zMinusFirst * ( secondVertexComplex - firstVertexComplex ) / up + firstVertexComplex def getClosestDistanceIndexToPoint(point, loop): 'Get the distance squared to the closest point of the loop and index of that point.' smallestDistance = 987654321987654321.0 closestDistanceIndex = None pointComplex = point.dropAxis() for otherPointIndex, otherPoint in enumerate(loop): distance = abs(pointComplex - otherPoint.dropAxis()) if distance < smallestDistance: smallestDistance = distance closestDistanceIndex = euclidean.DistanceIndex(distance, otherPointIndex) return closestDistanceIndex def getDescendingAreaLoops(allPoints, corners, importRadius): 'Get descending area loops which include most of the points.' loops = intercircle.getCentersFromPoints(allPoints, importRadius) descendingAreaLoops = [] sortLoopsInOrderOfArea(True, loops) pointDictionary = {} for loop in loops: if len(loop) > 2 and getOverlapRatio(loop, pointDictionary) < 0.3: intercircle.directLoop(not euclidean.getIsInFilledRegion(descendingAreaLoops, loop[0]), loop) descendingAreaLoops.append(loop) addLoopToPointTable(loop, pointDictionary) descendingAreaLoops = euclidean.getSimplifiedLoops(descendingAreaLoops, importRadius) return getLoopsWithCorners(corners, importRadius, descendingAreaLoops, pointDictionary) def getDescendingAreaOrientedLoops(allPoints, corners, importRadius): 'Get descending area oriented loops which include most of the points.' return getOrientedLoops(getDescendingAreaLoops(allPoints, corners, importRadius)) def getGeometryOutputByFacesVertexes(faces, vertexes): 'Get geometry output dictionary by faces and vertexes.' return {'trianglemesh' : {'vertex' : vertexes, 'face' : faces}} def getGeometryOutputCopy(object): 'Get the geometry output copy.' objectClass = object.__class__ if objectClass == dict: objectCopy = {} for key in object: objectCopy[key] = getGeometryOutputCopy(object[key]) return objectCopy if objectClass == list: objectCopy = [] for value in object: objectCopy.append(getGeometryOutputCopy(value)) return objectCopy if objectClass == face.Face or objectClass == Vector3 or objectClass == Vector3Index: return object.copy() return object def getIndexedCellLoopsFromIndexedGrid( grid ): 'Get indexed cell loops from an indexed grid.' indexedCellLoops = [] for rowIndex in xrange( len( grid ) - 1 ): rowBottom = grid[ rowIndex ] rowTop = grid[ rowIndex + 1 ] for columnIndex in xrange( len( rowBottom ) - 1 ): columnIndexEnd = columnIndex + 1 indexedConvex = [] indexedConvex.append( rowBottom[ columnIndex ] ) indexedConvex.append( rowBottom[ columnIndex + 1 ] ) indexedConvex.append( rowTop[ columnIndex + 1 ] ) indexedConvex.append( rowTop[ columnIndex ] ) indexedCellLoops.append( indexedConvex ) return indexedCellLoops def getIndexedLoopFromIndexedGrid( indexedGrid ): 'Get indexed loop from around the indexed grid.' indexedLoop = indexedGrid[0][:] for row in indexedGrid[1 : -1]: indexedLoop.append( row[-1] ) indexedLoop += indexedGrid[-1][: : -1] for row in indexedGrid[ len( indexedGrid ) - 2 : 0 : - 1 ]: indexedLoop.append( row[0] ) return indexedLoop def getInfillDictionary(aroundInset, arounds, aroundWidth, infillInset, infillWidth, pixelTable, rotatedLoops, testLoops=None): 'Get combined fill loops which include most of the points.' slightlyGreaterThanInfillInset = intercircle.globalIntercircleMultiplier * infillInset allPoints = intercircle.getPointsFromLoops(rotatedLoops, infillInset, 0.7) centers = intercircle.getCentersFromPoints(allPoints, slightlyGreaterThanInfillInset) infillDictionary = {} for center in centers: insetCenter = intercircle.getSimplifiedInsetFromClockwiseLoop(center, infillInset) insetPoint = insetCenter[0] if len(insetCenter) > 2 and intercircle.getIsLarge(insetCenter, infillInset) and euclidean.getIsInFilledRegion(rotatedLoops, insetPoint): around = intercircle.getSimplifiedInsetFromClockwiseLoop(center, aroundInset) euclidean.addLoopToPixelTable(around, pixelTable, aroundWidth) arounds.append(around) insetLoop = intercircle.getSimplifiedInsetFromClockwiseLoop(center, infillInset) euclidean.addXIntersectionsFromLoopForTable(insetLoop, infillDictionary, infillWidth) if testLoops != None: testLoops.append(insetLoop) return infillDictionary def getInsetPoint( loop, tinyRadius ): 'Get the inset vertex.' pointIndex = getWideAnglePointIndex(loop) point = loop[ pointIndex % len(loop) ] afterPoint = loop[(pointIndex + 1) % len(loop)] beforePoint = loop[ ( pointIndex - 1 ) % len(loop) ] afterSegmentNormalized = euclidean.getNormalized( afterPoint - point ) beforeSegmentNormalized = euclidean.getNormalized( beforePoint - point ) afterClockwise = complex( afterSegmentNormalized.imag, - afterSegmentNormalized.real ) beforeWiddershins = complex( - beforeSegmentNormalized.imag, beforeSegmentNormalized.real ) midpoint = afterClockwise + beforeWiddershins midpointNormalized = midpoint / abs( midpoint ) return point + midpointNormalized * tinyRadius def getIsPathEntirelyOutsideTriangle(begin, center, end, vector3Path): 'Determine if a path is entirely outside another loop.' loop = [begin.dropAxis(), center.dropAxis(), end.dropAxis()] for vector3 in vector3Path: point = vector3.dropAxis() if euclidean.isPointInsideLoop(loop, point): return False return True def getIsPointCloseInline(close, loop, point, pointIndex): 'Insert a point into a loop, at the index at which the loop would be shortest.' afterCenterComplex = loop[pointIndex] if abs(afterCenterComplex - point) > close: return False afterEndComplex = loop[(pointIndex + 1) % len(loop)] if not isInline( point, afterCenterComplex, afterEndComplex ): return False beforeCenterComplex = loop[(pointIndex + len(loop) - 1) % len(loop)] if abs(beforeCenterComplex - point) > close: return False beforeEndComplex = loop[(pointIndex + len(loop) - 2) % len(loop)] return isInline(point, beforeCenterComplex, beforeEndComplex) def getLoopsFromCorrectMesh( edges, faces, vertexes, z ): 'Get loops from a carve of a correct mesh.' remainingEdgeTable = getRemainingEdgeTable(edges, vertexes, z) remainingValues = remainingEdgeTable.values() for edge in remainingValues: if len( edge.faceIndexes ) < 2: print('This should never happen, there is a hole in the triangle mesh, each edge should have two faces.') print(edge) print('Something will still be printed, but there is no guarantee that it will be the correct shape.' ) print('Once the gcode is saved, you should check over the layer with a z of:') print(z) return [] loops = [] while isPathAdded( edges, faces, loops, remainingEdgeTable, vertexes, z ): pass if euclidean.isLoopListIntersecting(loops): print('Warning, the triangle mesh slice intersects itself in getLoopsFromCorrectMesh in triangle_mesh.') print('Something will still be printed, but there is no guarantee that it will be the correct shape.') print('Once the gcode is saved, you should check over the layer with a z of:') print(z) return [] return loops # untouchables = [] # for boundingLoop in boundingLoops: # if not boundingLoop.isIntersectingList( untouchables ): # untouchables.append( boundingLoop ) # if len( untouchables ) < len( boundingLoops ): # print('This should never happen, the carve layer intersects itself. Something will still be printed, but there is no guarantee that it will be the correct shape.') # print('Once the gcode is saved, you should check over the layer with a z of:') # print(z) # remainingLoops = [] # for untouchable in untouchables: # remainingLoops.append( untouchable.loop ) # return remainingLoops def getLoopsFromUnprovenMesh(edges, faces, importRadius, vertexes, z): 'Get loops from a carve of an unproven mesh.' edgePairTable = {} corners = [] remainingEdgeTable = getRemainingEdgeTable(edges, vertexes, z) remainingEdgeTableKeys = remainingEdgeTable.keys() for remainingEdgeIndexKey in remainingEdgeTable: edge = remainingEdgeTable[remainingEdgeIndexKey] carveIntersection = getCarveIntersectionFromEdge(edge, vertexes, z) corners.append(carveIntersection) for edgeFaceIndex in edge.faceIndexes: face = faces[edgeFaceIndex] for edgeIndex in face.edgeIndexes: addEdgePair(edgePairTable, edges, edgeIndex, remainingEdgeIndexKey, remainingEdgeTable) allPoints = corners[:] for edgePairValue in edgePairTable.values(): addPointsAtZ(edgePairValue, allPoints, importRadius, vertexes, z) pointTable = {} return getDescendingAreaLoops(allPoints, corners, importRadius) def getLoopLayerAppend(loopLayers, z): 'Get next z and add extruder loops.' settings.printProgress(len(loopLayers), 'slice') loopLayer = euclidean.LoopLayer(z) loopLayers.append(loopLayer) return loopLayer def getLoopsWithCorners(corners, importRadius, loops, pointTable): 'Add corners to the loops.' for corner in corners: if corner not in pointTable: addWithLeastLength(importRadius, loops, corner) pointTable[corner] = None return euclidean.getSimplifiedLoops(loops, importRadius) def getMeldedPillarOutput(loops): 'Get melded pillar output.' faces = [] vertexes = getUniqueVertexes(loops) addMeldedPillarByLoops(faces, loops) return getGeometryOutputByFacesVertexes(faces, vertexes) def getNewDerivation(elementNode): 'Get new derivation.' return evaluate.EmptyObject(elementNode) def getNextEdgeIndexAroundZ(edge, faces, remainingEdgeTable): 'Get the next edge index in the mesh carve.' for faceIndex in edge.faceIndexes: face = faces[faceIndex] for edgeIndex in face.edgeIndexes: if edgeIndex in remainingEdgeTable: return edgeIndex return -1 def getOrientedLoops(loops): 'Orient the loops which must be in descending order.' for loopIndex, loop in enumerate(loops): leftPoint = euclidean.getLeftPoint(loop) isInFilledRegion = euclidean.getIsInFilledRegion(loops[: loopIndex] + loops[loopIndex + 1 :], leftPoint) if isInFilledRegion == euclidean.isWiddershins(loop): loop.reverse() return loops def getOverlapRatio( loop, pointTable ): 'Get the overlap ratio between the loop and the point table.' numberOfOverlaps = 0 for point in loop: if point in pointTable: numberOfOverlaps += 1 return float( numberOfOverlaps ) / float(len(loop)) def getPath( edges, pathIndexes, loop, z ): 'Get the path from the edge intersections.' path = [] for pathIndexIndex in xrange( len( pathIndexes ) ): pathIndex = pathIndexes[ pathIndexIndex ] edge = edges[ pathIndex ] carveIntersection = getCarveIntersectionFromEdge( edge, loop, z ) path.append( carveIntersection ) return path def getPillarOutput(loops): 'Get pillar output.' faces = [] vertexes = getUniqueVertexes(loops) addPillarByLoops(faces, loops) return getGeometryOutputByFacesVertexes(faces, vertexes) def getPillarsOutput(loopLists): 'Get pillars output.' pillarsOutput = [] for loopList in loopLists: pillarsOutput.append(getPillarOutput(loopList)) return getUnifiedOutput(pillarsOutput) def getRemainingEdgeTable(edges, vertexes, z): 'Get the remaining edge hashtable.' remainingEdgeTable = {} if len(edges) > 0: if edges[0].zMinimum == None: for edge in edges: setEdgeMaximumMinimum(edge, vertexes) for edgeIndex in xrange(len(edges)): edge = edges[edgeIndex] if (edge.zMinimum < z) and (edge.zMaximum > z): remainingEdgeTable[edgeIndex] = edge return remainingEdgeTable def getRemainingLoopAddFace(faces, remainingLoop): 'Get the remaining loop and add face.' for indexedVertexIndex, indexedVertex in enumerate(remainingLoop): nextIndex = (indexedVertexIndex + 1) % len(remainingLoop) previousIndex = (indexedVertexIndex + len(remainingLoop) - 1) % len(remainingLoop) nextVertex = remainingLoop[nextIndex] previousVertex = remainingLoop[previousIndex] remainingPath = euclidean.getAroundLoop((indexedVertexIndex + 2) % len(remainingLoop), previousIndex, remainingLoop) if len(remainingLoop) < 4 or getIsPathEntirelyOutsideTriangle(previousVertex, indexedVertex, nextVertex, remainingPath): faceConvex = face.Face() faceConvex.index = len(faces) faceConvex.vertexIndexes.append(indexedVertex.index) faceConvex.vertexIndexes.append(nextVertex.index) faceConvex.vertexIndexes.append(previousVertex.index) faces.append(faceConvex) return euclidean.getAroundLoop(nextIndex, indexedVertexIndex, remainingLoop) print('Warning, could not decompose polygon in getRemainingLoopAddFace in trianglemesh for:') print(remainingLoop) return [] def getSharedFace( firstEdge, faces, secondEdge ): 'Get the face which is shared by two edges.' for firstEdgeFaceIndex in firstEdge.faceIndexes: for secondEdgeFaceIndex in secondEdge.faceIndexes: if firstEdgeFaceIndex == secondEdgeFaceIndex: return faces[ firstEdgeFaceIndex ] return None def getSymmetricXLoop(path, vertexes, x): 'Get symmetrix x loop.' loop = [] for point in path: vector3Index = Vector3Index(len(vertexes), x, point.real, point.imag) loop.append(vector3Index) vertexes.append(vector3Index) return loop def getSymmetricYLoop(path, vertexes, y): 'Get symmetrix y loop.' loop = [] for point in path: vector3Index = Vector3Index(len(vertexes), point.real, y, point.imag) loop.append(vector3Index) vertexes.append(vector3Index) return loop def getUnifiedOutput(outputs): 'Get unified output.' if len(outputs) < 1: return {} if len(outputs) == 1: return outputs[0] return {'union' : {'shapes' : outputs}} def getUniqueVertexes(loops): 'Get unique vertexes.' vertexDictionary = {} uniqueVertexes = [] for loop in loops: for vertexIndex, vertex in enumerate(loop): vertexTuple = (vertex.x, vertex.y, vertex.z) if vertexTuple in vertexDictionary: loop[vertexIndex] = vertexDictionary[vertexTuple] else: if vertex.__class__ == Vector3Index: loop[vertexIndex].index = len(vertexDictionary) else: loop[vertexIndex] = Vector3Index(len(vertexDictionary), vertex.x, vertex.y, vertex.z) vertexDictionary[vertexTuple] = loop[vertexIndex] uniqueVertexes.append(loop[vertexIndex]) return uniqueVertexes def getWideAnglePointIndex(loop): 'Get a point index which has a wide enough angle, most point indexes have a wide enough angle, this is just to make sure.' dotProductMinimum = 9999999.9 widestPointIndex = 0 for pointIndex in xrange(len(loop)): point = loop[ pointIndex % len(loop) ] afterPoint = loop[(pointIndex + 1) % len(loop)] beforePoint = loop[ ( pointIndex - 1 ) % len(loop) ] afterSegmentNormalized = euclidean.getNormalized( afterPoint - point ) beforeSegmentNormalized = euclidean.getNormalized( beforePoint - point ) dotProduct = euclidean.getDotProduct( afterSegmentNormalized, beforeSegmentNormalized ) if dotProduct < .99: return pointIndex if dotProduct < dotProductMinimum: dotProductMinimum = dotProduct widestPointIndex = pointIndex return widestPointIndex def isInline( beginComplex, centerComplex, endComplex ): 'Determine if the three complex points form a line.' centerBeginComplex = beginComplex - centerComplex centerEndComplex = endComplex - centerComplex centerBeginLength = abs( centerBeginComplex ) centerEndLength = abs( centerEndComplex ) if centerBeginLength <= 0.0 or centerEndLength <= 0.0: return False centerBeginComplex /= centerBeginLength centerEndComplex /= centerEndLength return euclidean.getDotProduct( centerBeginComplex, centerEndComplex ) < -0.999 def isPathAdded( edges, faces, loops, remainingEdgeTable, vertexes, z ): 'Get the path indexes around a triangle mesh carve and add the path to the flat loops.' if len( remainingEdgeTable ) < 1: return False pathIndexes = [] remainingEdgeIndexKey = remainingEdgeTable.keys()[0] pathIndexes.append( remainingEdgeIndexKey ) del remainingEdgeTable[remainingEdgeIndexKey] nextEdgeIndexAroundZ = getNextEdgeIndexAroundZ( edges[remainingEdgeIndexKey], faces, remainingEdgeTable ) while nextEdgeIndexAroundZ != - 1: pathIndexes.append( nextEdgeIndexAroundZ ) del remainingEdgeTable[ nextEdgeIndexAroundZ ] nextEdgeIndexAroundZ = getNextEdgeIndexAroundZ( edges[ nextEdgeIndexAroundZ ], faces, remainingEdgeTable ) if len( pathIndexes ) < 3: print('Dangling edges, will use intersecting circles to get import layer at height %s' % z) del loops[:] return False loops.append( getPath( edges, pathIndexes, vertexes, z ) ) return True def processElementNode(elementNode): 'Process the xml element.' evaluate.processArchivable(TriangleMesh, elementNode) def setEdgeMaximumMinimum(edge, vertexes): 'Set the edge maximum and minimum.' beginIndex = edge.vertexIndexes[0] endIndex = edge.vertexIndexes[1] if beginIndex >= len(vertexes) or endIndex >= len(vertexes): print('Warning, there are duplicate vertexes in setEdgeMaximumMinimum in triangle_mesh.') print('Something might still be printed, but there is no guarantee that it will be the correct shape.' ) edge.zMaximum = -987654321.0 edge.zMinimum = -987654321.0 return beginZ = vertexes[beginIndex].z endZ = vertexes[endIndex].z edge.zMinimum = min(beginZ, endZ) edge.zMaximum = max(beginZ, endZ) def sortLoopsInOrderOfArea(isDescending, loops): 'Sort the loops in the order of area according isDescending.' loops.sort(key=euclidean.getAreaLoopAbsolute, reverse=isDescending) class EdgePair: def __init__(self): 'Pair of edges on a face.' self.edgeIndexes = [] self.edges = [] def __repr__(self): 'Get the string representation of this EdgePair.' return str( self.edgeIndexes ) def getFromIndexesEdges( self, edgeIndexes, edges ): 'Initialize from edge indices.' self.edgeIndexes = edgeIndexes[:] self.edgeIndexes.sort() for edgeIndex in self.edgeIndexes: self.edges.append( edges[ edgeIndex ] ) return self class FaceGenerator: 'A face generator.' def __init__(self, faces, indexedLoopBottom, indexedLoopTop): 'Initialize.' self.startTop = 0 if len(indexedLoopBottom) == 0 or len(indexedLoopTop) == 0: return smallestDistance = 987654321987654321.0 for pointIndex, point in enumerate(indexedLoopBottom): distanceIndex = getClosestDistanceIndexToPoint(point, indexedLoopTop) if distanceIndex.distance < smallestDistance: smallestDistance = distanceIndex.distance offsetBottom = pointIndex offsetTop = distanceIndex.index self.indexedLoopBottom = indexedLoopBottom[offsetBottom :] + indexedLoopBottom[: offsetBottom] self.indexedLoopTop = indexedLoopTop[offsetTop :] + indexedLoopTop[: offsetTop] for bottomIndex in xrange(len(self.indexedLoopBottom)): self.addFacesByBottomIndex(bottomIndex, faces) subsetTop = self.indexedLoopTop[self.startTop :] subsetTop.append(self.indexedLoopTop[0]) addFacesByConvexBottomTopLoop(faces, [self.indexedLoopBottom[0]], subsetTop[: : -1]) def addFacesByBottomIndex(self, bottomIndex, faces): 'Add faces from the bottom index to the next index.' bottomPoint = self.indexedLoopBottom[bottomIndex % len(self.indexedLoopBottom)] bottomPointNext = self.indexedLoopBottom[(bottomIndex + 1) % len(self.indexedLoopBottom)] topIndex = self.startTop + getClosestDistanceIndexToPoint(bottomPointNext, self.indexedLoopTop[self.startTop :]).index topIndexPlusOne = topIndex + 1 betweenIndex = self.getBetweenIndex(bottomPoint, bottomPointNext, topIndexPlusOne) betweenIndexPlusOne = betweenIndex + 1 subsetStart = self.indexedLoopTop[self.startTop : betweenIndexPlusOne] subsetEnd = self.indexedLoopTop[betweenIndex : topIndexPlusOne] addFacesByConvexBottomTopLoop(faces, [bottomPoint], subsetStart[: : -1]) addFacesByConvexBottomTopLoop(faces, [bottomPoint, bottomPointNext], [self.indexedLoopTop[betweenIndex]]) addFacesByConvexBottomTopLoop(faces, [bottomPointNext], subsetEnd[: : -1]) self.startTop = topIndex def getBetweenIndex(self, bottomPoint, bottomPointNext, topIndexPlusOne): 'Get the index of the last point along the loop which is closer to the bottomPoint.' betweenIndex = self.startTop bottomPointComplex = bottomPoint.dropAxis() bottomPointNextComplex = bottomPointNext.dropAxis() for topPointIndex in xrange(self.startTop, topIndexPlusOne): topPointComplex = self.indexedLoopTop[topPointIndex].dropAxis() if abs(topPointComplex - bottomPointComplex) > abs(topPointComplex - bottomPointNextComplex): return betweenIndex betweenIndex = topPointIndex return betweenIndex class TriangleMesh( group.Group ): 'A triangle mesh.' def __init__(self): 'Add empty lists.' group.Group.__init__(self) self.belowLoops = [] self.edges = [] self.faces = [] self.importCoarseness = 1.0 self.isCorrectMesh = True self.loopLayers = [] self.oldChainTetragrid = None self.transformedVertexes = None self.vertexes = [] def addXMLSection(self, depth, output): 'Add the xml section for this object.' xml_simple_writer.addXMLFromVertexes( depth, output, self.vertexes ) xml_simple_writer.addXMLFromObjects( depth, self.faces, output ) def getCarveBoundaryLayers(self): 'Get the boundary layers.' if self.getMinimumZ() == None: return [] halfHeight = 0.5 * self.layerThickness self.zoneArrangement = ZoneArrangement(self.layerThickness, self.getTransformedVertexes()) layerTop = self.cornerMaximum.z - halfHeight * 0.5 z = self.cornerMinimum.z + halfHeight while z < layerTop: getLoopLayerAppend(self.loopLayers, z).loops = self.getLoopsFromMesh(self.zoneArrangement.getEmptyZ(z)) z += self.layerThickness return self.loopLayers def getCarveCornerMaximum(self): 'Get the corner maximum of the vertexes.' return self.cornerMaximum def getCarveCornerMinimum(self): 'Get the corner minimum of the vertexes.' return self.cornerMinimum def getCarveLayerThickness(self): 'Get the layer thickness.' return self.layerThickness def getFabmetheusXML(self): 'Return the fabmetheus XML.' return None def getGeometryOutput(self): 'Get geometry output dictionary.' return getGeometryOutputByFacesVertexes(self.faces, self.vertexes) def getInterpretationSuffix(self): 'Return the suffix for a triangle mesh.' return 'xml' def getLoops(self, importRadius, z): 'Get loops sliced through shape.' self.importRadius = importRadius return self.getLoopsFromMesh(z) def getLoopsFromMesh( self, z ): 'Get loops from a carve of a mesh.' originalLoops = [] self.setEdgesForAllFaces() if self.isCorrectMesh: originalLoops = getLoopsFromCorrectMesh( self.edges, self.faces, self.getTransformedVertexes(), z ) if len( originalLoops ) < 1: originalLoops = getLoopsFromUnprovenMesh( self.edges, self.faces, self.importRadius, self.getTransformedVertexes(), z ) loops = euclidean.getSimplifiedLoops(originalLoops, self.importRadius) sortLoopsInOrderOfArea(True, loops) return getOrientedLoops(loops) def getMinimumZ(self): 'Get the minimum z.' self.cornerMaximum = Vector3(-987654321.0, -987654321.0, -987654321.0) self.cornerMinimum = Vector3(987654321.0, 987654321.0, 987654321.0) transformedVertexes = self.getTransformedVertexes() if len(transformedVertexes) < 1: return None for point in transformedVertexes: self.cornerMaximum.maximize(point) self.cornerMinimum.minimize(point) return self.cornerMinimum.z def getTransformedVertexes(self): 'Get all transformed vertexes.' if self.elementNode == None: return self.vertexes chainTetragrid = self.getMatrixChainTetragrid() if self.oldChainTetragrid != chainTetragrid: self.oldChainTetragrid = matrix.getTetragridCopy(chainTetragrid) self.transformedVertexes = None if self.transformedVertexes == None: if len(self.edges) > 0: self.edges[0].zMinimum = None self.transformedVertexes = matrix.getTransformedVector3s(chainTetragrid, self.vertexes) return self.transformedVertexes def getTriangleMeshes(self): 'Get all triangleMeshes.' return [self] def getVertexes(self): 'Get all vertexes.' self.transformedVertexes = None return self.vertexes def setCarveImportRadius( self, importRadius ): 'Set the import radius.' self.importRadius = importRadius def setCarveIsCorrectMesh( self, isCorrectMesh ): 'Set the is correct mesh flag.' self.isCorrectMesh = isCorrectMesh def setCarveLayerThickness( self, layerThickness ): 'Set the layer thickness.' self.layerThickness = layerThickness def setEdgesForAllFaces(self): 'Set the face edges of all the faces.' edgeTable = {} for face in self.faces: face.setEdgeIndexesToVertexIndexes( self.edges, edgeTable ) class ZoneArrangement: 'A zone arrangement.' def __init__(self, layerThickness, vertexes): 'Initialize the zone interval and the zZone table.' self.zoneInterval = layerThickness / math.sqrt(len(vertexes)) / 1000.0 self.zZoneSet = set() for point in vertexes: zoneIndexFloat = point.z / self.zoneInterval self.zZoneSet.add(math.floor(zoneIndexFloat)) self.zZoneSet.add(math.ceil(zoneIndexFloat )) def getEmptyZ(self, z): 'Get the first z which is not in the zone table.' zoneIndex = round(z / self.zoneInterval) if zoneIndex not in self.zZoneSet: return z zoneAround = 1 while 1: zoneDown = zoneIndex - zoneAround if zoneDown not in self.zZoneSet: return zoneDown * self.zoneInterval zoneUp = zoneIndex + zoneAround if zoneUp not in self.zZoneSet: return zoneUp * self.zoneInterval zoneAround += 1 sfact-2011.12.18/fabmetheus_utilities/geometry/solids/union.py000066400000000000000000000025331167321211700242630ustar00rootroot00000000000000""" Boolean geometry union of solids. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.solids import difference from fabmetheus_utilities.geometry.solids import group __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def convertElementNode(elementNode, geometryOutput): 'Convert the xml element to a union xml element.' group.convertContainerElementNode(elementNode, geometryOutput, Union()) def getNewDerivation(elementNode): 'Get new derivation.' return evaluate.EmptyObject(elementNode) def processElementNode(elementNode): 'Process the xml element.' evaluate.processArchivable(Union, elementNode) class Union(difference.Difference): 'A difference object.' def getLoopsFromObjectLoopsList(self, importRadius, visibleObjectLoopsList): 'Get loops from visible object loops list.' return self.getUnion(importRadius, visibleObjectLoopsList) sfact-2011.12.18/fabmetheus_utilities/geometry/statements/000077500000000000000000000000001167321211700234505ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry/statements/__init__.py000066400000000000000000000006571167321211700255710ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry/statements/_print.py000066400000000000000000000043351167321211700253220ustar00rootroot00000000000000""" Print statement. There is also the print attribute in geometry_utilities/evaluate_fundamentals/print.py The model is xml_models/geometry_utilities/evaluate_fundamentals/print.xml """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getLocalDictionary( attributesKey, elementNode): "Get the local dictionary." xmlProcessor = elementNode.getXMLProcessor() if len( xmlProcessor.functions ) < 1: return None return xmlProcessor.functions[-1].localDictionary def printAttributesKey( attributesKey, elementNode): "Print the attributesKey." if attributesKey.lower() == '_localdictionary': localDictionary = getLocalDictionary( attributesKey, elementNode) if localDictionary is not None: localDictionaryKeys = localDictionary.keys() attributeValue = elementNode.attributes[attributesKey] if attributeValue != '': attributeValue = ' - ' + attributeValue print('Local Dictionary Variables' + attributeValue ) localDictionaryKeys.sort() for localDictionaryKey in localDictionaryKeys: print('%s: %s' % ( localDictionaryKey, localDictionary[ localDictionaryKey ] ) ) return value = elementNode.attributes[attributesKey] evaluatedValue = None if value == '': evaluatedValue = evaluate.getEvaluatedExpressionValue(elementNode, attributesKey) else: evaluatedValue = evaluate.getEvaluatedExpressionValue(elementNode, value) print('%s: %s' % ( attributesKey, evaluatedValue ) ) def processElementNode(elementNode): "Process the xml element." if len(elementNode.getTextContent()) > 1: print(elementNode.getTextContent()) return attributesKeys = elementNode.attributes.keys() if len( attributesKeys ) < 1: print('') return attributesKeys.sort() for attributesKey in attributesKeys: printAttributesKey( attributesKey, elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry/statements/class.py000066400000000000000000000010411167321211700251230ustar00rootroot00000000000000""" Class. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def processElementNode(elementNode): 'Process the xml element.' pass sfact-2011.12.18/fabmetheus_utilities/geometry/statements/elif.py000066400000000000000000000013251167321211700247420ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def processElementNode(elementNode): "Process the xml element." pass def processElse(elementNode): "Process the else statement." evaluate.processCondition(elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry/statements/else.py000066400000000000000000000016351167321211700247570ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def processElementNode(elementNode): "Process the xml element." pass def processElse(elementNode): "Process the else statement." functions = elementNode.getXMLProcessor().functions if len(functions) < 1: print('Warning, "else" element is not in a function in processElse in else.py for:') print(elementNode) return functions[-1].processChildNodes(elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry/statements/for.py000066400000000000000000000052111167321211700246070ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def processChildNodesByIndexValue( elementNode, function, index, indexValue, value ): "Process childNodes by index value." if indexValue.indexName != '': function.localDictionary[ indexValue.indexName ] = index if indexValue.valueName != '': function.localDictionary[ indexValue.valueName ] = value function.processChildNodes(elementNode) def processElementNode(elementNode): "Process the xml element." if elementNode.xmlObject is None: elementNode.xmlObject = IndexValue(elementNode) if elementNode.xmlObject.inSplitWords is None: return xmlProcessor = elementNode.getXMLProcessor() if len( xmlProcessor.functions ) < 1: print('Warning, "for" element is not in a function in processElementNode in for.py for:') print(elementNode) return function = xmlProcessor.functions[-1] inValue = evaluate.getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject.inSplitWords) if inValue.__class__ == list or inValue.__class__ == str: for index, value in enumerate( inValue ): processChildNodesByIndexValue( elementNode, function, index, elementNode.xmlObject, value ) return if inValue.__class__ == dict: inKeys = inValue.keys() inKeys.sort() for inKey in inKeys: processChildNodesByIndexValue( elementNode, function, inKey, elementNode.xmlObject, inValue[ inKey ] ) class IndexValue: "Class to get the in attribute, the index name and the value name." def __init__(self, elementNode): "Initialize." self.inSplitWords = None self.indexName = '' if 'index' in elementNode.attributes: self.indexName = elementNode.attributes['index'] self.valueName = '' if 'value' in elementNode.attributes: self.valueName = elementNode.attributes['value'] if 'in' in elementNode.attributes: self.inSplitWords = evaluate.getEvaluatorSplitWords( elementNode.attributes['in'] ) else: print('Warning, could not find the "in" attribute in IndexValue in for.py for:') print(elementNode) return if len( self.inSplitWords ) < 1: self.inSplitWords = None print('Warning, could not get split words for the "in" attribute in IndexValue in for.py for:') print(elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry/statements/function.py000066400000000000000000000010501167321211700256430ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def processElementNode(elementNode): "Process the xml element." pass sfact-2011.12.18/fabmetheus_utilities/geometry/statements/if.py000066400000000000000000000012211167321211700244140ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def processElementNode(elementNode): "Process the xml element." evaluate.processCondition(elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry/statements/return.py000066400000000000000000000021521167321211700253410ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def processElementNode(elementNode): "Process the xml element." functions = elementNode.getXMLProcessor().functions if len(functions) < 1: return function = functions[-1] function.shouldReturn = True if elementNode.xmlObject is None: if 'return' in elementNode.attributes: value = elementNode.attributes['return'] elementNode.xmlObject = evaluate.getEvaluatorSplitWords(value) else: elementNode.xmlObject = [] if len( elementNode.xmlObject ) > 0: function.returnValue = evaluate.getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject) sfact-2011.12.18/fabmetheus_utilities/geometry/statements/statement.py000066400000000000000000000033531167321211700260320ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def processElementNode(elementNode): "Process the xml element." functions = elementNode.getXMLProcessor().functions if len(functions) < 1: print('Warning, there are no functions in processElementNode in statement for:') print(elementNode) return function = functions[-1] evaluate.setLocalAttribute(elementNode) if elementNode.xmlObject.value is None: print('Warning, elementNode.xmlObject.value is None in processElementNode in statement for:') print(elementNode) return localValue = evaluate.getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject.value) keywords = elementNode.xmlObject.key.split('.') if len(keywords) == 0: print('Warning, there are no keywords in processElementNode in statement for:') print(elementNode) return firstWord = keywords[0] if len(keywords) == 1: function.localDictionary[firstWord] = localValue return attributeName = keywords[-1] object = None if firstWord == 'self': object = function.classObject else: object = function.localDictionary[firstWord] for keywordIndex in xrange(1, len(keywords) - 1): object = object._getAccessibleAttribute(keywords[keywordIndex]) object._setAccessibleAttribute(attributeName, localValue) sfact-2011.12.18/fabmetheus_utilities/geometry/statements/while.py000066400000000000000000000022151167321211700251320ustar00rootroot00000000000000""" Polygon path. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Art of Illusion ' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def processElementNode(elementNode): "Process the xml element." if elementNode.xmlObject is None: if 'condition' in elementNode.attributes: value = elementNode.attributes['condition'] elementNode.xmlObject = evaluate.getEvaluatorSplitWords(value) else: elementNode.xmlObject = [] if len( elementNode.xmlObject ) < 1: return xmlProcessor = elementNode.getXMLProcessor() if len( xmlProcessor.functions ) < 1: return function = xmlProcessor.functions[-1] while evaluate.getEvaluatedExpressionValueBySplitLine(elementNode, elementNode.xmlObject) > 0: function.processChildNodes(elementNode) sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/000077500000000000000000000000001167321211700230225ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/__init__.py000066400000000000000000000006571167321211700251430ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 2 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/creation/000077500000000000000000000000001167321211700246265ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/creation/__init__.py000066400000000000000000000006571167321211700267470ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/manipulation_matrix/000077500000000000000000000000001167321211700271065ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/manipulation_matrix/__init__.py000066400000000000000000000006571167321211700312270ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/manipulation_meta/000077500000000000000000000000001167321211700265305ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/manipulation_meta/__init__.py000066400000000000000000000006571167321211700306510ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/manipulation_paths/000077500000000000000000000000001167321211700267215ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/manipulation_paths/__init__.py000066400000000000000000000006571167321211700310420ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/manipulation_shapes/000077500000000000000000000000001167321211700270655ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/geometry_plugins/manipulation_shapes/__init__.py000066400000000000000000000006571167321211700312060ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/hidden_scrollbar.py000066400000000000000000000015751167321211700233060ustar00rootroot00000000000000""" Hidden scrollbar is in its own file so that even if Tkinter is not installed, settings can still be imported. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ try: import Tkinter class HiddenScrollbar(Tkinter.Scrollbar): 'A class to hide the scrollbar if it is not needed.' def set(self, lo, hi): 'Add to grid is needed, remove if not.' if float(lo) <= 0.0 and float(hi) >= 1.0: self.grid_remove() self.visible = False else: self.grid() self.visible = True Tkinter.Scrollbar.set(self, lo, hi) except: pass __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/23/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' sfact-2011.12.18/fabmetheus_utilities/images/000077500000000000000000000000001167321211700206735ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/images/display_line.ppm000066400000000000000000000043051167321211700240670ustar00rootroot00000000000000P6 # CREATOR: The GIMP's PNM Filter Version 1.0 27 27 255 ðôôðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòîòòîòòíññÙØZäâHîìMõóP÷õRôòRíìcåéééíííññîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòíññÜÞ«ÖÔCæäHïíM÷õRüúVÿÿ\ÿÿkÿÿ\õóTáâ¦äèèëïïíññîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòëïïÎÍ@àÞEëéKõóPüúVÿÿ~ÿÿÉÿÿãÿÿÉÿÿ~õóTÐÔÔãççëïïîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòíññÄÃRÖÕ@ãáFîìLøöSÿÿ\ÿÿÉÿÿþÿÿÛÿÿþÿÿÉÿÿ\åä\ÐÔÔäèèíññîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòéííÄÃ:×Ö@äâGïíMù÷TÿÿkÿÿãÿÿÛÿýYÿÿÛÿÿãÿÿkòðQº½½ÙÜÜéííîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòåééÇÆ:ÖÕ@ãáFîìLøöSÿÿ\ÿÿÉÿÿþÿÿÛÿÿþÿÿÉÿÿ\õóQ¢¥¥ËÏÏåééîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòàääÆÄ9ÔÒ?àÞEëéKõóPüúVÿÿ~ÿÿÉÿÿãÿÿÉÿÿ~üúVõóP”——ÃÆÆàääîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòÞâ⿾6ÏÍ=ÛÙBæäHïíM÷õRüúVÿÿ\ÿÿkÿÿ\üúV÷õRìêK޾ÂÂÞââîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòÞâⱯ4ÈÇ:ÕÓ?ßÝDèæIïíMõóPøöSù÷TøöSõóPïíMàÞE޾ÂÂÞââîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòÞâ⢢CÀ¿7ÌÊ<ÖÕ@ßÝDæäHëéKîìLïíMîìLëéKæäHÆÄG޾ÂÂÞââîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòàääÃÆÆ©¨2ÂÀ8ÌÊ<ÕÓ?ÛÙBàÞEãáFäâGãáFàÞEÑÏ@rtt”——ÃÆÆàääîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòåééËÏÏœw¨¦2ÑÐ@óñRÿýYôòSæåWÿýYôòSÉÇ=ŠŠV}¢¥¥ËÏÏåééîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòéííÙÜܺ½½“––ÞÜCæäHðîNûùWòòtÿÿ׿åLfggwyy“––º½½ÙÜÜéííîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòíññäèèÐÔÔ¯²²ÞÜCëéJöôQÿýYÿÿÍÿÿãÿýYrttޝ²²ÐÔÔäèèíññîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòëïïãççÊÍÍÞÜCëéJöôQÿýYÿÿÑÿÿåÿýYƒƒ¨««ÊÍÍãççëïïîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòíññëïïÙÜÜÞÜCëéJöôQÿýYÿÿÑÿÿåÿýY‰ŒŒ·ººÙÜÜëïïíññîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòîòòîòòÞâ⃃ƒ›››±±±ÄÄÄÓÓÓüüüÓÓÓŽ½ÁÁÞââîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòîòòîòòÞâ⎎™šš¬¬¬­®®¹ººÙÚÚ½½½’’¿ÃÃÞââîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòîòòîòòßãã‹‹‹ššš¬¬¬½½½ËËËñññÌÌÌ“••ÀÃÃßããîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòîòòîòòàää‘’’𛛤¤¤¶¶¶£¤¤ÐÑÑÂÃÙœœÃÆÆàääîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòîòòîòòâææ¶¸¸›››®®®ÀÀÀÂÃÃää䧨¨ž  ÆÉÉáååîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòîòòîòòåééÉÍÍ›››±±±ÄÄÄÓÓÓüüü™œœ¦©©ËÏÏãççîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòîòòîòòèììÕØØµ¸¸“••€‚‚z||„††•˜˜²µµÓÖÖçêêîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòîòòîòòìððßããÈËË«®®›žž”——œžž¬¯¯ÅÈÈÜààêîîîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòîòòîòòîòòíññçëëÜààÍÑÑÃÆÆ¿ÃÃÃÆÆÌÐÐÚÞÞæééíññîòòîòòîòòîòòîòòîòòîòòsfact-2011.12.18/fabmetheus_utilities/images/dive.ppm000066400000000000000000000014721167321211700223440ustar00rootroot00000000000000P6 # CREATOR: The GIMP's PNM Filter Version 1.0 16 16 255 ÿÿÿÿÿÿÿÿÿÿÿÿìôÿØéÿÉáÿ¾Ûÿ¾ÛÿÉáÿØéÿìôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöúÿÙêÿÇÝùÐÞïÕÛãÖØÚÕ×ÙÑØáÍÛìÆÜøÙêÿöúÿÿÿÿÿÿÿÿÿÿöúÿÓæÿÓáòÙÝâèìñóöúûýþûýþòõùåéîÏÔÚÎÜîÓæÿöúÿÿÿÿÿÿÿÙêÿÓáòÖÚà÷øûÿÿÿöùüîóúíóúôøüÿÿÿóöùÇÌÓÍÛìÙêÿÿÿÿìôÿÇÝùÙÝâ÷øûÿÿÿëñùãì÷èïùèïùæïøßéöÿÿÿóöùÄÉÏÃÙõìôÿØéÿÐÝîèìñÿÿÿëñùãì÷YŒÍèïùæïøßéöX‹Ëãì÷ÿÿÿØßçÀÎߨéÿÉáÿÔÚâóöúôøüáë÷S„ÃYŒÍåîøÝèöN{´X‹Ëáë÷ñõûêïö¶½ÅÉáÿ¾ÛÿÔÖØûýþéðùRƒÀRƒÁX‹ËßéöMz³Mz´WŠÊßéöãì÷ùûý«­¯¾Ûÿ¾ÛÿÓÕ×ûýþìòúZŽÑQ€½X‹ËéðùU†ÅP~¹VˆÈÝèöáë÷ñõú§©ª¾ÛÿÉáÿÐ×ßïóøòöûäí÷YÐYŒÏàêöáë÷X‹ËX‹ÍÜçõîóúÛäדּ»ÉáÿØéÿÌÙëáåìþþÿáë÷ãì÷\ÒÝèöÝèößéö[ÑÚåõúüþ¿ÉÖµÃÔØéÿìôÿÄÚ÷ÈÌÒíñ÷ÿÿÿÝèöàêöÜçõÛæõÚåõÛæõþþÿÜä±¾ÔðìôÿÿÿÿÙêÿÉ×è·¾Æèîôþþÿïôûáë÷àêöíóúúüþÛäî–¡¬»ÉÛÙêÿÿÿÿÿÿÿöúÿÓæÿÅÒ䱸¾ÈÑÜáèñòöûîóúÖàí¸ÃÒ¤­ºÈÚÓæÿöúÿÿÿÿÿÿÿÿÿÿöúÿÙêÿÀÖò·ÅÖ¨¯·œŸ˜šœ£ª³±¿Ð¼ÓïÙêÿöúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìôÿØéÿÉáÿ¾Ûÿ¾ÛÿÉáÿØéÿìôÿÿÿÿÿÿÿÿÿÿÿÿÿsfact-2011.12.18/fabmetheus_utilities/images/soar.ppm000066400000000000000000000014721167321211700223610ustar00rootroot00000000000000P6 # CREATOR: The GIMP's PNM Filter Version 1.0 16 16 255 ÿÿÿÿÿÿÿÿÿÿÿÿìôÿØéÿÉáÿ¾Ûÿ¾ÛÿÉáÿØéÿìôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöúÿÙêÿÇÝùÐÞïÕÛãÖØÚÕ×ÙÑØáÍÛìÆÜøÙêÿöúÿÿÿÿÿÿÿÿÿÿöúÿÓæÿÓáòÙÝâèìñóöúûýþûýþòõùåéîÏÔÚÎÜîÓæÿöúÿÿÿÿÿÿÿÙêÿÓáòÖÚà÷øûÿÿÿöùüîóúíóúôøüÿÿÿóöùÇÌÓÍÛìÙêÿÿÿÿìôÿÇÝùÙÝâ÷øûÿÿÿÜçõéðùèïùèïùÚåõåîøÿÿÿóöùÄÉÏÃÙõìôÿØéÿÐÝîèìñÿÿÿëñùT…ÃÚåõèïùæïøRƒÁÕãóãì÷ÿÿÿØßçÀÎߨéÿÉáÿÔÚâóöúôøüèïùS„ÃS„ÁØåôäí÷RƒÀRƒÀÔâóñõûêïö¶½ÅÉáÿ¾ÛÿÔÖØûýþìòúèïùRƒÁRƒÁVˆÈÛæõRÀR¾U†ÆÛæõùûý«­¯¾Ûÿ¾ÛÿÓÕ×ûýþëñùåîøRƒÁU‡ÆRƒÀìòúQ€¾T…ÃQ€½ìòúñõú§©ª¾ÛÿÉáÿÐ×ßïóøòöûãì÷U‡ÆRÀìòúßéöT…ÃQ€½ëñùîóúÛäדּ»ÉáÿØéÿÌÙëáåìþþÿáë÷R¾ìòúÝèöÝèöQ½éðùÚåõúüþ¿ÉÖµÃÔØéÿìôÿÄÚ÷ÈÌÒíñ÷ÿÿÿëñùÝèöÜçõÛæõéðùØåôþþÿÜä±¾ÔðìôÿÿÿÿÙêÿÉ×è·¾Æèîôþþÿïôûáë÷àêöíóúúüþÛäî–¡¬»ÉÛÙêÿÿÿÿÿÿÿöúÿÓæÿÅÒ䱸¾ÈÑÜáèñòöûîóúÖàí¸ÃÒ¤­ºÈÚÓæÿöúÿÿÿÿÿÿÿÿÿÿöúÿÙêÿÀÖò·ÅÖ¨¯·œŸ˜šœ£ª³±¿Ð¼ÓïÙêÿöúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìôÿØéÿÉáÿ¾Ûÿ¾ÛÿÉáÿØéÿìôÿÿÿÿÿÿÿÿÿÿÿÿÿsfact-2011.12.18/fabmetheus_utilities/images/stop.ppm000066400000000000000000000014721167321211700224020ustar00rootroot00000000000000P6 # CREATOR: The GIMP's PNM Filter Version 1.0 16 16 255 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùâáï³¯íª¦íª¥í¨¤ë¤ží©¥÷ÙØþüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøáàò¹²üÓÂÿÖÁÿѽÿÏ»ÿιüȷퟘòÅÃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøáàð·±üÔÄÿ£ÿ¯‹ÿ«‰ÿ§„ÿ ~ÿ®‘ûÃ´í¢œöÖÕÿÿÿÿÿÿÿÿÿøáßñµ¯üÑÁÿ¿ ÿª†ÿ§…ÿ¢ÿ|ÿ˜xÿoÿ¡…ûº¬ê—öÓÒÿÿÿÿÿÿî«§üͼÿ»œÿ¥ÿ¢ÿž|ÿ™xÿ“tÿŽoÿ‰iÿ€`ÿ“xû­žå…ÿÿÿÿÿÿê˜ÿ͸ÿ }ÿ|ÿ™xÿ“sÿŽnÿ‰iÿƒeÿ~`ÿxYÿpOÿª˜ârkÿÿÿÿÿÿéš•ÿıÿ˜vÿ“sÿŽnÿ‰iÿƒeÿ~_ÿyZÿsUÿnOÿgHÿ¡áohÿÿÿÿÿÿè”ÿ¾«ÿmÿ‰iÿƒeÿ~_ÿyZÿtUÿoPÿiKÿcFÿ\?ÿ›Šßibÿÿÿÿÿÿ抄ÿ»¦ÿ_ÿ~_ÿyZÿsUÿnPÿiKÿdFÿ^AÿY;ÿO1ÿ™‡Ý^Vÿÿÿÿÿÿ莈ü²¢ÿsÿpOÿnOÿiKÿdFÿ^AÿZ<ÿU7ÿK,ÿgNú“„Þf_ÿÿÿÿÿÿõÒÐ鎇û­Ÿÿgÿ^@ÿ^@ÿY<ÿU7ÿP3ýF(ýeJö–‰áneòÃÁÿÿÿÿÿÿÿÿÿôÌÊç†~ú¥–ÿtZÿP2ÿO0þI,úB%ù`Hô”†âpiñÀ½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóÈÆç|tú—‰ÿ•„üúŽ}÷}ò‹}ÝYQꟛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóÆÄàkeÜYRÜ[SÚXPÚRIÜ`Yðº·þúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿsfact-2011.12.18/fabmetheus_utilities/images/view_move.ppm000066400000000000000000000043051167321211700234130ustar00rootroot00000000000000P6 # CREATOR: The GIMP's PNM Filter Version 1.0 27 27 255 ðôôðóóðóóðóóðóóðóóðóóãææ@AAãææðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóîòòîòòîòòîòòîòòîòòƒ……`bbîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòÓÖÖÓÖÖîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòîòòZ[[899îòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòòîòòÅÈȳ¶¶îòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòò¯±±îòòîòòîòòîòòîòòîòòÈËËîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòðóóîòòÐÔÔ$%%îòòîòòîòòîòòîòòîòòJKKÐÔÔîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòáääQSSîòòîòòîòòîòòîòòîòòwyyßããîòòîòòîòòîòòîòòîòòîòòîòòîòòîòò-..#$$#$$-..îòòîòòîòòîòòîòòîòòîòòîòòîòòîòòáääwyyîòòîòòîòòîòòîòòîòòQSSßããîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòðóóîòòÐÔÔJKKîòòîòòîòòîòòàßÚÒËÁŸ~¶¤ÏǽÜÛÖëïïíññîòòîòòîòòîòòîòòîòòîòòðóóîòòîòòîòò½ÀÀîòòîòòàßÚ”qN‰a9‰a9nN.‰a9‰a9‰a9‰a9‰a9’pM³¡Ù×Òêîîíññîòòîòòîòòîòòðóóîòòîòòîòòîòò¸»»{\>‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9¯‰ãççëïïîòòîòòîòòðóóîòòîòòîòòàßÚ›{Z 777¬§ŸpO•}d˜…qnN‰a9ŒiF”hjG‰a9‰a9”tTÒÐËèììíññîòòðóóîòòîòòÚÖÎiC‰a9zZ9³··×ÚÚÇÆÁ¤’~¨š‹ºº¸¦™Š‰a9oO±´´¡‘€‰a9‰a9ŒgAǺçêêíññðóóîòòèéæ”rO‰a9ŒfA¥ ™>??nppçëëëïïɾ²‰a9‰a9ŒgA§•§—†‰a9§š‹ÉÌÌ»µ®‹f@‰a9lIÎÏÌçëëðóóîòò§q‰a9‰a9¤Ÿ—¶¹¹ÄÈÈ¥‘|ßàÞêîîêîî’pM‰a9‰a9‰a9±ª lI•wYËÏÏÜà๯£‰a9‰a9˜~bØÛÛðóóÍ÷‰a9‰a9š‡s²µµÏÓÓæéé”qN£‹r«™…€bËĺ´¤“‰a9‰a9‰a9Šv ‹u‰a9ÂÅÅßããåé颊q‰a9‰a9°¦™ðóó¬”{‰a9‰a9¤Ÿ—ÄÇÇâææíññ‰a9¤’~–y[‰a9‰a9”tT‰a9‰a9‰a9“y]¢|‰a9½ÁÁÜààìððÏËÉa9‰a9˜€fðóóÚØÓ‰a9‰a9oOÊÍÍæééîòòŽhCœ…l¡Žz‰a9‰a9‰a9‰a9‰a9‰a9˜†r›ƒjlI½ÁÁÛßßîòò ƒd‰a9‹f@¨¥ ðóóéíí´¤’‰a9‰a9 ŠtÛßßëïmŒgA°«£ŒfA‰a9‰a9‰a9‰a9Še?¥ ˜ŒgA›ƒjÀÃÃÞâ⺨”‰a9‰a9œŒz¶¹¹ðóóíññäè衉p‰a9‰a9Ÿ‡nÞââɸ‰a9›ƒi¸·²›ƒi‰a9‰a9’za¤¢›ƒi‰a9­¥›ÆÉÉ´¢Ž‰a9‰a9—f¯²²ÊÍÍðóóîòòìððßã㟇n‰a9‰a9—z\Ǻ¢Šq‰a9™~c½ºµ»¼¹²³°¯­¨™c‰a9ŸŠs´±¬š}_‰a9‰a9˜€f¯±±ÄÇÇßããðóóîòòîòòëïïÝáᦔ€‰a9‰a9‰a9›eŒfA‰a9‰a9”tT‘nK‰a9‰a9ŒfA•{_‰a9‰a9‰a9œ‰u¯²²ÄÇÇÝááëïïðóóîòòîòòîòòëïïÞââÀ¾¹—|`‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9’uW¨¦¡´··ÈËËÞââëïïîòòðóóîòòîòòîòòîòòëïïãççÔ×׺¸³¡‘€’uW‹e@‰a9‰a9‰a9‰a9Še?rSšŠx©§¢´··ÀÃÃÓÖÖãççëïïîòòîòòðóóîòòîòòîòòîòòîòòíññéííáååÖÙÙÊÍ;·ºº´··³¶¶³¶¶´···ºº¾ÂÂÊÍÍÕØØàääéíííññîòòîòòîòòsfact-2011.12.18/fabmetheus_utilities/images/view_rotate.ppm000066400000000000000000000043051167321211700237430ustar00rootroot00000000000000P6 # CREATOR: The GIMP's PNM Filter Version 1.0 27 27 255 ðóóðóóÔ××ÃÅÅ€‚‚“––ÛßßîññíññîññŸŸ¨««èëëèëëðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóðóóÞââlnn^``'((?AAÌÐÐíññíññæéé¿Â [\\«®®çëëîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòÈËË455RTTÙÜÜîòòîòòíññîòòçëëxzzacc›èëëîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòæéé«®®hiiæééîòòîòòîòòîòòîòòÞâ⇊ŠZ[[»¾¾îòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòïòòØÛÛ?AAbddåééîòòîòòîòòîòòîòòîòòçëësuuwyyåééîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòðóósuuOQQ½ÀÀcee“––éííîòòîòòîòòîòòîòòîòòîòò±´´XYYËÏÏîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòÛßß>??™››îòòÕØØÞââîòòîòòîòòîòòîòòîòòîòòîòòÍÑÑacc´··îòòîòòîòòîòòîòòîòòîòòîòòîòòîòòÔÖÖghh¨««íññîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòÓÖÖkmmŠŒŒíññîòòîòòîòòîòòîòòîòòîòòîòòîòòÚÝÝdffŸ¡¡ëïïîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòÔ××RTTUWWÕØØîòòîòòîòòîòòîòòîòòîòòîòòîòòåééuwwƒ……îòòîòòîòòîòòîòòîòòîòòîòòîòòîòòîòòÞââ…‰‰ÖÛÛîòòîòòîòòîòòîòòîòòîòòîòòîòòðóó—ššZ[[ÙÜÜîòòîòòîòòîòòîòòîòòàßÚÒËÁ¹§“³¢ŽlbVª¨¤ÚÙÔëïïíññîòòîòòîòòîòòîòòîòòîòòðóóÌÐÐcee}ÞââîòòîòòàßÚ¹§“”qN‰a9‰a9‡_8kL,(YUN‡jL‰a9’pM³¡Ù×Òêîîíññîòòîòòîòòîòòðóóëïאָ¯fgg‡ŠŠîòòº¨”‰a9‰a9‰a9ŒgAŽkH^C'>,@.hO‰b<‰a9‰a9‰a9‰a9¯‰ãççëïïîòòîòòîòòðóóîòòêî==<9-!pP/vT1fL†~sŒŽŽ_\X:- OB5ˆxfoO‰a9ŒiF”hjG‰a9‰a9”tTÒÐËèëëíññîòòðóóîòòîòòÅÁºŒlK"41-IKKUWWIKKnoorqo–…s¨š‹ºº¸§š‹‰a9oO±´´¡‘€‰a9‰a9ŒgAǺçëëíññðóóîòòèéæ“rO‰b;ŒfBŸ›•¡¤¤}”——¿ÂÂÊÍÍɾ²‰a9‰a9ŒgA§•§—†‰a9§š‹ÉÌ̸³­‹f@‰a9lIÎÏÌçëëðóóîòò§q‰a9‰a9¤Ÿ—µ¸¸ÐÔÔ–{^°›„ÝÞÜêîîêîî’pM‰a9‰a9‰a9±«¢lI•wYËÏÏÝáṯ£‰a9‰a9™~cØÛÛðóóÍ÷‰a9‰a9š‡s²µµÏÓÓæéé”qN£‹r«™…€bÊù´¤“‰a9‰a9‰a9Šv ‹u‰a9ÃÅÅßããåé颊q‰a9‰a9°¦™ðóó¬”{‰a9‰a9¤Ÿ—ÄÇÇâææíññ‰a9¤’~–y[‰a9‰a9”tT‰a9‰a9‰a9“y]¢|‰a9¾ÁÁÝááíññÏËÉa9‰a9˜€fðóóÚÙÔ‰a9‰a9oOÊÍÍæééîòòŽhCœ…l¡Žz‰a9‰a9‰a9‰a9‰a9‰a9˜†r›ƒjlI¾ÁÁÛßßîòò ƒd‰a9‹f@¨¥ ðóóéíí´¤“‰a9‰a9ŸŠsÛßßëïmŒgA±«¢ŒgA‰a9‰a9‰a9‰a9Še?¥ ˜ŒgA›ƒjÀÃÃÞâ⺨”‰a9‰a9œŒz¶¹¹ðóóíññåé顉p‰a9‰a9Ÿ‡nÞââÊù‰a9›ƒi¸·²›ƒi‰a9‰a9’za¤¢›ƒi‰a9­¥›ÆÉÉ´¢Ž‰a9‰a9—f¯²²ÊÍÍðóóîòòíññßã㟇n‰a9‰a9—z\Ǻ¢Šq‰a9™~c¼¹´»¼¹²³°¯­¨™~c‰a9ŸŠs¸³­š}_‰a9‰a9˜€f¯±±ÄÇÇßããðóóîòòîòòëïïÝáá§•‰a9‰a9‰a9›eŒgA‰a9‰a9”tT‘nK‰a9‰a9ŒgA•{_‰a9‰a9‰a9œ‰u¯²²ÄÇÇÝááëïïðóóîòòîòòîòòëïïÞââÀ¾¹—|`‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9‰a9’uW¨¦¡´··ÈËËÞââëïïîòòðóóîòòîòòîòòîòòëïïãççÔ×׸·²¡‘€’uW‹e@‰a9‰a9‰a9‰a9Še?rSšŠx©§¢´··ÀÃÃÓÖÖãççëïïîòòîòòðóóîòòîòòîòòîòòîòòíññéííáååÖÙÙÊÍͿ·ºº´··³¶¶³¶¶´···ºº¿ÂÂÊÍÍÕØØáååéíííññîòòîòòîòòsfact-2011.12.18/fabmetheus_utilities/images/zoom_in.ppm000066400000000000000000000014721167321211700230670ustar00rootroot00000000000000P6 # CREATOR: The GIMP's PNM Filter Version 1.0 16 16 255 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôìÜÝÑҮmÏ©eΧcШjÙ»ŒóèÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìܿ԰p×·}æÑ¯÷ðåöïääάҭwÌ¡gçÓºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôìÜÔ°påÏ©÷úýïõûêòúëóúñöûùûýßţɛcñæØÿÿÿÿÿÿÿÿÿÿÿÿÝ‘׶}÷úýëóúèñùéòùéòúêòúîõûùûýͤqÒ®„ÿÿÿÿÿÿÿÿÿÿÿÿÒ­læÑ®ðöûèñùéòùéòúêòúëóúëóúò÷üßħÒ[ÿÿÿÿÿÿÿÿÿÿÿÿϨc÷ïåëóúéòúêòúêòúëóúg¶\a°W\¨Rôëâ¿‹Pÿÿÿÿÿÿÿÿÿÿÿÿͦböïäìóúêòúêòúëóúëóú_­V¦ÕSžKôë⾇Mÿÿÿÿÿÿÿÿÿÿÿÿͧhä̬ñ÷üëóúëóúc²Y^«Tv·mžÑ•k¬cD‹=>ƒ7ÿÿÿÿÿÿÿÿÿÿÿÿع‹Ñªvùûýïõûìôú\¨RŸÒ—šÏ’†Å}ʈ‹Æƒ5y0ÿÿÿÿÿÿÿÿÿÿÿÿòçÙÊŸeÞÄ£ùûþóøüSžKM–Ee§^‹Ç…Z›S3v..o)ãÍ»ÿÿÿÿÿÿÿÿÿÿÿÿæÑ¹Èš`Ê oÞçôëâôëâ>ƒ7‚Â}2t,ãÌ™ÞļƒOøñíÿÿÿÿÿÿÿÿÿÿÿÿñåØÑ«ƒÁZ¾‡M½…L5y00q+*k&èÕ£é×¥Ú»€¬e?÷ñíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâ˹ÁŽXßÅçÓ àǓɛa—aFÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáɸ¼„Q×µ}ÖµÑV¶{Qÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáɸ®mH¹€H·yRúöôÿÿÿsfact-2011.12.18/fabmetheus_utilities/images/zoom_out.ppm000066400000000000000000000014721167321211700232700ustar00rootroot00000000000000P6 # CREATOR: The GIMP's PNM Filter Version 1.0 16 16 255 ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôìÜÝÑҮmÏ©eΧcШjÙ»ŒóèÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìܿ԰p×·}æÑ¯÷ðåöïääάҭwÌ¡gçÓºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôìÜÔ°påÏ©÷úýïõûêòúëóúñöûùûýßţɛcñæØÿÿÿÿÿÿÿÿÿÿÿÿÝ‘׶}÷úýëóúèñùéòùéòúêòúîõûùûýͤqÒ®„ÿÿÿÿÿÿÿÿÿÿÿÿÒ­læÑ®ðöûèñùéòùéòúêòúëóúëóúò÷üßħÒ[ÿÿÿÿÿÿÿÿÿÿÿÿϨc÷ïåëóúéòúêòúêòúëóúëóúìóúîõûôëâ¿‹Pÿÿÿÿÿÿÿÿÿÿÿÿͦböïäìóúêòúêòúëóúëóúìóúìôúïõûôë⾇Mÿÿÿÿÿÿÿÿÿÿÿÿͧhä̬ñ÷üëóúëóúþxtüomúcb÷TVôEHñ5:î&.ÿÿÿÿÿÿÿÿÿÿÿÿع‹ÑªvùûýïõûìôúüomøÈ¿÷À·ö¶®ô«¤ó ›ì#ÿÿÿÿÿÿÿÿÿÿÿÿòçÙÊŸeÞÄ£ùûþóøüúcb÷TVôEHñ5:î&.ì#êãÍ»ÿÿÿÿÿÿÿÿÿÿÿÿæÑ¹Èš`Ê oÞçôëâôëâܾ¤ÁSÖ´yãÌ™ÞļƒOøñíÿÿÿÿÿÿÿÿÿÿÿÿñåØÑ«ƒÁZ¾‡M½…L»†R»LÛ¿‡èÕ£é×¥Ú»€¬e?÷ñíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿâ˹ÁŽXßÅçÓ àǓɛa—aFÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáɸ¼„Q×µ}ÖµÑV±rEÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàǶ¥\3¹€H³sKøòïÿÿÿsfact-2011.12.18/fabmetheus_utilities/intercircle.py000066400000000000000000000742171167321211700223160ustar00rootroot00000000000000""" Intercircle is a collection of utilities for intersecting circles, used to get smooth loops around a collection of points and inset & outset loops. """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalDecreasingRadiusMultipliers = [1.0, 0.55, 0.35, 0.2] globalIntercircleMultiplier = 1.04 # 1.02 is enough to stop known intersection def addCircleIntersectionLoop(circleIntersectionLoop, circleIntersections): 'Add a circle intersection loop.' firstCircleIntersection = circleIntersectionLoop[0] circleIntersectionAhead = firstCircleIntersection for circleIntersectionIndex in xrange(len(circleIntersections) + 1): circleIntersectionAhead = circleIntersectionAhead.getCircleIntersectionAhead() if circleIntersectionAhead == firstCircleIntersection or circleIntersectionAhead is None: firstCircleIntersection.steppedOn = True return circleIntersectionAhead.addToList(circleIntersectionLoop) firstCircleIntersection.steppedOn = True print( 'addCircleIntersectionLoop would have gone into an endless loop, this should never happen.' ) print( 'circleIntersectionLoop' ) for circleIntersection in circleIntersectionLoop: print(circleIntersection) print(circleIntersection.circleNodeAhead) print(circleIntersection.circleNodeBehind) print('firstCircleIntersection') print(firstCircleIntersection) print('circleIntersections') for circleIntersection in circleIntersections: print(circleIntersection) def addEndCap(begin, end, points, radius): 'Get circular end cap.' beginMinusEnd = begin - end beginMinusEndLength = abs(beginMinusEnd) if beginMinusEndLength <= 0.0: points.append(begin) return beginMinusEnd *= radius / beginMinusEndLength perpendicular = complex(-beginMinusEnd.imag, beginMinusEnd.real) numberOfSides = 20 # to end up with close to unit length corners, 5 * 4 numberOfPositiveSides = numberOfSides / 2 totalAngle = 0.0 angle = euclidean.globalTau / float(numberOfSides) # dotProductMultiplier to compensate for the corner outset in addInsetPointFromClockwiseTriple dotProductMultiplier = 2.0 - 1.0 / math.cos(0.5 * angle) for sideIndex in xrange(numberOfPositiveSides + 1): circumferentialPoint = math.sin(totalAngle) * beginMinusEnd + math.cos(totalAngle) * perpendicular points.append(begin + circumferentialPoint * dotProductMultiplier) totalAngle += angle def addHalfPath(path, points, radius, thresholdRatio=0.9): 'Add the points from every point on a half path and between points.' lessThanRadius = 0.75 * radius for pointIndex in xrange(len(path) - 1): begin = path[pointIndex] center = path[pointIndex + 1] centerBegin = getWiddershinsByLength(begin, center, radius) if centerBegin is not None: addPointsFromSegment(begin + centerBegin, center + centerBegin, points, lessThanRadius, thresholdRatio) endIndex = pointIndex + 2 if endIndex < len(path): end = path[endIndex] centerEnd = getWiddershinsByLength(center, end, radius) if centerBegin is not None and centerEnd is not None: centerPerpendicular = 0.5 * (centerBegin + centerEnd) points.append(center + centerPerpendicular) if euclidean.getCrossProduct(centerBegin, centerEnd) < 0.0: points.append(center + centerBegin) points.append(center + centerEnd) else: points.append(center) addEndCap(path[0], path[1], points, radius) def addInsetPointFromClockwiseTriple(begin, center, end, loop, radius): 'Get inset point with possible intersection from clockwise triple, out from widdershins loop.' centerMinusBegin = center - begin centerMinusBeginLength = abs(centerMinusBegin) centerMinusBeginClockwise = None if centerMinusBeginLength > 0.0: centerMinusBeginClockwise = complex(centerMinusBegin.imag, -centerMinusBegin.real) / centerMinusBeginLength endMinusCenter = end - center endMinusCenterLength = abs(endMinusCenter) endMinusCenterClockwise = None if endMinusCenterLength > 0.0: endMinusCenterClockwise = complex(endMinusCenter.imag, -endMinusCenter.real) / endMinusCenterLength if centerMinusBeginClockwise is None and endMinusCenterClockwise is None: return if centerMinusBeginClockwise is None: loop.append(center + endMinusCenterClockwise * radius) return if endMinusCenterClockwise is None: loop.append(center + centerMinusBeginClockwise * radius) return centerClockwise = 0.5 * (centerMinusBeginClockwise + endMinusCenterClockwise) dotProduct = euclidean.getDotProduct(centerMinusBeginClockwise, centerClockwise) loop.append(center + centerClockwise * radius / max(0.4, abs(dotProduct))) # 0.4 to avoid pointy corners def addOrbits( distanceFeedRate, loop, orbitalFeedRatePerSecond, temperatureChangeTime, z ): 'Add orbits with the extruder off.' timeInOrbit = 0.0 while timeInOrbit < temperatureChangeTime: for point in loop: distanceFeedRate.addGcodeMovementZWithFeedRate( 60.0 * orbitalFeedRatePerSecond, point, z ) timeInOrbit += euclidean.getLoopLength(loop) / orbitalFeedRatePerSecond def addOrbitsIfLarge( distanceFeedRate, loop, orbitalFeedRatePerSecond, temperatureChangeTime, z ): 'Add orbits with the extruder off if the orbits are large enough.' if orbitsAreLarge( loop, temperatureChangeTime ): addOrbits( distanceFeedRate, loop, orbitalFeedRatePerSecond, temperatureChangeTime, z ) def addPointsFromSegment( pointBegin, pointEnd, points, radius, thresholdRatio=0.9 ): 'Add point complexes between the endpoints of a segment.' if radius <= 0.0: print('This should never happen, radius should never be zero or less in addPointsFromSegment in intercircle.') thresholdRadius = radius * thresholdRatio # a higher number would be faster but would leave bigger dangling loops and extra dangling loops. thresholdDiameter = thresholdRadius + thresholdRadius segment = pointEnd - pointBegin segmentLength = abs(segment) extraCircles = int( math.floor( segmentLength / thresholdDiameter ) ) if extraCircles < 1: return if segmentLength == 0.0: print('This should never happen, segmentLength = 0.0 in intercircle.') print('pointBegin') print( pointBegin ) print( pointEnd ) return if extraCircles < 2: lengthIncrement = segmentLength / ( float(extraCircles) + 1.0 ) segment *= lengthIncrement / segmentLength pointBegin += segment else: pointBegin += segment * thresholdDiameter / segmentLength remainingLength = segmentLength - thresholdDiameter - thresholdDiameter lengthIncrement = remainingLength / ( float(extraCircles) - 1.0 ) segment *= lengthIncrement / segmentLength for circleIndex in xrange(extraCircles): points.append( pointBegin ) pointBegin += segment def directLoop(isWiddershins, loop): 'Direct the loop.' if euclidean.isWiddershins(loop) != isWiddershins: loop.reverse() def directLoopLists(isWiddershins, loopLists): 'Direct the loop lists.' for loopList in loopLists: directLoops(isWiddershins, loopList) def directLoops(isWiddershins, loops): 'Direct the loops.' for loop in loops: directLoop(isWiddershins, loop) def getAroundsFromLoop(loop, radius, thresholdRatio=0.9): 'Get the arounds from the loop.' return getAroundsFromPoints(getPointsFromLoop(loop, radius, thresholdRatio), radius) def getAroundsFromLoops( loops, radius, thresholdRatio=0.9 ): 'Get the arounds from the loops.' return getAroundsFromPoints(getPointsFromLoops(loops, radius, thresholdRatio), radius) def getAroundsFromPath(path, radius, thresholdRatio=0.9): 'Get the arounds from the path.' radius = abs(radius) points = getPointsFromPath(path, radius, thresholdRatio) return getAroundsFromPathPoints(points, radius, thresholdRatio=0.9) def getAroundsFromPathPoints(points, radius, thresholdRatio=0.9): 'Get the arounds from the path.' centers = getCentersFromPoints(points, 0.7854 * radius) arounds = [] for center in centers: if euclidean.isWiddershins(center): arounds.append(euclidean.getSimplifiedPath(center, radius)) return arounds def getAroundsFromPaths(paths, radius, thresholdRatio=0.9): 'Get the arounds from the path.' radius = abs(radius) points = [] for path in paths: points += getPointsFromPath(path, radius, thresholdRatio) return getAroundsFromPathPoints(points, radius, thresholdRatio=0.9) def getAroundsFromPoints( points, radius ): 'Get the arounds from the points.' arounds = [] radius = abs(radius) centers = getCentersFromPoints(points, globalIntercircleMultiplier * radius) for center in centers: inset = getSimplifiedInsetFromClockwiseLoop(center, radius) if isLargeSameDirection(inset, center, radius): arounds.append(inset) return arounds def getCentersFromCircleNodes( circleNodes, radius ): 'Get the complex centers of the circle intersection loops from circle nodes.' if len( circleNodes ) < 2: return [] circleIntersections = getCircleIntersectionsFromCircleNodes( circleNodes ) circleIntersectionLoops = getCircleIntersectionLoops( circleIntersections ) return getCentersFromIntersectionLoops( circleIntersectionLoops, radius ) def getCentersFromIntersectionLoop(circleIntersectionLoop, radius): 'Get the centers from the intersection loop.' loop = [] for circleIntersection in circleIntersectionLoop: loop.append(circleIntersection.circleNodeAhead.actualPoint) return loop def getCentersFromIntersectionLoops( circleIntersectionLoops, radius ): 'Get the centers from the intersection loops.' centers = [] for circleIntersectionLoop in circleIntersectionLoops: centers.append( getCentersFromIntersectionLoop( circleIntersectionLoop, radius ) ) return centers def getCentersFromLoop( loop, radius ): 'Get the centers of the loop.' circleNodes = getCircleNodesFromLoop( loop, radius ) return getCentersFromCircleNodes( circleNodes, radius ) def getCentersFromLoopDirection( isWiddershins, loop, radius ): 'Get the centers of the loop which go around in the given direction.' centers = getCentersFromLoop( loop, radius ) return getLoopsFromLoopsDirection( isWiddershins, centers ) def getCentersFromPoints(points, radius): 'Get the centers from the points.' circleNodes = getCircleNodesFromPoints(points, abs(radius)) return getCentersFromCircleNodes(circleNodes, abs(radius)) def getCircleIntersectionLoops( circleIntersections ): 'Get all the loops going through the circle intersections.' circleIntersectionLoops = [] for circleIntersection in circleIntersections: if not circleIntersection.steppedOn: circleIntersectionLoop = [ circleIntersection ] circleIntersectionLoops.append( circleIntersectionLoop ) addCircleIntersectionLoop( circleIntersectionLoop, circleIntersections ) return circleIntersectionLoops def getCircleIntersectionsFromCircleNodes(circleNodes): 'Get all the circle intersections which exist between all the circle nodes.' if len( circleNodes ) < 1: return [] circleIntersections = [] index = 0 pixelTable = {} for circleNode in circleNodes: euclidean.addElementToPixelListFromPoint(circleNode, pixelTable, circleNode.dividedPoint) accumulatedCircleNodeTable = {} for circleNodeIndex in xrange(len(circleNodes)): circleNodeBehind = circleNodes[circleNodeIndex] circleNodeIndexMinusOne = circleNodeIndex - 1 if circleNodeIndexMinusOne >= 0: circleNodeAdditional = circleNodes[circleNodeIndexMinusOne] euclidean.addElementToPixelListFromPoint(circleNodeAdditional, accumulatedCircleNodeTable, 0.5 * circleNodeAdditional.dividedPoint) withinNodes = circleNodeBehind.getWithinNodes(accumulatedCircleNodeTable) for circleNodeAhead in withinNodes: circleIntersectionForward = CircleIntersection(circleNodeAhead, index, circleNodeBehind) if not circleIntersectionForward.isWithinCircles(pixelTable): circleIntersections.append(circleIntersectionForward) circleNodeBehind.circleIntersections.append(circleIntersectionForward) index += 1 circleIntersectionBackward = CircleIntersection(circleNodeBehind, index, circleNodeAhead) if not circleIntersectionBackward.isWithinCircles(pixelTable): circleIntersections.append(circleIntersectionBackward) circleNodeAhead.circleIntersections.append(circleIntersectionBackward) index += 1 return circleIntersections def getCircleNodesFromLoop(loop, radius, thresholdRatio=0.9): 'Get the circle nodes from every point on a loop and between points.' radius = abs(radius) points = getPointsFromLoop( loop, radius, thresholdRatio ) return getCircleNodesFromPoints( points, radius ) def getCircleNodesFromPoints(points, radius): 'Get the circle nodes from a path.' if radius == 0.0: print('Warning, radius is 0 in getCircleNodesFromPoints in intercircle.') print(points) return [] circleNodes = [] oneOverRadius = 1.000001 / radius # to avoid problem of accidentally integral radius points = euclidean.getAwayPoints(points, radius) for point in points: circleNodes.append(CircleNode(oneOverRadius, point)) return circleNodes def getInsetLoopsFromLoop(loop, radius, thresholdRatio=0.9): 'Get the inset loops, which might overlap.' if radius == 0.0: return [loop] isInset = radius > 0 insetLoops = [] isLoopWiddershins = euclidean.isWiddershins(loop) arounds = getAroundsFromLoop(loop, radius, thresholdRatio) for around in arounds: leftPoint = euclidean.getLeftPoint(around) shouldBeWithin = (isInset == isLoopWiddershins) if euclidean.isPointInsideLoop(loop, leftPoint) == shouldBeWithin: if isLoopWiddershins != euclidean.isWiddershins(around): around.reverse() insetLoops.append(around) return insetLoops def getInsetLoopsFromLoops(loops, radius): 'Get the inset loops, which might overlap.' insetLoops = [] for loop in loops: insetLoops += getInsetLoopsFromLoop(loop, radius) return insetLoops def getInsetLoopsFromVector3Loop(loop, radius, thresholdRatio=0.9): 'Get the inset loops from vector3 loop, which might overlap.' if len(loop) < 2: return [loop] loopComplex = euclidean.getComplexPath(loop) loopComplexes = getInsetLoopsFromLoop(loopComplex, radius) return euclidean.getVector3Paths(loopComplexes, loop[0].z) def getInsetSeparateLoopsFromLoops(loops, radius, thresholdRatio=0.9): 'Get the separate inset loops.' if radius == 0.0: return loops isInset = radius > 0 insetSeparateLoops = [] arounds = getAroundsFromLoops(loops, abs(radius), thresholdRatio) for around in arounds: if isInset == euclidean.getIsInFilledRegion(loops, around[0]): if isInset: around.reverse() insetSeparateLoops.append(around) return insetSeparateLoops def getInsetSeparateLoopsFromAroundLoops(loops, radius, radiusAround, thresholdRatio=0.9): 'Get the separate inset loops.' if radius == 0.0: return loops isInset = radius > 0 insetSeparateLoops = [] radius = abs(radius) radiusAround = max(abs(radiusAround), radius) points = getPointsFromLoops(loops, radiusAround, thresholdRatio) centers = getCentersFromPoints(points, globalIntercircleMultiplier * radiusAround) for center in centers: inset = getSimplifiedInsetFromClockwiseLoop(center, radius) if isLargeSameDirection(inset, center, radius): if isInset == euclidean.getIsInFilledRegion(loops, inset[0]): if isInset: inset.reverse() insetSeparateLoops.append(inset) return insetSeparateLoops def getIsLarge(loop, radius): 'Determine if the loop is large enough.' return euclidean.getMaximumSpan(loop) > 2.01 * abs(radius) def getLargestCenterOutsetLoopFromLoop(loop, radius, thresholdRatio=0.9): 'Get the largest circle outset loop from the loop.' if radius == 0.0: return loop radius = abs(radius) points = getPointsFromLoop(loop, radius, thresholdRatio) centers = getCentersFromPoints(points, globalIntercircleMultiplier * radius) largestCenterOutset = None largestOutsetArea = -987654321.0 for center in centers: outset = getSimplifiedInsetFromClockwiseLoop(center, radius) if isLargeSameDirection(outset, center, radius): if euclidean.isPathInsideLoop(loop, outset) != euclidean.isWiddershins(loop): centerOutset = CenterOutset(center, outset) outsetArea = abs(euclidean.getAreaLoop(outset)) if outsetArea > largestOutsetArea: largestOutsetArea = outsetArea largestCenterOutset = centerOutset if largestCenterOutset is None: return None largestCenterOutset.center = euclidean.getSimplifiedLoop(largestCenterOutset.center, radius) return largestCenterOutset def getLargestCenterOutsetLoopFromLoopRegardless(loop, radius): 'Get the largest circle outset loop from the loop, even if the radius has to be shrunk and even if there is still no outset loop.' global globalDecreasingRadiusMultipliers for decreasingRadiusMultiplier in globalDecreasingRadiusMultipliers: decreasingRadius = radius * decreasingRadiusMultiplier largestCenterOutsetLoop = getLargestCenterOutsetLoopFromLoop(loop, decreasingRadius) if largestCenterOutsetLoop is not None: return largestCenterOutsetLoop return CenterOutset(loop, loop) def getLargestInsetLoopFromLoop(loop, radius): 'Get the largest inset loop from the loop.' loops = getInsetLoopsFromLoop(loop, radius) return euclidean.getLargestLoop(loops) def getLargestInsetLoopFromLoopRegardless( loop, radius ): 'Get the largest inset loop from the loop, even if the radius has to be shrunk and even if there is still no inset loop.' global globalDecreasingRadiusMultipliers for decreasingRadiusMultiplier in globalDecreasingRadiusMultipliers: decreasingRadius = radius * decreasingRadiusMultiplier largestInsetLoop = getLargestInsetLoopFromLoop( loop, decreasingRadius ) if len( largestInsetLoop ) > 0: return largestInsetLoop print('This should never happen, there should always be a largestInsetLoop in getLargestInsetLoopFromLoopRegardless in intercircle.') print(loop) return loop def getLoopsFromLoopsDirection( isWiddershins, loops ): 'Get the loops going round in a given direction.' directionalLoops = [] for loop in loops: if euclidean.isWiddershins(loop) == isWiddershins: directionalLoops.append(loop) return directionalLoops def getPointsFromLoop(loop, radius, thresholdRatio=0.9): 'Get the points from every point on a loop and between points.' if radius == 0.0: print('Warning, radius is 0 in getPointsFromLoop in intercircle.') print(loop) return loop radius = abs(radius) points = [] for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] points.append( pointBegin ) addPointsFromSegment( pointBegin, pointEnd, points, radius, thresholdRatio ) return points def getPointsFromLoops(loops, radius, thresholdRatio=0.9): 'Get the points from every point on a loop and between points.' points = [] for loop in loops: points += getPointsFromLoop(loop, radius, thresholdRatio) return points def getPointsFromPath(path, radius, thresholdRatio=0.9): 'Get the points from every point on a path and between points.' if len(path) < 1: return [] if len(path) < 2: return path radius = abs(radius) points = [] addHalfPath(path, points, radius, thresholdRatio) addHalfPath(path[: : -1], points, radius, thresholdRatio) return points def getSimplifiedInsetFromClockwiseLoop(loop, radius): 'Get loop inset from clockwise loop, out from widdershins loop.' inset = [] for pointIndex, begin in enumerate(loop): center = loop[(pointIndex + 1) % len(loop)] end = loop[(pointIndex + 2) % len(loop)] addInsetPointFromClockwiseTriple(begin, center, end, inset, radius) return getWithoutIntersections(euclidean.getSimplifiedLoop(inset, radius)) def getWiddershinsByLength(begin, end, length): 'Get the widdershins by length.' endMinusBegin = end - begin endMinusBeginLength = abs(endMinusBegin) if endMinusBeginLength <= 0.0: return None endMinusBegin *= length / endMinusBeginLength return complex(-endMinusBegin.imag, endMinusBegin.real) def getWithoutIntersections( loop ): 'Get loop without intersections.' lastLoopLength = len( loop ) while lastLoopLength > 3: removeIntersection( loop ) if len( loop ) == lastLoopLength: return loop lastLoopLength = len( loop ) return loop def isLargeSameDirection(inset, loop, radius): 'Determine if the inset is in the same direction as the loop and it is large enough.' if euclidean.isWiddershins(inset) != euclidean.isWiddershins(loop): return False return getIsLarge(inset, radius) and len(inset) > 2 def isLoopIntersectingLoop( anotherLoop, loop ): 'Determine if the a loop is intersecting another loop.' for pointIndex in xrange(len(loop)): pointFirst = loop[pointIndex] pointSecond = loop[(pointIndex + 1) % len(loop)] segment = pointFirst - pointSecond normalizedSegment = euclidean.getNormalized(segment) segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) segmentFirstPoint = segmentYMirror * pointFirst segmentSecondPoint = segmentYMirror * pointSecond if euclidean.isLoopIntersectingInsideXSegment( anotherLoop, segmentFirstPoint.real, segmentSecondPoint.real, segmentYMirror, segmentFirstPoint.imag ): return True return False def orbitsAreLarge( loop, temperatureChangeTime ): 'Determine if the orbits are large enough.' if len(loop) < 1: print('Zero length loop which was skipped over, this should never happen.') return False return temperatureChangeTime > 1.5 def removeIntersection( loop ): 'Get loop without the first intersection.' for pointIndex, ahead in enumerate(loop): behind = loop[ ( pointIndex + len( loop ) - 1 ) % len( loop ) ] behindEnd = loop[ ( pointIndex + len( loop ) - 2 ) % len( loop ) ] behindMidpoint = 0.5 * ( behind + behindEnd ) aheadEnd = loop[ (pointIndex + 1) % len( loop ) ] aheadMidpoint = 0.5 * ( ahead + aheadEnd ) normalizedSegment = behind - behindMidpoint normalizedSegmentLength = abs( normalizedSegment ) if normalizedSegmentLength > 0.0: normalizedSegment /= normalizedSegmentLength segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) behindRotated = segmentYMirror * behind behindMidpointRotated = segmentYMirror * behindMidpoint aheadRotated = segmentYMirror * ahead aheadMidpointRotated = segmentYMirror * aheadMidpoint y = behindRotated.imag xIntersection = euclidean.getXIntersectionIfExists( aheadRotated, aheadMidpointRotated, y ) if xIntersection is not None: if xIntersection > min( behindMidpointRotated.real, behindRotated.real ) and xIntersection < max( behindMidpointRotated.real, behindRotated.real ): intersectionPoint = normalizedSegment * complex( xIntersection, y ) loop[ ( pointIndex + len( loop ) - 1 ) % len( loop ) ] = intersectionPoint del loop[pointIndex] return class BoundingLoop: 'A class to hold a bounding loop composed of a minimum complex, a maximum complex and an outset loop.' def __eq__(self, other): 'Determine whether this bounding loop is identical to other one.' if other is None: return False return self.minimum == other.minimum and self.maximum == other.maximum and self.loop == other.loop def __repr__(self): 'Get the string representation of this bounding loop.' return '%s, %s, %s' % ( self.minimum, self.maximum, self.loop ) def getFromLoop( self, loop ): 'Get the bounding loop from a path.' self.loop = loop self.maximum = euclidean.getMaximumByComplexPath(loop) self.minimum = euclidean.getMinimumByComplexPath(loop) return self def getOutsetBoundingLoop( self, outsetDistance ): 'Outset the bounding rectangle and loop by a distance.' outsetBoundingLoop = BoundingLoop() outsetBoundingLoop.maximum = self.maximum + complex( outsetDistance, outsetDistance ) outsetBoundingLoop.minimum = self.minimum - complex( outsetDistance, outsetDistance ) greaterThanOutsetDistance = 1.1 * outsetDistance centers = getCentersFromLoopDirection( True, self.loop, greaterThanOutsetDistance ) outsetBoundingLoop.loop = getSimplifiedInsetFromClockwiseLoop( centers[0], outsetDistance ) return outsetBoundingLoop def isEntirelyInsideAnother( self, anotherBoundingLoop ): 'Determine if this bounding loop is entirely inside another bounding loop.' if self.minimum.imag < anotherBoundingLoop.minimum.imag or self.minimum.real < anotherBoundingLoop.minimum.real: return False if self.maximum.imag > anotherBoundingLoop.maximum.imag or self.maximum.real > anotherBoundingLoop.maximum.real: return False for point in self.loop: if euclidean.getNumberOfIntersectionsToLeft( anotherBoundingLoop.loop, point ) % 2 == 0: return False return not isLoopIntersectingLoop( anotherBoundingLoop.loop, self.loop ) #later check for intersection on only acute angles def isOverlappingAnother( self, anotherBoundingLoop ): 'Determine if this bounding loop is intersecting another bounding loop.' if self.isRectangleMissingAnother( anotherBoundingLoop ): return False for point in self.loop: if euclidean.getNumberOfIntersectionsToLeft( anotherBoundingLoop.loop, point ) % 2 == 1: return True for point in anotherBoundingLoop.loop: if euclidean.getNumberOfIntersectionsToLeft( self.loop, point ) % 2 == 1: return True return isLoopIntersectingLoop( anotherBoundingLoop.loop, self.loop ) #later check for intersection on only acute angles def isOverlappingAnotherInList( self, boundingLoops ): 'Determine if this bounding loop is intersecting another bounding loop in a list.' for boundingLoop in boundingLoops: if self.isOverlappingAnother( boundingLoop ): return True return False def isRectangleMissingAnother( self, anotherBoundingLoop ): 'Determine if the rectangle of this bounding loop is missing the rectangle of another bounding loop.' if self.maximum.imag < anotherBoundingLoop.minimum.imag or self.maximum.real < anotherBoundingLoop.minimum.real: return True return self.minimum.imag > anotherBoundingLoop.maximum.imag or self.minimum.real > anotherBoundingLoop.maximum.real class CenterOutset: 'A class to hold a center and an outset.' def __init__(self, center, outset): 'Set the center and outset.' self.center = center self.outset = outset def __repr__(self): 'Get the string representation of this CenterOutset.' return '%s\n%s' % (self.center, self.outset) class CircleIntersection: 'An intersection of two complex circles.' def __init__( self, circleNodeAhead, index, circleNodeBehind ): self.aheadMinusBehind = 0.5 * ( circleNodeAhead.dividedPoint - circleNodeBehind.dividedPoint ) self.circleNodeAhead = circleNodeAhead self.circleNodeBehind = circleNodeBehind self.index = index self.steppedOn = False demichordWidth = math.sqrt( 1.0 - self.aheadMinusBehind.real * self.aheadMinusBehind.real - self.aheadMinusBehind.imag * self.aheadMinusBehind.imag ) rotatedClockwiseQuarter = complex( self.aheadMinusBehind.imag, - self.aheadMinusBehind.real ) rotatedClockwiseQuarterLength = abs( rotatedClockwiseQuarter ) if rotatedClockwiseQuarterLength == 0: print('this should never happen, rotatedClockwiseQuarter in getDemichord in intercircle is 0') print( circleNodeAhead.dividedPoint ) print( circleNodeBehind.dividedPoint ) self.demichord = 0.0 else: self.demichord = rotatedClockwiseQuarter * demichordWidth / rotatedClockwiseQuarterLength self.positionRelativeToBehind = self.aheadMinusBehind + self.demichord def __repr__(self): 'Get the string representation of this CircleIntersection.' return '%s, %s, %s, %s' % (self.index, self.getAbsolutePosition(), self.circleNodeBehind, self.circleNodeAhead) def addToList( self, circleIntersectionPath ): 'Add this to the circle intersection path, setting stepped on to be true.' self.steppedOn = True circleIntersectionPath.append(self) def getAbsolutePosition(self): 'Get the absolute position.' return self.positionRelativeToBehind + self.circleNodeBehind.dividedPoint def getCircleIntersectionAhead(self): 'Get the first circle intersection on the circle node ahead.' circleIntersections = self.circleNodeAhead.circleIntersections circleIntersectionAhead = None largestDot = -912345678.0 for circleIntersection in circleIntersections: if not circleIntersection.steppedOn: circleIntersectionRelativeToMidpoint = euclidean.getNormalized(circleIntersection.positionRelativeToBehind + self.aheadMinusBehind) dot = euclidean.getDotProduct(self.demichord, circleIntersectionRelativeToMidpoint) if dot > largestDot: largestDot = dot circleIntersectionAhead = circleIntersection if circleIntersectionAhead is None: print('Warning, circleIntersectionAhead in getCircleIntersectionAhead in intercircle is None for:') print(self.circleNodeAhead.dividedPoint) print('circleIntersectionsAhead') for circleIntersection in circleIntersections: print(circleIntersection.circleNodeAhead.dividedPoint) print('circleIntersectionsBehind') for circleIntersection in self.circleNodeBehind.circleIntersections: print(circleIntersection.circleNodeAhead.dividedPoint) print('This may lead to a loop not being sliced.') print('If this is a problem, you may as well send a bug report, even though I probably can not fix this particular problem.') return circleIntersectionAhead def isWithinCircles(self, pixelTable): 'Determine if this circle intersection is within the circle node circles.' absolutePosition = self.getAbsolutePosition() squareValues = euclidean.getSquareValuesFromPoint(pixelTable, absolutePosition) for squareValue in squareValues: if abs(squareValue.dividedPoint - absolutePosition) < 1.0: if squareValue != self.circleNodeAhead and squareValue != self.circleNodeBehind: return True return False class CircleNode: 'A complex node of complex circle intersections.' def __init__(self, oneOverRadius, point): self.actualPoint = point self.circleIntersections = [] self.dividedPoint = point * oneOverRadius # self.index = index # when debugging bring back index def __repr__(self): 'Get the string representation of this CircleNode.' # return '%s, %s, %s' % (self.index, self.dividedPoint, len(self.circleIntersections)) # when debugging bring back index return '%s, %s' % (self.dividedPoint, len(self.circleIntersections)) def getWithinNodes(self, pixelTable): 'Get the nodes this circle node is within.' withinNodes = [] squareValues = euclidean.getSquareValuesFromPoint(pixelTable, 0.5 * self.dividedPoint) for squareValue in squareValues: if abs(self.dividedPoint - squareValue.dividedPoint) < 2.0: withinNodes.append(squareValue) return withinNodes sfact-2011.12.18/fabmetheus_utilities/miscellaneous/000077500000000000000000000000001167321211700222715ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/miscellaneous/Art of Illusion Scripts/000077500000000000000000000000001167321211700265735ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/miscellaneous/Art of Illusion Scripts/Drill.bsh000066400000000000000000000135401167321211700303420ustar00rootroot00000000000000/* */ scene = window.getScene(); shapeChoice = new BComboBox (new String [] { "Round", "Hex (point down)", "Hex (flat down)" }); slopeField = new ValueField (45, ValueField.POSITIVE); sizeField = new ValueField (10, ValueField.POSITIVE); lengthField = new ValueField (20, ValueField.POSITIVE); errorField = new ValueField (0.05, ValueField.POSITIVE); dlg = new ComponentsDialog (window, "Drill Tool", new Widget [] {shapeChoice, slopeField, sizeField, lengthField, errorField}, new String [] {"Shape:", "Max slope:", "Size:", "Length:", "Max error:"}); if (!dlg.clickedOk()) { return; } shape = shapeChoice.getSelectedIndex(); double theta, size, length, maxError; theta = slopeField.getValue() * Math.PI / 180.0; size = sizeField.getValue(); length = lengthField.getValue(); maxError = errorField.getValue(); name = ""; double phi, angle; switch (shape) { case 0: // round { radius = size / 2; errorAngle = Math.acos((radius - maxError) / radius); numberSides = Math.ceil((Math.PI + 2 * theta) / errorAngle); phi = (Math.PI + 2 * theta) / (numberSides - 2); angle = ((Math.PI / 2.0) - theta); y0 = radius / Math.sin(theta); name = "Teardrop"; break; } case 1: // hex, point down { if (theta > (Math.PI / 3.0)) { theta = Math.PI / 3.0; } radius = size / Math.sqrt(3); numberSides = 6; phi = Math.PI / 3.0; angle = Math.PI / 3.0; y0 = (radius / 2.0) + (size / (2.0 * Math.tan(theta))); smooth = Mesh.NO_SMOOTHING; name = "Hexdrop(pointy)"; break; } case 2: // hex, flat down { radius = size / Math.sqrt(3); phi = Math.PI / 3.0; y0 = radius / Math.tan(theta); if (theta <= (Math.PI / 6.0)) { numberSides = 5; angle = Math.PI / 2.0; } else { numberSides = 7; angle = Math.PI / 6.0; y0 += size; y0 /= 2; } smooth = Mesh.NO_SMOOTHING; name = "Hexdrop(flat)"; break; } } name += " size " + size; // number of faces: // for each edge in our perimeter, two triangles to connect // the front and back, so 2*numberSides // for each end cap, we connect each vertex to the point. The // first and last vertices are connected by a perimeter edge, // leaving numberSides-2 edges to connect across the middle, // creating a face, for numberSides-2 triangles per end cap, // or (numberSides-2)*2 triangles for both end caps // Thus: // 2*numberSides + 2*(numberSides-2) // 2*numberSides + 2*numberSides - 4 // 4*numberSides - 4 Vec3[] v = new Vec3[numberSides * 2]; int[][] faces = new int[4*numberSides-4][3]; v[0] = new Vec3(0, y0, 0); v[1] = new Vec3(0, y0, -length); for (i = 0; i < (numberSides - 1); i++) { j = i * 2; x = Math.sin(angle + phi * i); y = Math.cos(angle + phi * i); v[j+2] = new Vec3(x, y, 0); v[j+2].scale (radius); v[j+3] = new Vec3(x, y, -length/radius); v[j+3].scale (radius); faces[j][0] = j; faces[j][1] = j+2; faces[j][2] = j+1; faces[j+1][0] = j+1; faces[j+1][1] = j+2; faces[j+1][2] = j+3; } //j = (numberSides-1)*2; j = i*2; faces[j][0] = 0; faces[j][1] = j+1; faces[j][2] = j; faces[j+1][0] = 0; faces[j+1][1] = 1; faces[j+1][2] = j+1; k = j; for (i = 1; i < (numberSides - 1); i++) { j = i * 2; faces[j+k][0] = 0; faces[j+k][1] = j+2; faces[j+k][2] = j; faces[j+k+1][0] = 1; faces[j+k+1][1] = j+1; faces[j+k+1][2] = j+3; } mesh = new TriangleMesh (v, faces); mesh.setSmoothingMethod(Mesh.NO_SMOOTHING); /* // At this point, we've finished constructing the mesh. Now we need // to set its smoothing properly. if (shape != 0) // hex { mesh.setSmoothingMethod(Mesh.NO_SMOOTHING); } else // round { mesh.setSmoothingMethod(Mesh.APPROXIMATING); edge = mesh.getEdges(); face = mesh.getFaces(); vert = mesh.getVertices(); cutoffAngle = (theta < (Math.PI/4.0))?(theta*2.0):(Math.PI/2.0); cutoff = Math.cos (cutoffAngle); for (int i = 0; i < edge.length; i++) { ed = edge[i]; f1 = face[ed.f1]; f2 = face[ed.f2]; norm1 = vert[f1.v1].r.minus(vert[f1.v2].r).cross(vert[f1.v1].r.minus(vert[f1.v3].r)); norm2 = vert[f2.v1].r.minus(vert[f2.v2].r).cross(vert[f2.v1].r.minus(vert[f2.v3].r)); norm1.normalize(); norm2.normalize(); ed.smoothness = (norm1.dot(norm2) < cutoff)?0.0f:1.0f; } } */ window.addObject (mesh, new CoordinateSystem(), name, null); undo = new UndoRecord (window, false, UndoRecord.DELETE_OBJECT, new Object[] { new Integer(window.getScene().getNumObjects()-1) }); window.setUndoRecord (undo); Export GNU Triangulated Surface.bsh000066400000000000000000000357071167321211700350760ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/miscellaneous/Art of Illusion Scripts/* */ //later once stable remove unused preferences, all the preferences will be kept in the unused Skeinforge, finish comments for this and import /** Get the info for all the selected curves and meshes. */ ObjectInfo[] getCurvesMeshesInfo() { scene = window.getScene(); selection = scene.getSelection(); Vector objectInfoVector = new Vector(); for ( int objectIndex = 0; objectIndex < selection.length; objectIndex++ ) { objectInfo = scene.getObject( selection[ objectIndex ] ); if ( objectInfo.object instanceof TriangleMesh ) { objectInfoVector.add( objectInfo ); } } if ( objectInfoVector.size() > 0 ) { return objectInfoVector.toArray( new ObjectInfo[ objectInfoVector.size() ] ); } for ( int objectIndex = 0; objectIndex < scene.getNumObjects(); objectIndex++ ) { objectInfo = scene.getObject( objectIndex ); if ( objectInfo.object instanceof TriangleMesh ) { return new ObjectInfo[] { objectInfo }; } } return new ObjectInfo[ 0 ]; } String getEdgeString( edges, edgeTriple, vertexIndexFirst, vertexIndexSecond ) { for ( int edgeTripleIndex = 0; edgeTripleIndex < edgeTriple.length; edgeTripleIndex++ ) { edgeIndex = edgeTriple[ edgeTripleIndex ]; edge = edges[ edgeIndex ]; if ( edge.v1 == vertexIndexFirst && edge.v2 == vertexIndexSecond ) { return getPlusOneToString( edgeIndex ); } if ( edge.v1 == vertexIndexSecond && edge.v2 == vertexIndexFirst ) { return getPlusOneToString( edgeIndex ); } } print( "Inconsistent triangle mesh." ); print( edgeTriple ); print( vertexIndexFirst ); print( vertexIndexSecond ); } String getPlusOneToString( int number ) { return ( number + 1 ).toString() ; } /** Get Vec3 rotated around X axis from counterclockwise angle and vector. @param angle counterclockwise angle from 1, 0 @param vector3 Vec3 whose rotation will be returned @return vector3 rotated around X axis */ Vec3 getRoundXAxis( double angle, Vec3 vector3 ) { x = Math.cos( angle ); y = Math.sin( angle ); return new Vec3( vector3.x, vector3.y * x - vector3.z * y, vector3.y * y + vector3.z * x ); } /** Get Vec3 rotated around Y axis from counterclockwise angle and vector. @param angle counterclockwise angle from 1, 0 @param vector3 Vec3 whose rotation will be returned @return vector3 rotated around Y axis */ Vec3 getRoundYAxis( double angle, Vec3 vector3 ) { x = Math.cos( angle ); y = Math.sin( angle ); return new Vec3( vector3.x * x - vector3.z * y, vector3.y, vector3.x * y + vector3.z * x ); } /** Get Vec3 rotated around Z axis from counterclockwise angle and vector. @param angle counterclockwise angle from 1, 0 @param vector3 Vec3 whose rotation will be returned @return vector3 rotated around Z axis */ Vec3 getRoundZAxis( double angle, Vec3 vector3 ) { x = Math.cos( angle ); y = Math.sin( angle ); return new Vec3( vector3.x * x - vector3.y * y, vector3.x * y + vector3.y * x, vector3.z ); } /** Output the curves and/or meshes. */ void outputCurvesMeshes( ObjectInfo[] objectInfoArray ) { if ( objectInfoArray.length < 1 ) { return; } for ( int objectIndex = 0; objectIndex < objectInfoArray.length; objectIndex++ ) { objectInfo = objectInfoArray[ objectIndex ]; if ( objectInfoArray.length > 1 && exportSelectionCheckbox.getState() ) { if ( bufferedWriter != null ) { //Close the output stream bufferedWriter.close(); bufferedWriter = null; } file = null; parentFile = new File( gnuSurfaceFilenameTextField.getText() ).getParentFile(); if ( parentFile != null ) { file = new File( parentFile, objectInfo.name + ".gts" ); } if ( file != null ) { bufferedWriter = new BufferedWriter( new FileWriter( file ) ); } } if ( file != null && bufferedWriter != null ) { print( objectInfo.name + " is being saved as the GNU Triangulated Surface file " + file.getAbsolutePath() ); } outputCurveMesh( objectInfo ); if ( bufferedWriter != null ) { //Close the output stream bufferedWriter.close(); bufferedWriter = null; } } } /** Output the curve and/or mesh. Quoted from http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE "All the lines beginning with GTS_COMMENTS (#!) are ignored. The first line contains three unsigned integers separated by spaces. The first integer is the number of vertices, nv, the second is the number of edges, ne and the third is the number of faces, nf. Follows nv lines containing the x, y and z coordinates of the vertices. Follows ne lines containing the two indices (starting from one) of the vertices of each edge. Follows nf lines containing the three ordered indices (also starting from one) of the edges of each face. The format described above is the least common denominator to all GTS files. Consistent with an object-oriented approach, the GTS file format is extensible. Each of the lines of the file can be extended with user-specific attributes accessible through the read() and write() virtual methods of each of the objects written (surface, vertices, edges or faces). When read with different object classes, these extra attributes are just ignored." */ void outputCurveMesh( ObjectInfo objectInfo ) { triangleMesh = objectInfo.object; edges = triangleMesh.getEdges(); faces = triangleMesh.getFaces(); vertexPositions = triangleMesh.getVertexPositions(); origin = objectInfo.coords.getOrigin(); orientation = objectInfo.coords.getRotationAngles(); orientationXRadians = orientation[ 0 ] * Math.PI / 180.0; orientationYRadians = orientation[ 1 ] * Math.PI / 180.0; orientationZRadians = orientation[ 2 ] * Math.PI / 180.0; outputString( vertexPositions.length + " " + edges.length + " " + faces.length + " Number of Vertices, Number of Edges, Number of Faces" ); for ( int vertexIndex = 0; vertexIndex < vertexPositions.length; vertexIndex++ ) { vertexPosition = vertexPositions[ vertexIndex ]; vertexPosition = getRoundZAxis( - orientationZRadians, vertexPosition ); vertexPosition = getRoundXAxis( - orientationXRadians, vertexPosition ); vertexPosition = getRoundYAxis( orientationYRadians, vertexPosition ); vertexPosition.add( origin ); vertexLine = vertexPosition.x.toString() + " " + vertexPosition.y.toString() + " " + vertexPosition.z.toString(); if ( vertexIndex == 0 ) { vertexLine += " Vertex Coordinates XYZ"; } outputString( vertexLine ); } for ( int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++ ) { edge = edges[ edgeIndex ]; edgeLine = getPlusOneToString( edge.v1 ) + " " + getPlusOneToString( edge.v2 ); if ( edgeIndex == 0 ) { edgeLine += " Edge Vertex Indices Starting from 1"; } outputString( edgeLine ); } for ( int faceIndex = 0; faceIndex < faces.length; faceIndex++ ) { face = faces[ faceIndex ]; int[] edgeTriple = { face.e1, face.e2, face.e3 }; faceLine = getEdgeString( edges, edgeTriple, face.v1, face.v2 ) + " " + getEdgeString( edges, edgeTriple, face.v2, face.v3 ) + " " + getEdgeString( edges, edgeTriple, face.v3, face.v1 ); if ( faceIndex == 0 ) { faceLine += " Face Edge Indices Starting from 1"; } outputString( faceLine ); } } /** Output comma separated strings followed by a linefeed. */ void outputString( string ) { if ( printSelectionCheckbox.getState() ) { print( string ); } if ( bufferedWriter != null ) { bufferedWriter.write( string.replace( ", ", "," ) + "\n" ); } } /** Add radio button groups to the preference widgets. @param radioButtonGroups radio button groups which will be added to the memorable widgets @param widgetVector memorable widgets */ void preferencesAddRadioButtonGroups( RadioButtonGroup[] radioButtonGroups, Vector widgetVector ) { for ( int radioIndex = 0; radioIndex < radioButtonGroups.length; radioIndex++ ) { radioButtonGroup = radioButtonGroups[ radioIndex ]; radioButtonGroupIterator = radioButtonGroup.getRadioButtons(); while ( radioButtonGroupIterator.hasNext() ) { radioButton = radioButtonGroupIterator.next(); preferencesAddWidgetWithString( radioButton, radioButton.getText(), widgetVector ); } } } /** Add widgets which have titles. @param widgets widgets which have titles @param widgetStrings widget titles @param widgetVector memorable widgets */ void preferencesAddWidgetsWithStrings( Widget[] widgets, String[] widgetStrings, Vector widgetVector ) { for ( int widgetIndex = 0; widgetIndex < widgets.length; widgetIndex++ ) { widget = widgets[ widgetIndex ]; if ( widget instanceof BCheckBox || widget instanceof BOutline || widget instanceof BTextField || widget instanceof ValueField ) { preferencesAddWidgetWithString( widget, widgetStrings[ widgetIndex ], widgetVector ); } } } /** Give the widget a name and add it to the widget vector. @param widget widget which will be given a name @param widgetStrings widget name @param widgetVector memorable widgets */ void preferencesAddWidgetWithString( Widget widget, String widgetString, Vector widgetVector ) { widget.setName( widgetString ); widgetVector.add( widget ); } /** Read widget settings from preferences file. @param preferencesFilename preferences filename @param widgetVector memorable widgets */ void preferencesRead( String preferencesFilename, Vector widgetVector ) { preferencesFile = new File( preferencesFilename ); if ( !preferencesFile.canRead() ) { return; } BufferedReader preferencesReader = new BufferedReader( new FileReader( preferencesFile ) ); line = preferencesReader.readLine(); while ( line != null ) { preferencesReadLine( line, widgetVector ); line = preferencesReader.readLine(); } } /** Read line of preferences and set widget to that line. @param line line of preferences @param widgetVector memorable widgets */ void preferencesReadLine( String line, Vector widgetVector ) { splitLine = line.split( "\t" ); if ( splitLine.length < 2 ) { return; } name = splitLine[ 0 ]; for ( int widgetIndex = 0; widgetIndex < widgetVector.size(); widgetIndex++ ) { widget = widgetVector.elementAt( widgetIndex ); if ( widget.getName().equals( name ) ) { preferencesReadWidget( splitLine[ 1 ], widget ); return; } } } /** Set widget to preferences value. @param value preferences value @param widget widget to be set to value */ void preferencesReadWidget( String value, Widget widget ) { if ( widget instanceof BCheckBox || widget instanceof BRadioButton ) { widget.setState( Boolean.valueOf( value ) ); return; } if ( widget instanceof BOutline ) { // it would be better to save the value instead of index because the list might change, but I'm lazy bList = widget.getContent().getContent(); selectedIndex = Integer.valueOf( value ); bList.setSelected( selectedIndex, true ); bList.scrollToItem( selectedIndex ); return; } if ( widget instanceof BTextField ) { widget.setText( value ); return; } if ( widget instanceof ValueField ) { widget.setValue( Double.valueOf( value ) ); } } /** Write widget settings to preferences file. @param preferencesFilename preferences filename @param widgetVector memorable widgets */ void preferencesWrite( String preferencesFilename, Vector widgetVector ) { preferencesFile = new File( preferencesFilename ); if ( preferencesFile == null ) { print( "Can not write preferences to " + preferencesFilename ); return; } BufferedWriter preferencesWriter = new BufferedWriter( new FileWriter( preferencesFile ) ); for ( int widgetIndex = 0; widgetIndex < widgetVector.size(); widgetIndex++ ) { widget = widgetVector.elementAt( widgetIndex ); preferencesWriteWidget( preferencesWriter, widget ); } //Close the output stream preferencesWriter.close(); } /** Write widget settings to line of preferences. @param preferencesWriter buffered preferences file writer @param widget widget to be written */ void preferencesWriteWidget( BufferedWriter preferencesWriter, Widget widget ) { widgetString = widget.getName() + "\t"; if ( widget instanceof BCheckBox || widget instanceof BRadioButton ) { preferencesWriter.write( widgetString + widget.getState().toString() + "\n" ); return; } if ( widget instanceof BOutline ) { // it would be better to save the value because the list might change, but I'm lazy BList bList = widget.getContent().getContent(); bList = widget.getContent().getContent(); preferencesWriter.write( widgetString + bList.getSelectedIndex().toString() + "\n" ); return; } if ( widget instanceof BTextField ) { preferencesWriter.write( widgetString + widget.getText() + "\n" ); return; } if ( widget instanceof ValueField ) { preferencesWriter.write( widgetString + widget.getValue().toString() + "\n" ); } } // Set default parameters. bufferedWriter = null; exportSelectionCheckbox = new BCheckBox( "", false ); file = null; gnuSurfaceFilenameTextField = new BTextField( "triangle_mesh.gts" ); String preferencesFilename = "gnu_triangulated_surface_preferences.csv"; printSelectionCheckbox = new BCheckBox( "", true ); Widget[] widgets = new Widget[] { exportSelectionCheckbox, printSelectionCheckbox }; String[] widgetStrings = new String[] { "Export Selection:", "Print Selection:" }; // change the user interface parameters from default to preferences Vector widgetVector = new Vector(); preferencesAddWidgetsWithStrings( widgets, widgetStrings, widgetVector ); preferencesAddWidgetWithString( gnuSurfaceFilenameTextField, "GNU Triangulated Surface Filename:", widgetVector ); preferencesRead( preferencesFilename, widgetVector ); curvesMeshesInfo = getCurvesMeshesInfo(); if ( curvesMeshesInfo.length < 1 ) { print( "There is no triangle mesh in the scene, so nothing will be done." ); print( "It may be that there is a solid shape which is not a triangle mesh, in which case convert that shape to a triangle mesh." ); return; } dialog = new ComponentsDialog( window, "Export and/or Print Selection", widgets, widgetStrings ); if ( !dialog.clickedOk() ) return; if ( exportSelectionCheckbox.getState() ) { fileDescriptor = new BFileChooser( BFileChooser.SAVE_FILE, "Select name for the GNU Triangulated Surface file."); fileDescriptor.setSelectedFile( new File( gnuSurfaceFilenameTextField.getText() ) ); fileDescriptor.showDialog( window ); file = fileDescriptor.getSelectedFile(); if ( file != null ) { gnuSurfaceFilenameTextField.setText( file.getAbsolutePath() ); bufferedWriter = new BufferedWriter( new FileWriter( file ) ); } } preferencesWrite( preferencesFilename, widgetVector ); outputCurvesMeshes( curvesMeshesInfo ); sfact-2011.12.18/fabmetheus_utilities/miscellaneous/Art of Illusion Scripts/Export Topology.bsh000066400000000000000000000122571167321211700323560ustar00rootroot00000000000000/* */ /** Get the info for all the selected curves and meshes. */ ObjectInfo[] getCurvesMeshesInfo() { scene = window.getScene(); selection = scene.getSelection(); Vector objectInfoVector = new Vector(); for ( int objectIndex = 0; objectIndex < selection.length; objectIndex++ ) { objectInfo = scene.getObject( selection[ objectIndex ] ); if ( objectInfo.object instanceof Curve || objectInfo.object instanceof TriangleMesh ) { objectInfoVector.add( objectInfo ); } } if ( objectInfoVector.size() > 0 ) { return objectInfoVector.toArray( new ObjectInfo[ objectInfoVector.size() ] ); } for ( int objectIndex = 0; objectIndex < scene.getNumObjects(); objectIndex++ ) { objectInfo = scene.getObject( objectIndex ); if ( objectInfo.object instanceof Curve || objectInfo.object instanceof TriangleMesh ) { return new ObjectInfo[] { objectInfo }; } } return new ObjectInfo[ 0 ]; } /** Output the curves and/or meshes. */ void outputCurvesMeshes( ObjectInfo[] objectInfoArray ) { if ( objectInfoArray.length < 1 ) { return; } outputCurveMesh( objectInfoArray[ 0 ] ); for ( int objectIndex = 1; objectIndex < objectInfoArray.length; objectIndex++ ) { outputString( "" ); outputCurveMesh( objectInfoArray[ objectIndex ] ); } if ( bufferedWriter != null ) { //Close the output stream bufferedWriter.close(); } } /** Output the curve and/or mesh. */ void outputCurveMesh( ObjectInfo objectInfo ) { className = objectInfo.object.getClass().getName(); classNameEnd = className.substring( className.lastIndexOf( "." ) + 1 ); outputString( "Class, " + classNameEnd ); outputString( "Name, " + objectInfo.name ); origin = objectInfo.coords.getOrigin(); outputString( "Origin, Vector (xyz), " + origin.x + ", " + origin.y + ", " + origin.z ); orientation = objectInfo.coords.getRotationAngles(); outputString( "Orientation, Vector (xyz), " + orientation[ 0 ] + ", " + orientation[ 1 ] + ", " + orientation[ 2 ] ); outputVertexPositions( objectInfo ); if ( objectInfo.object instanceof Curve ) { return; } outputString( "Faces, Face Index, Vertex 1, Vertex 2, Vertex 3" ); faces = objectInfo.object.getFaces(); for ( int faceIndex = 0; faceIndex < faces.length; faceIndex++ ) { face = faces[ faceIndex ]; outputString( "Face, " + faceIndex.toString() + ", " + face.v1 + ", " + face.v2 + ", " + face.v3 ); } outputString( "Edges, Edge Index, Face 1, Face 2, Smoothness, Vertex 1, Vertex 2" ); edges = objectInfo.object.getEdges(); for ( int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++ ) { edge = edges[ edgeIndex ]; outputString( "Edge, " + edgeIndex.toString() + ", " + edge.f1 + ", " + edge.f2 + ", " + edge.smoothness + ", " + edge.v1 + ", " + edge.v2 ); } } /** Output comma separated strings followed by a linefeed. */ void outputString( string ) { if ( printSelection.getState() || exportPrintSelection.getState() ) { print( string ); } if ( bufferedWriter != null ) { bufferedWriter.write( string.replace( ", ", "," ) + "\n" ); } } /** Output the vertex positions. */ void outputVertexPositions( ObjectInfo objectInfo ) { outputString( "VertexPositions, Vertex Index, x, y, z" ); vertexPositions = objectInfo.object.getVertexPositions(); for ( int vertexIndex = 0; vertexIndex < vertexPositions.length; vertexIndex++ ) { vertexPosition = vertexPositions[ vertexIndex ]; outputString( "Vertex Position, " + vertexIndex.toString() + ", " + vertexPosition.x + ", " + vertexPosition.y + ", " + vertexPosition.z ); } } // Get parameters. actionRadioButtonGroup = new RadioButtonGroup(); exportSelection = new BRadioButton( "Export Selection", false, actionRadioButtonGroup ); exportPrintSelection = new BRadioButton( "Export and Print Selection", true, actionRadioButtonGroup ); printSelection = new BRadioButton( "Print Selection", false, actionRadioButtonGroup ); actionGridContainer = new GridContainer( 1, 3 ); actionGridContainer.setDefaultLayout( new LayoutInfo( LayoutInfo.WEST, LayoutInfo.NONE, new Insets( 2, 2, 2, 2 ), null ) ); actionGridContainer.add( exportSelection, 0, 0 ); actionGridContainer.add( exportPrintSelection, 0, 1 ); actionGridContainer.add( printSelection, 0, 2 ); bufferedWriter = null; dlg = new ComponentsDialog( window, "Export and/or Print Selection", new Widget [] { actionGridContainer }, new String [] { "Action:" } ); if ( !dlg.clickedOk() ) return; if ( exportSelection.getState() || exportPrintSelection.getState() ) { fileDescriptor = new BFileChooser( BFileChooser.SAVE_FILE, "Select name for the topology file."); fileDescriptor.setSelectedFile( new File( "polygon.csv" ) ); fileDescriptor.showDialog( window ); filename = fileDescriptor.getSelectedFile(); if ( filename != null ) { bufferedWriter = new BufferedWriter( new FileWriter( filename ) ); } } curvesMeshesInfo = getCurvesMeshesInfo(); outputCurvesMeshes( curvesMeshesInfo );sfact-2011.12.18/fabmetheus_utilities/miscellaneous/Art of Illusion Scripts/Gearweaver.bsh000066400000000000000000001365721167321211700313770ustar00rootroot00000000000000/* */ /** Add a side to the bottom of the truncated shaft. @param bisectionRadius outer radius of shaft @param bottomShaftPolygon bottom shaft polygon @param currentAngle angle around the polygon @param nodeVector nodes of the trimesh @param sideAngle angle subtended by one side */ void addBottomSide( bisectionRadius, bottomShaftPolygon, currentAngle, nodeVector, sideAngle ) { bottom = - shaftRadius * ( 1.0 - shaftTruncationBottom ); currentSide = getPolar( currentAngle, bisectionRadius ); nextSide = getPolar( currentAngle + sideAngle, bisectionRadius ); if ( bottom > nextSide.y ) { return; } if ( currentSide.y > bottom ) { node = new Vec3( currentSide.x, currentSide.y, 0 ); bottomShaftPolygon.add( nodeVector.size() ); nodeVector.add( node ); return; } shaftMinusCurrent = bottom - currentSide.y; shaftMinusCurrent /= nextSide.y - currentSide.y; intersection = nextSide.minus( currentSide ); intersection.scale( shaftMinusCurrent ); intersection.add( currentSide ); node = new Vec3( intersection.x, intersection.y, 0 ); bottomShaftPolygon.add( nodeVector.size() ); nodeVector.add( node ); } /** Adds a clockwise triangle to the face array. @param face three index array @param beginIndex beginning index of the triangle @param centerIndex center index of the triangle @param endIndex end index of the triangle */ void addFace( int beginIndex, int centerIndex, int endIndex, Vector faces ) { int[] face = new int[ 3 ]; faces.add( face ); face[ 0 ] = beginIndex; face[ 1 ] = centerIndex; face[ 2 ] = endIndex; } /** Add faces between two layers of a convex concentric clockwise polygon and a convex anticlockwise polygon, both of which go around the origin. @param bottomOuterPolygon bottom outer polygon @param bottomInnerPolygon bottom inner polygon @param faceVector faces of the trimesh @param nodeVector nodes of the trimesh @param topOuterPolygon top outer polygon @param topInnerPolygon top inner polygon */ void addFacesBetweenConcentricPolygons( Vector bottomInnerPolygon, Vector bottomOuterPolygon, Vector faceVector, Vector nodeVector, Vector topInnerPolygon, Vector topOuterPolygon ) { oldClosestIndex = getClosestInnerIndex( bottomInnerPolygon, nodeVector, bottomOuterPolygon.elementAt( bottomOuterPolygon.size() - 1 ), bottomOuterPolygon.elementAt( 0 ) ); for ( int pointIndex = 0; pointIndex < bottomOuterPolygon.size(); pointIndex++ ) { rimPlusOneRemainder = ( pointIndex + 1 ) % bottomOuterPolygon.size(); bottomRimFirst = bottomOuterPolygon.elementAt( pointIndex ); bottomRimSecond = bottomOuterPolygon.elementAt( rimPlusOneRemainder ); topRimFirst = topOuterPolygon.elementAt( pointIndex ); closestInnerIndex = getClosestInnerIndex( bottomInnerPolygon, nodeVector, bottomRimFirst, bottomRimSecond ); addFace( bottomInnerPolygon.elementAt( closestInnerIndex ), bottomRimFirst, bottomRimSecond, faceVector ); addFace( topInnerPolygon.elementAt( closestInnerIndex ), topOuterPolygon.elementAt( rimPlusOneRemainder ), topRimFirst, faceVector ); if ( closestInnerIndex > oldClosestIndex ) { closestInnerIndex -= bottomInnerPolygon.size(); } for ( int sideIndex = closestInnerIndex; sideIndex < oldClosestIndex; sideIndex++ ) { sideRemainder = ( sideIndex + bottomInnerPolygon.size() ) % bottomInnerPolygon.size(); sidePlusOneRemainder = ( sideIndex + bottomInnerPolygon.size() + 1 ) % bottomInnerPolygon.size(); addFace( bottomInnerPolygon.elementAt( sidePlusOneRemainder ), bottomRimFirst, bottomInnerPolygon.elementAt( sideRemainder ), faceVector ); addFace( topInnerPolygon.elementAt( sidePlusOneRemainder ), topInnerPolygon.elementAt( sideRemainder ), topRimFirst, faceVector ); } oldClosestIndex = closestInnerIndex; } return faceIndex; } /** Add faces between a bottom and top polygon. @param bottomPolygon bottom polygon @param faceVector faces of the trimesh @param topPolygon top polygon */ void addFacesBetweenPolygons( Vector bottomPolygon, Vector faceVector, Vector topPolygon ) { for ( int beginIndex = 0; beginIndex < bottomPolygon.size(); beginIndex++ ) { beginBottomIndex = bottomPolygon.elementAt( beginIndex ); beginTopIndex = topPolygon.elementAt( beginIndex ); endBottomIndex = bottomPolygon.elementAt( ( beginIndex + 1 ) % bottomPolygon.size() ); endTopIndex = topPolygon.elementAt( ( beginIndex + 1 ) % bottomPolygon.size() ); addFace( beginBottomIndex, beginTopIndex, endTopIndex, faceVector ); addFace( beginBottomIndex, endTopIndex, endBottomIndex, faceVector ); } } /** Add gear outline to scene. @param coordinateSystem coordinate system of the gear @param name name of the gear @param numberOfTeeth number of teeth in the gear @param toothProfile profile of one of the teeth of the gear */ void addGear( CoordinateSystem coordinateSystem, String name, double numberOfTeeth, Vec2[] toothProfile ) { int numberOfCircumferencePoints = toothProfile.length * numberOfTeeth; Vec3[] gearVertexPositions = new Vec3[ numberOfCircumferencePoints ]; float[] smoothness = new float[ numberOfCircumferencePoints ]; int index = 0; double toothAngleRadian = 2.0 * Math.PI / numberOfTeeth; for ( int tooth = 0; tooth < numberOfTeeth; tooth++ ) { double totalToothAngle = - toothAngleRadian * tooth; for ( int toothSurface = 0; toothSurface < toothProfile.length; toothSurface++ ) { rotatedVector = getRotatedVector( totalToothAngle, toothProfile[ toothSurface ] ); gearVertexPositions[ index ] = new Vec3( rotatedVector.x, rotatedVector.y, 0 ); smoothness[ index ] = 0; index++; } } curve = new Curve( gearVertexPositions, smoothness, Mesh.APPROXIMATING, true ); window.addObject( curve, coordinateSystem, name, null ); } /** Add the top side of the truncated shaft. @param bisectionRadius outer radius of the shaft @param bottomShaftPolygon bottom shaft polygon @param currentAngle current angle of the polygon point @param nodeVector nodes of the trimesh @param sideAngle angle subtended by a side of the polygon */ void addTopSide( bisectionRadius, bottomShaftPolygon, currentAngle, nodeVector, sideAngle ) { top = shaftRadius; if ( shaftSides % 2 == 1 ) { top = bisectionRadius; } top *= ( 1.0 - shaftTruncationTop ); currentSide = getPolar( currentAngle, bisectionRadius ); lastSide = getPolar( currentAngle - sideAngle, bisectionRadius ); if ( lastSide.y > top ) { return; } if ( currentSide.y < top ) { gearNode = new Vec3( currentSide.x, currentSide.y, 0 ); bottomShaftPolygon.add( nodeVector.size() ); nodeVector.add( gearNode ); return; } shaftMinusLast = top - lastSide.y; shaftMinusLast /= currentSide.y - lastSide.y; intersection = currentSide.minus( lastSide ); intersection.scale( shaftMinusLast ); intersection.add( lastSide ); node = new Vec3( intersection.x, intersection.y, 0 ); bottomShaftPolygon.add( nodeVector.size() ); nodeVector.add( node ); } /** Add triangle pairs in two layers of a convex polygon. @param bottomPolygon bottom polygon @param faceVector faces of the trimesh @param topPolygon top polygon */ void addTrianglePairsInPolygon( Vector bottomPolygon, Vector faceVector, Vector topPolygon ) { for ( int begin = 0; begin < ( bottomPolygon.size() - 1 ) / 2; begin++ ) { end = bottomPolygon.size() - begin - 1; centerIndex = bottomPolygon.elementAt( end - 1 ); quadrilateralBegin = bottomPolygon.elementAt( begin ); addFace( quadrilateralBegin, centerIndex, bottomPolygon.elementAt( end ), faceVector ); centerIndex = topPolygon.elementAt( end - 1 ); quadrilateralBegin = topPolygon.elementAt( begin ); addFace( quadrilateralBegin, topPolygon.elementAt( end ), centerIndex, faceVector ); } for ( int begin = 0; begin < bottomPolygon.size() / 2 - 1; begin++ ) { end = bottomPolygon.size() - begin - 1; centerIndex = bottomPolygon.elementAt( end - 1 ); quadrilateralBegin = bottomPolygon.elementAt( begin ); addFace( quadrilateralBegin, bottomPolygon.elementAt( begin + 1 ), centerIndex, faceVector ); centerIndex = topPolygon.elementAt( end - 1 ); quadrilateralBegin = topPolygon.elementAt( begin ); addFace( quadrilateralBegin, centerIndex, topPolygon.elementAt( begin + 1 ), faceVector ); } } /** Convert gear profile to thick gear. @param coordinateSystem coordinate system of the gear @param numberOfTeeth number of teeth in the gear @param pitchRadius pitch radius of the gear @param shovelDirection direction that the teeth curve @param thickName name of the solid gear, the name of the gear profile is the name of the solid gear plus " Profile" */ void convertToSolid( CoordinateSystem coordinateSystem, int numberOfTeeth, double pitchRadius, double shovelDirection, String thickName ) { scene = window.getScene(); gearProfile = scene.getObject( thickName + " Profile" ); gearVertexPositions = gearProfile.object.getVertexPositions(); innerRadius = getInnerRadius( numberOfTeeth, pitchRadius ); layers = 1 + shovelSegments; topVertexPositionOffsets = gearVertexPositions.length * shovelSegments; Vector gearFaceVector = new Vector(); Vector gearNodeVector = new Vector(); for ( int vertexIndex = 0; vertexIndex < gearVertexPositions.length; vertexIndex++ ) { gearNode = new Vec3( gearVertexPositions[ vertexIndex ] ); gearNodeVector.add( gearNode ); } for ( int segmentIndex = 1; segmentIndex < layers; segmentIndex++ ) { polarShovel = getPolar( shovelAngle, 1.0 ); shovelWidth = 2.0 * polarShovel.y; upRatio = ( double )segmentIndex / ( double )shovelSegments; digY = polarShovel.y - upRatio * shovelWidth; digRatio = Math.sqrt( 1.0 - digY * digY ) - polarShovel.x; digRotation = shovelDirection * digRatio * thickness / pitchRadius; up = upRatio * thickness; for ( int vertexIndex = 0; vertexIndex < gearVertexPositions.length; vertexIndex++ ) { gearNode = gearNodeVector.elementAt( vertexIndex ); rotatedGearNode = getRotatedVector( digRotation, new Vec2( gearNode.x, gearNode.y ) ); layerNode = new Vec3( rotatedGearNode.x, rotatedGearNode.y, up ); gearNodeVector.add( layerNode ); } } Vector bottomShaftVector = new Vector(); Vector topShaftVector = new Vector(); bisectionRadius = shaftRadius; if ( bisectionRadius > innerRadius ) { bisectionRadius = 0.0; shaftRadius = 0.0; print( "The requested shaft is larger than the gear, so the shaft will not be removed." ); } if ( shaftRadius > 0.0 ) { halfSideAngle = Math.PI / shaftSides; shaftStart = 1.5 * Math.PI + halfSideAngle; sideAngle = 2.0 * halfSideAngle; bisectionRadius /= Math.cos( halfSideAngle ); int sideIndex = 0; for ( ; shaftStart + sideIndex * sideAngle < 2 * Math.PI; sideIndex++ ) { currentAngle = shaftStart + sideIndex * sideAngle; addBottomSide( bisectionRadius, bottomShaftVector, currentAngle, gearNodeVector, sideAngle ); } for ( ; shaftStart + sideIndex * sideAngle < 2.5 * Math.PI + halfSideAngle / 2; sideIndex++ ) { currentAngle = shaftStart + sideIndex * sideAngle; addTopSide( bisectionRadius, bottomShaftVector, currentAngle, gearNodeVector, sideAngle ); } originalHalfShaftLength = bottomShaftVector.size(); mirrorStart = originalHalfShaftLength; if ( Math.abs( gearNodeVector.elementAt( bottomShaftVector.elementAt( originalHalfShaftLength - 1 ) ).x ) < 0.00001 ) { mirrorStart++; } for ( int sideIndex = mirrorStart; sideIndex < 2 * originalHalfShaftLength; sideIndex++ ) { gearShaftNode = gearNodeVector.elementAt( bottomShaftVector.elementAt( 2 * originalHalfShaftLength - sideIndex - 1 ) ); bottomShaftVector.add( gearNodeVector.size() ); gearNodeVector.add( new Vec3( - gearShaftNode.x, gearShaftNode.y, gearShaftNode.z ) ); } copyHigh( bottomShaftVector, gearNodeVector, thickness, topShaftVector ); } pointsPerTooth = ( int )Math.round( gearVertexPositions.length / numberOfTeeth ); // Add faces around the perimeter. for ( int segmentIndex = 0; segmentIndex < shovelSegments; segmentIndex++ ) { vertexPositionOffset = segmentIndex * gearVertexPositions.length; Vector bottomPerimeter = new Vector(); Vector topPerimeter = new Vector(); for ( int beginIndex = vertexPositionOffset; beginIndex < vertexPositionOffset + gearVertexPositions.length; beginIndex++ ) { bottomPerimeter.add( beginIndex ); topPerimeter.add( beginIndex + gearVertexPositions.length ); } addFacesBetweenPolygons( bottomPerimeter, gearFaceVector, topPerimeter ); } // Add faces to the top and bottom. Vector bottomRim = new Vector(); Vector topRim = new Vector(); for ( int tooth = 0; tooth < numberOfTeeth; tooth++ ) { toothStart = tooth * pointsPerTooth; bottomRim.add( toothStart ); topRim.add( toothStart + topVertexPositionOffsets ); Vector bottomTooth = new Vector(); Vector topTooth = new Vector(); for ( int beginIndex = 0; beginIndex <= pointsPerTooth; beginIndex++ ) { toothStartBegin = ( toothStart + beginIndex ) % gearVertexPositions.length; bottomTooth.add( toothStartBegin ); topTooth.add( toothStartBegin + topVertexPositionOffsets ); } addTrianglePairsInPolygon( bottomTooth, gearFaceVector, topTooth ); } // Add faces around cutout circles. rimThickness = minimumRimThickness * innerRadius; centerThickness = bisectionRadius + rimThickness; remainingCutout = ( 1.0 - 2 * minimumRimThickness ); holeRadius = ( innerRadius - rimThickness - centerThickness ) / 2; if ( holeRadius > minimumRimCutoutRadius ) { int cutoutCircles = 5; int cutoutSides = 9; double cutoutCircleAngle = 2.0 * Math.PI / ( double )cutoutCircles; int sideBetweenStart = ( int )Math.round( ( double )cutoutSides / 7.0 ); int sideBetweenStartMirror = cutoutSides - sideBetweenStart; int sideBetweenEnd = ( int )Math.round( 3.0 * ( double )cutoutSides / 8.0 ); int sideBetweenEndMirror = cutoutSides - sideBetweenEnd; double cutoutSideAngle = 2.0 * Math.PI / ( double )cutoutSides; double holeY = innerRadius - rimThickness - holeRadius; double sinHalfCutoutCircleAngle = Math.sin( cutoutCircleAngle / 2 ); double overlap = holeRadius + rimThickness / 2 - holeY * sinHalfCutoutCircleAngle; Vector[] bottomCutoutVector = new Vector[ cutoutCircles ]; Vector[] topCutoutVector = new Vector[ cutoutCircles ]; if ( overlap > 0.0 ) { holeRadius -= overlap / ( 1.0 + sinHalfCutoutCircleAngle ); holeY = innerRadius - rimThickness - holeRadius; } for ( int circle = 0; circle < cutoutCircles; circle++ ) { bottomCutoutVector[ circle ] = new Vector(); topCutoutVector[ circle ] = new Vector(); for ( int side = 0; side < cutoutSides; side++ ) { cutoutPlanePoint = getPolar( Math.PI * 1.5 + cutoutSideAngle * side, holeRadius ); cutoutPlanePoint.y += holeY; cutoutPlanePoint = getRotatedVector( - cutoutCircleAngle * circle, cutoutPlanePoint ); gearNode = new Vec3( cutoutPlanePoint.x, cutoutPlanePoint.y, 0.0 ); bottomCutoutVector[ circle ].add( gearNodeVector.size() ); gearNodeVector.add( gearNode ); } copyHigh( bottomCutoutVector[ circle ], gearNodeVector, thickness, topCutoutVector[ circle ] ); addFacesBetweenPolygons( bottomCutoutVector[ circle ], gearFaceVector, topCutoutVector[ circle ] ); } Vector bottomOuterVector = new Vector(); Vector topOuterVector = new Vector(); for ( int circle = cutoutCircles - 1; circle >= 0; circle-- ) { for ( int side = sideBetweenEnd; side <= sideBetweenEndMirror; side++ ) { bottomOuterVector.add( bottomCutoutVector[ circle ].elementAt( side ) ); topOuterVector.add( topCutoutVector[ circle ].elementAt( side ) ); } } addFacesBetweenConcentricPolygons( bottomOuterVector, bottomRim, gearFaceVector, gearNodeVector, topOuterVector, topRim ); // Add outside of cutout circles. bottomRim = new Vector(); topRim = new Vector(); for ( int side = 0; side <= sideBetweenStart; side++ ) { bottomRim.add( bottomCutoutVector[ 0 ].elementAt( side ) ); topRim.add( topCutoutVector[ 0 ].elementAt( side ) ); } for ( int circle = 1; circle < cutoutCircles; circle++ ) { for ( int side = sideBetweenStartMirror; side <= sideBetweenStart + cutoutSides; side++ ) { sideRemainder = side % cutoutSides; bottomRim.add( bottomCutoutVector[ circle ].elementAt( sideRemainder ) ); topRim.add( topCutoutVector[ circle ].elementAt( sideRemainder ) ); } } for ( int side = sideBetweenStartMirror; side < cutoutSides; side++ ) { bottomRim.add( bottomCutoutVector[ 0 ].elementAt( side ) ); topRim.add( topCutoutVector[ 0 ].elementAt( side ) ); } for ( int circle = 0; circle < cutoutCircles; circle++ ) { Vector bottomSides = new Vector(); Vector topSides = new Vector(); for ( int side = sideBetweenStart; side <= sideBetweenEnd; side++ ) { bottomSides.add( bottomCutoutVector[ circle ].elementAt( side ) ); topSides.add( topCutoutVector[ circle ].elementAt( side ) ); } for ( int side = sideBetweenEndMirror; side <= sideBetweenStartMirror; side++ ) { nextCircle = ( circle + 1 ) % cutoutCircles; bottomSides.add( bottomCutoutVector[ nextCircle ].elementAt( side ) ); topSides.add( topCutoutVector[ nextCircle ].elementAt( side ) ); } addTrianglePairsInPolygon( bottomSides, gearFaceVector, topSides ); } } if ( shaftRadius == 0.0 ) { addTrianglePairsInPolygon( bottomRim, gearFaceVector, topRim ); } else { addFacesBetweenConcentricPolygons( bottomShaftVector, bottomRim, gearFaceVector, gearNodeVector, topShaftVector, topRim ); addFacesBetweenPolygons( bottomShaftVector, gearFaceVector, topShaftVector ); } int[][] gearFaceArray = gearFaceVector.toArray( new int[ gearFaceVector.size() ][ 3 ] ); Vec3[] gearNodeArray = gearNodeVector.toArray( new Vec3[ gearNodeVector.size() ] ); mesh = new TriangleMesh ( gearNodeArray, gearFaceArray ); mesh.setSmoothingMethod( Mesh.NO_SMOOTHING ); window.addObject( mesh, coordinateSystem, thickName, null ); window.removeObject( scene.indexOf( gearProfile ), null ); } /** Copy the bottom polygon into a top polygon which is thickness high. @param bottomPolygon bottom polygon @param nodeVector nodes of the trimesh @param thickness height of the top polygon @param topPolygon top polygon */ void copyHigh( Vector bottomPolygon, Vector nodeVector, double thickness, Vector topPolygon ) { for ( int pointIndex = 0; pointIndex < bottomPolygon.size(); pointIndex++ ) { node = nodeVector.elementAt( bottomPolygon.elementAt( pointIndex ) ); topPolygon.add( nodeVector.size() ); nodeVector.add( new Vec3( node.x, node.y, thickness ) ); } } /** End the turning gear profile simulation and create the finished gear. */ void endTurnGear() { scene = window.getScene(); timer.cancel(); firstGearCoordinateSystem.copyCoords( firstGearCoordinateSystemOld ); secondGearCoordinateSystem.copyCoords( secondGearCoordinateSystemOld ); if ( sceneCameraInfo != null ) { sceneCameraInfo.coords.copyCoords( sceneCameraCoordsOld ); for ( propertyIndex = 0; propertyIndex < sceneCameraPropertiesOld.length; propertyIndex++ ) { sceneCameraInfo.object.setPropertyValue( propertyIndex, sceneCameraPropertiesOld[ propertyIndex ] ); } scene.objectModified( sceneCameraInfo.object ); } window.updateImage(); if ( thickness > 0.0 ) { convertToSolid( firstGearCoordinateSystemOld, ( int )numberOfTeethFirstGear, pitchRadiusFirstGear, 1.0, "First Gear" ); convertToSolid( secondGearCoordinateSystemOld, ( int )numberOfTeethSecondGear, pitchRadiusSecondGear, - 1.0, "Second Gear" ); } undoAdd = new UndoRecord ( window, false, UndoRecord.DELETE_OBJECT, new Object[] { new Integer( scene.getNumObjects() - 2 ) } ); window.setUndoRecord( undoAdd ); undoAdd = new UndoRecord ( window, false, UndoRecord.DELETE_OBJECT, new Object[] { new Integer( scene.getNumObjects() - 1 ) } ); window.setUndoRecord( undoAdd ); window.updateImage(); // number of faces: // for each edge in our perimeter, two triangles to connect // the front and back, so 2*numberSides // for each end cap, we connect each vertex to the point. The // first and last vertices are connected by a perimeter edge, // leaving numberSides-2 edges to connect across the middle, // creating a face, for numberSides-2 triangles per end cap, // or (numberSides-2)*2 triangles for both end caps // Thus: // 2*numberSides + 2*(numberSides-2) // 2*numberSides + 2*numberSides - 4 // 4*numberSides - 4 //Vec3[] v = new Vec3[numberSides * 2]; //int[][] faces = new int[4*numberSides-4][3]; //v[0] = new Vec3(0, y0, 0); //v[1] = new Vec3(0, y0, -length); } /** Get the Camera Info from the first camera in the scene. */ ObjectInfo getCameraInfo() { scene = window.getScene(); for ( int objectIndex = 0; objectIndex < scene.getNumObjects(); objectIndex++ ) { objectInfo = scene.getObject( objectIndex ); if ( objectInfo.object instanceof SceneCamera ) { return objectInfo; } } return null; } /** Get the index of the point on the inner polygon which is closest to the average angle of the first and second points on the outer polygon. @param innerPolygon inner polygon index array @param nodes Vector of nodes @param outerPolygonFirstIndex index of first point on outer polygon @param outerPolygonSecondIndex index of second point on outer polygon @return closest index on the inner polygon to the average angle of the first and second points on the outer polygon */ int getClosestInnerIndex( Vector innerPolygon, Vector nodes, int outerPolygonFirstIndex, int outerPolygonSecondIndex ) { closestIndex = 0; largestDot = - 9999999.0; rimFirstPlane = nodes.elementAt( outerPolygonFirstIndex ).dropAxis( 2 ); rimSecondPlane = nodes.elementAt( outerPolygonSecondIndex ).dropAxis( 2 ); rimFirstPlane.normalize(); rimSecondPlane.normalize(); rimFirstPlane.add( rimSecondPlane ); rimFirstPlane.normalize(); for ( int innerIndex = 0; innerIndex < innerPolygon.size(); innerIndex++ ) { innerPlane = nodes.elementAt( innerPolygon.elementAt( innerIndex ) ).dropAxis( 2 ); innerPlane.normalize(); innerDot = innerPlane.dot( rimFirstPlane ); if ( innerDot > largestDot ) { largestDot = innerDot; closestIndex = innerIndex; } } return closestIndex; } /** Get number of teeth from the field value if it is not zero bounded to a minimum of 3, otherwise get number from the prime list. @param primeList scroll list of prime numbers @param numberOfTeethValueField number of gear teeth value field @return number of gear teeth */ double getNumberOfTeeth( BList primeList, ValueField numberOfTeethValueField ) { if ( numberOfTeethValueField.getValue() < 1.0 ) { return Double.valueOf( primeList.getSelectedValue() ); } return Math.max( 2, Math.round( numberOfTeethValueField.getValue() ) ); } /** Get gear inner radius. @param numberOfTeeth number of gear teeth @param pitchRadius pitch radius of the gear @return gear inner radius */ double getInnerRadius( double numberOfTeeth, double pitchRadius ) { return pitchRadius * ( 1 - Math.PI / numberOfTeeth ); } /** Get ratio outside of the pitch. @param numberOfTeeth number of gear teeth @param pitchRadius pitch radius of the gear @return ratio outside of the pitch */ double getOutsidePitch( double numberOfTeeth ) { return 2.0 / numberOfTeeth; } /** Get ratio of second gear according to the number of teeth. @param numberOfTeethFirstGear number of gear teeth on the first gear @param numberOfTeethSecondGear number of gear teeth on the second gear @param pitchRadiusFirstGear pitch radius of the first gear @return ratio of second gear */ double getPitchRadiusSecondGear( double numberOfTeethFirstGear, double numberOfTeethSecondGear, double pitchRadiusFirstGear ) { return pitchRadiusFirstGear * numberOfTeethSecondGear / numberOfTeethFirstGear;; } /** Get polar Vec2 from counterclockwise angle from 1, 0 and radius. @param angle counterclockwise angle from 1, 0 @param radius radius of vector @return polar vector */ Vec2 getPolar( double angle, double radius ) { return new Vec2( radius * Math.cos( angle ), radius * Math.sin( angle ) ); } /** Get scroll list of prime numbers, with visible selection. @param selectedIndex selected index of the scroll list @return scroll list of prime numbers */ BList getPrimeList( int selectedIndex ) { String[] primeNumberStrings = new String[ primeNumbers.length ]; for ( int primeIndex = 0; primeIndex < primeNumbers.length; primeIndex++ ) { primeNumberStrings[ primeIndex ] = primeNumbers[ primeIndex ].toString(); } primeList = new BList( primeNumberStrings ); primeList.setPreferredVisibleRows( ( int )Math.max( 4.0, selectedIndex + 1 ) ); primeList.setMultipleSelectionEnabled( false ); primeList.setSelected( selectedIndex, true ); primeList.scrollToItem( selectedIndex ); return primeList; } /** Get rotated Vec2 from counterclockwise angle and vector. @param angle counterclockwise angle from 1, 0 @param vector2 plane vector @return rotated vector */ Vec2 getRotatedVector( double angle, Vec2 vector2 ) { x = Math.cos( angle ); y = Math.sin( angle ); return new Vec2( vector2.x * x - vector2.y * y, vector2.x * y + vector2.y * x ); } /** Get profile for one tooth. @param numberOfTeeth number of gear teeth @param pitchRadius pitch radius of the gear @param pressureAngle pressure angle of the gear tooth @param profileDefinitionSurfaces profile definition surfaces, which should be at least six @return profile for one tooth */ Vec2[] getToothProfile( double numberOfTeeth, double pitchRadius, double pressureAngle, int profileDefinitionSurfaces ) { double toothAngleRadian = 2.0 * Math.PI / numberOfTeeth; double innerRadius = getInnerRadius( numberOfTeeth, pitchRadius ); double outerRadius = pitchRadius * ( 1 + getOutsidePitch( numberOfTeeth ) ); double bevelRadius = pitchRadius * Math.cos( pressureAngle ); double angleBeginRadian = Math.PI / 2 - toothAngleRadian / 4 + pressureAngle - pitchRadius * Math.sin( pressureAngle ) / bevelRadius; double angleEndRadian = Math.sqrt( outerRadius * outerRadius - bevelRadius * bevelRadius ) / bevelRadius + angleBeginRadian; double angleDifferenceRadian = ( angleEndRadian - angleBeginRadian ) / ( profileDefinitionSurfaces - 1 ); Vector toothProfileVector = new Vector(); toothProfileVector.add( getPolar( Math.PI - angleBeginRadian, innerRadius ) ); angleRadian = angleBeginRadian; abovePoint = null; pointMoved = false; for ( int profileIndex = 0; profileIndex < profileDefinitionSurfaces; profileIndex++ ) { length = bevelRadius * ( angleRadian - angleBeginRadian ); toothPoint = new Vec2( - bevelRadius, length ); toothPoint = getRotatedVector( angleRadian, toothPoint ); toothPoint.y = - toothPoint.y; toothProfileVector.add( toothPoint ); angleRadian = angleRadian + angleDifferenceRadian; if ( toothPoint.length() > innerRadius ) { if ( abovePoint == null ) { abovePoint = toothPoint; } } } // Move out, remove or replace the points which are inside the inner radius. for ( int profileIndex = profileDefinitionSurfaces-1; profileIndex >= 1; profileIndex-- ) { toothProfileLength = toothProfileVector.elementAt( profileIndex ).length(); if ( toothProfileLength < innerRadius ) { if ( pointMoved ) { toothProfileVector.removeElementAt( profileIndex ); } else { lengthBelow = innerRadius - toothProfileLength; toothPoint = toothProfileVector.elementAt( profileIndex ); lastMinusShort = abovePoint.minus( toothPoint ); lastMinusShort.scale( lengthBelow / lastMinusShort.length() ); toothPoint.add( lastMinusShort ); pointMoved = true; } } } if ( pointMoved ) { toothProfileVector.removeElementAt( 0 ); } // Mirror the tooth profile. int toothProfileLimit = toothProfileVector.size() - 1; for ( int profileIndex = toothProfileLimit; profileIndex >= 0; profileIndex-- ) { toothPoint = toothProfileVector.elementAt( profileIndex ); toothProfileVector.add( new Vec2( - toothPoint.x, toothPoint.y ) ); } return toothProfileVector.toArray( new Vec2[ toothProfileVector.size() ] ); } /** Add radio button groups to the preference widgets. @param radioButtonGroups radio button groups which will be added to the memorable widgets @param widgetVector memorable widgets */ void preferencesAddRadioButtonGroups( RadioButtonGroup[] radioButtonGroups, Vector widgetVector ) { for ( int radioIndex = 0; radioIndex < radioButtonGroups.length; radioIndex++ ) { radioButtonGroup = radioButtonGroups[ radioIndex ]; radioButtonGroupIterator = radioButtonGroup.getRadioButtons(); while ( radioButtonGroupIterator.hasNext() ) { radioButton = radioButtonGroupIterator.next(); preferencesAddWidgetWithString( radioButton, radioButton.getText(), widgetVector ); } } } /** Add widgets which have titles. @param widgets widgets which have titles @param widgetStrings widget titles @param widgetVector memorable widgets */ void preferencesAddWidgetsWithStrings( Widget[] widgets, String[] widgetStrings, Vector widgetVector ) { for ( int widgetIndex = 0; widgetIndex < widgets.length; widgetIndex++ ) { widget = widgets[ widgetIndex ]; if ( widget instanceof BCheckBox || widget instanceof BOutline || widget instanceof BTextField || widget instanceof ValueField ) { preferencesAddWidgetWithString( widget, widgetStrings[ widgetIndex ], widgetVector ); } } } /** Give the widget a name and add it to the widget vector. @param widget widget which will be given a name @param widgetStrings widget name @param widgetVector memorable widgets */ void preferencesAddWidgetWithString( Widget widget, String widgetString, Vector widgetVector ) { widget.setName( widgetString ); widgetVector.add( widget ); } /** Read widget settings from preferences file. @param preferencesFilename preferences filename @param widgetVector memorable widgets */ void preferencesRead( String preferencesFilename, Vector widgetVector ) { preferencesFile = new File( preferencesFilename ); if ( !preferencesFile.canRead() ) { return; } BufferedReader preferencesReader = new BufferedReader( new FileReader( preferencesFile ) ); line = preferencesReader.readLine(); while ( line != null ) { preferencesReadLine( line, widgetVector ); line = preferencesReader.readLine(); } } /** Read line of preferences and set widget to that line. @param line line of preferences @param widgetVector memorable widgets */ void preferencesReadLine( String line, Vector widgetVector ) { splitLine = line.split( "\t" ); if ( splitLine.length < 2 ) { return; } name = splitLine[ 0 ]; for ( int widgetIndex = 0; widgetIndex < widgetVector.size(); widgetIndex++ ) { widget = widgetVector.elementAt( widgetIndex ); if ( widget.getName().equals( name ) ) { preferencesReadWidget( splitLine[ 1 ], widget ); return; } } } /** Set widget to preferences value. @param value preferences value @param widget widget to be set to value */ void preferencesReadWidget( String value, Widget widget ) { if ( widget instanceof BCheckBox || widget instanceof BRadioButton ) { widget.setState( Boolean.valueOf( value ) ); return; } if ( widget instanceof BOutline ) { // it would be better to save the value instead of index because the list might change, but I'm lazy bList = widget.getContent().getContent(); selectedIndex = Integer.valueOf( value ); bList.setSelected( selectedIndex, true ); bList.scrollToItem( selectedIndex ); return; } if ( widget instanceof BTextField ) { widget.setText( value ); return; } if ( widget instanceof ValueField ) { widget.setValue( Double.valueOf( value ) ); } } /** Write widget settings to preferences file. @param preferencesFilename preferences filename @param widgetVector memorable widgets */ void preferencesWrite( String preferencesFilename, Vector widgetVector ) { preferencesFile = new File( preferencesFilename ); if ( preferencesFile == null ) { print( "Can not write preferences to " + preferencesFilename ); return; } BufferedWriter preferencesWriter = new BufferedWriter( new FileWriter( preferencesFile ) ); for ( int widgetIndex = 0; widgetIndex < widgetVector.size(); widgetIndex++ ) { widget = widgetVector.elementAt( widgetIndex ); preferencesWriteWidget( preferencesWriter, widget ); } //Close the output stream preferencesWriter.close(); } /** Write widget settings to line of preferences. @param preferencesWriter buffered preferences file writer @param widget widget to be written */ void preferencesWriteWidget( BufferedWriter preferencesWriter, Widget widget ) { widgetString = widget.getName() + "\t"; if ( widget instanceof BCheckBox || widget instanceof BRadioButton ) { preferencesWriter.write( widgetString + widget.getState().toString() + "\n" ); return; } if ( widget instanceof BOutline ) { // it would be better to save the value because the list might change, but I'm lazy BList bList = widget.getContent().getContent(); bList = widget.getContent().getContent(); preferencesWriter.write( widgetString + bList.getSelectedIndex().toString() + "\n" ); return; } if ( widget instanceof BTextField ) { preferencesWriter.write( widgetString + widget.getText() + "\n" ); return; } if ( widget instanceof ValueField ) { preferencesWriter.write( widgetString + widget.getValue().toString() + "\n" ); } } /** Set the coordinate system to a rotation around the z axis in degrees. @param coordinateSystem coordinate system with rotations defined around the x, y, z axes in degrees @param rotationDegree axis rotation angle in degrees */ void setCoordinateSystemToRotationDegree( CoordinateSystem coordinateSystem, double rotationDegree ) { coordinateSystem.setOrientation( 0.0, 0.0, rotationDegree ); } // Trim outer tooth of the first gear which collides with the second gear. void trimCollision( double numberOfTeethFirstGear, double numberOfTeethSecondGear, double pitchRadiusFirstGear, Vec2[] toothProfileFirstGear, Vec2[] toothProfileSecondGear ) { maximumAngle = Math.PI / 8; if ( numberOfTeethFirstGear > numberOfTeethSecondGear ) { maximumAngle *= numberOfTeethSecondGear / numberOfTeethFirstGear; } for ( double angle = 0.0; angle < maximumAngle; angle += 0.01 ) { trimCollisionAtAngle( angle, numberOfTeethFirstGear, numberOfTeethSecondGear, pitchRadiusFirstGear, toothProfileFirstGear, toothProfileSecondGear ); } } // Trim outer tooth of the first gear which collides with the second gear at an angle. void trimCollisionAtAngle( double angle, double numberOfTeethFirstGear, double numberOfTeethSecondGear, double pitchRadiusFirstGear, Vec2[] toothProfileFirstGear, Vec2[] toothProfileSecondGear ) { double pitchRadiusSecondGear = getPitchRadiusSecondGear( numberOfTeethFirstGear, numberOfTeethSecondGear, pitchRadiusFirstGear ); toothProfileSecondGearRotated = new Vec2[ toothProfileSecondGear.length ]; rotationSecondGear = Math.PI - Math.PI / numberOfTeethSecondGear - angle * numberOfTeethFirstGear / numberOfTeethSecondGear; for ( int profilePointIndex = 0; profilePointIndex < toothProfileSecondGear.length; profilePointIndex++ ) { rotated = getRotatedVector( rotationSecondGear, toothProfileSecondGear[ profilePointIndex ] ); rotated.y += pitchRadiusFirstGear + pitchRadiusSecondGear; toothProfileSecondGearRotated[ profilePointIndex ] = getRotatedVector( - angle, rotated ); } for ( int profilePointIndex = 0; profilePointIndex < toothProfileFirstGear.length; profilePointIndex++ ) { trimCollisionProfilePoint( profilePointIndex, toothProfileFirstGear, toothProfileSecondGearRotated ); } } // Trim point from first gear which collides with the second gear. void trimCollisionProfilePoint( int profilePointIndex, Vec2[] toothProfileFirstGear, Vec2[] toothProfileSecondGearRotated ) { firstGearProfilePoint = toothProfileFirstGear[ profilePointIndex ]; if ( firstGearProfilePoint.length() < pitchRadiusFirstGear ) { return; } if ( firstGearProfilePoint.x > 0.0 ) { return; } for ( int secondGearPointIndex = 0; secondGearPointIndex < toothProfileSecondGearRotated.length - 1; secondGearPointIndex++ ) { firstPointSecondGear = toothProfileSecondGearRotated[ secondGearPointIndex ]; secondPointSecondGear = toothProfileSecondGearRotated[ secondGearPointIndex + 1 ]; firstPointAbove = firstPointSecondGear.y - firstGearProfilePoint.y; secondPointAbove = secondPointSecondGear.y - firstGearProfilePoint.y; if ( firstPointAbove * secondPointAbove <= 0.0 ) { verticalSeparation = firstPointSecondGear.y - secondPointSecondGear.y; horizontalToothAxisIntersection = firstPointSecondGear.minus( secondPointSecondGear ); horizontalToothAxisIntersection.scale( - secondPointAbove / verticalSeparation ); horizontalToothAxisIntersection.add( secondPointSecondGear ); collision = horizontalToothAxisIntersection.x - firstGearProfilePoint.x; if ( collision > 0.0 ) { firstGearProfilePoint.x += collision; mirrorPointIndex = toothProfileFirstGear.length - 1 - profilePointIndex; toothProfileFirstGear[ mirrorPointIndex ].x -= collision; } } } } // Trim outer tooth by tolerance. void trimTolerance( double numberOfTeeth, double pitchRadius, double tolerance, Vec2[] toothProfile ) { if ( tolerance == 0.0 ) { return; } double otherGearStart = pitchRadius * ( 1 - getOutsidePitch( numberOfTeeth ) ) - tolerance; double innerRadius = getInnerRadius( numberOfTeeth, pitchRadius ); for ( int profilePointIndex = 0; profilePointIndex < toothProfile.length; profilePointIndex++ ) { toothProfilePoint = toothProfile[ profilePointIndex ]; toothProfilePointLength = toothProfilePoint.length(); shortenRatio = 1.0; if ( toothProfilePointLength < otherGearStart ) { shortenRatio = ( toothProfilePointLength - innerRadius ) / ( otherGearStart - innerRadius ); shortenRatio = Math.max( 0.0, shortenRatio ); } xAbsolute = Math.abs( toothProfilePoint.x ); xAbsoluteTrimmed = xAbsolute - tolerance * shortenRatio; xAbsoluteTrimmed = Math.max( 0.0, xAbsoluteTrimmed ); if ( xAbsolute > 0.0 ) { toothProfilePoint.x *= xAbsoluteTrimmed / xAbsolute; } } } // Get parameters. int[] primeNumbers = { 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149 }; firstGearPrimeList = getPrimeList( 6 ); numberOfTeethFirstGearValueField = new ValueField( 0, ValueField.NONNEGATIVE ); pitchRadiusFirstGearValueField = new ValueField( 75, ValueField.NONNEGATIVE ); secondGearPrimeList = getPrimeList( 1 ); numberOfTeethSecondGearValueField = new ValueField( 0, ValueField.NONNEGATIVE ); minimumRimCutoutRadiusValueField = new ValueField( 2.0, ValueField.NONNEGATIVE ); minimumRimThicknessValueField = new ValueField( 0.2, ValueField.NONNEGATIVE ); String preferencesFilename = "gearweaver_preferences.csv"; pressureAngleDegreeValueField = new ValueField( 20, ValueField.NONNEGATIVE ); profileDefinitionValueField = new ValueField( 9, ValueField.NONNEGATIVE ); shaftRadiusValueField = new ValueField( 5.0, ValueField.NONNEGATIVE); shaftSidesValueField = new ValueField( 4.0, ValueField.NONNEGATIVE); shaftTruncationBottomValueField = new ValueField( 0.0, ValueField.NONNEGATIVE); shaftTruncationTopValueField = new ValueField( 0.0, ValueField.NONNEGATIVE); shovelAngleValueField = new ValueField( 20.0, ValueField.NONNEGATIVE); shovelSegmentsValueField = new ValueField( 3, ValueField.NONNEGATIVE); //simulationDurationValueField = new ValueField( 10, ValueField.NONNEGATIVE); simulationDurationValueField = new ValueField( 0, ValueField.NONNEGATIVE); simulationRotationRateValueField = new ValueField( 0.1, ValueField.NONNEGATIVE ); thicknessValueField = new ValueField( 30.0, ValueField.NONNEGATIVE ); //thicknessValueField = new ValueField( 0.0, ValueField.NONNEGATIVE ); toleranceValueField = new ValueField( 0.0, ValueField.NONNEGATIVE ); Widget[] widgets = new Widget [] { UIUtilities.createScrollingList( firstGearPrimeList ), numberOfTeethFirstGearValueField, pitchRadiusFirstGearValueField, UIUtilities.createScrollingList( secondGearPrimeList ), numberOfTeethSecondGearValueField, minimumRimCutoutRadiusValueField, minimumRimThicknessValueField, pressureAngleDegreeValueField, profileDefinitionValueField, shaftRadiusValueField, shaftSidesValueField, shaftTruncationBottomValueField, shaftTruncationTopValueField, shovelAngleValueField, shovelSegmentsValueField, simulationDurationValueField, simulationRotationRateValueField, thicknessValueField, toleranceValueField }; String[] widgetStrings = new String [] { "Number of Teeth for First Gear (prime):", "or Number of Teeth for First Gear (integer):", "Pitch Radius First Gear (mm):", "Number of Teeth for Second Gear (prime):", "or Number of Teeth for Second Gear (integer):", "Minimum Rim Cutout Radius (mm):", "Minimum Rim Thickness (ratio):", "Pressure Angle (degrees):", "Profile Definition (surfaces):", "Shaft Radius (mm):", "Shaft Sides (surfaces):", "Shaft Truncation Bottom (ratio):", "Shaft Truncation Top (ratio):", "Shovel Angle (degrees):", "Shovel Segments (surfaces):", "Simulation Duration (seconds):", "Simulation Rotation Rate (teeth / second):", "Thickness (mm):", "Tolerance (mm):" }; // change the user interface parameters from default to preferences Vector widgetVector = new Vector(); preferencesAddWidgetsWithStrings( widgets, widgetStrings, widgetVector ); preferencesRead( preferencesFilename, widgetVector ); dialog = new ComponentsDialog( window, "Gearweaver Generator", widgets, widgetStrings ); if ( !dialog.clickedOk() ) return; preferencesWrite( preferencesFilename, widgetVector ); double numberOfTeethFirstGear = getNumberOfTeeth( firstGearPrimeList, numberOfTeethFirstGearValueField ); double numberOfTeethSecondGear = getNumberOfTeeth( secondGearPrimeList, numberOfTeethSecondGearValueField ); double pitchRadiusFirstGear = pitchRadiusFirstGearValueField.getValue(); double pitchRadiusSecondGear = getPitchRadiusSecondGear( numberOfTeethFirstGear, numberOfTeethSecondGear, pitchRadiusFirstGear ); double minimumRimCutoutRadius = minimumRimCutoutRadiusValueField.getValue(); double minimumRimThickness = minimumRimThicknessValueField.getValue(); int profileDefinitionSurfaces = ( int )Math.max( 1.0, Math.min( 30.0, profileDefinitionValueField.getValue() ) ); double pressureAngle = pressureAngleDegreeValueField.getValue() * Math.PI / 180.0; double shaftRadius = shaftRadiusValueField.getValue(); int shaftSides = ( int )Math.max( 3.0, shaftSidesValueField.getValue() ); double shaftTruncationBottom = shaftTruncationBottomValueField.getValue(); double shaftTruncationTop = shaftTruncationTopValueField.getValue(); double shovelAngle = shovelAngleValueField.getValue() * Math.PI / 180.0; int shovelSegments = ( int )Math.max( 1.0, shovelSegmentsValueField.getValue() ); double simulationDuration = simulationDurationValueField.getValue(); double simulationRotationRate = simulationRotationRateValueField.getValue(); double thickness = thicknessValueField.getValue(); double tolerance = toleranceValueField.getValue(); // Create gear pair. toothProfileFirstGear = getToothProfile( numberOfTeethFirstGear, pitchRadiusFirstGear, pressureAngle, profileDefinitionSurfaces ); toothProfileSecondGear = getToothProfile( numberOfTeethSecondGear, pitchRadiusSecondGear, pressureAngle, profileDefinitionSurfaces ); trimCollision( numberOfTeethFirstGear, numberOfTeethSecondGear, pitchRadiusFirstGear, toothProfileFirstGear, toothProfileSecondGear ); trimCollision( numberOfTeethSecondGear, numberOfTeethFirstGear, pitchRadiusSecondGear, toothProfileSecondGear, toothProfileFirstGear ); firstGearCoordinateSystem = new CoordinateSystem(); firstGearCoordinateSystemOld = firstGearCoordinateSystem.duplicate(); trimTolerance( numberOfTeethFirstGear, pitchRadiusFirstGear, tolerance, toothProfileFirstGear ); addGear( firstGearCoordinateSystem, "First Gear Profile", numberOfTeethFirstGear, toothProfileFirstGear ); secondGearCoordinateSystem = new CoordinateSystem(); secondGearCoordinateSystem.setOrigin( new Vec3( 0.0, pitchRadiusFirstGear + pitchRadiusSecondGear, 0.0 ) ); secondGearCoordinateOffsetDegree = 180.0 * ( numberOfTeethSecondGear % 2 + 1 ) / numberOfTeethSecondGear; setCoordinateSystemToRotationDegree( secondGearCoordinateSystem, secondGearCoordinateOffsetDegree ); secondGearCoordinateSystemOld = secondGearCoordinateSystem.duplicate(); trimTolerance( numberOfTeethSecondGear, pitchRadiusSecondGear, tolerance, toothProfileSecondGear ); addGear( secondGearCoordinateSystem, "Second Gear Profile", numberOfTeethSecondGear, toothProfileSecondGear ); import java.util.Timer; import java.util.TimerTask; Timer timer = new Timer(); startTime = System.currentTimeMillis(); sceneCameraInfo = getCameraInfo(); sceneCameraCoordsOld = null; sceneCameraPropertiesOld = null; if ( sceneCameraInfo != null ) { sceneCameraCoordsOld = sceneCameraInfo.coords.duplicate(); sceneCamera = sceneCameraInfo.object; properties = sceneCamera.getProperties(); propertiesLength = properties.length; sceneCameraPropertiesOld = new double[ propertiesLength ]; for ( propertyIndex = 0; propertyIndex < propertiesLength; propertyIndex++ ) { sceneCameraPropertiesOld[ propertyIndex ] = sceneCamera.getPropertyValue( propertyIndex ); propertyName = properties[ propertyIndex ].getName(); if ( propertyName.equals( "Depth of Field" ) ) { sceneCamera.setPropertyValue( propertyIndex, 10.0 ); } if ( propertyName.equals( "Field of View" ) ) { sceneCamera.setPropertyValue( propertyIndex, 30.0 ); } if ( propertyName.equals( "Focal Distance" ) ) { sceneCamera.setPropertyValue( propertyIndex, 20.0 ); } } sceneCameraInfo.coords.setOrigin( new Vec3( 0.0, pitchRadiusFirstGear, 15.0 * pitchRadiusFirstGear / numberOfTeethFirstGear ) ); sceneCameraInfo.coords.setOrientation( 0.0, 180.0, 0.0 ); sceneCameraInfo.coords.setOrientation( 0.0, 180.0, 0.0 ); } public final class TurnGear extends TimerTask { /** * Implements TimerTask's abstract run method. */ public void run() { elapsed = ( System.currentTimeMillis() - startTime ) / 1000.0; elapsedRotation = 360.0 * elapsed * simulationRotationRate; setCoordinateSystemToRotationDegree( firstGearCoordinateSystem, - elapsedRotation / numberOfTeethFirstGear ); setCoordinateSystemToRotationDegree( secondGearCoordinateSystem, elapsedRotation / numberOfTeethSecondGear + secondGearCoordinateOffsetDegree ); scene = window.getScene(); scene.objectModified( scene.getObject( "First Gear Profile" ).object ); scene.objectModified( scene.getObject( "Second Gear Profile" ).object ); window.updateImage(); if ( elapsed > simulationDuration ) { endTurnGear(); } } } TimerTask turnGear = new TurnGear(); timer.scheduleAtFixedRate( turnGear, 0, 13 );Import GNU Triangulated Surface.bsh000066400000000000000000000305161167321211700350600ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/miscellaneous/Art of Illusion Scripts/* */ /** Add a delete the last object of the scene undo record, to the scene. */ void addUndoRecord() { scene = window.getScene(); undoAdd = new UndoRecord ( window, false, UndoRecord.DELETE_OBJECT, new Object[] { new Integer( scene.getNumObjects() - 1 ) } ); window.setUndoRecord( undoAdd ); } int getSameVertexIndex( edgeFirst, edgeSecond ) { for ( int endpointIndex = 0; endpointIndex < 2; endpointIndex++ ) { endpoint = edgeFirst[ endpointIndex ]; if ( endpoint == edgeSecond[ 0 ] ) { return endpoint; } if ( endpoint == edgeSecond[ 1 ] ) { return endpoint; } } print( "Inconsistent GNU Triangulated Surface" ); print( edgeFirst ); print( edgeSecond ); return 0; } /** Import GNU Triangulated Surface from a file. Quoted from http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE "All the lines beginning with GTS_COMMENTS (#!) are ignored. The first line contains three unsigned integers separated by spaces. The first integer is the number of vertices, nv, the second is the number of edges, ne and the third is the number of faces, nf. Follows nv lines containing the x, y and z coordinates of the vertices. Follows ne lines containing the two indices (starting from one) of the vertices of each edge. Follows nf lines containing the three ordered indices (also starting from one) of the edges of each face. The format described above is the least common denominator to all GTS files. Consistent with an object-oriented approach, the GTS file format is extensible. Each of the lines of the file can be extended with user-specific attributes accessible through the read() and write() virtual methods of each of the objects written (surface, vertices, edges or faces). When read with different object classes, these extra attributes are just ignored." */ void importFile( gnuFile ) { bufferedReader = new BufferedReader( new FileReader( gnuFile ) ); Vector lineVector = new Vector(); line = bufferedReader.readLine(); name = gnuFile.getName(); int lastIndexOfDot = name.lastIndexOf( '.' ); if ( lastIndexOfDot > 0 ) { name = name.substring( 0, lastIndexOfDot ); } while ( line != null ) { if ( line.length() > 0 ) { firstCharacter = line.charAt( 0 ); if ( firstCharacter != '#' && firstCharacter != '!' ) { lineVector.add( line ); } } line = bufferedReader.readLine(); } splitLine = lineVector.get( 0 ).split( " " ); int numberOfVertices = Integer.valueOf( splitLine[ 0 ] ); int numberOfEdges = Integer.valueOf( splitLine[ 1 ] ); int numberOfFaces = Integer.valueOf( splitLine[ 2 ] ); edges = new int[ numberOfEdges ][ 2 ]; faces = new int[ numberOfFaces ][ 3 ]; vertices = new Vec3[ numberOfVertices ]; for ( int vertexIndex = 0; vertexIndex < numberOfVertices; vertexIndex++ ) { line = lineVector.get( vertexIndex + 1 ); splitLine = line.split( " " ); vertex = new Vec3( Double.valueOf( splitLine[ 0 ] ), Double.valueOf( splitLine[ 1 ] ), Double.valueOf( splitLine[ 2 ] ) ); vertices[ vertexIndex ] = vertex; } int edgeStart = numberOfVertices + 1; for ( int edgeIndex = 0; edgeIndex < numberOfEdges; edgeIndex++ ) { line = lineVector.get( edgeIndex + edgeStart ); splitLine = line.split( " " ); int[] edge = { Integer.valueOf( splitLine[ 0 ] ) - 1, Integer.valueOf( splitLine[ 1 ] ) - 1 }; edges[ edgeIndex ] = edge; } int faceStart = edgeStart + numberOfEdges; for ( int faceIndex = 0; faceIndex < numberOfFaces; faceIndex++ ) { line = lineVector.get( faceIndex + faceStart ); splitLine = line.split( " " ); edgeFirst = edges[ Integer.valueOf( splitLine[ 0 ] ) - 1 ]; edgeSecond = edges[ Integer.valueOf( splitLine[ 1 ] ) - 1 ]; edgeThird = edges[ Integer.valueOf( splitLine[ 2 ] ) - 1 ]; int[] vertexIndices = { getSameVertexIndex( edgeFirst, edgeSecond ), getSameVertexIndex( edgeSecond, edgeThird ), getSameVertexIndex( edgeThird, edgeFirst ) }; faces[ faceIndex ] = vertexIndices; } CoordinateSystem coordinateSystem = new CoordinateSystem(); while ( window.getScene().getObject( name ) != null ) { name += "2"; } mesh = new TriangleMesh ( vertices, faces ); mesh.setSmoothingMethod( Mesh.NO_SMOOTHING ); window.addObject( mesh, coordinateSystem, name, null ); addUndoRecord(); } /** Import GNU Triangulated Surface from a file or from files in a directory. */ void importFiles() { if ( openFileButton.getState() ) { importFile( file ); return; } filesInDirectory = file.getParentFile().listFiles(); for ( int fileIndex = 0; fileIndex < filesInDirectory.length; fileIndex++ ) { directoryFile = filesInDirectory[ fileIndex ]; String directoryFileName = directoryFile.getName(); if ( directoryFileName.endsWith( ".gts" ) ) { importFile( directoryFile ); } } } /** Add radio button groups to the preference widgets. @param radioButtonGroups radio button groups which will be added to the memorable widgets @param widgetVector memorable widgets */ void preferencesAddRadioButtonGroups( RadioButtonGroup[] radioButtonGroups, Vector widgetVector ) { for ( int radioIndex = 0; radioIndex < radioButtonGroups.length; radioIndex++ ) { radioButtonGroup = radioButtonGroups[ radioIndex ]; radioButtonGroupIterator = radioButtonGroup.getRadioButtons(); while ( radioButtonGroupIterator.hasNext() ) { radioButton = radioButtonGroupIterator.next(); preferencesAddWidgetWithString( radioButton, radioButton.getText(), widgetVector ); } } } /** Add widgets which have titles. @param widgets widgets which have titles @param widgetStrings widget titles @param widgetVector memorable widgets */ void preferencesAddWidgetsWithStrings( Widget[] widgets, String[] widgetStrings, Vector widgetVector ) { for ( int widgetIndex = 0; widgetIndex < widgets.length; widgetIndex++ ) { widget = widgets[ widgetIndex ]; if ( widget instanceof BCheckBox || widget instanceof BOutline || widget instanceof BTextField || widget instanceof ValueField ) { preferencesAddWidgetWithString( widget, widgetStrings[ widgetIndex ], widgetVector ); } } } /** Give the widget a name and add it to the widget vector. @param widget widget which will be given a name @param widgetStrings widget name @param widgetVector memorable widgets */ void preferencesAddWidgetWithString( Widget widget, String widgetString, Vector widgetVector ) { widget.setName( widgetString ); widgetVector.add( widget ); } /** Read widget settings from preferences file. @param preferencesFilename preferences filename @param widgetVector memorable widgets */ void preferencesRead( String preferencesFilename, Vector widgetVector ) { preferencesFile = new File( preferencesFilename ); if ( !preferencesFile.canRead() ) { return; } BufferedReader preferencesReader = new BufferedReader( new FileReader( preferencesFile ) ); line = preferencesReader.readLine(); while ( line != null ) { preferencesReadLine( line, widgetVector ); line = preferencesReader.readLine(); } } /** Read line of preferences and set widget to that line. @param line line of preferences @param widgetVector memorable widgets */ void preferencesReadLine( String line, Vector widgetVector ) { splitLine = line.split( "\t" ); if ( splitLine.length < 2 ) { return; } name = splitLine[ 0 ]; for ( int widgetIndex = 0; widgetIndex < widgetVector.size(); widgetIndex++ ) { widget = widgetVector.elementAt( widgetIndex ); if ( widget.getName().equals( name ) ) { preferencesReadWidget( splitLine[ 1 ], widget ); return; } } } /** Set widget to preferences value. @param value preferences value @param widget widget to be set to value */ void preferencesReadWidget( String value, Widget widget ) { if ( widget instanceof BCheckBox || widget instanceof BRadioButton ) { widget.setState( Boolean.valueOf( value ) ); return; } if ( widget instanceof BOutline ) { // it would be better to save the value instead of index because the list might change, but I'm lazy bList = widget.getContent().getContent(); selectedIndex = Integer.valueOf( value ); bList.setSelected( selectedIndex, true ); bList.scrollToItem( selectedIndex ); return; } if ( widget instanceof BTextField ) { widget.setText( value ); return; } if ( widget instanceof ValueField ) { widget.setValue( Double.valueOf( value ) ); } } /** Write widget settings to preferences file. @param preferencesFilename preferences filename @param widgetVector memorable widgets */ void preferencesWrite( String preferencesFilename, Vector widgetVector ) { preferencesFile = new File( preferencesFilename ); if ( preferencesFile == null ) { print( "Can not write preferences to " + preferencesFilename ); return; } BufferedWriter preferencesWriter = new BufferedWriter( new FileWriter( preferencesFile ) ); for ( int widgetIndex = 0; widgetIndex < widgetVector.size(); widgetIndex++ ) { widget = widgetVector.elementAt( widgetIndex ); preferencesWriteWidget( preferencesWriter, widget ); } //Close the output stream preferencesWriter.close(); } /** Write widget settings to line of preferences. @param preferencesWriter buffered preferences file writer @param widget widget to be written */ void preferencesWriteWidget( BufferedWriter preferencesWriter, Widget widget ) { widgetString = widget.getName() + "\t"; if ( widget instanceof BCheckBox || widget instanceof BRadioButton ) { preferencesWriter.write( widgetString + widget.getState().toString() + "\n" ); return; } if ( widget instanceof BOutline ) { // it would be better to save the value because the list might change, but I'm lazy BList bList = widget.getContent().getContent(); bList = widget.getContent().getContent(); preferencesWriter.write( widgetString + bList.getSelectedIndex().toString() + "\n" ); return; } if ( widget instanceof BTextField ) { preferencesWriter.write( widgetString + widget.getText() + "\n" ); return; } if ( widget instanceof ValueField ) { preferencesWriter.write( widgetString + widget.getValue().toString() + "\n" ); } } // Set default parameters. directoryRadioButtonGroup = new RadioButtonGroup(); openDirectoryButton = new BRadioButton( "Import All GNU Triangulated Surface Files in a Directory", false, directoryRadioButtonGroup ); openFileButton = new BRadioButton( "Import File", true, directoryRadioButtonGroup ); directoryGridContainer = new GridContainer( 1, 2 ); directoryGridContainer.setDefaultLayout( new LayoutInfo( LayoutInfo.WEST, LayoutInfo.NONE, new Insets( 2, 2, 2, 2 ), null ) ); directoryGridContainer.add( openDirectoryButton, 0, 0 ); directoryGridContainer.add( openFileButton, 0, 1 ); gnuSurfaceFilenameTextField = new BTextField( "" ); String preferencesFilename = "import_gnu_triangulated_surface_preferences.csv"; Widget[] widgets = new Widget[] { directoryGridContainer }; String[] widgetStrings = new String[] { "Open File or Directory:" }; // change the user interface parameters from default to preferences Vector widgetVector = new Vector(); RadioButtonGroup[] radioButtonGroups = new RadioButtonGroup[] { directoryRadioButtonGroup }; preferencesAddRadioButtonGroups( radioButtonGroups, widgetVector ); preferencesAddWidgetsWithStrings( widgets, widgetStrings, widgetVector ); preferencesAddWidgetWithString( gnuSurfaceFilenameTextField, "GCode Filename:", widgetVector ); preferencesRead( preferencesFilename, widgetVector ); dialog = new ComponentsDialog( window, "Import GNU Triangulated Surface File or Directory", widgets, widgetStrings ); if ( !dialog.clickedOk() ) return; fileChooser = new BFileChooser( BFileChooser.OPEN_FILE, "Import GNU Triangulated Surface File"); gnuSurfaceFile = new File( gnuSurfaceFilenameTextField.getText() ); if ( gnuSurfaceFile.canRead() ) { fileChooser.setSelectedFile( gnuSurfaceFile ); } fileChooser.showDialog( window ); file = fileChooser.getSelectedFile(); if ( file == null ) { return; } gnuSurfaceFilenameTextField.setText( file.getAbsolutePath() ); preferencesWrite( preferencesFilename, widgetVector ); importFiles(); sfact-2011.12.18/fabmetheus_utilities/miscellaneous/Art of Illusion Scripts/Import Topology.bsh000066400000000000000000000126451167321211700323500ustar00rootroot00000000000000/* */ String addShape( BufferedReader bufferedReader, String line ) { importShape = ImportShape(); importShape.setBufferedReaderLine( bufferedReader, line ); while ( importShape.splitLine.length > 1 ) { importShape.shouldRead = true; switch( importShape.firstLower ) { case "class": importShape.setClass(); break; case "faces": importShape.setFaces(); break; case "name": importShape.setName(); break; case "orientation": importShape.setOrientation(); break; case "origin": importShape.setOrigin(); break; case "vertexpositions": importShape.setVertexPositions(); break; } if ( importShape.shouldRead ) { importShape.readLine(); } } importShape.addShapeIfParametersSet(); return importShape.bufferedReader.readLine(); } /** Add curves and/or meshes from the file through the buffered reader. */ void addShapes( BufferedReader bufferedReader ) { line = bufferedReader.readLine(); while ( line != null ) { line = addShape( bufferedReader, line ); } } /** Get a Vec3 from a string array. */ Vec3 getFromStringArray( String[] stringArray ) { return new Vec3( Double.valueOf( stringArray[ 2 ] ), Double.valueOf( stringArray[ 3 ] ), Double.valueOf( stringArray[ 4 ] ) ); } /** Import the topology of a shape from the file through the buffered reader. */ ImportShape() { BufferedReader bufferedReader = null; String className = null; Vector facesVector = null; String firstLower = null; String line = null; String name = null; Vec3 orientation = null; Vec3 origin = null; boolean shouldRead = true; String[] splitLine = null; Vector vertexPositionsVector = null; /** Add the topology of a shape from the file through the buffered reader if all the parameters have been set. */ addShapeIfParametersSet() { if ( className == null || name == null || orientation == null || origin == null || vertexPositionsVector == null ) { print( "Shape has a null parameter and was not imported." ); print( className ); print( name ); print( orientation ); print( origin ); print( vertexPositionsVector ); return; } vertexPositionsArray = vertexPositionsVector.toArray( new Vec3[ vertexPositionsVector.size() ] ); CoordinateSystem coordinateSystem = new CoordinateSystem(); coordinateSystem.setOrientation( orientation.x, orientation.y, orientation.z ); coordinateSystem.setOrigin( origin ); while ( window.getScene().getObject( name ) != null ) { name += "a"; } if ( className.equals( "curve" ) ) { float[] smoothness = new float[ vertexPositionsArray.length ]; curve = new Curve( vertexPositionsArray, smoothness, Mesh.APPROXIMATING, true ); window.addObject( curve, coordinateSystem, name, null ); addUndoRecord(); return; } if ( facesVector == null ) { return; } if ( className.equals( "trianglemesh" ) ) { facesArray = facesVector.toArray( new int[ facesVector.size() ][ 3 ] ); mesh = new TriangleMesh ( vertexPositionsArray, facesArray ); mesh.setSmoothingMethod( Mesh.NO_SMOOTHING ); window.addObject( mesh, coordinateSystem, name, null ); addUndoRecord(); } } addUndoRecord() { scene = window.getScene(); undoAdd = new UndoRecord ( window, false, UndoRecord.DELETE_OBJECT, new Object[] { new Integer( scene.getNumObjects() - 1 ) } ); window.setUndoRecord( undoAdd ); } readLine() { line = bufferedReader.readLine(); setSplitLine(); } setBufferedReaderLine( BufferedReader argumentBufferedReader, String argumentLine ) { bufferedReader = argumentBufferedReader; line = argumentLine; setSplitLine(); } setClass() { className = splitLine[ 1 ].toLowerCase(); } setFaces() { readLine(); shouldRead = false; facesVector = new Vector(); while ( splitLine[ 0 ].toLowerCase().equals( "face" ) ) { int[] face = { Integer.valueOf( splitLine[ 2 ] ), Integer.valueOf( splitLine[ 3 ] ), Integer.valueOf( splitLine[ 4 ] ) }; facesVector.add( face ); readLine(); } } setName() { name = splitLine[ 1 ]; } setOrientation() { orientation = getFromStringArray( splitLine ); } setOrigin() { origin = getFromStringArray( splitLine ); } setSplitLine() { if ( line == null ) { splitLine = new String[] { "" }; return; } splitLine = line.split( "," ); firstLower = splitLine[ 0 ].toLowerCase(); } setVertexPositions() { readLine(); shouldRead = false; vertexPositionsVector = new Vector(); while ( splitLine[ 0 ].toLowerCase().equals( "vertex position" ) ) { vertexPositionsVector.add( getFromStringArray( splitLine ) ); readLine(); } } return this; } // Get parameters. fileChooser = new BFileChooser( BFileChooser.OPEN_FILE, "Import Comma Separated Values Topology"); fileChooser.showDialog( window ); filename = fileChooser.getSelectedFile(); if ( filename == null ) { return; } bufferedReader = new BufferedReader( new FileReader( filename ) ); addShapes( bufferedReader );sfact-2011.12.18/fabmetheus_utilities/miscellaneous/Art of Illusion Scripts/Platonic Solid.bsh000066400000000000000000000347541167321211700321120ustar00rootroot00000000000000/* */ /* Copyright (C) 2004 by Fran�ois Guillet This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ //Script localization test HashMap translations = new HashMap(); if (Translate.getLocale().equals(Locale.FRENCH)) { translations.put("Hexahedron", "Hexah\u00E8dre (6)"); translations.put("Tetrahedron", "Tetrah\u00E8dre (4)"); translations.put("Octahedron", "Octah\u00E8dre (8)"); translations.put("Dodecahedron", "Dodecah\u00E8dre (12)"); translations.put("Icosahedron", "Icosah\u00E8dre (20)"); translations.put("centeredFaces", "sommets aux centres des faces"); translations.put("selectPolyhedron", "S\u00E9lectionnez un polyh\u00E8dre :"); translations.put("noSmoothing", "Pas de lissage" ); translations.put("smoothShading", "Ombrage doux" ); translations.put("interpolating", "Interpolation" ); translations.put("approximating", "Approximation" ); translations.put("polyhedron", "Polyh\u00E8dre:" ); translations.put("faceCenteredMesh", "Maillage face centr\u00E9e" ); translations.put("radius", "Rayon :" ); translations.put("smoothingMethod", "M\u00E9thode de lissage:"); translations.put("verticesSmoothness", "Lissage des sommets :"); translations.put("edgesSmoothness", "Lissages des ar\u00EAtes :"); translations.put("texture", "Texture :"); translations.put("material", "Mat\u00E9riau :"); translations.put("hexahedron", "Hexah\u00E8dre"); translations.put("tetrahedron", "Tetrah\u00E8dre"); translations.put("octahedron", "Octah\u00E8dre"); translations.put("dodecahedron", "Dodecah\u00E8dre"); translations.put("icosahedron", "Icosah\u00E8dre"); } else { translations.put("Hexahedron", "Hexahedron (6)"); translations.put("Tetrahedron", "Tetrahedron (4)"); translations.put("Octahedron", "Octahedron (8)"); translations.put("Dodecahedron", "Dodecahedron (12)"); translations.put("Icosahedron", "Icosahedron (20)"); translations.put("centeredFaces", "vertices at faces centers"); translations.put("selectPolyhedron", "Select a polyhedron:"); translations.put("noSmoothing", "No Smoothing" ); translations.put("smoothShading", "Smooth Shading" ); translations.put("interpolating", "Interpolating" ); translations.put("approximating", "Approximating" ); translations.put("polyhedron", "Polyhedron:" ); translations.put("faceCenteredMesh", "Face centered mesh" ); translations.put("radius", "Radius:" ); translations.put("smoothingMethod", "Smoothing Method:"); translations.put("verticesSmoothness", "Vertices Smoothness:"); translations.put("edgesSmoothness", "Edges smoothness:"); translations.put("texture", "Texture:"); translations.put("material", "Material:"); translations.put("hexahedron", "Hexahedron"); translations.put("tetrahedron", "Tetrahedron"); translations.put("octahedron", "Octahedron"); translations.put("dodecahedron", "Dodecahedron"); translations.put("icosahedron", "Icosahedron"); } //end of script localization test //given a set of faces, this function computes the centers of the faces and adds them to the list of vertices Vec3[] completeVertices(Vec3[] vert, int[][] polyFaces, int vertNum) { vertices = new Vec3[vert.length + polyFaces.length]; for (i = 0 ; i < vert.length ; ++i) vertices[i] = vert[i]; for (i = vertNum; i < vertNum + polyFaces.length; ++i) { v = new Vec3(); for (j = 0 ; j < polyFaces[i - vertNum].length; ++j) v.add(vertices[polyFaces[i - vertNum][j]]); v.scale(1.0/polyFaces[i - vertNum].length); vertices[i] = v; } return vertices; } //given a set of faces and a set of vertices, //this function computes centered faces to form a triangular mesh //presumably equivalent to subdivide face command in the mesh editor TriangleMesh triangulateFaces(Vec3[] vertices, int[][] polyFaces, int vertNum) { vertices = completeVertices(vertices, polyFaces, vertNum); faces = new int[polyFaces.length * polyFaces[0].length][3]; f = 0; for (i = 0 ; i < polyFaces.length ; ++i) { for (j = 0; j < polyFaces[i].length ; ++j) { if (j < polyFaces[i].length-1) { faces[f][0] = polyFaces[i][j]; faces[f][1] = polyFaces[i][j+1]; faces[f][2] = vertNum + i; } else { faces[f][0] = polyFaces[i][j]; faces[f][1] = polyFaces[i][0]; faces[f][2] = vertNum + i; } ++f; } } mesh = new TriangleMesh(vertices, faces); return mesh; } scene = window.getScene(); //setup the list of polyhedra polyList = new BList(new String [] { translations.get("Tetrahedron"), translations.get("Hexahedron"), translations.get("Octahedron"), translations.get("Dodecahedron"), translations.get("Icosahedron") }); polyList.setPreferredVisibleRows(5); polyList.setSelected(0, true); //face centered checkbox centeredCheckbox = new BCheckBox(translations.get("centeredFaces"), false); //radius value field radiusValueField = new ValueField(1.0, ValueField.NONNEGATIVE); //smoothing method smoothList = new BList(new String [] { translations.get("noSmoothing"), translations.get("smoothShading"), translations.get("interpolating"), translations.get("approximating") }); smoothList.setPreferredVisibleRows(4); smoothList.setSelected(0, true); //vertices smoothness value field vertSmoothnessValueField = new ValueField(1.0, ValueField.NONNEGATIVE); //edges smoothness value field edgesSmoothnessValueField = new ValueField(1.0, ValueField.NONNEGATIVE); // get list of scene textures numTex=scene.getNumTextures(); textureList=new BList(); textureList.setPreferredVisibleRows(3 < numTex ? 3 : numTex); for (i = 0 ; i < numTex ; i++) { iTex=scene.getTexture(i); name=iTex.getName(); textureList.add(name); } textureList.setSelected(0, true); // get list of materials numMat=scene.getNumMaterials(); materialList=new BList(); materialList.setPreferredVisibleRows(3 < numMat + 1 ? 3 : numMat + 1); materialList.add("none"); for (i = 0 ; i < numMat ; i++) { iMat=scene.getMaterial(i); name=iMat.getName(); materialList.add(name); } materialList.setSelected(0, true); dlg = new ComponentsDialog(window, translations.get("selectPolyhedron"), new Widget [] { UIUtilities.createScrollingList(polyList), centeredCheckbox, radiusValueField, UIUtilities.createScrollingList(smoothList), vertSmoothnessValueField, edgesSmoothnessValueField, UIUtilities.createScrollingList(textureList), UIUtilities.createScrollingList(materialList)}, new String [] { translations.get("polyhedron"), translations.get("faceCenteredMesh"), translations.get("radius"), translations.get("smoothingMethod"), translations.get("verticesSmoothness"), translations.get("edgesSmoothness"), translations.get("texture"), translations.get("material") } ); if (!dlg.clickedOk()) return; centered = centeredCheckbox.getState(); switch (polyList.getSelectedIndex()) { case 0 : //tetrahedra vertices = new Vec3[4]; // 4 vertices + 4 faces vertices[0] = new Vec3(0, 0, 1); vertices[1] = new Vec3(2*Math.sqrt(2)/3, 0, -1.0/3.0); vertices[2] = new Vec3(-Math.sqrt(2)/3, Math.sqrt(6)/3, -1.0/3.0); vertices[3] = new Vec3(-Math.sqrt(2)/3, -Math.sqrt(6)/3, -1.0/3.0); int[][] faces = {{ 0, 1, 2 }, { 0, 2, 3 }, { 0, 3, 1 }, { 1, 3, 2 }}; if (centered) mesh = triangulateFaces(vertices, faces, 4); else mesh = new TriangleMesh(vertices, faces); name = translations.get("tetrahedron") + (centered ? " FC" : ""); break; case 1 : //hexahedron vertices = new Vec3[8]; // 8 vertices + 6 faces vertices[0] = new Vec3(-1, -1, -1); vertices[1] = new Vec3(1, -1, -1); vertices[2] = new Vec3(1, 1, -1); vertices[3] = new Vec3(-1, 1, -1); vertices[4] = new Vec3(-1, -1, 1); vertices[5] = new Vec3(1, -1, 1); vertices[6] = new Vec3(1, 1, 1); vertices[7] = new Vec3(-1, 1, 1); for (i = 0 ; i < 8 ; ++i) vertices[i].scale(1.0/Math.sqrt(3)); //polygon faces when different from triangular faces int[][] hexaFaces = {{ 0, 3, 2, 1 }, { 0, 1, 5, 4 }, { 0, 4, 7, 3 }, { 6, 5, 1, 2 }, { 6, 2, 3, 7 }, { 6, 7, 4, 5 } }; //triangular faces int[][] faces = {{ 0, 3, 2}, { 0, 2, 1}, { 0, 1, 5}, { 0, 5, 4}, { 0, 4, 7}, {0, 7, 3}, { 6, 5, 1}, { 6, 1, 2}, { 6, 2, 3}, { 6, 3, 7}, { 6, 7, 4}, {6, 4, 5}}; if (centered) mesh = triangulateFaces(vertices, hexaFaces, 8); else mesh = new TriangleMesh(vertices, faces); name = translations.get("hexahedron") + (centered ? " FC" : ""); break; case 2 : //octahedron vertices = new Vec3[6]; // 6 vertices + 8 faces vertices[0] = new Vec3(1, 0, 0); vertices[1] = new Vec3(-1, 0, 0); vertices[2] = new Vec3(0, 1, 0); vertices[3] = new Vec3(0, -1, 0); vertices[4] = new Vec3(0, 0, 1); vertices[5] = new Vec3(0, 0, -1); int[][] faces = { { 4, 0, 2 }, { 4, 2, 1 }, { 4, 1, 3 }, { 4, 3, 0 }, { 5, 2, 0 }, { 5, 1, 2 }, { 5, 3, 1 }, { 5, 0, 3 } }; if (centered) mesh = triangulateFaces(vertices, faces, 6); else mesh = new TriangleMesh(vertices, faces); name = translations.get("octahedron") + (centered ? " FC" : ""); break; case 3 : //dodecahedron vertices = new Vec3[20]; // 20 vertices + 12 faces a = 1/Math.sqrt(3); b = Math.sqrt( (3.0 - Math.sqrt(5)) /6.0); c = Math.sqrt( (3.0 + Math.sqrt(5)) /6.0); vertices[0] = new Vec3(a, a, a); vertices[1] = new Vec3(a, a, -a); vertices[2] = new Vec3(a, -a, a); vertices[3] = new Vec3(a, -a, -a); vertices[4] = new Vec3(-a, a, a); vertices[5] = new Vec3(-a, a, -a); vertices[6] = new Vec3(-a, -a, a); vertices[7] = new Vec3(-a, -a, -a); vertices[8] = new Vec3(b, c, 0); vertices[9] = new Vec3(-b, c, 0); vertices[10] = new Vec3(b, -c, 0); vertices[11] = new Vec3(-b, -c, 0); vertices[12] = new Vec3(c, 0, b); vertices[13] = new Vec3(c, 0, -b); vertices[14] = new Vec3(-c, 0, b); vertices[15] = new Vec3(-c, 0, -b); vertices[16] = new Vec3(0, b, c); vertices[17] = new Vec3(0, -b, c); vertices[18] = new Vec3(0, b, -c); vertices[19] = new Vec3(0, -b, -c); int[][] faces = { //*quite* dull { 0, 8, 9 }, { 0, 12, 13 }, { 0, 16, 17 }, { 8, 1, 18 }, { 12, 2, 10 }, { 16, 4, 14 }, { 9, 5, 15 }, { 6, 11, 10 }, { 3, 19, 18 }, { 7, 15, 5 }, { 7, 11, 6 }, { 7, 19, 3 }, { 0, 9, 4 }, { 0, 13, 1 }, { 0, 17, 2 }, { 8, 18, 5 }, { 12, 10, 3 }, { 16, 14, 6 }, { 9, 15, 14 }, { 6, 10, 2 }, { 3, 18, 1 }, { 7, 5, 18 }, { 7, 6, 14 }, { 7, 3, 10 }, { 0, 4, 16 }, { 0, 1, 8 }, { 0, 2, 12 }, { 8, 5, 9 }, { 12, 3, 13 }, { 16, 6, 17 }, { 9, 14, 4 }, { 6, 2, 17 }, { 3, 1, 13 }, { 7, 18, 19 }, { 7, 14, 15 }, { 7, 10, 11 } }; int[][] dodeFaces = { { 0, 8, 9, 4, 16}, { 0, 16, 17, 2, 12}, { 12, 2, 10, 3, 13}, { 9, 5, 15, 14, 4}, { 3, 19, 18, 1, 13}, { 7, 11, 6, 14, 15}, { 0, 12, 13, 1, 8}, { 8, 1, 18, 5, 9}, { 16, 4, 14, 6, 17}, { 6, 11, 10, 2, 17}, { 7, 15, 5, 18, 19}, { 7, 19, 3, 10, 11} }; if (centered) mesh = triangulateFaces(vertices, dodeFaces, 20); else mesh = new TriangleMesh(vertices, faces); name = translations.get("dodecahedron") + (centered ? " FC" : ""); break; case 4 : //icosahedron vertices = new Vec3[12]; // 12 vertices + 20 faces t = ( 1.0 + Math.sqrt(5) )/2.0; vertices[0] = new Vec3(t, 1, 0); vertices[1] = new Vec3(-t, 1, -0); vertices[2] = new Vec3(t, -1, 0); vertices[3] = new Vec3(-t, -1, 0); vertices[4] = new Vec3(1, 0, t); vertices[5] = new Vec3(1, 0, -t); vertices[6] = new Vec3(-1, 0, t); vertices[7] = new Vec3(-1, 0, -t); vertices[8] = new Vec3(0, t, 1); vertices[9] = new Vec3(0, -t, 1); vertices[10] = new Vec3(0, t, -1); vertices[11] = new Vec3(0, -t, -1); for (i = 0 ; i < 12 ; ++i) vertices[i].scale( 1.0 / Math.sqrt( 1.0 + t*t) ); int[][] faces = { { 0, 8, 4 }, { 0, 5, 10 }, { 2, 4, 9 }, { 2, 11, 5 }, { 1, 6, 8 }, { 1, 10, 7 }, { 3, 9, 6 }, { 3, 7, 11 }, { 0, 10, 8 }, { 1, 8, 10 }, { 2, 9, 11 }, { 3, 11, 9 }, { 4, 2, 0 }, { 5, 0, 2 }, { 6, 1, 3 }, { 7, 3, 1 }, { 8, 6, 4 }, { 9, 4, 6 }, { 10, 5, 7 }, { 11, 7, 5 } }; if (centered) mesh = triangulateFaces(vertices, faces, 12); else mesh = new TriangleMesh(vertices, faces); name = translations.get("icosahedron") + (centered ? " FC" : ""); break; default : return; } //set vertices smoothness and scale mesh in the process meshVertices = mesh.getVertices(); radius = radiusValueField.getValue(); for ( i = 0 ; i < meshVertices.length ; ++i) { meshVertices[i].smoothness = (float) vertSmoothnessValueField.getValue(); meshVertices[i].r.scale(radius); } //set edges smoothness meshEdges = mesh.getEdges(); for ( i = 0 ; i < meshEdges.length ; ++i) meshEdges[i].smoothness = (float) edgesSmoothnessValueField.getValue(); //set mesh smoothing method mesh.setSmoothingMethod(smoothList.getSelectedIndex()); //set texture //tex = scene.getTexture(textureList.getSelectedIndex()); //mesh.setTexture(tex, tex.getDefaultMapping()); //set material matIndex = materialList.getSelectedIndex(); if ( matIndex > 0 ) { mat = scene.getMaterial(matIndex-1); mesh.setMaterial(mat, mat.getDefaultMapping()); } //we're done window.addObject(mesh, new CoordinateSystem(), name, null); Truncated Teardrop Shaper.bsh000066400000000000000000000103271167321211700341120ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/miscellaneous/Art of Illusion Scripts/* */ do { scene = window.getScene(); directionType = new RadioButtonGroup(); up = new BRadioButton("Up", false, directionType); down = new BRadioButton("Down", false, directionType); left = new BRadioButton("Left", false, directionType); right = new BRadioButton("Right", false, directionType); directional = new GridContainer(2, 2); directional.setDefaultLayout(new LayoutInfo(LayoutInfo.WEST, LayoutInfo.NONE, new Insets(2, 2, 2, 2), null)); directional.add(up, 0, 0); directional.add(down, 0, 1); directional.add(left, 1, 0); directional.add(right, 1, 1); vertexValueField = new ValueField(45, ValueField.NONNEGATIVE); radiusValueField = new ValueField(1.0, ValueField.NONNEGATIVE); maxErrorValueField = new ValueField(0.05, ValueField.NONNEGATIVE); directionValueField = new ValueField(0.0, ValueField.NONNEGATIVE); truncationValueField = new ValueField(0.0, ValueField.NONNEGATIVE); dlg = new ComponentsDialog(window, "TearDrop Tool" , new Widget [] { directional, directionValueField, vertexValueField, truncationValueField, radiusValueField, maxErrorValueField }, new String [] { "Orientation about z-axis: ", "or specific rotation about z-axis (degrees): ", "Vertex angle (degrees): ", "Truncation: ", "Radius: ", "Max error: " } ); if (!dlg.clickedOk()) return; theta = vertexValueField.getValue() / 180 * Math.PI; radius = radiusValueField.getValue(); maxError = maxErrorValueField.getValue(); directionAngle = directionValueField.getValue() / 180 * Math.PI; errorAngle = Math.acos((radius - maxError) / radius); // inverse cosine // numberSides = Math.ceil(((2 * Math.PI) - 2 * (Math.PI / 2 - theta)) / errorAngle); // rounded up numberSides = Math.ceil(((2 * Math.PI) - 2 * (Math.PI / 2 - theta)) / errorAngle) + 1; // rounded up if (numberSides <= 10) new MessageDialog(window, "Please decrease the value of the maximum error"); } while (numberSides < 10); // Setting the orientation of the teardrop shape depending on the outcome of Radio Buttons if (up.getState()) directionAngle = Math.PI / 2; if (down.getState()) directionAngle = (3 * Math.PI) / 2; if (left.getState()) directionAngle = Math.PI; if (right.getState()) directionAngle = 0; Vec3[] v = new Vec3[numberSides]; float[] smoothness = new float[numberSides]; //double phi = ((2.0 * Math.PI) - (2.0 * ((Math.PI / 2) - theta))) / (numberSides - 2); double phi = ((2.0 * Math.PI) - (2.0 * ((Math.PI / 2) - theta))) / (numberSides - 3); double angle = ((Math.PI / 2.0) - theta); //for (int i = 0 ; i < (numberSides - 1) ; i++) for (int i = 0 ; i < (numberSides - 2) ; i++) { x1 = Math.cos(angle + phi * i); y1 = Math.sin(angle + phi * i); x2 = x1 * Math.cos(directionAngle) - y1 * Math.sin(directionAngle); // rotational vectors - x y2 = y1 * Math.cos(directionAngle) + x1 * Math.sin(directionAngle); // rotational vectors - y v[i] = new Vec3(x2, y2, 0); v[i].scale(radius); smoothness[i] = 0; } // final vertex point at the sharp tip //x3 = Math.cos(directionAngle) * (radius / Math.sin(theta)); //y3 = Math.sin(directionAngle) * (radius / Math.sin(theta)); //v[numberSides - 2.0] = new Vec3(x3, y3, 0); truncationToVertex = truncationValueField.getValue() * (2 - Math.sqrt(2)); xTip = Math.cos(directionAngle) * (radius / Math.sin(theta)); yTip = Math.sin(directionAngle) * (radius / Math.sin(theta)); vTip = new Vec3(xTip, yTip, 0); vLast = v[numberSides - 3.0]; vFromTipToLast = vLast.minus( vTip ); vFromTipToLast.scale( truncationToVertex ); v[numberSides - 2.0] = vTip.plus( vFromTipToLast ); vStart = v[0]; vFromTipToStart = vStart.minus( vTip ); vFromTipToStart.scale( truncationToVertex ); x4 = xTip + 0.2; y4 = yTip + 0.3; v[numberSides - 1.0] = vTip.plus( vFromTipToStart ); name = "Truncated Teardrop (" + numberSides + " sides)"; tolerance = 0.02; //surface accuracy curve = new Curve(v, smoothness, Mesh.APPROXIMATING, true); window.addObject(curve, new CoordinateSystem(), name, null); // Finishedsfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/000077500000000000000000000000001167321211700242115ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/RepRapArduinoSerialSender.py000066400000000000000000000107731167321211700316070ustar00rootroot00000000000000#!/usr/bin/env python # encoding: utf-8 """ Extrude requires pySerial installed for this module to work. If you are using Fedora it is available on yum (run "sudo yum install pyserial"). To actually control the reprap requires write access to the serial device, running as root is one way to get that access. Created by Brendan Erwin on 2008-05-21. Copyright (c) 2008 Brendan Erwin. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """ try: import serial # Import the pySerial modules. except: print('You do not have pySerial installed, which is needed to control the serial port.') print('Information on pySerial is at:\nhttp://pyserial.wiki.sourceforge.net/pySerial') import os import sys import time class RepRapArduinoSerialSender: """ A utility class for communication with the Arduino from python. Intended for g-code only. Raises ValueException if the arduino returns an unexpected response. Usually caused by sending invalid g-code. """ _verbose = False block = "empty" def __init__(self, port, baud, verbose=False): """ Opens the serial port and prepares for writing. port MUST be set, and values are operating system dependant. """ self._verbose = verbose if self._verbose: print >> sys.stdout, "Opening serial port: " + port #Timeout value 10" max travel, 1RPM, 20 threads/in = 200 seconds self.ser = serial.Serial(port, baud, timeout=200) if self._verbose: print >> sys.stdout, "Serial Open?: " + str(self.ser.isOpen()) print >> sys.stdout, "Baud Rate: " + str(self.ser.baudrate) def reset(self): """ Resets the arduino by droping DTR for 1 second This will then wait for a response ("ready") and return. """ #Reboot the arduino, and wait for it's response if self._verbose: print "Resetting arduino..." self.ser.setDTR(0) # There is presumably some latency required. time.sleep(1) self.ser.setDTR(1) self.read("Start") def write(self, block): """ Writes one block of g-code out to arduino and waits for an "ok". This version will wait for an "ok" before returning and prints any intermediate output received. No error will be raised if non-ok response is received. Loop in read() is infinite if "ok" does not come back! This routine also removes all whitespace before sending it to the arduino, which is handy for gcode, but will screw up if you try to do binary communications. """ if self._verbose: print "> " + block # The arduino GCode interperter firmware doesn't like whitespace # and if there's anything other than space and tab, we have other problems. block=block.strip() block=block.replace(' ','') block=block.replace("\t",'') #Skip blank blocks. if len(block) == 0: return self.ser.write(block + "\n") self.read("OK") def read(self, expect=None): """ This routine should never be called directly. It's used by write() and reset() to read a one-line response from the Arduino. This version will wait for an "ok" before returning and prints any intermediate output received. No error will be raised if non-ok response is received. Loop is infinite if "ok" does not come back! """ #The g-code firmware returns exactly ONE line per block of gcode sent. #Unless it is M104, M105 or other code that returns info!! #It WILL return "ok" once the command has finished sending and completed. while True: response = self.ser.readline().strip() if expect is None: return if expect.lower() in response.lower(): if self._verbose: print "< " + response return else: #Just print the response since it is useful data or an error message print "< " + response def close(): """ Closes the serial port, terminating communications with the arduino. """ if self._verbose: print >> sys.stdout, "Closing serial port." self.ser.close() if self._verbose: print >> sys.stdout, "Serial Open?: " + str(self.ser.isOpen()) sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/__init__.py000066400000000000000000000006611167321211700263250ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 2 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/demo.py000066400000000000000000000026421167321211700255130ustar00rootroot00000000000000try: import serial except: print('You do not have pySerial installed, which is needed to control the serial port.') print('Information on pySerial is at:\nhttp://pyserial.wiki.sourceforge.net/pySerial') import reprap, time # Import the reprap and pySerial modules. reprap.serial = serial.Serial(0, 19200, timeout = reprap.snap.messageTimeout) # Initialise serial port, here the first port (0) is used. reprap.cartesian.x.active = True # These devices are present in network, will automatically scan in the future. reprap.cartesian.y.active = True reprap.cartesian.z.active = True reprap.extruder.active = True # The module is now ready to recieve commands # moveSpeed = 220 reprap.cartesian.homeReset( moveSpeed, True ) # Send all axies to home position. Wait until arrival. reprap.cartesian.seek( (1000, 1000, 0), moveSpeed, True ) # Seek to (1000, 1000, 0). Wait until arrival. time.sleep(2) # Pause. reprap.cartesian.seek( (500, 1000, 0), moveSpeed, True ) # Seek to (500, 1000, 0). Wait until arrival. time.sleep(2) reprap.cartesian.seek( (1000, 500, 0), moveSpeed, True ) # Seek to (1000, 500, 0). Wait until arrival. time.sleep(2) reprap.cartesian.seek( (100, 100, 0), moveSpeed, True ) # Seek to (100, 100, 0). Wait until arrival. reprap.cartesian.homeReset( moveSpeed, True ) # Send all axies to home position. Wait until arrival. reprap.cartesian.free() # Shut off power to all motors. sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/example.py000066400000000000000000000072341167321211700262240ustar00rootroot00000000000000#!/usr/bin/python try: import serial except: print('You do not have pySerial installed, which is needed to control the serial port.') print('Information on pySerial is at:\nhttp://pyserial.wiki.sourceforge.net/pySerial') import reprap, time, sys #reprap.snap.printOutgoingPackets = True #reprap.snap.printIncomingPackets = True #reprap.snap.printFailedPackets = True #reprap.printDebug = True #work surface approx x 2523, y 2743 #reprap.serial = serial.Serial(0, 19200, timeout = reprap.snap.messageTimeout) reprap.serial = serial.Serial(0, 19200, timeout = 60) reprap.cartesian.x.active = True # these devices are present in network reprap.cartesian.y.active = True reprap.cartesian.z.active = True reprap.extruder.active = True reprap.cartesian.x.setNotify() reprap.cartesian.y.setNotify() reprap.cartesian.z.setNotify() reprap.cartesian.x.limit = 2523 #reprap.cartesian.y.limit = 2743 reprap.cartesian.y.limit = 2000 def printPos(): x, y, z = reprap.cartesian.getPos() print "Location [" + str(x) + ", " + str(y) + ", " + str(z) + "]" print "================================================================" ########### control of cartesian frame as a whole ######### #stop all steppers if sys.argv[1] == "stop": reprap.cartesian.stop() #goto 0,0 if sys.argv[1] == "reset": reprap.cartesian.homeReset( 200, True ) #time.sleep(2) printPos() #print current positon if sys.argv[1] == "pos": printPos() #goto a specific location if sys.argv[1] == "goto": reprap.cartesian.seek( ( int(sys.argv[2]), int(sys.argv[3]), 0 ), 200, False) printPos() #goto a specific location (use sync) if sys.argv[1] == "gotos": reprap.cartesian.syncSeek( ( int(sys.argv[2]), int(sys.argv[3]), 0 ), 200, False) printPos() if sys.argv[1] == "power": reprap.cartesian.setPower( int( sys.argv[2] ) ) # This is a value from 0 to 63 (6 bits) #test routine if sys.argv[1] == "go": #stepper test reprap.cartesian.seek( (1000, 1000, 0), 200, True ) time.sleep(2) reprap.cartesian.seek( (500, 1000, 0), 200, True ) time.sleep(2) reprap.cartesian.seek( (500, 500, 0), 200, True ) time.sleep(2) reprap.cartesian.seek( (10, 10, 0), 200, True ) #free motors (switch off all coils) if sys.argv[1] == "free": reprap.axies.free(reprap.axisX) reprap.axies.free(reprap.axisY) ############## control of individual steppers ############# #spin stepper if sys.argv[1] == "run": # run axis if sys.argv[2] == "x": reprap.cartesian.x.forward( int(sys.argv[3]) ) elif sys.argv[2] == "y": reprap.cartesian.y.forward( int(sys.argv[3]) ) #spin stepper in reverse if sys.argv[1] == "runb": #runb axis if sys.argv[2] == "x": reprap.axies.backward( reprap.axisX, int(sys.argv[3]) ) elif sys.argv[2] == "y": reprap.axies.backward( reprap.axisY, int(sys.argv[3]) ) if sys.argv[1] == "step": if sys.argv[2] == "x": reprap.cartesian.x.forward1() elif sys.argv[2] == "y": reprap.cartesian.y.forward1() ################# control of extruder ##################### #test extrder motor elif sys.argv[1] == "motor": nn = 0 while 1: if nn > 0: nn = 0 else: nn = 150 reprap.extruder.setMotor(reprap.CMD_REVERSE, nn) time.sleep(1) elif sys.argv[1] == "getinfo": mtype = reprap.extruder.getModuleType() version = reprap.extruder.getVersion() print "module", mtype, "version", version elif sys.argv[1] == "heat": reprap.extruder.setHeat(255, 255, 255, 255) #setHeat(self, lowHeat, highHeat, tempTarget, tempMax elif sys.argv[1] == "temp": print "Temp is ", reprap.extruder.getTemp() elif sys.argv[1] == "setref": reprap.extruder.setVoltateReference( int(sys.argv[2]) ) ############### scan network for devices ################### #scan snap network elif sys.argv[1] == "scan": reprap.scanNetwork() sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/extrude.py000066400000000000000000000336401167321211700262510ustar00rootroot00000000000000""" Extrude is a script to display and extrude a gcode file. It controls the extruder and movement. It can read linear and helical move commands. It saves a log file with the suffix _log. To run extrude, install python 2.x on your machine, which is avaliable from http://www.python.org/download/ Then in the folder which extrude is in, type 'python' in a shell to run the python interpreter. Finally type 'import extrude' to import this program. Extrude requires pySerial installed for this module to work. If you are using Fedora it is available on yum (run "sudo yum install pyserial"). To actually control the reprap requires write access to the serial device, running as root is one way to get that access. This example displays and extrudes a gcode file. This example is run in a terminal as root in the folder which contains Hollow Square.gcode, and extrude.py. >>> import extrude Extrude has been imported. The gcode files in this directory that are not log files are the following: ['Hollow Square.gcode'] >>> extrude.display() File Hollow Square.gcode is being displayed. reprap.serial = serial.Serial(0, 19200, timeout = 60) reprap.cartesian.x.active = True reprap.cartesian.y.active = True reprap.cartesian.z.active = True reprap.extruder.active = True reprap.cartesian.x.setNotify() reprap.cartesian.y.setNotify() reprap.cartesian.z.setNotify() reprap.cartesian.x.limit = 2523 reprap.cartesian.y.limit = 2000 reprap.cartesian.homeReset( 200, True ) ( GCode generated by March 29,2007 Skeinforge ) ( Extruder Initialization ) M100 P210 M103 reprap.extruder.setMotor(reprap.CMD_REVERSE, 0) .. many lines of gcode and extruder commands .. reprap.cartesian.homeReset( 600, True ) reprap.cartesian.free() The gcode log file is saved as Hollow Square_log.gcode >>> extrude.displayFile("Hollow Square.gcode") File Hollow Square.gcode is being displayed. .. The gcode log file is saved as Hollow Square_log.gcode >>> extrude.displayFiles(["Hollow Square.gcode"]) File Hollow Square.gcode is being displayed. .. The gcode log file is saved as Hollow Square_log.gcode >>> extrude.displayText(" ( GCode generated by March 29,2007 Skeinforge ) ( Extruder Initialization ) .. many lines of gcode .. ") reprap.serial = serial.Serial(0, 19200, timeout = 60) reprap.cartesian.x.active = True reprap.cartesian.y.active = True reprap.cartesian.z.active = True reprap.extruder.active = True reprap.cartesian.x.setNotify() reprap.cartesian.y.setNotify() reprap.cartesian.z.setNotify() reprap.cartesian.x.limit = 2523 reprap.cartesian.y.limit = 2000 reprap.cartesian.homeReset( 200, True ) ( GCode generated by March 29,2007 Skeinforge ) ( Extruder Initialization ) M100 P210 M103 reprap.extruder.setMotor(reprap.CMD_REVERSE, 0) .. many lines of gcode and extruder commands .. reprap.cartesian.homeReset( 600, True ) reprap.cartesian.free() Note: On my system the reprap is not connected, so I get can not connect messages, like: >>> extrude.extrude() File Hollow Square.gcode is being extruded. reprap.serial = serial.Serial(0, 19200, timeout = 60) reprap.cartesian.x.active = True reprap.cartesian.y.active = True reprap.cartesian.z.active = True reprap.extruder.active = True reprap.cartesian.x.setNotify() Error: Serial timeout Error: ACK not recieved .. On a system where a reprap is connected to the serial port, you should get the following: >>> extrude.extrude() File Hollow Square.gcode is being extruded. .. The gcode log file is saved as Hollow Square_log.gcode >>> extrude.extrudeFile("Hollow Square.gcode") File Hollow Square.gcode is being extruded. .. The gcode log file is saved as Hollow Square_log.gcode >>> extrude.extrudeFiles(["Hollow Square.gcode"]) File Hollow Square.gcode is being extruded. .. The gcode log file is saved as Hollow Square_log.gcode >>> extrude.extrudeText(" ( GCode generated by March 29,2007 Skeinforge ) ( Extruder Initialization ) .. many lines of gcode .. ") reprap.serial = serial.Serial(0, 19200, timeout = 60) reprap.cartesian.x.active = True reprap.cartesian.y.active = True reprap.cartesian.z.active = True reprap.extruder.active = True reprap.cartesian.x.setNotify() reprap.cartesian.y.setNotify() reprap.cartesian.z.setNotify() reprap.cartesian.x.limit = 2523 reprap.cartesian.y.limit = 2000 reprap.cartesian.homeReset( 200, True ) ( GCode generated by March 29,2007 Skeinforge ) ( Extruder Initialization ) M100 P210 M103 reprap.extruder.setMotor(reprap.CMD_REVERSE, 0) .. many lines of gcode and extruder commands .. reprap.cartesian.homeReset( 600, True ) reprap.cartesian.free() """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ try: import serial # Import the pySerial modules. except: print('You do not have pySerial installed, which is needed to control the serial port.') print('Information on pySerial is at:\nhttp://pyserial.wiki.sourceforge.net/pySerial') from skeinforge_tools.skeinforge_utilities.vector3 import Vector3 from skeinforge_tools.skeinforge_utilities import archive from skeinforge_tools.skeinforge_utilities import euclidean from skeinforge_tools.skeinforge_utilities import gcodec import math import os import reprap # Import the reprap module. import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'greenarrow ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def display( filename = ''): "Parse a gcode file and display the commands. If no filename is specified, parse all the gcode files which are not log files in this folder." if filename == '': displayFiles( getGCodeFilesWhichAreNotLogFiles() ) return displayFile( filename ) def displayFile( filename ): "Parse a gcode file and display the commands." print('File ' + filename + ' is being displayed.') fileText = archive.getFileText( filename ) gcodec.writeFileMessageSuffix( filename, displayText(fileText), 'The gcode log file is saved as ', '_log') def displayFiles( filenames ): "Parse gcode files and display the commands." for filename in filenames: displayFile( filename ) def displayText(gcodeText): "Parse a gcode text and display the commands." skein = displaySkein() skein.parseText(gcodeText) return skein.output def extrude( filename = ''): """Parse a gcode file and send the commands to the extruder. If no filename is specified, parse all the gcode files which are not log files in this folder. This function requires write access to the serial device, running as root is one way to get that access.""" if filename == '': extrudeFiles( getGCodeFilesWhichAreNotLogFiles() ) return extrudeFile( filename ) def extrudeFile( filename ): """Parse a gcode file and send the commands to the extruder. This function requires write access to the serial device, running as root is one way to get that access.""" print('File ' + filename + ' is being extruded.') fileText = archive.getFileText( filename ) gcodec.writeFileMessageSuffix( filename, extrudeText(fileText), 'The gcode log file is saved as ', '_log') def extrudeFiles( filenames ): """Parse gcode files and send the commands to the extruder. This function requires write access to the serial device, running as root is one way to get that access.""" for filename in filenames: extrudeFile( filename ) def extrudeText(gcodeText): """Parse a gcode text and send the commands to the extruder. This function requires write access to the serial device, running as root is one way to get that access.""" skein = extrudeSkein() skein.parseText(gcodeText) return skein.output def getGCodeFilesWhichAreNotLogFiles(): "Get gcode files which are not log files." return archive.getFilesWithFileTypeWithoutWords('gcode', ['_log'] ) def getIntegerString(number): "Get integer as string." return str( int(number) ) class displaySkein: "A class to display a gcode skein of extrusions." def __init__(self): self.extruderActive = 0 self.feedrateMinute = 200.0 self.oldLocation = None self.output = '' def addToOutput(self, line): "Add line with a newline at the end to the output." print(line) self.output += line + '\n' def evaluateCommand( self, command ): "Add an extruder command to the output." self.addToOutput( command ) def helicalMove( self, isCounterclockwise, splitLine ): "Parse a helical move gcode line and send the commands to the extruder." if self.oldLocation is None: return location = Vector3( self.oldLocation ) self.setFeedrate(splitLine) setPointToSplitLine( location, splitLine ) location = location + self.oldLocation center = Vector3( self.oldLocation ) indexOfR = getIndexOfStartingWithSecond( "R", splitLine ) if indexOfR > 0: radius = getDoubleAfterFirstLetter( splitLine[ indexOfR ] ) halfLocationMinusOld = location - self.oldLocation halfLocationMinusOld *= 0.5 halfLocationMinusOldLength = halfLocationMinusOld.length() centerMidpointDistance = math.sqrt( radius * radius - halfLocationMinusOldLength * halfLocationMinusOldLength ) centerMinusMidpoint = getRotatedWiddershinsQuarterAroundZAxis( halfLocationMinusOld ) centerMinusMidpoint.normalize() centerMinusMidpoint *= centerMidpointDistance if isCounterclockwise: center.setToVec3( halfLocationMinusOld + centerMinusMidpoint ) else: center.setToVec3( halfLocationMinusOld - centerMinusMidpoint ) else: center.x = getDoubleForLetter( "I", splitLine ) center.y = getDoubleForLetter( "J", splitLine ) curveSection = 0.5 center += self.oldLocation afterCenterSegment = location - center beforeCenterSegment = self.oldLocation - center afterCenterDifferenceAngle = getAngleAroundZAxisDifference( afterCenterSegment, beforeCenterSegment ) absoluteDifferenceAngle = abs( afterCenterDifferenceAngle ) steps = int( math.ceil( max( absoluteDifferenceAngle * 2.4, absoluteDifferenceAngle * beforeCenterSegment.length() / curveSection ) ) ) stepPlaneAngle = getPolar( afterCenterDifferenceAngle / steps, 1.0 ) zIncrement = ( afterCenterSegment.z - beforeCenterSegment.z ) / float( steps ) for step in range( 1, steps ): beforeCenterSegment = getRoundZAxisByPlaneAngle( stepPlaneAngle, beforeCenterSegment ) beforeCenterSegment.z += zIncrement arcPoint = center + beforeCenterSegment self.moveExtruder( arcPoint ) self.moveExtruder( location ) self.oldLocation = location def homeReset(self): "Send all axies to home position. Wait until arrival." homeCommandString = 'reprap.cartesian.homeReset(' + getIntegerString( self.feedrateMinute ) + ', True )' self.evaluateCommand( homeCommandString ) def linearMove( self, splitLine ): "Parse a linear move gcode line and send the commands to the extruder." location = Vector3() if self.oldLocation is not None: location = self.oldLocation self.setFeedrate(splitLine) setPointToSplitLine( location, splitLine ) self.moveExtruder( location ) self.oldLocation = location def moveExtruder(self, location): "Seek to location. Wait until arrival." moveSpeedString = getIntegerString( self.feedrateMinute ) xMoveString = getIntegerString(location.x) yMoveString = getIntegerString(location.y) zMoveString = getIntegerString(location.z) moveCommandString = 'reprap.cartesian.seek( (' + xMoveString + ', ' + yMoveString + ', ' + zMoveString + '), ' + moveSpeedString + ', True )' self.evaluateCommand( moveCommandString ) def parseGCode(self, lines): "Parse gcode and send the commands to the extruder." self.evaluateCommand('reprap.serial = serial.Serial(0, 19200, timeout = 60)') # Initialise serial port, here the first port (0) is used. self.evaluateCommand('reprap.cartesian.x.active = True') # These devices are present in network, will automatically scan in the future. self.evaluateCommand('reprap.cartesian.y.active = True') self.evaluateCommand('reprap.cartesian.z.active = True') self.evaluateCommand('reprap.extruder.active = True') self.evaluateCommand('reprap.cartesian.x.setNotify()') self.evaluateCommand('reprap.cartesian.y.setNotify()') self.evaluateCommand('reprap.cartesian.z.setNotify()') self.evaluateCommand('reprap.cartesian.x.limit = 2523') self.evaluateCommand('reprap.cartesian.y.limit = 2000') self.homeReset() # The module is now ready to receive commands for line in lines: self.parseLine(line) self.homeReset() self.evaluateCommand('reprap.cartesian.free()') # Shut off power to all motors. def parseLine(self, line): "Parse a gcode line and send the command to the extruder." self.addToOutput(line) splitLine = line.split(' ') if len(splitLine) < 1: return 0 firstWord = splitLine[0] if firstWord == 'G1': self.linearMove(splitLine) if firstWord == 'G2': self.helicalMove( False, splitLine ) if firstWord == 'G3': self.helicalMove( True, splitLine ) if firstWord == 'M101': self.extruderActive = 1 self.evaluateCommand('reprap.extruder.setMotor(reprap.CMD_REVERSE, 150)') if firstWord == 'M103': self.extruderActive = 0 self.evaluateCommand('reprap.extruder.setMotor(reprap.CMD_REVERSE, 0)') self.oldActiveLocation = None def parseText( self, text ): "Parse a gcode text and evaluate the commands." textLines = getTextLines(text) self.parseGCode( textLines ) def setFeedrate( self, splitLine ): "Set the feedrate to the gcode split line." indexOfF = getIndexOfStartingWithSecond( "F", splitLine ) if indexOfF > 0: self.feedrateMinute = getDoubleAfterFirstLetter( splitLine[indexOfF] ) class extrudeSkein( displaySkein ): "A class to extrude a gcode skein of extrusions." def evaluateCommand( self, command ): """Add an extruder command to the output and evaluate the extruder command. Display the entire command, but only evaluate the command after the first equal sign.""" self.addToOutput( command ) firstEqualIndex = command.find('=') exec( command ) print('Extrude has been imported.') print('The gcode files in this directory that are not log files are the following:') print( getGCodeFilesWhichAreNotLogFiles() ) sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/frank_davies/000077500000000000000000000000001167321211700266455ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/frank_davies/bring_to_temp.py000066400000000000000000000017671167321211700320620ustar00rootroot00000000000000# bring reprap to temperature # Frank Davies import serial import time import sys def out_rep(out_string): ser.write(out_string) print out_string #print "waiting for OK" start_time=time.clock() while (ser.inWaiting()==0) and (time.clock()temp.gcode # make temporary file with extra at the beginning ascii-xfr -sv temp.gcode >/dev/ttyUSB0 # transfer the file #cp $1 /dev/ttyUSB0 # alternate transfer method commented out. echo DONE sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/reprap.py000066400000000000000000000362711167321211700260650ustar00rootroot00000000000000""" pyRepRap is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. pyRepRap is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with pyRepRap. If not, see . """ """ This is the main user imported module containing all end user functions """ # add commands to switch to gcode mode to allow any script using this library to write gcode too. try: import serial # Import the pySerial modules. except: print('You do not have pySerial installed, which is needed to control the serial port.') print('Information on pySerial is at:\nhttp://pyserial.wiki.sourceforge.net/pySerial') import snap import time printDebug = False # print debug info # SNAP Control Commands - Taken from PIC code # # extruder commands # CMD_VERSION = 0 CMD_FORWARD = 1 CMD_REVERSE = 2 CMD_SETPOS = 3 CMD_GETPOS = 4 CMD_SEEK = 5 CMD_FREE = 6 CMD_NOTIFY = 7 CMD_ISEMPTY = 8 CMD_SETHEAT = 9 CMD_GETTEMP = 10 CMD_SETCOOLER = 11 CMD_PWMPERIOD = 50 CMD_PRESCALER = 51 CMD_SETVREF = 52 CMD_SETTEMPSCALER = 53 CMD_GETDEBUGINFO = 54 CMD_GETTEMPINFO = 55 # stepper commands # CMD_VERSION = 0 CMD_FORWARD = 1 CMD_REVERSE = 2 CMD_SETPOS = 3 CMD_GETPOS = 4 CMD_SEEK = 5 CMD_FREE = 6 CMD_NOTIFY = 7 CMD_SYNC = 8 CMD_CALIBRATE = 9 CMD_GETRANGE = 10 CMD_DDA = 11 CMD_FORWARD1 = 12 CMD_BACKWARD1 = 13 CMD_SETPOWER = 14 CMD_GETSENSOR = 15 CMD_HOMERESET = 16 CMD_GETMODULETYPE = 255 # sync modes # sync_none = 0 # no sync (default) sync_seek = 1 # synchronised seeking sync_inc = 2 # inc motor on each pulse sync_dec = 3 # dec motor on each pulse snap.localAddress = 0 # local address of host PC. This will always be 0. #global serialPort #serialPort = False def openSerial( port, rate, tout ): global serialPort try: serialPort = serial.Serial( port, rate, timeout = tout ) return True except 13: print "You do not have permissions to use the serial port, try running as root" def closeSerial(): serialPort.close() # Convert two 8 bit bytes to one integer def bytes2int(LSB, MSB): return int( (0x100 * int(MSB) ) | int(LSB) ) # Convert integer to two 8 bit bytes def int2bytes(val): MSB = int( ( int(val) & 0xFF00) / 0x100 ) LSB = int( int(val) & 0xFF ) return LSB, MSB #def loopTest(): # p = snap.SNAPPacket( serial, snap.localAddress, snap.localAddress, 0, 1, [] ) # Scan reprap network for devices (incomplete) - this will be used by autoconfig functions when complete def scanNetwork(): devices = [] for remoteAddress in range(1, 10): # For every address in range. full range will be 255 print "Trying address " + str(remoteAddress) p = snap.SNAPPacket( serialPort, remoteAddress, snap.localAddress, 0, 1, [CMD_GETMODULETYPE] ) # Create snap packet requesting module type #p = snap.SNAPPacket( serialPort, remoteAddress, snap.localAddress, 0, 1, [CMD_VERSION] ) if p.send(): # Send snap packet, if sent ok then await reply rep = p.getReply() if rep: #devices[ rep.dataBytes[1] ] = remoteAddress devices.append( { 'address':remoteAddress, 'type':rep.dataBytes[1], 'subType':rep.dataBytes[2] } ) # If device replies then add to device list. else: "print na" else: print "scan no ack" time.sleep(0.5) for d in devices: #now get versions print "device", d def getNotification(serialPort): return snap.getPacket(serialPort) class extruderClass: def __init__(self): self.address = 8 self.active = False def getModuleType(self): #note: do pics not support this yet? I can't see it in code and get no reply from pic if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_GETMODULETYPE] ) # Create SNAP packet requesting module type if p.send(): rep = p.getReply() data = checkReplyPacket( rep, 2, CMD_GETMODULETYPE ) # If packet sent ok and was acknoledged then await reply, otherwise return False if data: return data[1] # If valid reply is recieved then return it, otherwise return False return False def getVersion(self): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_VERSION] ) if p.send(): rep = p.getReply() data = checkReplyPacket( rep, 3, CMD_VERSION ) if data: return data[1], data[2] return False def setMotor(self, direction, speed): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [int(direction), int(speed)] ) ##no command being sent, whats going on? if p.send(): return True return False def getTemp(self): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_GETTEMP] ) if p.send(): rep = p.getReply() data = checkReplyPacket( rep, 2, CMD_GETTEMP ) if data: return data[1] return False def setVoltateReference(self, val): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SETVREF, int(val)] ) if p.send(): return True return False def setHeat(self, lowHeat, highHeat, tempTarget, tempMax): if self.active: tempTargetMSB, tempTargetLSB = int2bytes( tempTarget ) tempMaxMSB ,tempMaxLSB = int2bytes( tempMax ) p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SETHEAT, int(lowHeat), int(highHeat), tempTargetMSB, tempTargetLSB, tempMaxMSB, tempMaxLSB] ) # assumes MSB first (don't know this!) if p.send(): return True return False def setCooler(self, speed): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SETCOOLER, int(speed)] ) if p.send(): return True return False def freeMotor(self): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_FREE] ) if p.send(): return True return False extruder = extruderClass() def checkReplyPacket (packet, numExpectedBytes, command): if packet: if len( packet.dataBytes ) == numExpectedBytes: # check correct number of data bytes have been recieved if packet.dataBytes[0] == command: # check reply is a reply to sent command return packet.dataBytes return False class axisClass: def __init__(self, address): self.address = address self.active = False # when scanning network, set this, then in each func below, check alive before doing anything self.limit = 100000 # limit effectively disabled unless set #move axis one step forward def forward1(self): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_FORWARD1] ) if p.send(): return True return False #move axis one step backward def backward1(self): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_BACKWARD1] ) if p.send(): return True return False #spin axis forward at given speed def forward(self, speed): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_FORWARD, int(speed)] ) if p.send(): return True return False #spin axis backward at given speed def backward(self, speed): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_REVERSE, int(speed)] ) if p.send(): return True return False #debug only def getSensors(self): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_GETSENSOR] ) if p.send(): rep = p.getReply() data = checkReplyPacket( rep, 3, CMD_GETSENSOR ) # replace this with a proper object in SNAP module? if data: print data[1], data[2] return False #get current axis position def getPos(self): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_GETPOS] ) if p.send(): rep = p.getReply() data = checkReplyPacket( rep, 3, CMD_GETPOS ) if data: pos = bytes2int( data[1], data[2] ) return pos # return value return False #set current position (set variable not robot position) def setPos(self, pos): if self.active: posMSB ,posLSB = int2bytes( pos ) p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SETPOS, posMSB, posLSB] ) if p.send(): return True return False #power off coils on stepper def free(self): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_FREE] ) if p.send(): return True return False #seek to axis location. When waitArrival is True, funtion does not return until seek is compete def seek(self, pos, speed, waitArrival = True): if self.active and pos <= self.limit: posMSB ,posLSB = int2bytes( pos ) p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SEEK, int(speed), posMSB ,posLSB] ) if p.send(): if waitArrival: if printDebug: print " wait notify" notif = getNotification( serialPort ) if notif.dataBytes[0] == CMD_SEEK: if printDebug: print " valid notification for seek" else: return False if printDebug: print " rec notif" return True return False #goto 0 position. When waitArrival is True, funtion does not return until reset is compete def homeReset(self, speed, waitArrival = True): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_HOMERESET, int(speed)] ) if p.send(): if waitArrival: if printDebug: print "reset wait" notif = getNotification( serialPort ) if notif.dataBytes[0] == CMD_HOMERESET: if printDebug: print " valid notification for reset" else: return False if printDebug: print "reset done" return True return False def setNotify(self): #global serialPort if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_NOTIFY, snap.localAddress] ) # set notifications to be sent to host if p.send(): return True return False def setSync( self, syncMode ): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SYNC, int(syncMode)] ) if p.send(): return True return False def DDA( self, speed, seekTo, slaveDelta, waitArrival = True): if self.active and seekTo <= self.limit: masterPosMSB, masterPosLSB = int2bytes( seekTo ) slaveDeltaMSB, slaveDeltaLSB = int2bytes( slaveDelta ) p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_DDA, int(speed), masterPosMSB ,masterPosLSB, slaveDeltaMSB, slaveDeltaLSB] ) #start sync if p.send(): if waitArrival: notif = getNotification( serialPort ) if notif.dataBytes[0] == CMD_DDA: if printDebug: print " valid notification for DDA" # todo: add actual enforement on wrong notification else: return False return True return False def setPower( self, power ): if self.active: p = snap.SNAPPacket( serialPort, self.address, snap.localAddress, 0, 1, [CMD_SETPOWER, int( power * 0.63 )] ) # This is a value from 0 to 63 (6 bits) if p.send(): return True return False class syncAxis: def __init__( self, axis, seekTo, delta, direction ): self.axis = axis self.seekTo = seekTo self.delta = delta self.direction = direction if self.direction > 0: self.syncMode = sync_inc else: self.syncMode = sync_dec class cartesianClass: def __init__(self): # initiate axies with addresses self.x = axisClass(2) self.y = axisClass(3) self.z = axisClass(4) # goto home position (all axies) def homeReset(self, speed, waitArrival = True): if self.x.homeReset( speed, waitArrival ): #setting these to true breaks waitArrival convention. need to rework waitArrival and possibly have each axis storing it's arrival flag and pos as variables? print "X Reset" if self.y.homeReset( speed, waitArrival ): print "Y Reset" if self.z.homeReset( speed, waitArrival ): print "Z Reset" # add a way to collect all three notifications (in whatever order) then check they are all there. this will allow symultanious axis movement and use of waitArrival # seek to location (all axies). When waitArrival is True, funtion does not return until all seeks are compete # seek will automatically use syncSeek when it is required. Always use the seek function def seek(self, pos, speed, waitArrival = True): curX, curY, curZ = self.x.getPos(), self.y.getPos(), self.z.getPos() x, y, z = pos if x <= self.x.limit and y <= self.y.limit and z <= self.z.limit: if printDebug: print "seek from [", curX, curY, curZ, "] to [", x, y, z, "]" if x == curX or y == curY: if printDebug: print " standard seek" self.x.seek( x, speed, True ) #setting these to true breaks waitArrival convention. need to rework waitArrival and possibly have each axis storing it's arrival flag and pos as variables? self.y.seek( y, speed, True ) else: if printDebug: print " sync seek" self.syncSeek( pos, speed, waitArrival ) if z != curZ: self.z.seek( z, speed, True ) else: print "Trying to print outside of limit, aborting seek" # perform syncronised x/y movement. This is called by seek when needed. def syncSeek(self, pos, speed, waitArrival = True): curX, curY = self.x.getPos(), self.y.getPos() newX, newY, nullZ = pos deltaX = abs( curX - newX ) # calc delta movements deltaY = abs( curY - newY ) directionX = ( curX - newX ) / -deltaX # gives direction -1 or 1 directionY = ( curY - newY ) / -deltaY if printDebug: print " dx", deltaX, "dy", deltaY, "dirX", directionX, "dirY", directionY if printDebug: print " using x master" master = syncAxis( self.x, newX, deltaX, directionX ) # create two swapable data structures, set x as master, y as slave slave = syncAxis( self.y, newY, deltaY, directionY ) if slave.delta > master.delta: # if y has the greater movement then make y master slave, master = master, slave if printDebug: print " switching to y master" if printDebug: print " masterPos", master.seekTo, "slaveDelta", slave.delta slave.axis.setSync( slave.syncMode ) master.axis.DDA( speed, master.seekTo, slave.delta, True ) time.sleep(0.1) slave.axis.setSync( sync_none ) if printDebug: print " sync seek complete" # get current position of all three axies def getPos(self): return self.x.getPos(), self.y.getPos(), self.z.getPos() # stop all motors def stop(self): self.x.forward( 0 ) self.y.forward( 0 ) self.z.forward( 0 ) # free all motors (no current on coils) def free(self): self.x.free() self.y.free() self.z.free() def setPower(self, power): self.x.setPower( power ) self.y.setPower( power ) self.z.setPower( power ) #def lockout(): #keep sending power down commands to all board every second cartesian = cartesianClass() #wait on serial only when after somthing? or do pics send messages without pc request? sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/send.html000066400000000000000000000056671167321211700260460ustar00rootroot00000000000000

send.py is "glue" for sending a skeinforge-generated gcode file to your arduino-based reprap.

It is a command-line only utility, starting it from your GUI of choice will not be useful.

Syntax is simple:

send.py [options] <gcode or file> [<gcode or file>...]

To send your extruder.gcode file to your reprap, type:

send.py extruder.gcode

This will print the extruder.gcode shape, and print comments to the console. Typically, comments are such things as (>layerStart< 0.402 ) which can be very useful to track the progress of your build, so these are "on" by default.

There are a simple options that may be useful for special circumstances. These are --quiet, --noreset, --port, and --verbose. These can also be writted -q, -n, -p, and -v for short. If you are writing a script (for instance, the M100 scripts for use with EMC) then I'd recommend that you use the long options, so future maintainers don't have to look things up.

Quiet will suppress all but the most basic messages. It won't supress everything, however. Error messages will still be printed. But it will supress almost everything. Since options are processed in order on the command line, so if you want to supress messages about processing options, you'll have to make Quiet the first option.

Normally, the arduino is reset by dropping the DTR line for 1 second. Since the Arduino takes several seconds to reboot, you will want to disable this behavior when including send.py in scripts.

The verbose option will cause not just comments, but every command sent to and every response recieved from the arduino to be printed out. Useful for debugging, but it prints a great deal of text in ordinary usage.

The port option uses reasonable defaults for most operating systems - /dev/ttyUSB0 for posix systems, and COM3 for windows systems. If you have some other port you'll have to set in manually as "send.py -p COM5 extruder.gcode" or "send.py --port /dev/ttyUSB5 extruder.gcode" or something.

Future improvements:

I would like to add support for more g-code contructs on the python side of things. Stuff like variables, subroutines, etc. Stuff that the g-code firmware is unlikely to ever implement because of size restrictions. The current version works, and skeinforge doesn't use these features. It might be nice for a future "print several objects at once, automatically filling the bed area" interface. And if I get my extruder built, I might even take the time to do that!

RepRapArduinoSerialSender.py

This, like send.py, was cribbed from Brenden Erwin's code for using EMC. It's been modified somewhat for more general use. There are only five methods:

__init__
reset
write
read
close

Of these, you should not directly use read(). It's used internally by write and reset to verify that the operation was completed successfully.

sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/send.py000066400000000000000000000117251167321211700255220ustar00rootroot00000000000000#!/usr/bin/python2.5 # encoding: utf-8 """ Created by Brendan Erwin on 2008-05-21. Modified by John Gilmore 2008-08-23 Copyright (c) 2008 Brendan Erwin. All rights reserved. Copyright (c) 2008 John Gilmore. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ import os import sys import getopt import RepRapArduinoSerialSender help_message = ''' Usage: send [options] [...] --verbose : Verbose - print ALL communication, not just comments. -v : prints responses from the arduino, and every command sent. --quiet : Quiet - don't print anything, whereas -q : normally comments are printed. --noreset : skip the reset. -n : causes the arduino to not be deliberately reset. --port : Set the port to write to -p : default is "/dev/ttyUSB0" for posix, "COM3" for windows. --baud : Set the baud rate to use -b : defaults to 19200 You may call this with either a single statement of g-code to be sent to the arduino, or with the name of a g-code file. ------------------------------------------------------------------ Copyright (C) 2008 Brendan Erwin Copyright (C) 2008 John Gilmore This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ''' #This was originally release by Brendan under GPLv2 or later class Usage(Exception): def __init__(self, msg): self.msg = msg def main(argv=None): # Set resonable defaults for port, verbosity, and reset. verbose = 1 baud = 19200 reset = True if os.name == "posix": port = "/dev/ttyUSB0" elif os.name == "nt": port = "COM3" else: port = "/dev/ttyUSB0" if argv is None: argv = sys.argv try: try: opts, argv = getopt.getopt(argv[1:], "vqnhb:p:", ["verbose","quiet","noreset","help","baud=","port="]) except getopt.error, msg: raise Usage(msg) # option processing for option, value in opts: if option in ( "-v" , "--verbose" ): verbose = 2 print "You have requested that verbosity be set to True" print "All communication with the arduino will be printed" elif option in ( "-q" , "--quiet" ): verbose = 0 #don't print "quiet mode on" elif option in ( "-n" , "--noreset" ): reset = False if verbose: print "Arduino will not be reset before sending gcode" elif option in ( "-p" , "--port" ): port = value elif option in ("-h", "--help" ): raise Usage(help_message) elif option in ("-b", "--baud" ): baud = int(value) if verbose: print "Arduino port set to " + port except Usage, err: #print >> sys.stderr, sys.argv[0].split("/")[-1] + ": " + str(err.msg) print >> sys.stderr, str(err.msg) print >> sys.stderr, "For help use --help" return 2 sender = RepRapArduinoSerialSender.RepRapArduinoSerialSender(port, baud, verbose>1) if reset: sender.reset() for filename in argv: processfile(filename,sender,verbose) def processfile(filename,sender,verbose): try: datafile = open(filename) except IOError: #Ignore verbosity settings here, as if it's a typo we'll want to know. line=filename if line.lstrip().startswith(("G","X","Y","Z","M")): if verbose: print "Unable to open file \"" + line + "\", assuming it's one line of direct G-code..." sender.write(line) return 0 else: print "Unable to open file \"" + line + "\"" sys.exit(-1) try: for line in datafile: line=line.rstrip() # Ignore lines with comments (not technically correct, should ignore only the comment, # but all gcode files that I've actually seen so far don't have code on comment lines. if line.lstrip().startswith( ('(', '"' , '\\') ): if verbose: print line continue # This is the place to insert G-Code interpretation. # Subroutines, Variables, all sorts of fun stuff. # probably by calling a "gcode interpreter" class intead # of simply "sender". sender.write(line) finally: datafile.close() return 0 if __name__ == "__main__": sys.exit(main()) sfact-2011.12.18/fabmetheus_utilities/miscellaneous/fabricate/snap.py000066400000000000000000000212511167321211700255250ustar00rootroot00000000000000""" pyRepRap is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. pyRepRap is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with pyRepRap. If not, see . """ try: import serial # Import the pySerial modules. except: print('You do not have pySerial installed, which is needed to control the serial port.') print('Information on pySerial is at:\nhttp://pyserial.wiki.sourceforge.net/pySerial') offset_payload = 5 offset_hdb1 = 2 #ackTimeout = 0.3 # unused messageTimeout = 0.3 # used for ack also (possible to split?) #messageTimeout = 2 # used for ack also (possible to split?) retries = 3 # number of packet send retries allowed (for whatever failed reason printOutgoingPackets = False printIncomingPackets = False printFailedPackets = False #this is done again in full decode, but needed here so num bytes to expect is known. def getPacketLen(buffer): l = breakHDB1( buffer[offset_hdb1] ) #l = buffer[offset_hdb1] & 0x0f; #if (l & 8) != 0: # return 8 << (l & 7) return l #PCaddress = 0 #wait for a packet on serial - note : packets addressed to something other than 0 get recieved if you try sending to a non existant pcb (looped round). should we delete or pass on? (they cause errors right now in getpacket) def getPacket(ser): buffer = [] while 1: byte = ser.read() # read serial byte. if len(byte) > 0: buffer.append( ord (byte) ) # add serial byte to buffer. else: print "Error: Serial timeout" #clear buffer on timeout? return False # timeout has occured. #TODO - add check for sync on first byte if len(buffer) > 4: # one packet length is recieved (HDB1?). expectedLength = getPacketLen(buffer) + offset_payload + 1; # read num data bytes. if len(buffer) >= expectedLength: # check we have enough data, otherwise continue reading from serial. #print "############PR#############" p = SNAPPacket( ser, 0, 0, 0, 0, [] ) # create empty packet for b in buffer: p.addByte(b) # add byte to packet p.decode() if printIncomingPackets: print "###INCOMING PACKET##" p.printPacket() print "###END INCOMING PACKET##" return p # return recieved packet #need to check if packet is for pc (0), if not send on. #class for checksum calculator class SNAPChecksum: def __init__(self): self.crc = 0 def addData(self, data): #byte i = (byte)(data ^ self.crc) i = data ^ self.crc self.crc = 0 if((i & 1) != 0): self.crc ^= 0x5e if((i & 2) != 0): self.crc ^= 0xbc if((i & 4) != 0): self.crc ^= 0x61 if((i & 8) != 0): self.crc ^= 0xc2 if((i & 0x10) != 0): self.crc ^= 0x9d if((i & 0x20) != 0): self.crc ^= 0x23 if((i & 0x40) != 0): self.crc ^= 0x46 if((i & 0x80) != 0): self.crc ^= 0x8c return data def getResult(self): return self.crc #class for snap packet class SNAPPacket: def __init__(self, serial, DAB, SAB, ACK, NAK, dataBytes): #specify serial here, not reason not to self.SYNC = 0x54 self.DAB = DAB self.SAB = SAB self.ACK = ACK self.NAK = NAK self.dataBytes = dataBytes self.bytes = [] self.leftoverBytes = [] self.encoded = False self.decoded = False self.valid = False self.serial = serial #manually add a byte to packet (unused) def addByte(self, byte): self.bytes.append(byte) #convert individual packet properties into table self.bytes (raw data packet) def encode(self): self.NDB = len(self.dataBytes) self.bytes = [] self.bytes.insert( 0, 0xFF & self.SYNC ) #SYNC self.bytes.insert( 1, 0xFF & makeHDB2(self.ACK, self.NAK) ) #HDB2 self.bytes.insert( 2, 0xFF & makeHDB1(self.NDB) ) #HDB1 self.bytes.insert( 3, 0xFF & self.DAB ) #DAB self.bytes.insert( 4, 0xFF & self.SAB ) #SAB for d in self.dataBytes: self.bytes.append( 0xFF & d ) #DATA checksum = SNAPChecksum() for d in self.bytes[1:]: checksum.addData(d) self.CRC = checksum.getResult() self.bytes.append( self.CRC ) #CRC #print self.bytes self.encoded = True #convert table self.bytes (raw data packet) into individual packet properties def decode(self): self.SYNC = self.bytes[0] self.HDB2 = self.bytes[1] self.HDB1 = self.bytes[2] self.DAB = self.bytes[3] self.SAB = self.bytes[4] self.NDB = breakHDB1(self.HDB1) self.dataBytes = [] for d in self.bytes[5:5 + self.NDB]: self.dataBytes.append(d) #print self.bytes, self.NDB self.CRC = self.bytes[5 + self.NDB::6 + self.NDB][0] numLeftoverBytes = len(self.bytes) - 6 - self.NDB self.leftoverBytes = self.bytes[6 + self.NDB:len(self.bytes)] if numLeftoverBytes > 0: print "leftover bytes", numLeftoverBytes, self.leftoverBytes self.ACK, self.NAK = breakHDB2(self.HDB2) self.bytes = self.bytes[:6 + self.NDB] #print "newb", self.bytes self.decoded = True #calculate checksum, compare to value in recieved packet def check(self): newChecksum = SNAPChecksum() for d in self.bytes[1:-1]: newChecksum.addData(d) testCRC = newChecksum.getResult() if testCRC == self.CRC: self.valid = True return True else: self.valid = False return False, testCRC, self.CRC #actual sending of data packet (self.bytes) def sendBytes(self): if self.encoded == True: for d in self.bytes: #print "sending", d, chr(d) self.serial.write(chr(d)) else: print "Error: packet not encoded" #user send function, sends packet and awaits and checks acknoledgement. def send(self): self.encode() retriesLeft = retries while retriesLeft > 0: # try sending define number of times only self.sendBytes() # send data if printOutgoingPackets: print "###OUTGOING PACKET##" self.decode() #remove need for this (tidy up) self.printPacket() print "###END OUTGOING PACKET##" ack = getPacket(self.serial) # await ack, returns false on timout if ack: ack.decode() if ack.ACK == 1 and ack.SAB == self.DAB: # check that packet is an acknoledgement and that it is from the device we just messaged. return True #do some check on ack - TODO if printFailedPackets: print "###FAILED OUTGOING PACKET##" self.decode() #remove need for this (tidy up) self.printPacket() print "###END FAILED OUTGOING PACKET##" else: print "Error: ACK not recieved" if printFailedPackets: print "###FAILED OUTGOING PACKET##" self.decode() #remove need for this (tidy up) self.printPacket() print "###END FAILED OUTGOING PACKET##" retriesLeft = retriesLeft - 1 print "Error: Packet send FAILED (or reply)" return False # get a modules reply packet (not ack) def getReply(self): rep = getPacket(self.serial) return rep #print packet info to console def printPacket(self): if self.decoded == True: print self.bytes print "SNAP Packet:" if self.SYNC == 0x54: print "...Sync OK" else: print "...Sync Error" print "...Check: ", self.check() print "...DATA", self.dataBytes print "...CRC", self.CRC print "...SAB", self.SAB print "...DAB", self.DAB print "...HDB1", self.HDB1, ":" print "...........NDB", self.NDB print "...HDB2", self.HDB2, ":" print "...........ACK", self.ACK print "...........NAK", self.NAK print "END OF PACKET" else: print "Error: packet not decoded" #create HDB2 def makeHDB2(ACK, NAK): SAB = 1 # Length of the Source Address Bytes, in Binary. RepRap currently only accepts source addresses of 1 byte length DAB = 1 # Length of the Destination Address Bytes, in Binary. RepRap currently only accepts destinations of 1 byte length PFB = 0 # Length of Protocol Flag Bytes. RepRap does not accept any protocol flag bytes, so this must be set to 00 HDB2val = ((DAB & 0x3) * pow(2,6)) | ((SAB & 0x3) * pow(2,4)) | ((PFB & 0x3) * pow(2,2)) | ((ACK & 0x1) * pow(2,1)) | (NAK & 0x1) #print "HDB2 = '" + str(HDB2val) + "'" return HDB2val def breakHDB2(HDB2): ACK = (HDB2 & 0x2) / pow(2,1) NAK = (HDB2 & 0x1) return ACK, NAK #create HDB1 def makeHDB1(NDB): CMD = 0 # Command Mode Bit. Not implemented by RepRap and should be set to 0 EMD = 0x3 # Currently RepRap only implements 8-bit self.crc. this should be set to 011 HDB1val = ((CMD & 0x1) * pow(2,7)) | ((EMD & 0x7) * pow(2,4)) | (0xF & NDB) #print "HDB1 = '" + str(HDB1val) + "'" return HDB1val def breakHDB1(HDB1): NDB = HDB1 & 0xF return NDB sfact-2011.12.18/fabmetheus_utilities/miscellaneous/nophead/000077500000000000000000000000001167321211700237075ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/miscellaneous/nophead/enrique.py000066400000000000000000000112611167321211700257320ustar00rootroot00000000000000import Image, ImageDraw, ImageChops from GifImagePlugin import getheader, getdata from vector3 import Vector3 # Get the entire text of a file. # @param fileName name of the file # @return entire text of a file. def getFileText(fileName): file = open( fileName, 'r') fileText = file.read() file.close() return fileText # Get the all the lines of text of a text. # @param text text # @return the lines of text of a text def getTextLines(text): return text.replace('\r', '\n').split('\n') # Get the double value of the word after the first letter. # @param word string with value starting after the first letter # @return double value of the word after the first letter def getDoubleAfterFirstLetter(word): return float( word[1 :] ) # Get the double value of the word after the first occurence of the letter in the split line. def getDoubleForLetter(letter, splitLine): return getDoubleAfterFirstLetter( splitLine[ getIndexOfStartingWithSecond(letter, splitLine) ] ) # Get index of the first occurence of the given letter in the split line, starting with the second word. Return - 1 if letter is not found def getIndexOfStartingWithSecond(letter, splitLine): for wordIndex in xrange( 1, len(splitLine) ): word = splitLine[ wordIndex ] firstLetter = word[0] if firstLetter == letter: return wordIndex return - 1 # straightforward delta encoding taken from gifmaker.py def makedelta(fp, sequence): """Convert list of image frames to a GIF animation file""" previous = None for im in sequence: if not previous: # global header for s in getheader(im) + getdata(im): fp.write(s) else: # delta frame delta = ImageChops.subtract_modulo(im, previous) bbox = delta.getbbox() if not bbox: bbox = (0,0, 1,1) # compress difference for s in getdata(im.crop(bbox), offset = bbox[:2]): fp.write(s) previous = im.copy() fp.write(";") class g2gif: def __init__(self,fileName, outfile): self.last_pos = Vector3() self.last_pos.z = 999 self.do_move = 1 fileText = getFileText(fileName) textLines = getTextLines(fileText) self.images = [] self.image = None for line in textLines: self.parseLine(line) self.images.append(self.image) # write GIF animation fp = open(outfile, "wb") makedelta(fp, self.images) fp.close() def parseLine(self, line): splitLine = line.split(' ') if len(splitLine) < 1: return 0 firstWord = splitLine[0] if firstWord == 'G1': self.linearMove(splitLine) if firstWord == 'M101': self.do_move = 1 # Set the feedRate to the gcode split line. def setFeedRate( self, splitLine ): indexOfF = getIndexOfStartingWithSecond( "F", splitLine ) if indexOfF > 0: self.feedRateMinute = getDoubleAfterFirstLetter( splitLine[indexOfF] ) # Set a point to the gcode split line. def setPointComponent( self, point, splitLine ): point.x = getDoubleForLetter( "X", splitLine ) point.y = getDoubleForLetter( "Y", splitLine ) indexOfZ = getIndexOfStartingWithSecond( "Z", splitLine ) if indexOfZ > 0: point.z = getDoubleAfterFirstLetter( splitLine[indexOfZ] ) def scale( self, x, y ): return x * 5 + 150, - y * 5 + 100 def linearMove( self, splitLine ): location = Vector3() self.setFeedRate(splitLine) self.setPointComponent( location, splitLine ) if location.z != self.last_pos.z: if self.image: for i in xrange(10): self.images.append(self.image) self.image = Image.new('P', (300, 200), 255) palette = [] for red in xrange(8): for green in xrange(8): for blue in xrange(4): palette.extend((red * 255 / 7, green * 255 / 7, blue * 255 / 3)) self.image.putpalette(palette) self.segment = 0 else: if self.do_move: draw = ImageDraw.Draw(self.image) draw.line( ( self.scale( self.last_pos.x, self.last_pos.y ), self.scale( location.x, location.y ) ), fill = 192 ) self.segment = self.segment + 1 else: draw = ImageDraw.Draw(self.image) draw.line( ( self.scale( self.last_pos.x, self.last_pos.y ), self.scale(location.x, location.y ) ), fill = self.segment ) self.last_pos = location self.do_move = 0 sfact-2011.12.18/fabmetheus_utilities/miscellaneous/nophead/gRead.py000066400000000000000000000070641167321211700253120ustar00rootroot00000000000000from vector3 import Vector3 # Get the entire text of a file. # @param fileName name of the file # @return entire text of a file. def getFileText(fileName): file = open( fileName, 'r') fileText = file.read() file.close() return fileText # Get the all the lines of text of a text. # @param text text # @return the lines of text of a text def getTextLines(text): return text.replace('\r', '\n').split('\n') # Get the double value of the word after the first letter. # @param word string with value starting after the first letter # @return double value of the word after the first letter def getDoubleAfterFirstLetter(word): return float( word[1 :] ) # Get index of the first occurence of the given letter in the split line, starting with the second word. Return - 1 if letter is not found def getIndexOfStartingWithSecond(letter, splitLine): for wordIndex in xrange( 1, len(splitLine) ): word = splitLine[ wordIndex ] firstLetter = word[0] if firstLetter == letter: return wordIndex return - 1 class gRead: def __init__(self,fileName, layers,gcodeText = ''): if gcodeText == '': gcodeText = getFileText(fileName) textLines = getTextLines(gcodeText) self.last_pos = Vector3() self.layers = layers self.layer = None self.thread = None self.skeinforge = 0 self.max_z = -9999999999 for line in textLines: self.parseLine(line) self.newLayer() def parseLine(self, line): if line.startswith( "(" ): if line.startswith( "(" ): self.newLayer() return splitLine = line.split() if len(splitLine) < 1: return 0 firstWord = splitLine[0] if firstWord == 'G1': self.linearMove(splitLine) if firstWord == 'M110': #filament height only sent by skeinforge at the moment self.skeinforge = 1 self.newThread() if firstWord == 'M103': #extruder off if self.skeinforge: self.newThread() #end of thread if skeinforge if firstWord == 'G92': #offset coordinate system self.newThread() #for RepRap # Set a point to the gcode split line. def setPointComponent( self, point, splitLine ): indexOfX = getIndexOfStartingWithSecond( "X", splitLine ) if indexOfX > 0: point.x = getDoubleAfterFirstLetter( splitLine[indexOfX] ) indexOfY = getIndexOfStartingWithSecond( "Y", splitLine ) if indexOfY > 0: point.y = getDoubleAfterFirstLetter( splitLine[indexOfY] ) indexOfZ = getIndexOfStartingWithSecond( "Z", splitLine ) if indexOfZ > 0: point.z = getDoubleAfterFirstLetter( splitLine[indexOfZ] ) def newLayer(self): self.newThread() if self.layer: self.layers.append(self.layer) self.layer = [] def newThread(self): if self.thread: self.layer.append(self.thread) self.thread = [] def linearMove( self, splitLine ): if self.thread is not None: pos = self.last_pos.copy() self.setPointComponent( pos, splitLine ) if pos.z > self.max_z: # self.newLayer() self.max_z = pos.z if pos.z < self.last_pos.z: self.newThread() if self.skeinforge or pos.z < self.max_z: self.thread.append(pos) self.last_pos = pos sfact-2011.12.18/fabmetheus_utilities/miscellaneous/nophead/hexgrid.py000066400000000000000000000017251167321211700257200ustar00rootroot00000000000000import math # root parameters drillDiameter = 25.4 / 16.0 # 1/16 of an inch separationMultiplier = 2.5 safetyMultiplier = 1.0 bottomLeft = complex( - 10.0, - 10.0 ) topRight = complex( 10.0, 10.0 ) # derived parameters separation = drillDiameter * separationMultiplier horizontalSeparation = separation * math.cos( math.radians( 30.0 ) ) oddRowOffset = separation * math.sin( math.radians( 30.0 ) ) safetyMargin = complex( separation, separation ) * safetyMultiplier safeBottomLeft = bottomLeft + safetyMargin safeTopRight = topRight - safetyMargin # generate drill locations drillLocation = safeBottomLeft * 1.0 offset = 0.0 while drillLocation.imag < safeTopRight.imag: print('') while drillLocation.real < safeTopRight.real: print( drillLocation ) drillLocation = complex( drillLocation.real + separation, drillLocation.imag ) offset = oddRowOffset - offset drillLocation = complex( safeBottomLeft.real + offset, drillLocation.imag + horizontalSeparation ) print('') sfact-2011.12.18/fabmetheus_utilities/miscellaneous/nophead/layers.py000066400000000000000000000047711167321211700255710ustar00rootroot00000000000000from vector3 import Vector3 import Image, ImageDraw def bounding_cube(layers): min_x = 999999 min_y = 999999 min_z = 999999 max_x = -999999 max_y = -999999 max_z = -999999 for layer in layers: for thread in layer: for point in thread: if point.x > max_x: max_x = point.x if point.y > max_y: max_y = point.y if point.z > max_z: max_z = point.z if point.x < min_x: min_x = point.x if point.y < min_y: min_y = point.y if point.z < min_z: min_z = point.z return Vector3(min_x, min_y, min_z), Vector3(max_x, max_y, max_z) def make_images(layers): palette = [] for i in xrange(256): #resistor colour codes if i == 1: palette.extend((134, 100, 57)) # brown elif i == 2: palette.extend((255, 0, 0)) # red elif i == 3: palette.extend((218, 90, 35)) # orange elif i == 4: palette.extend((255, 255, 0)) # yellow elif i == 5: palette.extend(( 0, 255, 0)) # green elif i == 6: palette.extend(( 0, 0, 255)) # blue elif i == 7: palette.extend((255, 0, 255)) # purple else: palette.extend((i, i, i)) # shades of grey cube = bounding_cube(layers) scale = 10 x0 = int(cube[0].x) - 1 y0 = int(cube[0].y) - 1 width = int(round(cube[1].x - x0) + 1) * scale height = int(round(cube[1].y - y0) + 1) * scale last_pos = None images = [] for layer in layers: image = Image.new('P', (width, height), 255) image.putpalette(palette) draw = ImageDraw.Draw(image) segment = 0 for thread in layer: if last_pos is not None: draw.line(((( last_pos.x - x0) * scale, height - ( last_pos.y - y0) * scale), ((thread[0].x - x0) * scale, height - (thread[0].y - y0) * scale)), fill = 128) last_pos = thread[0].copy() for point in thread[1:]: draw.line((((last_pos.x - x0) * scale, height - (last_pos.y - y0) * scale), ( (point.x - x0) * scale, height - (point.y - y0) * scale)), fill = segment % 8) last_pos = point.copy() segment = segment + 1 images.append(image) return images sfact-2011.12.18/fabmetheus_utilities/miscellaneous/nophead/preview.py000066400000000000000000000046531167321211700257520ustar00rootroot00000000000000import sys try: import Tkinter except: print('You do not have Tkinter, which is needed for the graphical interface.') print('Information on how to download Tkinter is at:\nwww.tcl.tk/software/tcltk/') try: from layers import * from gRead import * import ImageTk except: print('You do not have the Python Imaging Library, which is needed by preview and gifview to view the gcode.') print('The Python Imaging Library can be downloaded from:\nwww.pythonware.com/products/pil/') class Preview: def __init__(self, layers): self.images = make_images(layers) self.index = 0 size = self.images[0].size self.root = Tkinter.Tk() self.root.title("Gifscene from HydraRaptor") frame = Tkinter.Frame(self.root) frame.pack() self.canvas = Tkinter.Canvas(frame, width = size[0], height = size[1]) self.canvas.pack() self.canvas.config(scrollregion=self.canvas.bbox(Tkinter.ALL)) self.exit_button = Tkinter.Button(frame, text = "Exit", fg = "red", command = frame.quit) self.exit_button.pack(side=Tkinter.RIGHT) self.down_button = Tkinter.Button(frame, text = "Down", command = self.down) self.down_button.pack(side=Tkinter.LEFT) self.up_button = Tkinter.Button(frame, text = "Up", command = self.up) self.up_button.pack(side=Tkinter.LEFT) self.update() self.root.mainloop() def update(self): # FIXME: Somehow this fails if this is launched using the Preferences, # but works from the command-line. self.image = ImageTk.PhotoImage(self.images[self.index]) self.canvas.create_image(0,0, anchor= Tkinter.NW, image = self.image) if self.index < len(self.images) - 1: self.up_button.config(state = Tkinter.NORMAL) else: self.up_button.config(state = Tkinter.DISABLED) if self.index > 0: self.down_button.config(state = Tkinter.NORMAL) else: self.down_button.config(state = Tkinter.DISABLED) def up(self): self.index += 1 self.update() def down(self): self.index -= 1 self.update() def viewGif( fileName, gcodeText = ''): layers = [] try: gRead(fileName, layers, gcodeText) Preview(layers) except Exception, why: print('Preview failed: ' + str( why ) ) if __name__ == "__main__": viewGif(' '.join(sys.argv[1 :])) sfact-2011.12.18/fabmetheus_utilities/miscellaneous/nophead/vector3.py000066400000000000000000000317511167321211700256550ustar00rootroot00000000000000""" Vec3 is a three dimensional vector class. Below are examples of Vector3 use. >>> from vector3 import Vector3 >>> origin = Vector3() >>> origin 0.0, 0.0, 0.0 >>> pythagoras = Vector3( 3, 4, 0 ) >>> pythagoras 3.0, 4.0, 0.0 >>> pythagoras.magnitude() 5.0 >>> pythagoras.magnitudeSquared() 25 >>> triplePythagoras = pythagoras * 3.0 >>> triplePythagoras 9.0, 12.0, 0.0 >>> plane = pythagoras.dropAxis() >>> plane (3+4j) """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ import math import operator __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' class Vector3: "A three dimensional vector class." __slots__ = ['x', 'y', 'z'] def __init__( self, x = 0.0, y = 0.0, z = 0.0 ): self.x = x self.y = y self.z = z def __abs__(self): "Get the magnitude of the Vector3." return math.sqrt( self.x * self.x + self.y * self.y + self.z * self.z ) magnitude = __abs__ def __add__(self, other): "Get the sum of this Vector3 and other one." return Vector3( self.x + other.x, self.y + other.y, self.z + other.z ) def __copy__(self): "Get the copy of this Vector3." return Vector3( self.x, self.y, self.z ) __pos__ = __copy__ copy = __copy__ def __div__(self, other): "Get a new Vector3 by dividing each component of this one." return Vector3( self.x / other, self.y / other, self.z / other ) def __eq__(self, other): "Determine whether this vector is identical to other one." if other is None: return False return self.x == other.x and self.y == other.y and self.z == other.z def __floordiv__(self, other): "Get a new Vector3 by floor dividing each component of this one." return Vector3( self.x // other, self.y // other, self.z // other ) def __hash__(self): "Determine whether this vector is identical to other one." return self.__repr__().__hash__() def __iadd__(self, other): "Add other Vector3 to this one." self.x += other.x self.y += other.y self.z += other.z return self def __idiv__(self, other): "Divide each component of this Vector3." self.x /= other self.y /= other self.z /= other return self def __ifloordiv__(self, other): "Floor divide each component of this Vector3." self.x //= other self.y //= other self.z //= other return self def __imul__(self, other): "Multiply each component of this Vector3." self.x *= other self.y *= other self.z *= other return self def __isub__(self, other): "Subtract other Vector3 from this one." self.x -= other.x self.y -= other.y self.z -= other.z return self def __itruediv__(self, other): "True divide each component of this Vector3." self.x = operator.truediv( self.x, other ) self.y = operator.truediv( self.y, other ) self.z = operator.truediv( self.z, other ) return self def __mul__(self, other): "Get a new Vector3 by multiplying each component of this one." return Vector3( self.x * other, self.y * other, self.z * other ) def __ne__(self, other): "Determine whether this vector is not identical to other one." return not self.__eq__(other) def __neg__(self): return Vector3( - self.x, - self.y, - self.z ) def __nonzero__(self): return self.x != 0 or self.y != 0 or self.z != 0 def __repr__(self): "Get the string representation of this Vector3." return '%s, %s, %s' % ( self.x, self.y, self.z ) def __rdiv__(self, other): "Get a new Vector3 by dividing each component of this one." return Vector3( other / self.x, other / self.y, other / self.z ) def __rfloordiv__(self, other): "Get a new Vector3 by floor dividing each component of this one." return Vector3( other // self.x, other // self.y, other // self.z ) def __rmul__(self, other): "Get a new Vector3 by multiplying each component of this one." return Vector3( self.x * other, self.y * other, self.z * other ) def __rtruediv__(self, other): "Get a new Vector3 by true dividing each component of this one." return Vector3( operator.truediv( other , self.x ), operator.truediv( other, self.y ), operator.truediv( other, self.z ) ) def __sub__(self, other): "Get the difference between the Vector3 and other one." return Vector3( self.x - other.x, self.y - other.y, self.z - other.z ) def __truediv__(self, other): "Get a new Vector3 by true dividing each component of this one." return Vector3( operator.truediv( self.x, other ), operator.truediv( self.y, other ), operator.truediv( self.z, other ) ) def cross(self, other): "Calculate the cross product of this vector with other one." return Vector3( self.y * other.z - self.z * other.y, - self.x * other.z + self.z * other.x, self.x * other.y - self.y * other.x ) def distance(self, other): "Get the Euclidean distance between this vector and other one." return math.sqrt( self.distanceSquared(other) ) def distanceSquared(self, other): "Get the square of the Euclidean distance between this vector and other one." separationX = self.x - other.x separationY = self.y - other.y separationZ = self.z - other.z return separationX * separationX + separationY * separationY + separationZ * separationZ def dot(self, other): "Calculate the dot product of this vector with other one." return self.x * other.x + self.y * other.y + self.z * other.z def dropAxis( self, which ): """Get a complex by removing one axis of this one. Keyword arguments: which -- the axis to drop (0=X, 1=Y, 2=Z)""" if which == 0: return complex( self.y, self.z ) if which == 1: return complex( self.x, self.z ) if which == 2: return complex( self.x, self.y ) def getNormalized(self, other): "Get the normalized Vector3." magnitude = abs(self) if magnitude == 0.0: return self.copy() return self / magnitude def magnitudeSquared(self): "Get the square of the magnitude of the Vector3." return self.x * self.x + self.y * self.y + self.z * self.z def normalize(self): "Scale each component of this Vector3 so that it has a magnitude of 1. If this Vector3 has a magnitude of 0, this method has no effect." magnitude = abs(self) if magnitude != 0.0: self /= magnitude def reflect( self, normal ): "Reflect the Vector3 across the normal, which is assumed to be normalized." distance = 2 * ( self.x * normal.x + self.y * normal.y + self.z * normal.z ) return Vector3( self.x - distance * normal.x, self.y - distance * normal.y, self.z - distance * normal.z ) def setToVec3(self, other): "Set this Vector3 to be identical to other one." self.x = other.x self.y = other.y self.z = other.z def setToXYZ( self, x, y, z ): "Set the x, y, and z components of this Vector3." self.x = x self.y = y self.z = z """ class Vector3: __slots__ = ['x', 'y', 'z'] def __init__(self, x, y, z): self.x = x self.y = y self.z = z def __copy__(self): return self.__class__(self.x, self.y, self.z) copy = __copy__ def __repr__(self): return 'Vector3(%.2f, %.2f, %.2f)' % (self.x, self.y, self.z) def __eq__(self, other): if isinstance(other, Vector3): return self.x == other.x and \ self.y == other.y and \ self.z == other.z else: assert hasattr(other, '__len__') and len(other) == 3 return self.x == other[0] and \ self.y == other[1] and \ self.z == other[2] def __ne__(self, other): return not self.__eq__(other) def __nonzero__(self): return self.x != 0 or self.y != 0 or self.z != 0 def __len__(self): return 3 def __getitem__(self, key): return (self.x, self.y, self.z)[key] def __setitem__(self, key, value): l = [self.x, self.y, self.z] l[key] = value self.x, self.y, self.z = l def __iter__(self): return iter((self.x, self.y, self.z)) def __getattr__(self, name): try: return tuple([(self.x, self.y, self.z)['xyz'.index(c)] \ for c in name]) except ValueError: raise AttributeError, name if _enable_swizzle_set: # This has detrimental performance on ordinary setattr as well # if enabled def __setattr__(self, name, value): if len(name) == 1: object.__setattr__(self, name, value) else: try: l = [self.x, self.y, self.z] for c, v in map(None, name, value): l['xyz'.index(c)] = v self.x, self.y, self.z = l except ValueError: raise AttributeError, name def __add__(self, other): if isinstance(other, Vector3): # Vector + Vector -> Vector # Vector + Point -> Point # Point + Point -> Vector if self.__class__ is other.__class__: _class = Vector3 else: _class = Point3 return _class(self.x + other.x, self.y + other.y, self.z + other.z) else: assert hasattr(other, '__len__') and len(other) == 3 return Vector3(self.x + other[0], self.y + other[1], self.z + other[2]) __radd__ = __add__ def __iadd__(self, other): if isinstance(other, Vector3): self.x += other.x self.y += other.y self.z += other.z else: self.x += other[0] self.y += other[1] self.z += other[2] return self def __sub__(self, other): if isinstance(other, Vector3): # Vector - Vector -> Vector # Vector - Point -> Point # Point - Point -> Vector if self.__class__ is other.__class__: _class = Vector3 else: _class = Point3 return Vector3(self.x - other.x, self.y - other.y, self.z - other.z) else: assert hasattr(other, '__len__') and len(other) == 3 return Vector3(self.x - other[0], self.y - other[1], self.z - other[2]) def __rsub__(self, other): if isinstance(other, Vector3): return Vector3(other.x - self.x, other.y - self.y, other.z - self.z) else: assert hasattr(other, '__len__') and len(other) == 3 return Vector3(other.x - self[0], other.y - self[1], other.z - self[2]) def __mul__(self, other): if isinstance(other, Vector3): # TODO component-wise mul/div in-place and on Vector2; docs. if self.__class__ is Point3 or other.__class__ is Point3: _class = Point3 else: _class = Vector3 return _class(self.x * other.x, self.y * other.y, self.z * other.z) else: assert type(other) in (int, long, float) return Vector3(self.x * other, self.y * other, self.z * other) __rmul__ = __mul__ def __imul__(self, other): assert type(other) in (int, long, float) self.x *= other self.y *= other self.z *= other return self def __div__(self, other): assert type(other) in (int, long, float) return Vector3(operator.div(self.x, other), operator.div(self.y, other), operator.div(self.z, other)) def __rdiv__(self, other): assert type(other) in (int, long, float) return Vector3(operator.div(other, self.x), operator.div(other, self.y), operator.div(other, self.z)) def __floordiv__(self, other): assert type(other) in (int, long, float) return Vector3(operator.floordiv(self.x, other), operator.floordiv(self.y, other), operator.floordiv(self.z, other)) def __rfloordiv__(self, other): assert type(other) in (int, long, float) return Vector3(operator.floordiv(other, self.x), operator.floordiv(other, self.y), operator.floordiv(other, self.z)) def __truediv__(self, other): assert type(other) in (int, long, float) return Vector3(operator.truediv(self.x, other), operator.truediv(self.y, other), operator.truediv(self.z, other)) def __rtruediv__(self, other): assert type(other) in (int, long, float) return Vector3(operator.truediv(other, self.x), operator.truediv(other, self.y), operator.truediv(other, self.z)) def __neg__(self): return Vector3(-self.x, -self.y, -self.z) __pos__ = __copy__ def __abs__(self): return math.sqrt(self.x ** 2 + \ self.y ** 2 + \ self.z ** 2) magnitude = __abs__ def magnitude_squared(self): return self.x ** 2 + \ self.y ** 2 + \ self.z ** 2 def normalize(self): d = self.magnitude() if d: self.x /= d self.y /= d self.z /= d return self def normalized(self): d = self.magnitude() if d: return Vector3(self.x / d, self.y / d, self.z / d) return self.copy() def dot(self, other): assert isinstance(other, Vector3) return self.x * other.x + \ self.y * other.y + \ self.z * other.z def cross(self, other): assert isinstance(other, Vector3) return Vector3(self.y * other.z - self.z * other.y, -self.x * other.z + self.z * other.x, self.x * other.y - self.y * other.x) def reflect(self, normal): # assume normal is normalized assert isinstance(normal, Vector3) d = 2 * (self.x * normal.x + self.y * normal.y + self.z * normal.z) return Vector3(self.x - d * normal.x, self.y - d * normal.y, self.z - d * normal.z) """ sfact-2011.12.18/fabmetheus_utilities/settings.py000066400000000000000000002273371167321211700216560ustar00rootroot00000000000000""" Settings is a collection of utilities to display, read & write the settings and position widgets. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec import cStringIO import math import os import shutil import sys import traceback import webbrowser try: import Tkinter except: print('You do not have Tkinter, which is needed for the graphical interface, you will only be able to use the command line.') print('Information on how to download Tkinter is at:\nwww.tcl.tk/software/tcltk/') __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = "$Date: 2008/23/04 $" __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalRepositoryDialogListTable = {} globalProfileSaveListenerListTable = {} globalCloseListTables = [ globalRepositoryDialogListTable, globalProfileSaveListenerListTable ] globalSpreadsheetSeparator = '\t' globalTemporaryOverrides = {} def addAcceleratorCommand( acceleratorBinding, commandFunction, master, menu, text ): "Add accelerator command." acceleratorText = acceleratorBinding[1 : -1] lastIndexOfMinus = acceleratorText.rfind('-') if lastIndexOfMinus > - 1: acceleratorText = acceleratorText[ : lastIndexOfMinus + 1 ] + acceleratorText[ lastIndexOfMinus + 1 : ].capitalize() acceleratorText = acceleratorText.replace('KeyPress-', '') acceleratorText = acceleratorText.replace('-', '+') acceleratorText = acceleratorText.replace('Control', 'Ctrl') acceleratorBinding = acceleratorBinding.replace('KeyPress', '') menu.add_command( accelerator = acceleratorText, label = text, underline = 0, command = commandFunction ) master.bind( acceleratorBinding, commandFunction ) def addEmptyRow( gridPosition ): "Add an empty row." gridPosition.increment() Tkinter.Label( gridPosition.master ).grid( row = gridPosition.row, column = gridPosition.column ) def addListsToRepository(fileNameHelp, repository): 'Add the value to the lists.' addListsToRepositoryByFunction(fileNameHelp, None, repository) def addListsToRepositoryByFunction(fileNameHelp, getProfileDirectory, repository): 'Add the value to the lists.' repository.displayEntities = [] repository.executeTitle = None repository.fileNameHelp = fileNameHelp repository.fileNameInput = None repository.lowerName = fileNameHelp.split('.')[-2] repository.baseName = repository.lowerName + '.csv' repository.baseNameSynonym = None repository.capitalizedName = getEachWordCapitalized( repository.lowerName ) repository.getProfileDirectory = getProfileDirectory repository.openLocalHelpPage = HelpPage().getOpenFromDocumentationSubName( repository.fileNameHelp ) repository.openWikiManualHelpPage = None repository.preferences = [] repository.repositoryDialog = None repository.saveListenerTable = {} repository.title = repository.capitalizedName + ' Settings' repository.menuEntities = [] repository.saveCloseTitle = 'Save and Close' repository.windowPosition = WindowPosition().getFromValue( repository, '0+0') for setting in repository.preferences: setting.repository = repository def addMenuEntitiesToMenu( menu, menuEntities ): "Add the menu entities to the menu." for menuEntity in menuEntities: menuEntity.addToMenu( menu ) def addMenuEntitiesToMenuFrameable( menu, menuEntities ): "Add the menu entities to the menu." for menuEntity in menuEntities: menuEntity.addToMenuFrameable( menu ) def addPluginsParentToMenu( directoryPath, menu, parentPath, pluginFileNames ): "Add plugins and the parent to the menu." ToolDialog().addPluginToMenu( menu, parentPath[ : parentPath.rfind('.') ] ) menu.add_separator() addPluginsToMenu( directoryPath, menu, pluginFileNames ) def addPluginsToMenu( directoryPath, menu, pluginFileNames ): "Add plugins to the menu." for pluginFileName in pluginFileNames: ToolDialog().addPluginToMenu( menu, os.path.join( directoryPath, pluginFileName ) ) def cancelRepository(repository): "Read the repository then set all the entities to the read repository values." getReadRepository(repository) for setting in repository.displayEntities: if setting in repository.preferences: setting.setStateToValue() def deleteDirectory( directory, subfolderName ): "Delete the directory if it exists." subDirectory = os.path.join( directory, subfolderName ) if os.path.isdir( subDirectory ): shutil.rmtree( subDirectory ) def deleteMenuItems( menu ): "Delete the menu items." try: lastMenuIndex = menu.index( Tkinter.END ) if lastMenuIndex is not None: menu.delete( 0, lastMenuIndex ) except: print('this should never happen, the lastMenuIndex in deleteMenuItems in settings could not be determined.') def getAlongWayHexadecimalColor( beginBrightness, colorWidth, difference, endColorTuple, wayLength ): "Get a color along the way from begin brightness to the end color." alongWay = 1.0 if wayLength != 0.0: alongWay = 0.4 + 0.6 * min( 1.0, abs( float( difference ) / float( wayLength ) ) ) hexadecimalColor = '#' oneMinusAlongWay = 1.0 - alongWay for primaryIndex in xrange(3): hexadecimalColor += getAlongWayHexadecimalPrimary( beginBrightness, oneMinusAlongWay, colorWidth, endColorTuple[ primaryIndex ], alongWay ) return hexadecimalColor def getAlongWayHexadecimalPrimary( beginBrightness, beginRatio, colorWidth, endBrightness, endRatio ): "Get a primary color along the way from grey to the end color." brightness = beginRatio * float( beginBrightness ) + endRatio * float( endBrightness ) return getWidthHex( int( round( brightness ) ), colorWidth ) def getAlterationFile(fileName): "Get the file from the fileName or the lowercase fileName in the alterations directories." settingsAlterationsDirectory = archive.getSettingsPath('alterations') archive.makeDirectory(settingsAlterationsDirectory) fileInSettingsAlterationsDirectory = getFileInGivenDirectory(settingsAlterationsDirectory, fileName) if fileInSettingsAlterationsDirectory != '': return fileInSettingsAlterationsDirectory alterationsDirectory = archive.getSkeinforgePath('alterations') return getFileInGivenDirectory(alterationsDirectory, fileName) def getAlterationFileLine(fileName): "Get the alteration file line from the fileName." lines = getAlterationLines(fileName) if len(lines) == 0: return [] return getAlterationFileLineBlindly(fileName) def getAlterationFileLineBlindly(fileName): "Get the alteration file line from the fileName." return '() %s ()' % fileName def getAlterationFileLines(fileName): 'Get the alteration file line and the text lines from the fileName in the alterations directories.' lines = getAlterationLines(fileName) if len(lines) == 0: return [] return [getAlterationFileLineBlindly(fileName)] + lines def getAlterationLines(fileName): "Get the text lines from the fileName in the alterations directories." return archive.getTextLines(getAlterationFile(fileName)) def getDisplayedDialogFromConstructor(repository): "Display the repository dialog." try: getReadRepository(repository) return RepositoryDialog( repository, Tkinter.Tk() ) except: print('this should never happen, getDisplayedDialogFromConstructor in settings could not open') print(repository) traceback.print_exc(file=sys.stdout) return None def getDisplayedDialogFromPath(path): "Display the repository dialog." pluginModule = archive.getModuleWithPath(path) if pluginModule is None: return None return getDisplayedDialogFromConstructor( pluginModule.getNewRepository() ) def getDisplayToolButtonsRepository( directoryPath, importantFileNames, names, repository ): "Get the display tool buttons." displayToolButtons = [] for name in names: displayToolButton = DisplayToolButton().getFromPath( name in importantFileNames, name, os.path.join( directoryPath, name ), repository ) displayToolButtons.append( displayToolButton ) return displayToolButtons def getEachWordCapitalized( name ): "Get the capitalized name." withSpaces = name.lower().replace('_', ' ') words = withSpaces.split(' ') capitalizedStrings = [] for word in words: capitalizedStrings.append( word.capitalize() ) return ' '.join( capitalizedStrings ) def getFileInGivenDirectory( directory, fileName ): "Get the file from the fileName or the lowercase fileName in the given directory." directoryListing = os.listdir(directory) lowerFileName = fileName.lower() for directoryFile in directoryListing: if directoryFile.lower() == lowerFileName: return getFileTextGivenDirectoryFileName( directory, directoryFile ) return '' def getFileTextGivenDirectoryFileName( directory, fileName ): "Get the entire text of a file with the given file name in the given directory." absoluteFilePath = os.path.join( directory, fileName ) return archive.getFileText( absoluteFilePath ) def getFolders(directory): "Get the folder list in a directory." archive.makeDirectory(directory) directoryListing = [] try: directoryListing = os.listdir(directory) except OSError: print('Skeinforge can not list the directory:') print(directory) print('so give it read/write permission for that directory.') folders = [] for fileName in directoryListing: if os.path.isdir( os.path.join( directory, fileName ) ): folders.append(fileName) return folders def getGlobalRepositoryDialogValues(): "Get the global repository dialog values." global globalRepositoryDialogListTable return euclidean.getListTableElements(globalRepositoryDialogListTable) def getPathInFabmetheusFromFileNameHelp( fileNameHelp ): "Get the directory path from file name help." fabmetheusPath = archive.getFabmetheusPath() splitFileNameHelps = fileNameHelp.split('.') splitFileNameDirectoryNames = splitFileNameHelps[ : - 1 ] for splitFileNameDirectoryName in splitFileNameDirectoryNames: fabmetheusPath = os.path.join( fabmetheusPath, splitFileNameDirectoryName ) return fabmetheusPath def getProfileBaseName(repository): "Get the profile base file name." if repository.getProfileDirectory is None: return repository.baseName return os.path.join(repository.getProfileDirectory(), repository.baseName) def getProfileBaseNameSynonym(repository): "Get the profile base file name synonym." if repository.getProfileDirectory is None: return repository.baseNameSynonym return os.path.join(repository.getProfileDirectory(), repository.baseNameSynonym) def getProfilesDirectoryInAboveDirectory(subName=''): "Get the profiles directory path in the above directory." aboveProfilesDirectory = archive.getSkeinforgePath('profiles') if subName == '': return aboveProfilesDirectory return os.path.join( aboveProfilesDirectory, subName ) def getRadioPluginsAddPluginFrame( directoryPath, importantFileNames, names, repository ): "Get the radio plugins and add the plugin frame." repository.pluginFrame = PluginFrame() radioPlugins = [] for name in names: radioPlugin = RadioPlugin().getFromRadio( name in importantFileNames, repository.pluginFrame.latentStringVar, name, repository, name == importantFileNames[0] ) radioPlugin.updateFunction = repository.pluginFrame.update radioPlugins.append( radioPlugin ) defaultRadioButton = getSelectedRadioPlugin( importantFileNames + [ radioPlugins[0].name ], radioPlugins ) repository.pluginFrame.getFromPath( defaultRadioButton, directoryPath, repository ) return radioPlugins def getReadRepository(repository): "Read and return settings from a file." text = archive.getFileText(archive.getProfilesPath(getProfileBaseName(repository)), False) if text == '': if repository.baseNameSynonym is not None: text = archive.getFileText(archive.getProfilesPath(getProfileBaseNameSynonym(repository)), False) if text == '': print('The default %s will be written in the sfact_profiles folder in the Application directory.' % repository.title.lower() ) text = archive.getFileText(getProfilesDirectoryInAboveDirectory(getProfileBaseName(repository)), False) if text != '': readSettingsFromText(repository, text) writeSettings(repository) temporaryApplyOverrides(repository) return repository readSettingsFromText(repository, text) temporaryApplyOverrides(repository) return repository def getRepositoryText(repository): "Get the text representation of the repository." repositoryWriter = getRepositoryWriter(repository.title.lower()) for setting in repository.preferences: setting.writeToRepositoryWriter(repositoryWriter) return repositoryWriter.getvalue() def getRepositoryWriter(title): "Get the repository writer for the title." repositoryWriter = cStringIO.StringIO() repositoryWriter.write('Format is tab separated %s.\n' % title) repositoryWriter.write('_Name %sValue\n' % globalSpreadsheetSeparator) return repositoryWriter def getSelectedPluginModuleFromPath(filePath, plugins): "Get the selected plugin module." for plugin in plugins: if plugin.value: return gcodec.getModuleFromPath(plugin.name, filePath) return None def getSelectedPluginName( plugins ): "Get the selected plugin name." for plugin in plugins: if plugin.value: return plugin.name return '' def getSelectedRadioPlugin( names, radioPlugins ): "Get the selected radio button if it exists, None otherwise." for radioPlugin in radioPlugins: if radioPlugin.value: return radioPlugin for name in names: for radioPlugin in radioPlugins: if radioPlugin.name == name: radioPlugin.value = True return radioPlugin print('this should never happen, no getSelectedRadioPlugin in settings') print( names ) return radioPlugin[0] def getShortestUniqueSettingName(settingName, settings): "Get the shortest unique name in the settings." for length in xrange(3, len(settingName)): numberOfEquals = 0 shortName = settingName[: length] for setting in settings: if setting.name[: length] == shortName: numberOfEquals += 1 if numberOfEquals < 2: return shortName.lower() return settingName.lower() def getSubfolderWithBasename( basename, directory ): "Get the subfolder in the directory with the basename." archive.makeDirectory(directory) directoryListing = os.listdir(directory) for fileName in directoryListing: joinedFileName = os.path.join( directory, fileName ) if os.path.isdir(joinedFileName): if basename == fileName: return joinedFileName return None def getTitleFromName( title ): "Get the title of this setting." if title[-1] == ':': title = title[ : - 1 ] spaceBracketIndex = title.find(' (') if spaceBracketIndex > - 1: return title[ : spaceBracketIndex ] return title def getUntilFirstBracket(text): 'Get the text until the first bracket, if any.' dotIndex = text.find('(') if dotIndex < 0: return text return text[: dotIndex] def getWidthHex( number, width ): "Get the first width hexadecimal digits." return ('0000%s' % hex(number)[ 2 : ] )[ - width : ] def liftRepositoryDialogs( repositoryDialogs ): "Lift the repository dialogs." for repositoryDialog in repositoryDialogs: repositoryDialog.root.withdraw() # the withdraw & deiconify trick is here because lift does not work properly on my linux computer repositoryDialog.root.lift() # probably not necessary, here in case the withdraw & deiconify trick does not work on some other computer repositoryDialog.root.deiconify() repositoryDialog.root.lift() # probably not necessary, here in case the withdraw & deiconify trick does not work on some other computer repositoryDialog.root.update_idletasks() def openSVGPage( fileName, svgViewer ): "Open svg page with an svg program." if svgViewer == '': return if svgViewer == 'webbrowser': openWebPage(fileName) return filePath = '"' + os.path.normpath(fileName) + '"' # " to send in file name with spaces shellCommand = svgViewer + ' ' + filePath commandResult = os.system(shellCommand) if commandResult != 0: print('It may be that the system could not find the %s program.' % svgViewer ) print('If so, try installing the %s program or look for another svg viewer, like Netscape which can be found at:' % svgViewer ) print('http://www.netscape.org/') print('') def openWebPage( webPagePath ): "Open a web page in a browser." if webPagePath.find('#') != - 1: # to get around # encode bug redirectionText = '\n\n\n' redirectionText += '\n\n' % webPagePath webPagePath = archive.getDocumentationPath('redirect.html') archive.writeFileText( webPagePath, redirectionText ) webPagePath = '"%s"' % webPagePath # " to get around space in url bug try: # " to get around using gnome-open or internet explorer for webbrowser default webbrowserController = webbrowser.get('firefox') except: webbrowserController = webbrowser.get() webbrowserName = webbrowserController.name if webbrowserName == '': try: os.startfile( webPagePath )#this is available on some python environments, but not all return except: pass print('Skeinforge was not able to open the file in a web browser. To see the documentation, open the following file in a web browser:') print( webPagePath ) return else: os.system(webbrowserName + ' ' + webPagePath)#used this instead of webbrowser.open() to workaround webbrowser open() bug def printProgress(layerIndex, procedureName): "Print layerIndex followed by a carriage return." printProgressByString('%s layer count %s...' % (procedureName.capitalize(), layerIndex + 1)) def printProgressByNumber(layerIndex, numberOfLayers, procedureName): "Print layerIndex and numberOfLayers followed by a carriage return." printProgressByString('%s layer count %s of %s...' % (procedureName.capitalize(), layerIndex + 1, numberOfLayers)) def printProgressByString(progressString): "Print progress string." sys.stdout.write(progressString) sys.stdout.write(chr(27) + '\r') sys.stdout.flush() def quitWindow(root): "Quit a window." try: root.destroy() except: pass def quitWindows( event=None ): "Quit all windows." global globalRepositoryDialogListTable globalRepositoryDialogValues = euclidean.getListTableElements( globalRepositoryDialogListTable ) for globalRepositoryDialogValue in globalRepositoryDialogValues: quitWindow(globalRepositoryDialogValue.root) def readSettingsFromText(repository, text): "Read settings from a text." text = text.replace(('\nName %sValue\n' % globalSpreadsheetSeparator), ('\n_Name %sValue\n' % globalSpreadsheetSeparator)) lines = archive.getTextLines(text) shortDictionary = {} for setting in repository.preferences: shortDictionary[getShortestUniqueSettingName(setting.name, repository.preferences)] = setting for lineIndex in xrange(len(lines)): setRepositoryToLine(lineIndex, lines, shortDictionary) def saveAll(): "Save all the dialogs." for globalRepositoryDialogValue in getGlobalRepositoryDialogValues(): globalRepositoryDialogValue.save() def saveRepository(repository): "Set the entities to the dialog then write them." for setting in repository.preferences: setting.setToDisplay() writeSettingsPrintMessage(repository) for saveListener in repository.saveListenerTable.values(): saveListener() def setButtonFontWeightString( button, isBold ): "Set button font weight given isBold." try: weightString = 'normal' if isBold: weightString = 'bold' splitFont = button['font'].split() button['font'] = ( splitFont[0], splitFont[1], weightString ) except: pass def setEntryText(entry, value): "Set the entry text." if entry is None: return entry.delete(0, Tkinter.END) entry.insert(0, str(value)) def setIntegerValueToString( integerSetting, valueString ): "Set the integer to the string." dotIndex = valueString.find('.') if dotIndex > - 1: valueString = valueString[: dotIndex] try: integerSetting.value = int( valueString ) return except: print('Warning, can not read integer ' + integerSetting.name + ' ' + valueString ) print('Will try reading as a boolean, which might be a mistake.') integerSetting.value = 0 if valueString.lower() == 'true': integerSetting.value = 1 def setRepositoryToLine(lineIndex, lines, shortDictionary): "Set setting dictionary to a setting line." line = lines[lineIndex] splitLine = line.split(globalSpreadsheetSeparator) if len(splitLine) < 2: return fileSettingName = splitLine[0] shortDictionaryKeys = shortDictionary.keys() shortDictionaryKeys.sort(key=len, reverse=True) # so that a short word like fill is not overidden by a longer word like fillet for shortDictionaryKey in shortDictionaryKeys: if fileSettingName[: len(shortDictionaryKey)].lower() == shortDictionaryKey: shortDictionary[shortDictionaryKey].setValueToSplitLine(lineIndex, lines, splitLine) return def setSpinColor( setting ): "Set the spin box color to the value, yellow if it is lower than the default and blue if it is higher." if setting.entry is None: return if setting.backgroundColor is None: setting.backgroundColor = setting.entry['background'] if setting.backgroundColor[0] != '#': setting.backgroundColor = '#ffffff' setting.colorWidth = len( setting.backgroundColor ) / 3 setting.grey = int( setting.backgroundColor[ 1 : 1 + setting.colorWidth ], 16 ) setting.white = int('f' * setting.colorWidth, 16 ) if abs( setting.value - setting.defaultValue ) <= 0.75 * setting.increment: setting.entry['background'] = setting.backgroundColor return difference = setting.value - setting.defaultValue if difference > 0.0: wayLength = setting.to - setting.defaultValue setting.entry['background'] = getAlongWayHexadecimalColor( setting.grey, setting.colorWidth, difference, ( 0, setting.white, setting.white ), wayLength ) return wayLength = setting.from_ - setting.defaultValue setting.entry['background'] = getAlongWayHexadecimalColor( setting.grey, setting.colorWidth, difference, ( setting.white, setting.white, 0 ), wayLength ) def startMainLoopFromConstructor(repository): "Display the repository dialog and start the main loop." try: import Tkinter except: return displayedDialogFromConstructor = getDisplayedDialogFromConstructor(repository) if displayedDialogFromConstructor is None: print('Warning, displayedDialogFromConstructor in settings is none, so the window will not be displayed.') else: displayedDialogFromConstructor.root.mainloop() def startMainLoopFromWindow(window): 'Display the tableau window and start the main loop.' if window is None: return if window.root is None: print('Warning, window.root in startMainLoopFromWindow in settings is none, so the window will not be displayed.') return window.root.mainloop() def temporaryAddPreferenceOverride(module, name, value): global globalTemporaryOverrides if not module in globalTemporaryOverrides: globalTemporaryOverrides[module] = {} globalTemporaryOverrides[module][name] = value print('OVERRIDE %s %s %s' % (module,name,value)) print(globalTemporaryOverrides[module]) def temporaryApplyOverrides(repository): 'Apply any overrides that have been set at the command line.' # The override dictionary is a mapping of repository names to # key-value mappings. global globalTemporaryOverrides if repository.baseName in globalTemporaryOverrides: settingTable = {} for setting in repository.preferences: settingTable[ setting.name ] = setting for (name, value) in overrides[repository.baseName].items(): if name in settingTable: settingTable[name].setValueToString(value) else: print('Override not applied for: %s, %s' % (name,value)) def writeSettings(repository): "Write the settings to a file." profilesDirectoryPath = archive.getProfilesPath(getProfileBaseName(repository)) archive.makeDirectory(os.path.dirname(profilesDirectoryPath)) archive.writeFileText(profilesDirectoryPath, getRepositoryText(repository)) for setting in repository.preferences: setting.updateSaveListeners() def writeSettingsPrintMessage(repository): "Set the settings to the dialog then write them." writeSettings(repository) print( repository.title.lower().capitalize() + ' have been saved.') def writeValueListToRepositoryWriter( repositoryWriter, setting ): "Write tab separated name and list to the repository writer." repositoryWriter.write( setting.name ) for item in setting.value: if item != '[]': repositoryWriter.write(globalSpreadsheetSeparator) repositoryWriter.write( item ) repositoryWriter.write('\n') class StringSetting: "A class to display, read & write a string." def __init__(self): "Set the update function to none." self.entry = None self.updateFunction = None def __repr__(self): "Get the string representation of this StringSetting." return str(self.__dict__) def addToDialog( self, gridPosition ): "Add this to the dialog." gridPosition.increment() self.label = Tkinter.Label( gridPosition.master, text = self.name ) self.label.grid( row = gridPosition.row, column = 0, columnspan = 3, sticky = Tkinter.W ) self.createEntry( gridPosition.master ) self.setStateToValue() self.entry.grid( row = gridPosition.row, column = 3, columnspan = 2, sticky = Tkinter.W ) self.bindEntry() LabelHelp( self.repository.fileNameHelp, gridPosition.master, self.name, self.label ) def addToMenu( self, repositoryMenu ): "Do nothing because this should only be added to a frameable repository menu." pass def addToMenuFrameable( self, repositoryMenu ): "Add this to the frameable repository menu." titleFromName = getTitleFromName( self.name ) helpWindowMenu = Tkinter.Menu( repositoryMenu, tearoff = 0 ) repositoryMenu.add_cascade( label = titleFromName, menu = helpWindowMenu, underline = 0 ) if self.name in self.repository.frameList.value: helpWindowMenu.add_command( label = 'Remove from Window', command = self.removeFromWindow ) else: helpWindowMenu.add_command( label = 'Add to Window', command = self.addToWindow ) helpWindowMenu.add_separator() helpWindowMenu.add_command( label = 'Help', command = HelpPage().getOpenFromDocumentationSubName( self.repository.fileNameHelp + '#' + titleFromName ) ) def addToWindow(self): "Add this to the repository frame list." self.repository.frameList.addToList( self.name ) def bindEntry(self): "Bind the entry to the update function." if self.updateFunction is not None: self.entry.bind('', self.updateFunction ) def createEntry( self, root ): "Create the entry." self.entry = Tkinter.Entry( root ) def getFromValue( self, name, repository, value ): "Initialize." return self.getFromValueOnlyAddToRepository( name, repository, value ) def getFromValueOnly( self, name, repository, value ): "Initialize." self.defaultValue = value self.name = name self.repository = repository self.value = value return self def getFromValueOnlyAddToRepository( self, name, repository, value ): "Initialize." repository.displayEntities.append(self) repository.menuEntities.append(self) repository.preferences.append(self) return self.getFromValueOnly( name, repository, value ) def removeFromWindow(self): "Remove this from the repository frame list." self.repository.frameList.removeFromList( self.name ) def setStateToValue(self): "Set the entry to the value." setEntryText(self.entry, self.value) def setToDisplay(self): "Set the string to the entry field." try: valueString = self.entry.get() self.setValueToString( valueString ) except: pass def setUpdateFunction( self, updateFunction ): "Set the update function." self.updateFunction = updateFunction def setValueToSplitLine( self, lineIndex, lines, splitLine ): "Set the value to the second word of a split line." self.setValueToString(splitLine[1]) def setValueToString( self, valueString ): "Set the value to the value string." self.value = valueString def updateSaveListeners(self): "Update save listeners if any." pass def writeToRepositoryWriter( self, repositoryWriter ): "Write tab separated name and value to the repository writer." repositoryWriter.write('%s%s%s\n' % ( self.name, globalSpreadsheetSeparator, self.value ) ) class BooleanSetting( StringSetting ): "A class to display, read & write a boolean." def addToDialog( self, gridPosition ): "Add this to the dialog." gridPosition.increment() self.checkbutton = Tkinter.Checkbutton( gridPosition.master, command = self.toggleCheckbutton, text = self.name ) #toggleCheckbutton is being used instead of a Tkinter IntVar because there is a weird bug where it doesn't work properly if this setting is not on the first window. self.checkbutton.grid( row = gridPosition.row, columnspan = 5, sticky = Tkinter.W ) self.setStateToValue() LabelHelp( self.repository.fileNameHelp, gridPosition.master, self.name, self.checkbutton ) def addToMenu( self, repositoryMenu ): "Add this to the repository menu." self.activateToggleMenuCheckbutton = False #activateToggleMenuCheckbutton is being used instead of setting command after because add_checkbutton does not return a checkbutton. repositoryMenu.add_checkbutton( label = getTitleFromName( self.name ), command = self.toggleMenuCheckbutton ) if self.value: repositoryMenu.invoke( repositoryMenu.index( Tkinter.END ) ) self.activateToggleMenuCheckbutton = True def addToMenuFrameable( self, repositoryMenu ): "Add this to the frameable repository menu." titleFromName = getTitleFromName( self.name ) helpWindowMenu = Tkinter.Menu( repositoryMenu, tearoff = 0 ) repositoryMenu.add_cascade( label = titleFromName, menu = helpWindowMenu, underline = 0 ) self.addToMenu( helpWindowMenu ) helpWindowMenu.add_separator() helpWindowMenu.add_command( label = 'Help', command = HelpPage().getOpenFromDocumentationSubName( self.repository.fileNameHelp + '#' + titleFromName ) ) def setStateToValue(self): "Set the checkbutton to the boolean." try: if self.value: self.checkbutton.select() else: self.checkbutton.deselect() except: pass def setToDisplay(self): "Do nothing because toggleCheckbutton is handling the value." pass def setValueToString( self, valueString ): "Set the boolean to the string." self.value = ( valueString.lower() == 'true') def toggleCheckbutton(self): "Workaround for Tkinter bug, toggle the value." self.value = not self.value self.setStateToValue() if self.updateFunction is not None: self.updateFunction() def toggleMenuCheckbutton(self): "Workaround for Tkinter bug, toggle the value." if self.activateToggleMenuCheckbutton: self.value = not self.value if self.updateFunction is not None: self.updateFunction() class CloseListener: "A class to listen to link a window to the global repository dialog list table." def __init__( self, window, closeFunction = None ): "Add the window to the global repository dialog list table." self.closeFunction = closeFunction self.window = window self.shouldWasClosedBeBound = True global globalRepositoryDialogListTable euclidean.addElementToListDictionaryIfNotThere( window, window, globalRepositoryDialogListTable ) def listenToWidget( self, widget ): "Listen to the destroy message of the widget." if self.shouldWasClosedBeBound: self.shouldWasClosedBeBound = False widget.bind('', self.wasClosed ) def wasClosed(self, event): "The dialog was closed." global globalCloseListTables for globalCloseListTable in globalCloseListTables: if self.window in globalCloseListTable: del globalCloseListTable[ self.window ] if self.closeFunction is not None: self.closeFunction() class DisplayToolButton: "A class to display the tool dialog button, in a two column wide table." def addToDialog( self, gridPosition ): "Add this to the dialog." self.displayButton = Tkinter.Button( gridPosition.master, activebackground = 'black', activeforeground = 'white', text = getEachWordCapitalized( self.name ), command = self.displayDialog ) setButtonFontWeightString( self.displayButton, self.important ) gridPosition.incrementGivenNumberOfColumns(2) self.displayButton.grid( row = gridPosition.row, column = gridPosition.column, columnspan = 2 ) def displayDialog(self): "Display function." ToolDialog().getFromPath( self.path ).display() def getFromPath( self, important, name, path, repository ): "Initialize." self.important = important self.name = name self.path = path self.repository = repository repository.displayEntities.append(self) return self class FileHelpMenuBar: def __init__( self, root ): "Create a menu bar with a file and help menu." self.underlineLetters = [] self.menuBar = Tkinter.Menu( root ) self.root = root root.config( menu = self.menuBar ) self.fileMenu = Tkinter.Menu( self.menuBar, tearoff = 0 ) self.menuBar.add_cascade( label = "File", menu = self.fileMenu, underline = 0 ) self.underlineLetters.append('f') def addMenuToMenuBar( self, labelText, menu ): "Add a menu to the menu bar." lowerLabelText = labelText.lower() for underlineLetterIndex in xrange( len( lowerLabelText ) ): underlineLetter = lowerLabelText[ underlineLetterIndex ] if underlineLetter not in self.underlineLetters: self.underlineLetters.append( underlineLetter ) self.menuBar.add_cascade( label = labelText, menu = menu, underline = underlineLetterIndex ) return self.menuBar.add_cascade( label = labelText, menu = menu ) def addPluginToMenuBar( self, modulePath, repository, window ): "Add a menu to the menu bar from a tool." pluginModule = archive.getModuleWithPath( modulePath ) if pluginModule is None: print('this should never happen, pluginModule in addMenuToMenuBar in settings is None.') return None repositoryMenu = Tkinter.Menu( self.menuBar, tearoff = 0 ) labelText = getEachWordCapitalized( os.path.basename( modulePath ) ) self.addMenuToMenuBar( labelText, repositoryMenu ) pluginModule.addToMenu( self.root, repositoryMenu, repository, window ) def completeMenu(self, closeFunction, repository, saveFunction, window): "Complete the menu." self.closeFunction = closeFunction self.saveFunction = saveFunction addAcceleratorCommand('', saveFunction, self.root, self.fileMenu, 'Save') self.fileMenu.add_command(label = "Save and Close", command = self.saveClose) addAcceleratorCommand('', closeFunction, self.root, self.fileMenu, 'Close') self.fileMenu.add_separator() addAcceleratorCommand('', quitWindows, self.root, self.fileMenu, 'Quit') skeinforgePluginsPath = archive.getSkeinforgePath('skeinforge_plugins') pluginFileNames = archive.getPluginFileNamesFromDirectoryPath(skeinforgePluginsPath) for pluginFileName in pluginFileNames: self.addPluginToMenuBar(os.path.join(skeinforgePluginsPath, pluginFileName), repository, window) def saveClose(self): "Call the save function then the close function." self.saveFunction() self.closeFunction() class FileNameInput( StringSetting ): "A class to display, read & write a fileName." def addToDialog( self, gridPosition ): "Add this to the dialog." self.gridPosition = gridPosition gridPosition.executables.append(self) def execute(self): "Open the file picker." self.wasCancelled = False parent = self.gridPosition.master try: import tkFileDialog summarized = archive.getSummarizedFileName(self.value) initialDirectory = os.path.dirname( summarized ) if len( initialDirectory ) > 0: initialDirectory += os.sep else: initialDirectory = "." fileName = tkFileDialog.askopenfilename( filetypes = self.getFileNameFirstTypes(), initialdir = initialDirectory, initialfile = os.path.basename( summarized ), parent = parent, title = self.name ) self.setCancelledValue(fileName) return except: print('Could not get the old directory in settings, so the file picker will be opened in the default directory.') try: fileName = tkFileDialog.askopenfilename( filetypes = self.getFileNameFirstTypes(), initialdir = '.', initialfile = '', parent = parent, title = self.name ) self.setCancelledValue(fileName) except: print('Error in execute in FileName in settings, ' + self.name ) def getFileNameFirstTypes(self): "Get the file types with the file type of the fileName moved to the front of the list." allFiles = [ ('All', '*.*') ] try: basename = os.path.basename(self.value) splitFile = basename.split('.') allReadables = [] if len( self.fileTypes ) > 1: for fileType in self.fileTypes: allReadable = ( ('All Readable', fileType[1] ) ) allReadables.append( allReadable ) if len( splitFile ) < 1: return allReadables + allFiles + self.fileTypes baseExtension = splitFile[-1] for fileType in self.fileTypes: fileExtension = fileType[1].split('.')[-1] if fileExtension == baseExtension: fileNameFirstTypes = self.fileTypes[:] fileNameFirstTypes.remove( fileType ) return [ fileType ] + allReadables + allFiles + fileNameFirstTypes return allReadables + allFiles + self.fileTypes except: return allFiles def getFromFileName( self, fileTypes, name, repository, value ): "Initialize." self.getFromValueOnly( name, repository, value ) self.fileTypes = fileTypes self.wasCancelled = False repository.displayEntities.append(self) repository.preferences.append(self) return self def setCancelledValue( self, fileName ): "Set the value to the file name and wasCancelled true if a file was not picked." if ( str(fileName) == '()' or str(fileName) == ''): self.wasCancelled = True else: self.value = fileName def setToDisplay(self): "Do nothing because the file dialog is handling the value." pass class FloatSetting( StringSetting ): "A class to display, read & write a float." def setValueToString( self, valueString ): "Set the float to the string." try: self.value = float( valueString ) except: print('Oops, can not read float' + self.name + ' ' + valueString ) class FloatSpin( FloatSetting ): "A class to display, read & write an float in a spin box." def addToMenuFrameable( self, repositoryMenu ): "Add this to the frameable repository menu." titleFromName = getTitleFromName( self.name ) helpWindowMenu = Tkinter.Menu( repositoryMenu, tearoff = 0 ) repositoryMenu.add_cascade( label = titleFromName, menu = helpWindowMenu, underline = 0 ) if self.name in self.repository.frameList.value: helpWindowMenu.add_command( label = 'Remove from Window', command = self.removeFromWindow ) else: helpWindowMenu.add_command( label = 'Add to Window', command = self.addToWindow ) helpWindowMenu.add_separator() changeString = ' by %s' % self.increment helpWindowMenu.add_command( label = 'Increase' + changeString, command = self.increase ) helpWindowMenu.add_command( label = 'Decrease' + changeString, command = self.decrease ) helpWindowMenu.add_separator() helpWindowMenu.add_command( label = 'Help', command = HelpPage().getOpenFromDocumentationSubName( self.repository.fileNameHelp + '#' + titleFromName ) ) def bindEntry(self): "Bind the entry to the update function." self.entry.bind('', self.entryUpdated ) self.setColor() def createEntry( self, root ): "Create the entry." self.entry = Tkinter.Spinbox( root, command = self.setColorToDisplay, from_ = self.from_, increment = self.increment, to = self.to ) def decrease(self): "Decrease the value then set the state and color to the value." self.value -= self.increment self.setStateUpdateColor() def entryUpdated(self, event=None): "Create the entry." self.setColorToDisplay() if self.updateFunction is not None: self.updateFunction(event) def getFromValue(self, from_, name, repository, to, value): "Initialize." self.backgroundColor = None self.from_ = from_ self.minimumWidth = min(value - from_, to - value) rank = euclidean.getRank(0.05 * (to - from_)) self.increment = euclidean.getIncrementFromRank(rank) self.to = to return self.getFromValueOnlyAddToRepository(name, repository, value) def increase(self): "Increase the value then set the state and color to the value." self.value += self.increment self.setStateUpdateColor() def setColor(self, event=None): "Set the color to the value, yellow if it is lower than the default and blue if it is higher." setSpinColor(self) def setColorToDisplay(self, event=None): "Set the color to the value, yellow if it is lower than the default and blue if it is higher." self.setToDisplay() self.setColor() def setStateToValue(self): "Set the entry to the value." setEntryText( self.entry, self.value ) self.setColor() def setStateUpdateColor(self): "Set the state to the value, call the update function, then set the color." self.setStateToValue() if self.updateFunction is not None: self.updateFunction() class FloatSpinNotOnMenu( FloatSpin ): "A class to display, read & write an float in a spin box, which is not to be added to a menu." def getFromValueOnlyAddToRepository( self, name, repository, value ): "Initialize." repository.displayEntities.append(self) repository.preferences.append(self) return self.getFromValueOnly( name, repository, value ) class FloatSpinUpdate( FloatSpin ): "A class to display, read, update & write an float in a spin box." def createEntry( self, root ): "Create the entry." self.entry = Tkinter.Spinbox( root, command = self.entryUpdated, from_ = self.from_, increment = self.increment, to = self.to ) class FrameList: "A class to list the frames." def addToList(self, word): "Add the word to the sorted list." self.value.append(word) self.value.sort() self.repository.window.redisplayWindowUpdate() def getFromValue( self, name, repository, value ): "Initialize." repository.preferences.append(self) self.name = name self.repository = repository self.value = value return self def removeFromList(self, word): "Remove the word from the sorted list." self.value.remove(word) self.value.sort() self.repository.window.redisplayWindowUpdate() def setToDisplay(self): "Do nothing because frame list does not have a display." pass def setValueToSplitLine( self, lineIndex, lines, splitLine ): "Set the value to the second and later words of a split line." self.value = splitLine[1 :] def updateSaveListeners(self): "Update save listeners if any." pass def writeToRepositoryWriter( self, repositoryWriter ): "Write tab separated name and list to the repository writer." writeValueListToRepositoryWriter( repositoryWriter, self ) class GridHorizontal: "A class to place elements horizontally on a grid." def __init__( self, column, row ): "Initialize the column and row." self.column = column self.columnStart = column self.row = row def getCopy(self): "Get a copy." copy = GridHorizontal( self.column, self.row ) copy.columnStart = self.columnStart return copy def increment(self): "Increment the position horizontally." self.column += 1 class GridVertical: "A class to place elements vertically on a grid." def __init__( self, column, row ): "Initialize the column and row." self.column = column self.columnOffset = column self.columnStart = column self.row = row self.rowStart = row def execute(self): "The execute button was clicked." for executable in self.executables: executable.execute() saveAll() self.repository.execute() def getCopy(self): "Get a copy." copy = GridVertical( self.column, self.row ) copy.columnOffset = self.columnOffset copy.columnStart = self.columnStart copy.rowStart = self.rowStart return copy def increment(self): "Increment the position vertically." self.column = self.columnStart self.columnOffset = self.columnStart self.row += 1 def incrementGivenNumberOfColumns( self, numberOfColumns ): "Increment the position vertically and offset it horizontally by the given number of columns." self.column = self.columnOffset if self.columnOffset == self.columnStart: self.columnOffset = self.columnStart + 1 self.row += 1 return if self.columnOffset < self.columnStart + numberOfColumns - 1: self.columnOffset += 1 return self.columnOffset = self.columnStart def setExecutablesRepository( self, repository ): "Set the executables to an empty list and set the repository." self.executables = [] self.repository = repository class HelpPage: "A class to open a help page." def __init__(self): "Initialize column." self.column = 3 def addToDialog( self, gridPosition ): "Add this to the dialog." capitalizedName = getEachWordCapitalized( self.name ) self.displayButton = Tkinter.Button( gridPosition.master, activebackground = 'black', activeforeground = 'white', command = self.openPage, text = capitalizedName ) if len( capitalizedName ) < 12: self.displayButton['width'] = 10 self.displayButton.grid( row = gridPosition.row, column = self.column, columnspan = 2 ) def addToMenu( self, repositoryMenu ): "Add this to the repository menu." repositoryMenu.add_command( label = getTitleFromName( self.name ), command = self.openPage ) def addToMenuFrameable( self, repositoryMenu ): "Add this to the frameable repository menu." self.addToMenu( repositoryMenu ) def getFromNameAfterHTTP( self, afterHTTP, name, repository ): "Initialize." self.setToNameRepository( name, repository ) self.hypertextAddress = 'http://' + afterHTTP return self def getFromNameAfterWWW( self, afterWWW, name, repository ): "Initialize." self.setToNameRepository( name, repository ) self.hypertextAddress = 'http://www.' + afterWWW return self def getFromNameSubName( self, name, repository, subName=''): "Initialize." self.setToNameRepository( name, repository ) self.hypertextAddress = archive.getDocumentationPath( subName ) return self def getOpenFromAbsolute( self, hypertextAddress ): "Get the open help page function from the hypertext address." self.hypertextAddress = hypertextAddress return self.openPage def getOpenFromAfterHTTP( self, afterHTTP ): "Get the open help page function from the part of the address after the HTTP." self.hypertextAddress = 'http://' + afterHTTP return self.openPage def getOpenFromAfterWWW( self, afterWWW ): "Get the open help page function from the afterWWW of the address after the www." self.hypertextAddress = 'http://www.' + afterWWW return self.openPage def getOpenFromDocumentationSubName( self, subName=''): "Get the open help page function from the afterWWW of the address after the www." self.hypertextAddress = archive.getDocumentationPath( subName ) return self.openPage def openPage(self, event=None): "Open the browser to the hypertext address." openWebPage( self.hypertextAddress ) def setToNameRepository( self, name, repository ): "Set to the name and repository." self.name = name self.repository = repository repository.displayEntities.append(self) repository.menuEntities.append(self) class HelpPageRepository: "A class to open a repository help page." def __init__( self, repository ): "Add this to the dialog." self.repository = repository def openPage(self, event=None): "Open the browser to the repository help page." if self.repository.openWikiManualHelpPage is None: self.repository.openLocalHelpPage() return from skeinforge_application.skeinforge_utilities import skeinforge_help helpRepository = getReadRepository( skeinforge_help.HelpRepository() ) if helpRepository.wikiManualPrimary.value: self.repository.openWikiManualHelpPage() return self.repository.openLocalHelpPage() class IntSetting( FloatSetting ): "A class to display, read & write an int." def setValueToString( self, valueString ): "Set the integer to the string." setIntegerValueToString( self, valueString ) class IntSpin(FloatSpin): "A class to display, read & write an int in a spin box." def getFromValue(self, from_, name, repository, to, value): "Initialize." self.backgroundColor = None self.from_ = from_ rank = euclidean.getRank(0.05 * (to - from_)) self.increment = max(1, int(euclidean.getIncrementFromRank(rank))) self.minimumWidth = min(value - from_, to - value) self.to = to return self.getFromValueOnlyAddToRepository(name, repository, value) def getSingleIncrementFromValue( self, from_, name, repository, to, value ): "Initialize." self.backgroundColor = None self.from_ = from_ self.increment = 1 self.minimumWidth = min(value - from_, to - value) self.to = to return self.getFromValueOnlyAddToRepository( name, repository, value ) def setValueToString( self, valueString ): "Set the integer to the string." setIntegerValueToString( self, valueString ) class IntSpinNotOnMenu( IntSpin ): "A class to display, read & write an integer in a spin box, which is not to be added to a menu." def getFromValueOnlyAddToRepository( self, name, repository, value ): "Initialize." repository.displayEntities.append(self) repository.preferences.append(self) return self.getFromValueOnly( name, repository, value ) class IntSpinUpdate( IntSpin ): "A class to display, read, update & write an int in a spin box." def createEntry( self, root ): "Create the entry." self.entry = Tkinter.Spinbox( root, command = self.entryUpdated, from_ = self.from_, increment = self.increment, to = self.to ) class LabelDisplay: "A class to add a label." def addToDialog( self, gridPosition ): "Add this to the dialog." gridPosition.increment() self.label = Tkinter.Label( gridPosition.master, text = self.name ) self.label.grid( row = gridPosition.row, column = 0, columnspan = self.columnspan, sticky = Tkinter.W ) LabelHelp( self.repository.fileNameHelp, gridPosition.master, self.name, self.label ) def getFromName( self, name, repository ): "Initialize." self.columnspan = 3 self.name = name self.repository = repository repository.displayEntities.append(self) return self class LabelHelp: "A class to add help to a widget." def __init__( self, fileNameHelp, master, name, widget ): "Add menu to the widget." if len( name ) < 1: return self.popupMenu = Tkinter.Menu( master, tearoff = 0 ) titleFromName = getTitleFromName( name.replace('- ', '').replace(' -', '') ) self.popupMenu.add_command( label = 'Help', command = HelpPage().getOpenFromDocumentationSubName( fileNameHelp + '#' + titleFromName ) ) widget.bind('', self.unpostPopupMenu ) widget.bind('', self.unpostPopupMenu ) widget.bind('', self.displayPopupMenu ) def displayPopupMenu(self, event=None): 'Display the popup menu when the button is right clicked.' try: self.popupMenu.tk_popup( event.x_root + 30, event.y_root, 0 ) finally: self.popupMenu.grab_release() def unpostPopupMenu(self, event=None): 'Unpost the popup menu.' self.popupMenu.unpost() class LabelSeparator: "A class to add a label and menu separator." def addToDialog( self, gridPosition ): "Add this to the dialog." gridPosition.increment() self.label = Tkinter.Label( gridPosition.master, text='') self.label.grid( row = gridPosition.row, column = 0, columnspan = 3, sticky = Tkinter.W ) def addToMenu( self, repositoryMenu ): "Add this to the repository menu." repositoryMenu.add_separator() def addToMenuFrameable( self, repositoryMenu ): "Add this to the frameable repository menu." self.addToMenu( repositoryMenu ) def getFromRepository( self, repository ): "Initialize." self.name = '' self.repository = repository repository.displayEntities.append(self) repository.menuEntities.append(self) return self class LatentStringVar: "A class to provide a StringVar when needed." def __init__(self): "Set the string var." self.stringVar = None def getString(self): "Get the string." return self.getVar().get() def getVar(self): "Get the string var." if self.stringVar is None: self.stringVar = Tkinter.StringVar() return self.stringVar def setString(self, word): "Set the string." self.getVar().set(word) class LayerCount: 'A class to handle the layerIndex.' def __init__(self): 'Initialize.' self.layerIndex = -1 def __repr__(self): 'Get the string representation of this LayerCount.' return str(self.layerIndex) def printProgressIncrement(self, procedureName): 'Print progress then increment layerIndex.' self.layerIndex += 1 printProgress(self.layerIndex, procedureName) class MenuButtonDisplay: "A class to add a menu button." def addRadiosToDialog( self, gridPosition ): "Add the menu radios to the dialog." for menuRadio in self.menuRadios: menuRadio.addToDialog( gridPosition ) def addToMenu( self, repositoryMenu ): "Add this to the repository menu." if len( self.menuRadios ) < 1: print('The MenuButtonDisplay in settings should have menu items.') print( self.name ) return self.menu = Tkinter.Menu( repositoryMenu, tearoff = 0 ) repositoryMenu.add_cascade( label = getTitleFromName( self.name ), menu = self.menu ) self.setRadioVarToName( self.menuRadios[0].name ) def addToMenuFrameable( self, repositoryMenu ): "Add this to the frameable repository menu." titleFromName = getTitleFromName( self.name ) self.addToMenu( repositoryMenu ) self.menu.add_command( label = 'Help', command = HelpPage().getOpenFromDocumentationSubName( self.repository.fileNameHelp + '#' + titleFromName ) ) self.menu.add_separator() def getFromName( self, name, repository ): "Initialize." self.columnspan = 2 self.menuRadios = [] self.name = name self.radioVar = None self.repository = repository repository.menuEntities.append(self) return self def removeMenus(self): "Remove all menus." deleteMenuItems( self.menu ) self.menuRadios = [] def setRadioVarToName(self, name): "Get the menu button." self.optionList = [name] self.radioVar = Tkinter.StringVar() self.radioVar.set( self.optionList[0] ) def setToNameAddToDialog( self, name, gridPosition ): "Get the menu button." if self.radioVar is not None: return gridPosition.increment() self.setRadioVarToName( name ) self.label = Tkinter.Label( gridPosition.master, text = self.name ) self.label.grid( row = gridPosition.row, column = 0, columnspan = 3, sticky = Tkinter.W ) self.menuButton = Tkinter.OptionMenu( gridPosition.master, self.radioVar, self.optionList ) self.menuButton.grid( row = gridPosition.row, column = 3, columnspan = self.columnspan, sticky = Tkinter.W ) self.menuButton.menu = Tkinter.Menu( self.menuButton, tearoff = 0 ) self.menu = self.menuButton.menu self.menuButton['menu'] = self.menu LabelHelp( self.repository.fileNameHelp, gridPosition.master, self.name, self.label ) class MenuRadio( BooleanSetting ): "A class to display, read & write a boolean with associated menu radio button." def addToDialog( self, gridPosition ): "Add this to the dialog." self.menuButtonDisplay.setToNameAddToDialog( self.name, gridPosition ) self.addToSubmenu() def addToMenu( self, repositoryMenu ): "Add this to the submenu set by MenuButtonDisplay, the repository menu is ignored" self.addToSubmenu() def addToMenuFrameable( self, repositoryMenu ): "Add this to the frameable repository menu." self.addToMenu( repositoryMenu ) def addToSubmenu(self): "Add this to the submenu." self.activate = False menu = self.menuButtonDisplay.menu menu.add_radiobutton( label = self.name, command = self.clickRadio, value = self.name, variable = self.menuButtonDisplay.radioVar ) self.menuLength = menu.index( Tkinter.END ) if self.value: self.menuButtonDisplay.radioVar.set( self.name ) self.invoke() self.activate = True def clickRadio(self): "Workaround for Tkinter bug, invoke and set the value when clicked." if not self.activate: return self.menuButtonDisplay.radioVar.set( self.name ) if self.updateFunction is not None: self.updateFunction() def getFromMenuButtonDisplay( self, menuButtonDisplay, name, repository, value ): "Initialize." self.getFromValueOnlyAddToRepository( name, repository, value ) self.menuButtonDisplay = menuButtonDisplay self.menuButtonDisplay.menuRadios.append(self) return self def invoke(self): "Workaround for Tkinter bug, invoke to set the value when changed." self.menuButtonDisplay.menu.invoke( self.menuLength ) def setStateToValue(self): "Set the checkbutton to the boolean." try: if self.value: self.invoke() except: pass def setToDisplay(self): "Set the boolean to the checkbutton." if self.menuButtonDisplay.radioVar is not None: self.value = ( self.menuButtonDisplay.radioVar.get() == self.name ) class PluginFrame: "A class to display the plugins in a frame." def __init__(self): "Initialize." self.gridTable = {} self.latentStringVar = LatentStringVar() self.oldLatentString = '' def addToDialog( self, gridPosition ): "Add this to the dialog." gridPosition.increment() self.gridPosition = gridPosition.getCopy() self.gridPosition.master = gridPosition.master self.createFrame( gridPosition ) def createFrame( self, gridPosition ): "Create the frame." gridVertical = GridVertical( 0, 0 ) gridVertical.master = Tkinter.LabelFrame( gridPosition.master, borderwidth = 3, relief = 'raised') gridVertical.master.grid( row = gridPosition.row, column = gridPosition.column, columnspan = 12, sticky = Tkinter.E + Tkinter.W + Tkinter.N + Tkinter.S ) gridPosition.master.grid_rowconfigure( gridPosition.row, weight = 1 ) gridPosition.master.grid_columnconfigure( gridPosition.column + 11, weight = 1 ) if self.latentStringVar.getString() == '': self.defaultRadioButton.setSelect() self.gridTable[ self.latentStringVar.getString() ] = gridVertical path = os.path.join( self.directoryPath, self.latentStringVar.getString() ) pluginModule = archive.getModuleWithPath(path) if pluginModule is None: print('this should never happen, pluginModule in addToDialog in PluginFrame in settings is None') print(path) return gridVertical.repository = getReadRepository( pluginModule.getNewRepository() ) gridVertical.frameGridVertical = GridVertical( 0, 0 ) gridVertical.frameGridVertical.setExecutablesRepository( gridVertical.repository ) executeTitle = gridVertical.repository.executeTitle if executeTitle is not None: executeButton = Tkinter.Button( gridVertical.master, activebackground = 'black', activeforeground = 'blue', text = executeTitle, command = gridVertical.frameGridVertical.execute ) executeButton.grid( row = gridVertical.row, column = gridVertical.column, sticky = Tkinter.W ) gridVertical.column += 1 self.helpButton = Tkinter.Button( gridVertical.master, activebackground = 'black', activeforeground = 'white', text = "?", command = HelpPageRepository( gridVertical.repository ).openPage ) self.helpButton.grid( row = gridVertical.row, column = gridVertical.column, sticky = Tkinter.W ) addEmptyRow( gridVertical ) gridVertical.increment() from fabmetheus_utilities.hidden_scrollbar import HiddenScrollbar gridVertical.xScrollbar = HiddenScrollbar( gridVertical.master, orient = Tkinter.HORIZONTAL ) gridVertical.xScrollbar.grid( row = gridVertical.row + 1, column = gridVertical.column, columnspan = 11, sticky = Tkinter.E + Tkinter.W ) gridVertical.yScrollbar = HiddenScrollbar( gridVertical.master ) gridVertical.yScrollbar.grid( row = gridVertical.row, column = gridVertical.column + 12, sticky = Tkinter.N + Tkinter.S ) canvasHeight = min( 1000, gridPosition.master.winfo_screenheight() - 540 ) - 6 - int( gridVertical.xScrollbar['width'] ) canvasWidth = min( 650, gridPosition.master.winfo_screenwidth() - 100 ) - 6 - int( gridVertical.yScrollbar['width'] ) gridVertical.canvas = Tkinter.Canvas( gridVertical.master, height = canvasHeight, highlightthickness = 0, width = canvasWidth ) gridVertical.frameGridVertical.master = Tkinter.Frame( gridVertical.canvas ) for setting in gridVertical.repository.displayEntities: setting.addToDialog( gridVertical.frameGridVertical ) addEmptyRow( gridVertical.frameGridVertical ) gridVertical.frameGridVertical.master.update_idletasks() gridVertical.xScrollbar.config( command = gridVertical.canvas.xview ) gridVertical.canvas['xscrollcommand'] = gridVertical.xScrollbar.set gridVertical.yScrollbar.config( command = gridVertical.canvas.yview ) gridVertical.canvas['yscrollcommand'] = gridVertical.yScrollbar.set gridVertical.canvas.create_window( 0, 0, anchor = Tkinter.NW, window = gridVertical.frameGridVertical.master ) gridVertical.canvas['scrollregion'] = gridVertical.frameGridVertical.master.grid_bbox() gridVertical.canvas.grid( row = gridVertical.row, column = gridVertical.column, columnspan = 12, sticky = Tkinter.E + Tkinter.W + Tkinter.N + Tkinter.S ) gridVertical.master.grid_rowconfigure( gridVertical.row, weight = 1 ) gridVertical.master.grid_columnconfigure( gridVertical.column + 11, weight = 1 ) gridVertical.frameGridVertical.master.lift() self.oldLatentString = self.latentStringVar.getString() def focusSetMaster( self, gridPosition ): "Set the focus to the plugin master." gridPosition.frameGridVertical.master.focus_set() def getFromPath( self, defaultRadioButton, directoryPath, repository ): "Initialize." self.defaultRadioButton = defaultRadioButton self.directoryPath = directoryPath self.name = 'PluginFrame' self.repository = repository repository.displayEntities.append(self) repository.preferences.append(self) return self def setStateToValue(self): "Set the state of all the plugins to the value." for gridTableValue in self.gridTable.values(): cancelRepository( gridTableValue.repository ) def setToDisplay(self): "Set the plugins to the display." pass def update(self): "Update the frame." if len(self.gridTable) < 1: return if self.oldLatentString == self.latentStringVar.getString(): return self.oldLatentString = self.latentStringVar.getString() self.repository.preferences.remove(self) for setting in self.repository.preferences: setting.setToDisplay() writeSettingsPrintMessage(self.repository) self.repository.preferences.append(self) if self.latentStringVar.getString() in self.gridTable: gridPosition = self.gridTable[self.latentStringVar.getString()] gridPosition.master.lift() self.focusSetMaster(gridPosition) return self.createFrame(self.gridPosition) def updateSaveListeners(self): "Update save listeners if any." gridTableKeys = self.gridTable.keys() gridTableKeys.sort() for gridTableKey in gridTableKeys: saveRepository( self.gridTable[ gridTableKey ].repository ) def writeToRepositoryWriter( self, repositoryWriter ): "Write tab separated name and value to the repository writer." pass class PluginGroupFrame( PluginFrame ): "A class to display the plugin groups in a frame." def createFrame( self, gridPosition ): "Create the frame." gridVertical = GridVertical( 0, 0 ) gridVertical.master = Tkinter.LabelFrame( gridPosition.master, borderwidth = 3, relief = 'raised') gridVertical.master.grid( row = gridPosition.row, column = gridPosition.column, columnspan = 11, sticky = Tkinter.E + Tkinter.W + Tkinter.N + Tkinter.S ) gridPosition.master.grid_rowconfigure( gridPosition.row, weight = 1 ) gridPosition.master.grid_columnconfigure( gridPosition.column + 10, weight = 1 ) if self.latentStringVar.getString() == '': self.defaultRadioButton.setSelect() self.gridTable[ self.latentStringVar.getString() ] = gridVertical path = os.path.join( self.directoryPath, self.latentStringVar.getString() ) pluginModule = archive.getModuleWithPath(path) if pluginModule is None: print('this should never happen, pluginModule in addToDialog in PluginFrame in settings is None') print(path) return gridVertical.repository = getReadRepository( pluginModule.getNewRepository() ) gridVertical.setExecutablesRepository( gridVertical.repository ) executeTitle = gridVertical.repository.executeTitle if executeTitle is not None: executeButton = Tkinter.Button( gridVertical.master, activebackground = 'black', activeforeground = 'blue', text = executeTitle, command = gridVertical.execute ) executeButton.grid( row = gridVertical.row, column = gridVertical.column, sticky = Tkinter.W ) gridVertical.column += 1 self.helpButton = Tkinter.Button( gridVertical.master, activebackground = 'black', activeforeground = 'white', text = "?", command = HelpPageRepository( gridVertical.repository ).openPage ) self.helpButton.grid( row = gridVertical.row, column = gridVertical.column, sticky = Tkinter.W ) addEmptyRow( gridVertical ) gridVertical.increment() for setting in gridVertical.repository.displayEntities: setting.addToDialog( gridVertical ) gridVertical.master.update_idletasks() gridVertical.master.lift() self.oldLatentString = self.latentStringVar.getString() def focusSetMaster( self, gridPosition ): "Set the focus to the plugin master." gridPosition.master.focus_set() class Radio( BooleanSetting ): "A class to display, read & write a boolean with associated radio button." def addToDialog( self, gridPosition ): "Add this to the dialog." gridPosition.increment() self.createRadioButton( gridPosition ) self.radiobutton.grid( row = gridPosition.row, column = 0, columnspan = 3, sticky = Tkinter.W ) self.setStateToValue() def clickRadio(self): "Workaround for Tkinter bug, set the value." self.latentStringVar.setString( self.radiobutton['value'] ) if self.updateFunction is not None: self.updateFunction() def createRadioButton( self, gridPosition ): "Create the radio button." self.radiobutton = Tkinter.Radiobutton( gridPosition.master, command = self.clickRadio, text = self.name, value = self.name, variable = self.latentStringVar.getVar() ) LabelHelp( self.repository.fileNameHelp, gridPosition.master, self.name, self.radiobutton ) def getFromRadio( self, latentStringVar, name, repository, value ): "Initialize." self.getFromValueOnly( name, repository, value ) self.latentStringVar = latentStringVar repository.displayEntities.append(self) repository.preferences.append(self) #when addToMenu is added to this entity, the line below should be uncommented # repository.menuEntities.append(self) return self def setSelect(self): "Set the int var and select the radio button." oldLatentStringValue = self.latentStringVar.getString() self.latentStringVar.setString( self.radiobutton['value'] ) self.radiobutton.select() if oldLatentStringValue == '': return False return oldLatentStringValue != self.latentStringVar.getString() def setStateToValue(self): "Set the checkbutton to the boolean." if self.value: if self.setSelect(): if self.updateFunction is not None: self.updateFunction() def setToDisplay(self): "Set the boolean to the checkbutton." self.value = ( self.latentStringVar.getString() == self.radiobutton['value'] ) class RadioCapitalized( Radio ): "A class to display, read & write a boolean with associated radio button." def createRadioButton( self, gridPosition ): "Create the radio button." capitalizedName = getEachWordCapitalized( self.name ) self.radiobutton = Tkinter.Radiobutton( gridPosition.master, command = self.clickRadio, text = capitalizedName, value = self.name, variable = self.latentStringVar.getVar() ) class RadioCapitalizedButton( Radio ): "A class to display, read & write a boolean with associated radio button." def createRadioButton( self, gridPosition ): "Create the radio button." capitalizedName = getEachWordCapitalized( self.name ) self.radiobutton = Tkinter.Radiobutton( gridPosition.master, command = self.clickRadio, text = capitalizedName, value = self.name, variable = self.latentStringVar.getVar() ) self.displayButton = Tkinter.Button( gridPosition.master, activebackground = 'black', activeforeground = 'white', text = capitalizedName, command = self.displayDialog ) self.displayButton.grid( row = gridPosition.row, column = 3, columnspan = 2 ) def displayDialog(self): "Display function." ToolDialog().getFromPath( self.path ).display() self.setSelect() def getFromPath( self, latentStringVar, name, path, repository, value ): "Initialize." self.getFromRadio( latentStringVar, name, repository, value ) self.path = path return self class RadioPlugin( RadioCapitalized ): "A class to display, read & write a boolean with associated radio button." def addToDialog( self, gridPosition ): "Add this to the dialog." self.createRadioButton( gridPosition ) self.radiobutton['activeforeground'] = 'magenta' self.radiobutton['selectcolor'] = 'white' self.radiobutton['borderwidth'] = 3 self.radiobutton['indicatoron'] = 0 setButtonFontWeightString( self.radiobutton, self.important ) self.incrementGridPosition( gridPosition ) self.setStateToValue() def getFromRadio( self, important, latentStringVar, name, repository, value ): "Initialize." self.important = important return RadioCapitalized.getFromRadio( self, latentStringVar, name, repository, value ) def incrementGridPosition( self, gridPosition ): "Increment the grid position." gridPosition.incrementGivenNumberOfColumns( 10 ) self.radiobutton.grid( row = gridPosition.row, column = gridPosition.column, sticky = Tkinter.W ) class TextSetting( StringSetting ): "A class to display, read & write a text." def __init__(self): "Set the update function to none." self.tokenConversions = [ TokenConversion(), TokenConversion('carriageReturn', '\r'), TokenConversion('doubleQuote', '"'), TokenConversion('newline', '\n'), TokenConversion('semicolon', ';'), TokenConversion('singleQuote', "'" ), TokenConversion('tab', '\t') ] self.updateFunction = None def addToDialog( self, gridPosition ): "Add this to the dialog." gridPosition.increment() self.label = Tkinter.Label( gridPosition.master, text = self.name ) self.label.grid( row = gridPosition.row, column = 0, columnspan = 3, sticky = Tkinter.W ) gridPosition.increment() self.entry = Tkinter.Text( gridPosition.master ) self.setStateToValue() self.entry.grid( row = gridPosition.row, column = 0, columnspan = 5, sticky = Tkinter.W ) LabelHelp( self.repository.fileNameHelp, gridPosition.master, self.name, self.label ) def getFromValue( self, name, repository, value ): "Initialize." self.getFromValueOnly( name, repository, value ) repository.displayEntities.append(self) repository.preferences.append(self) return self def setStateToValue(self): "Set the entry to the value." try: self.entry.delete( 1.0, Tkinter.END ) self.entry.insert( Tkinter.INSERT, self.value ) except: pass def setToDisplay(self): "Set the string to the entry field." valueString = self.entry.get( 1.0, Tkinter.END ) self.setValueToString( valueString ) def setValueToSplitLine( self, lineIndex, lines, splitLine ): "Set the value to the second word of a split line." replacedValue = splitLine[1] for tokenConversion in reversed( self.tokenConversions ): replacedValue = tokenConversion.getTokenizedString( replacedValue ) self.setValueToString( replacedValue ) def writeToRepositoryWriter( self, repositoryWriter ): "Write tab separated name and value to the repository writer." replacedValue = self.value for tokenConversion in self.tokenConversions: replacedValue = tokenConversion.getNamedString( replacedValue ) repositoryWriter.write('%s%s%s\n' % ( self.name, globalSpreadsheetSeparator, replacedValue ) ) class TokenConversion: "A class to convert tokens in a string." def __init__( self, name = 'replaceToken', token = '___replaced___'): "Set the name and token." self.replacedName = '___replaced___' + name self.token = token def getNamedString( self, text ): "Get a string with the tokens changed to names." return text.replace( self.token, self.replacedName ) def getTokenizedString( self, text ): "Get a string with the names changed to tokens." return text.replace( self.replacedName, self.token ) class ToolDialog: "A class to display the tool repository dialog." def addPluginToMenu( self, menu, path ): "Add the display command to the menu." name = os.path.basename(path) self.path = path menu.add_command( label = getEachWordCapitalized( name ) + '...', command = self.display ) def display(self): "Display the tool repository dialog." global globalRepositoryDialogListTable for repositoryDialog in globalRepositoryDialogListTable: if getPathInFabmetheusFromFileNameHelp( repositoryDialog.repository.fileNameHelp ) == self.path: liftRepositoryDialogs( globalRepositoryDialogListTable[ repositoryDialog ] ) return self.repositoryDialog = getDisplayedDialogFromPath( self.path ) def getFromPath( self, path ): "Initialize and return display function." self.path = path return self class WindowPosition( StringSetting ): "A class to display, read & write a window position." def addToDialog( self, gridPosition ): "Set the root to later get the geometry." self.root = gridPosition.master self.setToDisplay() def getFromValue( self, repository, value ): "Initialize." self.getFromValueOnly('WindowPosition', repository, value ) repository.displayEntities.append(self) repository.preferences.append(self) return self def setToDisplay(self): "Set the string to the window position." try: geometryString = self.root.geometry() except: return if geometryString == '1x1+0+0': return firstPlusIndexPlusOne = geometryString.find('+') + 1 self.value = geometryString[ firstPlusIndexPlusOne : ] def setWindowPosition(self): "Set the window position." movedGeometryString = '%sx%s+%s' % ( self.root.winfo_reqwidth(), self.root.winfo_reqheight(), self.value ) self.root.geometry( movedGeometryString ) class RepositoryDialog: def __init__( self, repository, root ): "Add entities to the dialog." self.isFirst = ( len( globalRepositoryDialogListTable.keys() ) == 0 ) self.closeListener = CloseListener(self) self.repository = repository self.gridPosition = GridVertical( 0, - 1 ) self.gridPosition.setExecutablesRepository(repository) self.gridPosition.master = root self.root = root self.openDialogListeners = [] repository.repositoryDialog = self root.withdraw() title = repository.title if repository.fileNameInput is not None: title = os.path.basename( repository.fileNameInput.value ) + ' - ' + title root.title( title ) fileHelpMenuBar = FileHelpMenuBar( root ) fileHelpMenuBar.completeMenu( self.close, repository, self.save, self ) for setting in repository.displayEntities: setting.addToDialog( self.gridPosition ) if self.gridPosition.row < 20: addEmptyRow( self.gridPosition ) self.addButtons( repository, root ) root.update_idletasks() self.setWindowPositionDeiconify() root.deiconify() for openDialogListener in self.openDialogListeners: openDialogListener.openDialog() def __repr__(self): "Get the string representation of this RepositoryDialog." return self.repository.title def addButtons( self, repository, root ): "Add buttons to the dialog." columnIndex = 0 self.gridPosition.increment() saveCommand = self.save saveText = 'Save' if self.isFirst: saveCommand = saveAll saveText = 'Save All' if repository.executeTitle is not None: executeButton = Tkinter.Button( root, activebackground = 'black', activeforeground = 'blue', text = repository.executeTitle, command = self.gridPosition.execute ) executeButton.grid( row = self.gridPosition.row, column = columnIndex, columnspan = 2, sticky = Tkinter.W ) columnIndex += 2 self.helpButton = Tkinter.Button( root, activebackground = 'black', activeforeground = 'white', text = "?", command = HelpPageRepository(self.repository).openPage ) self.helpButton.grid( row = self.gridPosition.row, column = columnIndex, sticky = Tkinter.W ) self.closeListener.listenToWidget( self.helpButton ) columnIndex += 6 cancelButton = Tkinter.Button( root, activebackground = 'black', activeforeground = 'orange', command = self.cancel, fg = 'orange', text = 'Cancel') cancelButton.grid( row = self.gridPosition.row, column = columnIndex ) columnIndex += 1 self.saveButton = Tkinter.Button( root, activebackground = 'black', activeforeground = 'darkgreen', command = saveCommand, fg = 'darkgreen', text = saveText ) self.saveButton.grid( row = self.gridPosition.row, column = columnIndex ) def cancel(self, event=None): "Set all entities to their saved state." cancelRepository(self.repository) def close(self, event=None): "The dialog was closed." try: self.root.destroy() except: pass def save(self, event=None): "Set the entities to the dialog then write them." saveRepository(self.repository) def setWindowPositionDeiconify(self): "Set the window position if that setting exists." for setting in self.repository.preferences: if setting.name == 'WindowPosition': setting.setWindowPosition() return sfact-2011.12.18/fabmetheus_utilities/svg_reader.py000066400000000000000000001135161167321211700221300ustar00rootroot00000000000000""" Svg reader. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.xml_simple_reader import DocumentNode from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from fabmetheus_utilities import svg_writer import math import os import sys import traceback __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalNumberOfCornerPoints = 11 globalNumberOfBezierPoints = globalNumberOfCornerPoints + globalNumberOfCornerPoints globalNumberOfCirclePoints = 4 * globalNumberOfCornerPoints def addFunctionsToDictionary( dictionary, functions, prefix ): "Add functions to dictionary." for function in functions: dictionary[ function.__name__[ len( prefix ) : ] ] = function def getArcComplexes(begin, end, largeArcFlag, radius, sweepFlag, xAxisRotation): 'Get the arc complexes, procedure at http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes' if begin == end: print('Warning, begin equals end in getArcComplexes in svgReader') print(begin) print(end) return [] if radius.imag < 0.0: print('Warning, radius.imag is less than zero in getArcComplexes in svgReader') print(radius) radius = complex(radius.real, abs(radius.imag)) if radius.real < 0.0: print('Warning, radius.real is less than zero in getArcComplexes in svgReader') print(radius) radius = complex(abs(radius.real), radius.imag) if radius.imag <= 0.0: print('Warning, radius.imag is too small for getArcComplexes in svgReader') print(radius) return [end] if radius.real <= 0.0: print('Warning, radius.real is too small for getArcComplexes in svgReader') print(radius) return [end] xAxisRotationComplex = euclidean.getWiddershinsUnitPolar(xAxisRotation) reverseXAxisRotationComplex = complex(xAxisRotationComplex.real, -xAxisRotationComplex.imag) beginRotated = begin * reverseXAxisRotationComplex endRotated = end * reverseXAxisRotationComplex beginTransformed = complex(beginRotated.real / radius.real, beginRotated.imag / radius.imag) endTransformed = complex(endRotated.real / radius.real, endRotated.imag / radius.imag) midpointTransformed = 0.5 * (beginTransformed + endTransformed) midMinusBeginTransformed = midpointTransformed - beginTransformed midMinusBeginTransformedLength = abs(midMinusBeginTransformed) if midMinusBeginTransformedLength > 1.0: print('The ellipse radius is too small for getArcComplexes in svgReader.') print('So the ellipse will be scaled to fit, according to the formulas in "Step 3: Ensure radii are large enough" of:') print('http://www.w3.org/TR/SVG/implnote.html#ArcCorrectionOutOfRangeRadii') print('') radius *= midMinusBeginTransformedLength beginTransformed /= midMinusBeginTransformedLength endTransformed /= midMinusBeginTransformedLength midpointTransformed /= midMinusBeginTransformedLength midMinusBeginTransformed /= midMinusBeginTransformedLength midMinusBeginTransformedLength = 1.0 midWiddershinsTransformed = complex(-midMinusBeginTransformed.imag, midMinusBeginTransformed.real) midWiddershinsLengthSquared = 1.0 - midMinusBeginTransformedLength * midMinusBeginTransformedLength if midWiddershinsLengthSquared < 0.0: midWiddershinsLengthSquared = 0.0 midWiddershinsLength = math.sqrt(midWiddershinsLengthSquared) midWiddershinsTransformed *= midWiddershinsLength / abs(midWiddershinsTransformed) centerTransformed = midpointTransformed if largeArcFlag == sweepFlag: centerTransformed -= midWiddershinsTransformed else: centerTransformed += midWiddershinsTransformed beginMinusCenterTransformed = beginTransformed - centerTransformed beginMinusCenterTransformedLength = abs(beginMinusCenterTransformed) if beginMinusCenterTransformedLength <= 0.0: return end beginAngle = math.atan2(beginMinusCenterTransformed.imag, beginMinusCenterTransformed.real) endMinusCenterTransformed = endTransformed - centerTransformed angleDifference = euclidean.getAngleDifferenceByComplex(endMinusCenterTransformed, beginMinusCenterTransformed) if sweepFlag: if angleDifference < 0.0: angleDifference += 2.0 * math.pi else: if angleDifference > 0.0: angleDifference -= 2.0 * math.pi global globalSideAngle sides = int(math.ceil(abs(angleDifference) / globalSideAngle)) sideAngle = angleDifference / float(sides) arcComplexes = [] center = complex(centerTransformed.real * radius.real, centerTransformed.imag * radius.imag) * xAxisRotationComplex for side in xrange(1, sides): unitPolar = euclidean.getWiddershinsUnitPolar(beginAngle + float(side) * sideAngle) circumferential = complex(unitPolar.real * radius.real, unitPolar.imag * radius.imag) * beginMinusCenterTransformedLength point = center + circumferential * xAxisRotationComplex arcComplexes.append(point) arcComplexes.append(end) return arcComplexes def getChainMatrixSVG(elementNode, matrixSVG): "Get chain matrixSVG by svgElement." matrixSVG = matrixSVG.getOtherTimesSelf(getMatrixSVG(elementNode).tricomplex) if elementNode.parentNode is not None: matrixSVG = getChainMatrixSVG(elementNode.parentNode, matrixSVG) return matrixSVG def getChainMatrixSVGIfNecessary(elementNode, yAxisPointingUpward): "Get chain matrixSVG by svgElement and yAxisPointingUpward." matrixSVG = MatrixSVG() if yAxisPointingUpward: return matrixSVG return getChainMatrixSVG(elementNode, matrixSVG) def getCubicPoint( along, begin, controlPoints, end ): 'Get the cubic point.' segmentBegin = getQuadraticPoint( along, begin, controlPoints[0], controlPoints[1] ) segmentEnd = getQuadraticPoint( along, controlPoints[0], controlPoints[1], end ) return ( 1.0 - along ) * segmentBegin + along * segmentEnd def getCubicPoints( begin, controlPoints, end, numberOfBezierPoints=globalNumberOfBezierPoints): 'Get the cubic points.' bezierPortion = 1.0 / float(numberOfBezierPoints) cubicPoints = [] for bezierIndex in xrange( 1, numberOfBezierPoints + 1 ): cubicPoints.append(getCubicPoint(bezierPortion * bezierIndex, begin, controlPoints, end)) return cubicPoints def getFontReader(fontFamily): 'Get the font reader for the fontFamily.' fontLower = fontFamily.lower().replace(' ', '_') global globalFontReaderDictionary if fontLower in globalFontReaderDictionary: return globalFontReaderDictionary[fontLower] global globalFontFileNames if globalFontFileNames is None: globalFontFileNames = archive.getFileNamesByFilePaths(archive.getFilePathsByDirectory(getFontsDirectoryPath())) if fontLower not in globalFontFileNames: print('Warning, the %s font was not found in the fabmetheus_utilities/fonts folder, so Gentium Basic Regular will be substituted.' % fontFamily) print('The available fonts are:') globalFontFileNames.sort() print(globalFontFileNames) print('') fontLower = 'gentium_basic_regular' fontReader = FontReader(fontLower) globalFontReaderDictionary[fontLower] = fontReader return fontReader def getFontsDirectoryPath(): "Get the fonts directory path." return archive.getFabmetheusUtilitiesPath('fonts') def getLabelString(dictionary): "Get the label string for the dictionary." for key in dictionary: labelIndex = key.find('label') if labelIndex >= 0: return dictionary[key] return '' def getMatrixSVG(elementNode): "Get matrixSVG by svgElement." matrixSVG = MatrixSVG() if 'transform' not in elementNode.attributes: return matrixSVG transformWords = [] for transformWord in elementNode.attributes['transform'].replace(')', '(').split('('): transformWordStrip = transformWord.strip() if transformWordStrip != '': # workaround for split(character) bug which leaves an extra empty element transformWords.append(transformWordStrip) global globalGetTricomplexDictionary getTricomplexDictionaryKeys = globalGetTricomplexDictionary.keys() for transformWordIndex, transformWord in enumerate(transformWords): if transformWord in getTricomplexDictionaryKeys: transformString = transformWords[transformWordIndex + 1].replace(',', ' ') matrixSVG = matrixSVG.getSelfTimesOther(globalGetTricomplexDictionary[ transformWord ](transformString.split())) return matrixSVG def getQuadraticPoint( along, begin, controlPoint, end ): 'Get the quadratic point.' oneMinusAlong = 1.0 - along segmentBegin = oneMinusAlong * begin + along * controlPoint segmentEnd = oneMinusAlong * controlPoint + along * end return oneMinusAlong * segmentBegin + along * segmentEnd def getQuadraticPoints(begin, controlPoint, end, numberOfBezierPoints=globalNumberOfBezierPoints): 'Get the quadratic points.' bezierPortion = 1.0 / float(numberOfBezierPoints) quadraticPoints = [] for bezierIndex in xrange(1, numberOfBezierPoints + 1): quadraticPoints.append(getQuadraticPoint(bezierPortion * bezierIndex, begin, controlPoint, end)) return quadraticPoints def getRightStripAlphabetPercent(word): "Get word with alphabet characters and the percent sign stripped from the right." word = word.strip() for characterIndex in xrange(len(word) - 1, -1, -1): character = word[characterIndex] if not character.isalpha() and not character == '%': return float(word[: characterIndex + 1]) return None def getRightStripMinusSplit(lineString): "Get string with spaces after the minus sign stripped." oldLineStringLength = -1 while oldLineStringLength < len(lineString): oldLineStringLength = len(lineString) lineString = lineString.replace('- ', '-') return lineString.split() def getStrokeRadius(elementNode): "Get the stroke radius." return 0.5 * getRightStripAlphabetPercent(getStyleValue('1.0', elementNode, 'stroke-width')) def getStyleValue(defaultValue, elementNode, key): "Get the stroke value string." if 'style' in elementNode.attributes: line = elementNode.attributes['style'] strokeIndex = line.find(key) if strokeIndex > -1: words = line[strokeIndex :].replace(':', ' ').replace(';', ' ').split() if len(words) > 1: return words[1] if key in elementNode.attributes: return elementNode.attributes[key] if elementNode.parentNode is None: return defaultValue return getStyleValue(defaultValue, elementNode.parentNode, key) def getTextComplexLoops(fontFamily, fontSize, text, yAxisPointingUpward=True): "Get text as complex loops." textComplexLoops = [] fontReader = getFontReader(fontFamily) horizontalAdvanceX = 0.0 for character in text: glyph = fontReader.getGlyph(character, yAxisPointingUpward) textComplexLoops += glyph.getSizedAdvancedLoops(fontSize, horizontalAdvanceX, yAxisPointingUpward) horizontalAdvanceX += glyph.horizontalAdvanceX return textComplexLoops def getTransformedFillOutline(elementNode, loop, yAxisPointingUpward): "Get the loops if fill is on, otherwise get the outlines." fillOutlineLoops = None if getStyleValue('none', elementNode, 'fill').lower() == 'none': fillOutlineLoops = intercircle.getAroundsFromLoop(loop, getStrokeRadius(elementNode)) else: fillOutlineLoops = [loop] return getChainMatrixSVGIfNecessary(elementNode, yAxisPointingUpward).getTransformedPaths(fillOutlineLoops) def getTransformedOutlineByPath(elementNode, path, yAxisPointingUpward): "Get the outline from the path." aroundsFromPath = intercircle.getAroundsFromPath(path, getStrokeRadius(elementNode)) return getChainMatrixSVGIfNecessary(elementNode, yAxisPointingUpward).getTransformedPaths(aroundsFromPath) def getTransformedOutlineByPaths(elementNode, paths, yAxisPointingUpward): "Get the outline from the paths." aroundsFromPaths = intercircle.getAroundsFromPaths(paths, getStrokeRadius(elementNode)) return getChainMatrixSVGIfNecessary(elementNode, yAxisPointingUpward).getTransformedPaths(aroundsFromPaths) def getTricomplexmatrix(transformWords): "Get matrixSVG by transformWords." tricomplex = [euclidean.getComplexByWords(transformWords)] tricomplex.append(euclidean.getComplexByWords(transformWords, 2)) tricomplex.append(euclidean.getComplexByWords(transformWords, 4)) return tricomplex def getTricomplexrotate(transformWords): "Get matrixSVG by transformWords." rotate = euclidean.getWiddershinsUnitPolar(math.radians(float(transformWords[0]))) return [rotate, complex(-rotate.imag,rotate.real), complex()] def getTricomplexscale(transformWords): "Get matrixSVG by transformWords." scale = euclidean.getComplexByWords(transformWords) return [complex(scale.real,0.0), complex(0.0,scale.imag), complex()] def getTricomplexskewX(transformWords): "Get matrixSVG by transformWords." skewX = math.tan(math.radians(float(transformWords[0]))) return [complex(1.0, 0.0), complex(skewX, 1.0), complex()] def getTricomplexskewY(transformWords): "Get matrixSVG by transformWords." skewY = math.tan(math.radians(float(transformWords[0]))) return [complex(1.0, skewY), complex(0.0, 1.0), complex()] def getTricomplexTimesColumn(firstTricomplex, otherColumn): "Get this matrix multiplied by the otherColumn." dotProductX = firstTricomplex[0].real * otherColumn.real + firstTricomplex[1].real * otherColumn.imag dotProductY = firstTricomplex[0].imag * otherColumn.real + firstTricomplex[1].imag * otherColumn.imag return complex(dotProductX, dotProductY) def getTricomplexTimesOther(firstTricomplex, otherTricomplex): "Get the first tricomplex multiplied by the other tricomplex." #A down, B right from http://en.wikipedia.org/wiki/Matrix_multiplication tricomplexTimesOther = [getTricomplexTimesColumn(firstTricomplex, otherTricomplex[0])] tricomplexTimesOther.append(getTricomplexTimesColumn(firstTricomplex, otherTricomplex[1])) tricomplexTimesOther.append(getTricomplexTimesColumn(firstTricomplex, otherTricomplex[2]) + firstTricomplex[2]) return tricomplexTimesOther def getTricomplextranslate(transformWords): "Get matrixSVG by transformWords." translate = euclidean.getComplexByWords(transformWords) return [complex(1.0, 0.0), complex(0.0, 1.0), translate] def processSVGElementcircle( elementNode, svgReader ): "Process elementNode by svgReader." attributes = elementNode.attributes center = euclidean.getComplexDefaultByDictionaryKeys( complex(), attributes, 'cx', 'cy') radius = euclidean.getFloatDefaultByDictionary( 0.0, attributes, 'r') if radius == 0.0: print('Warning, in processSVGElementcircle in svgReader radius is zero in:') print(attributes) return global globalNumberOfCirclePoints global globalSideAngle loop = [] loopLayer = svgReader.getLoopLayer() for side in xrange( globalNumberOfCirclePoints ): unitPolar = euclidean.getWiddershinsUnitPolar( float(side) * globalSideAngle ) loop.append( center + radius * unitPolar ) loopLayer.loops += getTransformedFillOutline(elementNode, loop, svgReader.yAxisPointingUpward) def processSVGElementellipse( elementNode, svgReader ): "Process elementNode by svgReader." attributes = elementNode.attributes center = euclidean.getComplexDefaultByDictionaryKeys( complex(), attributes, 'cx', 'cy') radius = euclidean.getComplexDefaultByDictionaryKeys( complex(), attributes, 'rx', 'ry') if radius.real == 0.0 or radius.imag == 0.0: print('Warning, in processSVGElementellipse in svgReader radius is zero in:') print(attributes) return global globalNumberOfCirclePoints global globalSideAngle loop = [] loopLayer = svgReader.getLoopLayer() for side in xrange( globalNumberOfCirclePoints ): unitPolar = euclidean.getWiddershinsUnitPolar( float(side) * globalSideAngle ) loop.append( center + complex( unitPolar.real * radius.real, unitPolar.imag * radius.imag ) ) loopLayer.loops += getTransformedFillOutline(elementNode, loop, svgReader.yAxisPointingUpward) def processSVGElementg(elementNode, svgReader): 'Process elementNode by svgReader.' if 'id' not in elementNode.attributes: return idString = elementNode.attributes['id'] if 'beginningOfControlSection' in elementNode.attributes: if elementNode.attributes['beginningOfControlSection'].lower()[: 1] == 't': svgReader.stopProcessing = True return idStringLower = idString.lower() zIndex = idStringLower.find('z:') if zIndex < 0: idStringLower = getLabelString(elementNode.attributes) zIndex = idStringLower.find('z:') if zIndex < 0: return floatFromValue = euclidean.getFloatFromValue(idStringLower[zIndex + len('z:') :].strip()) if floatFromValue is not None: svgReader.z = floatFromValue def processSVGElementline(elementNode, svgReader): "Process elementNode by svgReader." begin = euclidean.getComplexDefaultByDictionaryKeys(complex(), elementNode.attributes, 'x1', 'y1') end = euclidean.getComplexDefaultByDictionaryKeys(complex(), elementNode.attributes, 'x2', 'y2') loopLayer = svgReader.getLoopLayer() loopLayer.loops += getTransformedOutlineByPath(elementNode, [begin, end], svgReader.yAxisPointingUpward) def processSVGElementpath( elementNode, svgReader ): "Process elementNode by svgReader." if 'd' not in elementNode.attributes: print('Warning, in processSVGElementpath in svgReader can not get a value for d in:') print(elementNode.attributes) return loopLayer = svgReader.getLoopLayer() PathReader(elementNode, loopLayer.loops, svgReader.yAxisPointingUpward) def processSVGElementpolygon( elementNode, svgReader ): "Process elementNode by svgReader." if 'points' not in elementNode.attributes: print('Warning, in processSVGElementpolygon in svgReader can not get a value for d in:') print(elementNode.attributes) return loopLayer = svgReader.getLoopLayer() words = getRightStripMinusSplit(elementNode.attributes['points'].replace(',', ' ')) loop = [] for wordIndex in xrange( 0, len(words), 2 ): loop.append(euclidean.getComplexByWords(words[wordIndex :])) loopLayer.loops += getTransformedFillOutline(elementNode, loop, svgReader.yAxisPointingUpward) def processSVGElementpolyline(elementNode, svgReader): "Process elementNode by svgReader." if 'points' not in elementNode.attributes: print('Warning, in processSVGElementpolyline in svgReader can not get a value for d in:') print(elementNode.attributes) return loopLayer = svgReader.getLoopLayer() words = getRightStripMinusSplit(elementNode.attributes['points'].replace(',', ' ')) path = [] for wordIndex in xrange(0, len(words), 2): path.append(euclidean.getComplexByWords(words[wordIndex :])) loopLayer.loops += getTransformedOutlineByPath(elementNode, path, svgReader.yAxisPointingUpward) def processSVGElementrect( elementNode, svgReader ): "Process elementNode by svgReader." attributes = elementNode.attributes height = euclidean.getFloatDefaultByDictionary( 0.0, attributes, 'height') if height == 0.0: print('Warning, in processSVGElementrect in svgReader height is zero in:') print(attributes) return width = euclidean.getFloatDefaultByDictionary( 0.0, attributes, 'width') if width == 0.0: print('Warning, in processSVGElementrect in svgReader width is zero in:') print(attributes) return center = euclidean.getComplexDefaultByDictionaryKeys(complex(), attributes, 'x', 'y') inradius = 0.5 * complex( width, height ) cornerRadius = euclidean.getComplexDefaultByDictionaryKeys( complex(), attributes, 'rx', 'ry') loopLayer = svgReader.getLoopLayer() if cornerRadius.real == 0.0 and cornerRadius.imag == 0.0: inradiusMinusX = complex( - inradius.real, inradius.imag ) loop = [center + inradius, center + inradiusMinusX, center - inradius, center - inradiusMinusX] loopLayer.loops += getTransformedFillOutline(elementNode, loop, svgReader.yAxisPointingUpward) return if cornerRadius.real == 0.0: cornerRadius = complex( cornerRadius.imag, cornerRadius.imag ) elif cornerRadius.imag == 0.0: cornerRadius = complex( cornerRadius.real, cornerRadius.real ) cornerRadius = complex( min( cornerRadius.real, inradius.real ), min( cornerRadius.imag, inradius.imag ) ) ellipsePath = [ complex( cornerRadius.real, 0.0 ) ] inradiusMinusCorner = inradius - cornerRadius loop = [] global globalNumberOfCornerPoints global globalSideAngle for side in xrange( 1, globalNumberOfCornerPoints ): unitPolar = euclidean.getWiddershinsUnitPolar( float(side) * globalSideAngle ) ellipsePath.append( complex( unitPolar.real * cornerRadius.real, unitPolar.imag * cornerRadius.imag ) ) ellipsePath.append( complex( 0.0, cornerRadius.imag ) ) cornerPoints = [] for point in ellipsePath: cornerPoints.append( point + inradiusMinusCorner ) cornerPointsReversed = cornerPoints[: : -1] for cornerPoint in cornerPoints: loop.append( center + cornerPoint ) for cornerPoint in cornerPointsReversed: loop.append( center + complex( - cornerPoint.real, cornerPoint.imag ) ) for cornerPoint in cornerPoints: loop.append( center - cornerPoint ) for cornerPoint in cornerPointsReversed: loop.append( center + complex( cornerPoint.real, - cornerPoint.imag ) ) loop = euclidean.getLoopWithoutCloseSequentialPoints( 0.0001 * abs(inradius), loop ) loopLayer.loops += getTransformedFillOutline(elementNode, loop, svgReader.yAxisPointingUpward) def processSVGElementtext(elementNode, svgReader): "Process elementNode by svgReader." if svgReader.yAxisPointingUpward: return fontFamily = getStyleValue('Gentium Basic Regular', elementNode, 'font-family') fontSize = getRightStripAlphabetPercent(getStyleValue('12.0', elementNode, 'font-size')) matrixSVG = getChainMatrixSVGIfNecessary(elementNode, svgReader.yAxisPointingUpward) loopLayer = svgReader.getLoopLayer() translate = euclidean.getComplexDefaultByDictionaryKeys(complex(), elementNode.attributes, 'x', 'y') for textComplexLoop in getTextComplexLoops(fontFamily, fontSize, elementNode.getTextContent(), svgReader.yAxisPointingUpward): translatedLoop = [] for textComplexPoint in textComplexLoop: translatedLoop.append(textComplexPoint + translate ) loopLayer.loops.append(matrixSVG.getTransformedPath(translatedLoop)) class FontReader: "Class to read a font in the fonts folder." def __init__(self, fontFamily): "Initialize." self.fontFamily = fontFamily self.glyphDictionary = {} self.glyphElementNodeDictionary = {} self.missingGlyph = None fileName = os.path.join(getFontsDirectoryPath(), fontFamily + '.svg') documentElement = DocumentNode(fileName, archive.getFileText(fileName)).getDocumentElement() self.fontElementNode = documentElement.getFirstChildByLocalName('defs').getFirstChildByLocalName('font') self.fontFaceElementNode = self.fontElementNode.getFirstChildByLocalName('font-face') self.unitsPerEM = float(self.fontFaceElementNode.attributes['units-per-em']) glyphElementNodes = self.fontElementNode.getChildElementsByLocalName('glyph') for glyphElementNode in glyphElementNodes: self.glyphElementNodeDictionary[glyphElementNode.attributes['unicode']] = glyphElementNode def getGlyph(self, character, yAxisPointingUpward): "Get the glyph for the character." if character not in self.glyphElementNodeDictionary: if self.missingGlyph is None: missingGlyphElementNode = self.fontElementNode.getFirstChildByLocalName('missing-glyph') self.missingGlyph = Glyph(missingGlyphElementNode, self.unitsPerEM, yAxisPointingUpward) return self.missingGlyph if character not in self.glyphDictionary: self.glyphDictionary[character] = Glyph(self.glyphElementNodeDictionary[character], self.unitsPerEM, yAxisPointingUpward) return self.glyphDictionary[character] class Glyph: "Class to handle a glyph." def __init__(self, elementNode, unitsPerEM, yAxisPointingUpward): "Initialize." self.horizontalAdvanceX = float(elementNode.attributes['horiz-adv-x']) self.loops = [] self.unitsPerEM = unitsPerEM elementNode.attributes['fill'] = '' if 'd' not in elementNode.attributes: return PathReader(elementNode, self.loops, yAxisPointingUpward) def getSizedAdvancedLoops(self, fontSize, horizontalAdvanceX, yAxisPointingUpward=True): "Get loops for font size, advanced horizontally." multiplierX = fontSize / self.unitsPerEM multiplierY = multiplierX if not yAxisPointingUpward: multiplierY = -multiplierY sizedLoops = [] for loop in self.loops: sizedLoop = [] sizedLoops.append(sizedLoop) for point in loop: sizedLoop.append( complex(multiplierX * (point.real + horizontalAdvanceX), multiplierY * point.imag)) return sizedLoops class MatrixSVG: "Two by three svg matrix." def __init__(self, tricomplex=None): "Initialize." self.tricomplex = tricomplex def __repr__(self): "Get the string representation of this two by three svg matrix." return str(self.tricomplex) def getOtherTimesSelf(self, otherTricomplex): "Get the other matrix multiplied by this matrix." if otherTricomplex is None: return MatrixSVG(self.tricomplex) if self.tricomplex is None: return MatrixSVG(otherTricomplex) return MatrixSVG(getTricomplexTimesOther(otherTricomplex, self.tricomplex)) def getSelfTimesOther(self, otherTricomplex): "Get this matrix multiplied by the other matrix." if otherTricomplex is None: return MatrixSVG(self.tricomplex) if self.tricomplex is None: return MatrixSVG(otherTricomplex) return MatrixSVG(getTricomplexTimesOther(self.tricomplex, otherTricomplex)) def getTransformedPath(self, path): "Get transformed path." if self.tricomplex is None: return path complexX = self.tricomplex[0] complexY = self.tricomplex[1] complexTranslation = self.tricomplex[2] transformedPath = [] for point in path: x = complexX.real * point.real + complexY.real * point.imag y = complexX.imag * point.real + complexY.imag * point.imag transformedPath.append(complex(x, y) + complexTranslation) return transformedPath def getTransformedPaths(self, paths): "Get transformed paths." if self.tricomplex is None: return paths transformedPaths = [] for path in paths: transformedPaths.append(self.getTransformedPath(path)) return transformedPaths class PathReader: "Class to read svg path." def __init__(self, elementNode, loops, yAxisPointingUpward): "Add to path string to loops." self.controlPoints = None self.elementNode = elementNode self.loops = loops self.oldPoint = None self.outlinePaths = [] self.path = [] self.yAxisPointingUpward = yAxisPointingUpward pathString = elementNode.attributes['d'].replace(',', ' ') global globalProcessPathWordDictionary processPathWordDictionaryKeys = globalProcessPathWordDictionary.keys() for processPathWordDictionaryKey in processPathWordDictionaryKeys: pathString = pathString.replace( processPathWordDictionaryKey, ' %s ' % processPathWordDictionaryKey ) self.words = getRightStripMinusSplit(pathString) for self.wordIndex in xrange( len( self.words ) ): word = self.words[ self.wordIndex ] if word in processPathWordDictionaryKeys: globalProcessPathWordDictionary[word](self) if len(self.path) > 0: self.outlinePaths.append(self.path) self.loops += getTransformedOutlineByPaths(elementNode, self.outlinePaths, yAxisPointingUpward) def addPathArc( self, end ): "Add an arc to the path." begin = self.getOldPoint() self.controlPoints = None radius = self.getComplexByExtraIndex(1) xAxisRotation = math.radians(float(self.words[self.wordIndex + 3])) largeArcFlag = euclidean.getBooleanFromValue(self.words[ self.wordIndex + 4 ]) sweepFlag = euclidean.getBooleanFromValue(self.words[ self.wordIndex + 5 ]) self.path += getArcComplexes(begin, end, largeArcFlag, radius, sweepFlag, xAxisRotation) self.wordIndex += 8 def addPathCubic( self, controlPoints, end ): "Add a cubic curve to the path." begin = self.getOldPoint() self.controlPoints = controlPoints self.path += getCubicPoints( begin, controlPoints, end ) self.wordIndex += 7 def addPathCubicReflected( self, controlPoint, end ): "Add a cubic curve to the path from a reflected control point." begin = self.getOldPoint() controlPointBegin = begin if self.controlPoints is not None: if len(self.controlPoints) == 2: controlPointBegin = begin + begin - self.controlPoints[-1] self.controlPoints = [controlPointBegin, controlPoint] self.path += getCubicPoints(begin, self.controlPoints, end) self.wordIndex += 5 def addPathLine(self, lineFunction, point): "Add a line to the path." self.controlPoints = None self.path.append(point) self.wordIndex += 3 self.addPathLineByFunction(lineFunction) def addPathLineAxis(self, point): "Add an axis line to the path." self.controlPoints = None self.path.append(point) self.wordIndex += 2 def addPathLineByFunction( self, lineFunction ): "Add a line to the path by line function." while 1: if self.getFloatByExtraIndex() is None: return self.path.append(lineFunction()) self.wordIndex += 2 def addPathMove( self, lineFunction, point ): "Add an axis line to the path." self.controlPoints = None if len(self.path) > 0: self.outlinePaths.append(self.path) self.oldPoint = self.path[-1] self.path = [point] self.wordIndex += 3 self.addPathLineByFunction(lineFunction) def addPathQuadratic( self, controlPoint, end ): "Add a quadratic curve to the path." begin = self.getOldPoint() self.controlPoints = [controlPoint] self.path += getQuadraticPoints(begin, controlPoint, end) self.wordIndex += 5 def addPathQuadraticReflected( self, end ): "Add a quadratic curve to the path from a reflected control point." begin = self.getOldPoint() controlPoint = begin if self.controlPoints is not None: if len( self.controlPoints ) == 1: controlPoint = begin + begin - self.controlPoints[-1] self.controlPoints = [ controlPoint ] self.path += getQuadraticPoints(begin, controlPoint, end) self.wordIndex += 3 def getComplexByExtraIndex( self, extraIndex=0 ): 'Get complex from the extraIndex.' return euclidean.getComplexByWords(self.words, self.wordIndex + extraIndex) def getComplexRelative(self): "Get relative complex." return self.getComplexByExtraIndex() + self.getOldPoint() def getFloatByExtraIndex( self, extraIndex=0 ): 'Get float from the extraIndex.' totalIndex = self.wordIndex + extraIndex if totalIndex >= len(self.words): return None word = self.words[totalIndex] if word[: 1].isalpha(): return None return euclidean.getFloatFromValue(word) def getOldPoint(self): 'Get the old point.' if len(self.path) > 0: return self.path[-1] return self.oldPoint def processPathWordA(self): 'Process path word A.' self.addPathArc( self.getComplexByExtraIndex( 6 ) ) def processPathWorda(self): 'Process path word a.' self.addPathArc(self.getComplexByExtraIndex(6) + self.getOldPoint()) def processPathWordC(self): 'Process path word C.' end = self.getComplexByExtraIndex( 5 ) self.addPathCubic( [ self.getComplexByExtraIndex( 1 ), self.getComplexByExtraIndex(3) ], end ) def processPathWordc(self): 'Process path word C.' begin = self.getOldPoint() end = self.getComplexByExtraIndex( 5 ) self.addPathCubic( [ self.getComplexByExtraIndex( 1 ) + begin, self.getComplexByExtraIndex(3) + begin ], end + begin ) def processPathWordH(self): "Process path word H." beginY = self.getOldPoint().imag self.addPathLineAxis(complex(float(self.words[self.wordIndex + 1]), beginY)) while 1: floatByExtraIndex = self.getFloatByExtraIndex() if floatByExtraIndex is None: return self.path.append(complex(floatByExtraIndex, beginY)) self.wordIndex += 1 def processPathWordh(self): "Process path word h." begin = self.getOldPoint() self.addPathLineAxis(complex(float(self.words[self.wordIndex + 1]) + begin.real, begin.imag)) while 1: floatByExtraIndex = self.getFloatByExtraIndex() if floatByExtraIndex is None: return self.path.append(complex(floatByExtraIndex + self.getOldPoint().real, begin.imag)) self.wordIndex += 1 def processPathWordL(self): "Process path word L." self.addPathLine(self.getComplexByExtraIndex, self.getComplexByExtraIndex( 1 )) def processPathWordl(self): "Process path word l." self.addPathLine(self.getComplexRelative, self.getComplexByExtraIndex(1) + self.getOldPoint()) def processPathWordM(self): "Process path word M." self.addPathMove(self.getComplexByExtraIndex, self.getComplexByExtraIndex(1)) def processPathWordm(self): "Process path word m." self.addPathMove(self.getComplexRelative, self.getComplexByExtraIndex(1) + self.getOldPoint()) def processPathWordQ(self): 'Process path word Q.' self.addPathQuadratic( self.getComplexByExtraIndex( 1 ), self.getComplexByExtraIndex(3) ) def processPathWordq(self): 'Process path word q.' begin = self.getOldPoint() self.addPathQuadratic(self.getComplexByExtraIndex(1) + begin, self.getComplexByExtraIndex(3) + begin) def processPathWordS(self): 'Process path word S.' self.addPathCubicReflected( self.getComplexByExtraIndex( 1 ), self.getComplexByExtraIndex(3) ) def processPathWords(self): 'Process path word s.' begin = self.getOldPoint() self.addPathCubicReflected(self.getComplexByExtraIndex(1) + begin, self.getComplexByExtraIndex(3) + begin) def processPathWordT(self): 'Process path word T.' self.addPathQuadraticReflected( self.getComplexByExtraIndex( 1 ) ) def processPathWordt(self): 'Process path word t.' self.addPathQuadraticReflected(self.getComplexByExtraIndex(1) + self.getOldPoint()) def processPathWordV(self): "Process path word V." beginX = self.getOldPoint().real self.addPathLineAxis(complex(beginX, float(self.words[self.wordIndex + 1]))) while 1: floatByExtraIndex = self.getFloatByExtraIndex() if floatByExtraIndex is None: return self.path.append(complex(beginX, floatByExtraIndex)) self.wordIndex += 1 def processPathWordv(self): "Process path word v." begin = self.getOldPoint() self.addPathLineAxis(complex(begin.real, float(self.words[self.wordIndex + 1]) + begin.imag)) while 1: floatByExtraIndex = self.getFloatByExtraIndex() if floatByExtraIndex is None: return self.path.append(complex(begin.real, floatByExtraIndex + self.getOldPoint().imag)) self.wordIndex += 1 def processPathWordZ(self): "Process path word Z." self.controlPoints = None if len(self.path) < 1: return self.loops.append(getChainMatrixSVGIfNecessary(self.elementNode, self.yAxisPointingUpward).getTransformedPath(self.path)) self.oldPoint = self.path[0] self.path = [] def processPathWordz(self): "Process path word z." self.processPathWordZ() class SVGReader: "An svg carving." def __init__(self): "Add empty lists." self.loopLayers = [] self.sliceDictionary = None self.stopProcessing = False self.z = 0.0 def flipDirectLayer(self, loopLayer): "Flip the y coordinate of the layer and direct the loops." for loop in loopLayer.loops: for pointIndex, point in enumerate(loop): loop[pointIndex] = complex(point.real, -point.imag) triangle_mesh.sortLoopsInOrderOfArea(True, loopLayer.loops) for loopIndex, loop in enumerate(loopLayer.loops): isInsideLoops = euclidean.getIsInFilledRegion(loopLayer.loops[: loopIndex], euclidean.getLeftPoint(loop)) intercircle.directLoop((not isInsideLoops), loop) def getLoopLayer(self): "Return the rotated loop layer." if self.z is not None: loopLayer = euclidean.LoopLayer(self.z) self.loopLayers.append(loopLayer) self.z = None return self.loopLayers[-1] def parseSVG(self, fileName, svgText): "Parse SVG text and store the layers." self.fileName = fileName xmlParser = DocumentNode(fileName, svgText) self.documentElement = xmlParser.getDocumentElement() if self.documentElement is None: print('Warning, documentElement was None in parseSVG in SVGReader, so nothing will be done for:') print(fileName) return self.parseSVGByElementNode(self.documentElement) def parseSVGByElementNode(self, elementNode): "Parse SVG by elementNode." self.sliceDictionary = svg_writer.getSliceDictionary(elementNode) self.yAxisPointingUpward = euclidean.getBooleanFromDictionary(False, self.sliceDictionary, 'yAxisPointingUpward') self.processElementNode(elementNode) if not self.yAxisPointingUpward: for loopLayer in self.loopLayers: self.flipDirectLayer(loopLayer) def processElementNode(self, elementNode): 'Process the xml element.' if self.stopProcessing: return lowerLocalName = elementNode.getNodeName().lower() global globalProcessSVGElementDictionary if lowerLocalName in globalProcessSVGElementDictionary: try: globalProcessSVGElementDictionary[lowerLocalName](elementNode, self) except: print('Warning, in processElementNode in svg_reader, could not process:') print(elementNode) traceback.print_exc(file=sys.stdout) for childNode in elementNode.childNodes: self.processElementNode(childNode) globalFontFileNames = None globalFontReaderDictionary = {} globalGetTricomplexDictionary = {} globalGetTricomplexFunctions = [ getTricomplexmatrix, getTricomplexrotate, getTricomplexscale, getTricomplexskewX, getTricomplexskewY, getTricomplextranslate ] globalProcessPathWordFunctions = [ PathReader.processPathWordA, PathReader.processPathWorda, PathReader.processPathWordC, PathReader.processPathWordc, PathReader.processPathWordH, PathReader.processPathWordh, PathReader.processPathWordL, PathReader.processPathWordl, PathReader.processPathWordM, PathReader.processPathWordm, PathReader.processPathWordQ, PathReader.processPathWordq, PathReader.processPathWordS, PathReader.processPathWords, PathReader.processPathWordT, PathReader.processPathWordt, PathReader.processPathWordV, PathReader.processPathWordv, PathReader.processPathWordZ, PathReader.processPathWordz ] globalProcessPathWordDictionary = {} globalProcessSVGElementDictionary = {} globalProcessSVGElementFunctions = [ processSVGElementcircle, processSVGElementellipse, processSVGElementg, processSVGElementline, processSVGElementpath, processSVGElementpolygon, processSVGElementpolyline, processSVGElementrect, processSVGElementtext ] globalSideAngle = 0.5 * math.pi / float( globalNumberOfCornerPoints ) addFunctionsToDictionary( globalGetTricomplexDictionary, globalGetTricomplexFunctions, 'getTricomplex') addFunctionsToDictionary( globalProcessPathWordDictionary, globalProcessPathWordFunctions, 'processPathWord') addFunctionsToDictionary( globalProcessSVGElementDictionary, globalProcessSVGElementFunctions, 'processSVGElement') sfact-2011.12.18/fabmetheus_utilities/svg_writer.py000066400000000000000000000301601167321211700221730ustar00rootroot00000000000000""" Svg_writer is a class and collection of utilities to read from and write to an svg file. Svg_writer uses the layer_template.svg file in the templates folder in the same folder as svg_writer, to output an svg file. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities.xml_simple_reader import DocumentNode from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import xml_simple_reader from fabmetheus_utilities import xml_simple_writer import cStringIO import math import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalOriginalTextString = '' in lineStripped: isComment = False xml_simple_reader.CommentNode(self.svgElement, '%s%s-->\n' % (globalOriginalTextString, commentNodeOutput.getvalue())).appendSelfToParent() def getReplacedSVGTemplate(self, fileName, loopLayers, procedureName, elementNode=None): 'Get the lines of text from the layer_template.svg file.' self.extent = self.cornerMaximum - self.cornerMinimum svgTemplateText = archive.getFileText(archive.getTemplatesPath('layer_template.svg')) documentNode = DocumentNode(fileName, svgTemplateText) self.svgElement = documentNode.getDocumentElement() svgElementDictionary = self.svgElement.attributes self.sliceDictionary = getSliceDictionary(self.svgElement) self.controlBoxHeight = float(self.sliceDictionary['controlBoxHeight']) self.controlBoxWidth = float(self.sliceDictionary['controlBoxWidth']) self.margin = float(self.sliceDictionary['margin']) self.marginTop = float(self.sliceDictionary['marginTop']) self.textHeight = float(self.sliceDictionary['textHeight']) self.unitScale = float(self.sliceDictionary['unitScale']) svgMinWidth = float(self.sliceDictionary['svgMinWidth']) self.controlBoxHeightMargin = self.controlBoxHeight + self.marginTop if not self.addLayerTemplateToSVG: self.svgElement.getElementNodeByID('layerTextTemplate').removeFromIDNameParent() del self.svgElement.getElementNodeByID('sliceElementTemplate').attributes['transform'] self.graphicsElementNode = self.svgElement.getElementNodeByID('sliceElementTemplate') self.graphicsElementNode.attributes['id'] = 'z:' self.addLoopLayersToOutput(loopLayers) self.setMetadataNoscriptElement('layerThickness', 'Layer Thickness: ', self.layerThickness) self.setMetadataNoscriptElement('maxX', 'X: ', self.cornerMaximum.x) self.setMetadataNoscriptElement('minX', 'X: ', self.cornerMinimum.x) self.setMetadataNoscriptElement('maxY', 'Y: ', self.cornerMaximum.y) self.setMetadataNoscriptElement('minY', 'Y: ', self.cornerMinimum.y) self.setMetadataNoscriptElement('maxZ', 'Z: ', self.cornerMaximum.z) self.setMetadataNoscriptElement('minZ', 'Z: ', self.cornerMinimum.z) self.textHeight = float( self.sliceDictionary['textHeight'] ) controlTop = len(loopLayers) * (self.margin + self.extent.y * self.unitScale + self.textHeight) + self.marginTop + self.textHeight self.svgElement.getFirstChildByLocalName('title').setTextContent(os.path.basename(fileName) + ' - Slice Layers') svgElementDictionary['height'] = '%spx' % self.getRounded(max(controlTop, self.controlBoxHeightMargin)) width = max(self.extent.x * self.unitScale, svgMinWidth) svgElementDictionary['width'] = '%spx' % self.getRounded( width ) self.sliceDictionary['decimalPlacesCarried'] = str( self.decimalPlacesCarried ) if self.perimeterWidth is not None: self.sliceDictionary['perimeterWidth'] = self.getRounded( self.perimeterWidth ) self.sliceDictionary['yAxisPointingUpward'] = 'true' self.sliceDictionary['procedureName'] = procedureName self.setDimensionTexts('dimX', 'X: ' + self.getRounded(self.extent.x)) self.setDimensionTexts('dimY', 'Y: ' + self.getRounded(self.extent.y)) self.setDimensionTexts('dimZ', 'Z: ' + self.getRounded(self.extent.z)) self.setTexts('numberOfLayers', 'Number of Layers: %s' % len(loopLayers)) volume = 0.0 for loopLayer in loopLayers: volume += euclidean.getAreaLoops(loopLayer.loops) volume *= 0.001 * self.layerThickness self.setTexts('volume', 'Volume: %s cm3' % self.getRounded(volume)) if not self.addLayerTemplateToSVG: self.svgElement.getFirstChildByLocalName('script').removeFromIDNameParent() self.svgElement.getElementNodeByID('isoControlBox').removeFromIDNameParent() self.svgElement.getElementNodeByID('layerControlBox').removeFromIDNameParent() self.svgElement.getElementNodeByID('scrollControlBox').removeFromIDNameParent() self.graphicsElementNode.removeFromIDNameParent() self.addOriginalAsComment(elementNode) return documentNode.__repr__() def getRounded(self, number): 'Get number rounded to the number of carried decimal places as a string.' return euclidean.getRoundedToPlacesString(self.decimalPlacesCarried, number) def getRoundedComplexString(self, point): 'Get the rounded complex string.' return self.getRounded( point.real ) + ' ' + self.getRounded( point.imag ) def getSVGStringForLoop( self, loop ): 'Get the svg loop string.' if len(loop) < 1: return '' return self.getSVGStringForPath(loop) + ' z' def getSVGStringForLoops( self, loops ): 'Get the svg loops string.' loopString = '' if len(loops) > 0: loopString += self.getSVGStringForLoop( loops[0] ) for loop in loops[1 :]: loopString += ' ' + self.getSVGStringForLoop(loop) return loopString def getSVGStringForPath( self, path ): 'Get the svg path string.' svgLoopString = '' for point in path: stringBeginning = 'M ' if len( svgLoopString ) > 0: stringBeginning = ' L ' svgLoopString += stringBeginning + self.getRoundedComplexString(point) return svgLoopString def getTransformString(self): 'Get the svg transform string.' cornerMinimumXString = self.getRounded(-self.cornerMinimum.x) cornerMinimumYString = self.getRounded(-self.cornerMinimum.y) return 'scale(%s, %s) translate(%s, %s)' % (self.unitScale, - self.unitScale, cornerMinimumXString, cornerMinimumYString) def setDimensionTexts(self, key, valueString): 'Set the texts to the valueString followed by mm.' self.setTexts(key, valueString + ' mm') def setMetadataNoscriptElement(self, key, prefix, value): 'Set the metadata value and the text.' valueString = self.getRounded(value) self.sliceDictionary[key] = valueString self.setDimensionTexts(key, prefix + valueString) def setTexts(self, key, valueString): 'Set the texts to the valueString.' self.svgElement.getElementNodeByID(key + 'Iso').setTextContent(valueString) self.svgElement.getElementNodeByID(key + 'Layer').setTextContent(valueString) self.svgElement.getElementNodeByID(key + 'Scroll').setTextContent(valueString) sfact-2011.12.18/fabmetheus_utilities/templates/000077500000000000000000000000001167321211700214245ustar00rootroot00000000000000sfact-2011.12.18/fabmetheus_utilities/templates/canvas_template.svg000066400000000000000000000010601167321211700253100ustar00rootroot00000000000000 replaceLineWithTitle sfact-2011.12.18/fabmetheus_utilities/templates/layer_template.svg000066400000000000000000000552011167321211700251570ustar00rootroot00000000000000 replaceWith_Title Layer 1, z:0.1 Latitude < > Longitude < > Scale 1 < > Min Max Dimension Statistics Y X 0 1 Layer < > Scale 1 < > Min Max Dimension Statistics Y X Scale : 1 < > Min Max Dimension Statistics [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/fabmetheus_utilities/vector3.py000066400000000000000000000225551167321211700213760ustar00rootroot00000000000000""" Vector3 is a three dimensional vector class. Below are examples of Vector3 use. >>> from vector3 import Vector3 >>> origin = Vector3() >>> origin 0.0, 0.0, 0.0 >>> pythagoras = Vector3( 3, 4, 0 ) >>> pythagoras 3.0, 4.0, 0.0 >>> pythagoras.magnitude() 5.0 >>> pythagoras.magnitudeSquared() 25 >>> triplePythagoras = pythagoras * 3.0 >>> triplePythagoras 9.0, 12.0, 0.0 >>> plane = pythagoras.dropAxis() >>> plane (3+4j) """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import xml_simple_writer import math import operator __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' class Vector3: 'A three dimensional vector class.' __slots__ = ['x', 'y', 'z'] def __init__(self, x=0.0, y=0.0, z=0.0): self.x = x self.y = y self.z = z def __abs__(self): 'Get the magnitude of the Vector3.' return math.sqrt( self.x * self.x + self.y * self.y + self.z * self.z ) magnitude = __abs__ def __add__(self, other): 'Get the sum of this Vector3 and other one.' return Vector3( self.x + other.x, self.y + other.y, self.z + other.z ) def __copy__(self): 'Get the copy of this Vector3.' return Vector3( self.x, self.y, self.z ) __pos__ = __copy__ copy = __copy__ def __div__(self, other): 'Get a new Vector3 by dividing each component of this one.' return Vector3( self.x / other, self.y / other, self.z / other ) def __eq__(self, other): 'Determine whether this vector is identical to other one.' if other is None: return False if other.__class__ != self.__class__: return False return self.x == other.x and self.y == other.y and self.z == other.z def __floordiv__(self, other): 'Get a new Vector3 by floor dividing each component of this one.' return Vector3( self.x // other, self.y // other, self.z // other ) def __hash__(self): 'Determine whether this vector is identical to other one.' return self.__repr__().__hash__() def __iadd__(self, other): 'Add other Vector3 to this one.' self.x += other.x self.y += other.y self.z += other.z return self def __idiv__(self, other): 'Divide each component of this Vector3.' self.x /= other self.y /= other self.z /= other return self def __ifloordiv__(self, other): 'Floor divide each component of this Vector3.' self.x //= other self.y //= other self.z //= other return self def __imul__(self, other): 'Multiply each component of this Vector3.' self.x *= other self.y *= other self.z *= other return self def __isub__(self, other): 'Subtract other Vector3 from this one.' self.x -= other.x self.y -= other.y self.z -= other.z return self def __itruediv__(self, other): 'True divide each component of this Vector3.' self.x = operator.truediv( self.x, other ) self.y = operator.truediv( self.y, other ) self.z = operator.truediv( self.z, other ) return self def __mul__(self, other): 'Get a new Vector3 by multiplying each component of this one.' return Vector3( self.x * other, self.y * other, self.z * other ) def __ne__(self, other): 'Determine whether this vector is not identical to other one.' return not self.__eq__(other) def __neg__(self): return Vector3( - self.x, - self.y, - self.z ) def __nonzero__(self): return self.x != 0 or self.y != 0 or self.z != 0 def __rdiv__(self, other): 'Get a new Vector3 by dividing each component of this one.' return Vector3( other / self.x, other / self.y, other / self.z ) def __repr__(self): 'Get the string representation of this Vector3.' return '(%s, %s, %s)' % ( self.x, self.y, self.z ) def __rfloordiv__(self, other): 'Get a new Vector3 by floor dividing each component of this one.' return Vector3( other // self.x, other // self.y, other // self.z ) def __rmul__(self, other): 'Get a new Vector3 by multiplying each component of this one.' return Vector3( self.x * other, self.y * other, self.z * other ) def __rtruediv__(self, other): 'Get a new Vector3 by true dividing each component of this one.' return Vector3( operator.truediv( other , self.x ), operator.truediv( other, self.y ), operator.truediv( other, self.z ) ) def __sub__(self, other): 'Get the difference between the Vector3 and other one.' return Vector3( self.x - other.x, self.y - other.y, self.z - other.z ) def __truediv__(self, other): 'Get a new Vector3 by true dividing each component of this one.' return Vector3( operator.truediv( self.x, other ), operator.truediv( self.y, other ), operator.truediv( self.z, other ) ) def _getAccessibleAttribute(self, attributeName): 'Get the accessible attribute.' if attributeName in globalGetAccessibleAttributeSet: return getattr(self, attributeName, None) return None def _setAccessibleAttribute(self, attributeName, value): 'Set the accessible attribute.' if attributeName in globalSetAccessibleAttributeSet: setattr(self, attributeName, value) def cross(self, other): 'Calculate the cross product of this vector with other one.' return Vector3(self.y * other.z - self.z * other.y, -self.x * other.z + self.z * other.x, self.x * other.y - self.y * other.x) def distance(self, other): 'Get the Euclidean distance between this vector and other one.' return math.sqrt( self.distanceSquared(other) ) def distanceSquared(self, other): 'Get the square of the Euclidean distance between this vector and other one.' separationX = self.x - other.x separationY = self.y - other.y separationZ = self.z - other.z return separationX * separationX + separationY * separationY + separationZ * separationZ def dot(self, other): 'Calculate the dot product of this vector with other one.' return self.x * other.x + self.y * other.y + self.z * other.z def dropAxis( self, which = 2 ): 'Get a complex by removing one axis of the vector3.' if which == 0: return complex( self.y, self.z ) if which == 1: return complex( self.x, self.z ) if which == 2: return complex( self.x, self.y ) def getFloatList(self): 'Get the vector as a list of floats.' return [ float( self.x ), float( self.y ), float( self.z ) ] def getIsDefault(self): 'Determine if this is the zero vector.' if self.x != 0.0: return False if self.y != 0.0: return False return self.z == 0.0 def getNormalized(self): 'Get the normalized Vector3.' magnitude = abs(self) if magnitude == 0.0: return self.copy() return self / magnitude def magnitudeSquared(self): 'Get the square of the magnitude of the Vector3.' return self.x * self.x + self.y * self.y + self.z * self.z def maximize(self, other): 'Maximize the Vector3.' self.x =max(other.x, self.x) self.y =max(other.y, self.y) self.z =max(other.z, self.z) def minimize(self, other): 'Minimize the Vector3.' self.x =min(other.x, self.x) self.y =min(other.y, self.y) self.z =min(other.z, self.z) def normalize(self): 'Scale each component of this Vector3 so that it has a magnitude of 1. If this Vector3 has a magnitude of 0, this method has no effect.' magnitude = abs(self) if magnitude != 0.0: self /= magnitude def reflect( self, normal ): 'Reflect the Vector3 across the normal, which is assumed to be normalized.' distance = 2 * ( self.x * normal.x + self.y * normal.y + self.z * normal.z ) return Vector3( self.x - distance * normal.x, self.y - distance * normal.y, self.z - distance * normal.z ) def setToVector3(self, other): 'Set this Vector3 to be identical to other one.' self.x = other.x self.y = other.y self.z = other.z def setToXYZ( self, x, y, z ): 'Set the x, y, and z components of this Vector3.' self.x = x self.y = y self.z = z globalGetAccessibleAttributeSet = 'x y z'.split() globalSetAccessibleAttributeSet = globalGetAccessibleAttributeSet """ class Vector3: __slots__ = ['x', 'y', 'z'] copy = __copy__ def __eq__(self, other): if isinstance(other, Vector3): return self.x == other.x and \ self.y == other.y and \ self.z == other.z else: assert hasattr(other, '__len__') and len(other) == 3 return self.x == other[0] and \ self.y == other[1] and \ self.z == other[2] def __getattr__(self, name): try: return tuple([(self.x, self.y, self.z)['xyz'.index(c)] \ for c in name]) except ValueError: raise AttributeError, name def __getitem__(self, key): return (self.x, self.y, self.z)[key] def __iter__(self): return iter((self.x, self.y, self.z)) def __len__(self): return 3 def __repr__(self): return 'Vector3(%.2f, %.2f, %.2f)' % (self.x, self.y, self.z) if _enable_swizzle_set: # This has detrimental performance on ordinary setattr as well # if enabled def __setattr__(self, name, value): if len(name) == 1: object.__setattr__(self, name, value) else: try: l = [self.x, self.y, self.z] for c, v in map(None, name, value): l['xyz'.index(c)] = v self.x, self.y, self.z = l except ValueError: raise AttributeError, name def __setitem__(self, key, value): l = [self.x, self.y, self.z] l[key] = value self.x, self.y, self.z = l """ sfact-2011.12.18/fabmetheus_utilities/vector3index.py000066400000000000000000000206051167321211700224200ustar00rootroot00000000000000""" Vector3 is a three dimensional vector class. Below are examples of Vector3 use. >>> from vector3 import Vector3 >>> origin = Vector3() >>> origin 0.0, 0.0, 0.0 >>> pythagoras = Vector3( 3, 4, 0 ) >>> pythagoras 3.0, 4.0, 0.0 >>> pythagoras.magnitude() 5.0 >>> pythagoras.magnitudeSquared() 25 >>> triplePythagoras = pythagoras * 3.0 >>> triplePythagoras 9.0, 12.0, 0.0 >>> plane = pythagoras.dropAxis() >>> plane (3+4j) """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import xml_simple_writer import math import operator __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' class Vector3Index: 'A three dimensional vector index class.' __slots__ = ['index', 'x', 'y', 'z'] def __init__( self, index, x = 0.0, y = 0.0, z = 0.0 ): self.index = index self.x = x self.y = y self.z = z def __abs__(self): 'Get the magnitude of the Vector3.' return math.sqrt( self.x * self.x + self.y * self.y + self.z * self.z ) magnitude = __abs__ def __add__(self, other): 'Get the sum of this Vector3 and other one.' return Vector3Index( self.index, self.x + other.x, self.y + other.y, self.z + other.z ) def __copy__(self): 'Get the copy of this Vector3.' return Vector3Index( self.index, self.x, self.y, self.z ) __pos__ = __copy__ copy = __copy__ def __div__(self, other): 'Get a new Vector3 by dividing each component of this one.' return Vector3Index( self.index, self.x / other, self.y / other, self.z / other ) def __eq__(self, other): 'Determine whether this vector is identical to other one.' if other is None: return False if other.__class__ != self.__class__: return False return self.x == other.x and self.y == other.y and self.z == other.z def __floordiv__(self, other): 'Get a new Vector3 by floor dividing each component of this one.' return Vector3Index( self.index, self.x // other, self.y // other, self.z // other ) def __hash__(self): 'Determine whether this vector is identical to other one.' return self.__repr__().__hash__() def __iadd__(self, other): 'Add other Vector3 to this one.' self.x += other.x self.y += other.y self.z += other.z return self def __idiv__(self, other): 'Divide each component of this Vector3.' self.x /= other self.y /= other self.z /= other return self def __ifloordiv__(self, other): 'Floor divide each component of this Vector3.' self.x //= other self.y //= other self.z //= other return self def __imul__(self, other): 'Multiply each component of this Vector3.' self.x *= other self.y *= other self.z *= other return self def __isub__(self, other): 'Subtract other Vector3 from this one.' self.x -= other.x self.y -= other.y self.z -= other.z return self def __itruediv__(self, other): 'True divide each component of this Vector3.' self.x = operator.truediv( self.x, other ) self.y = operator.truediv( self.y, other ) self.z = operator.truediv( self.z, other ) return self def __mul__(self, other): 'Get a new Vector3 by multiplying each component of this one.' return Vector3Index( self.index, self.x * other, self.y * other, self.z * other ) def __ne__(self, other): 'Determine whether this vector is not identical to other one.' return not self.__eq__(other) def __neg__(self): return Vector3Index( self.index, - self.x, - self.y, - self.z ) def __nonzero__(self): return self.x != 0 or self.y != 0 or self.z != 0 def __rdiv__(self, other): 'Get a new Vector3 by dividing each component of this one.' return Vector3Index( self.index, other / self.x, other / self.y, other / self.z ) def __repr__(self): 'Get the string representation of this Vector3 index.' return '(%s, %s, %s, %s)' % (self.index, self.x, self.y, self.z) def __rfloordiv__(self, other): 'Get a new Vector3 by floor dividing each component of this one.' return Vector3Index( self.index, other // self.x, other // self.y, other // self.z ) def __rmul__(self, other): 'Get a new Vector3 by multiplying each component of this one.' return Vector3Index( self.index, self.x * other, self.y * other, self.z * other ) def __rtruediv__(self, other): 'Get a new Vector3 by true dividing each component of this one.' return Vector3Index( self.index, operator.truediv( other , self.x ), operator.truediv( other, self.y ), operator.truediv( other, self.z ) ) def __sub__(self, other): 'Get the difference between the Vector3 and other one.' return Vector3Index( self.index, self.x - other.x, self.y - other.y, self.z - other.z ) def __truediv__(self, other): 'Get a new Vector3 by true dividing each component of this one.' return Vector3Index( self.index, operator.truediv( self.x, other ), operator.truediv( self.y, other ), operator.truediv( self.z, other ) ) def _getAccessibleAttribute(self, attributeName): 'Get the accessible attribute.' global globalGetAccessibleAttributeSet if attributeName in globalGetAccessibleAttributeSet: return getattr(self, attributeName, None) return None def _setAccessibleAttribute(self, attributeName, value): 'Set the accessible attribute.' if attributeName in globalSetAccessibleAttributeSet: setattr(self, attributeName, value) def cross(self, other): 'Calculate the cross product of this vector with other one.' return Vector3Index( self.index, self.y * other.z - self.z * other.y, - self.x * other.z + self.z * other.x, self.x * other.y - self.y * other.x ) def distance(self, other): 'Get the Euclidean distance between this vector and other one.' return math.sqrt( self.distanceSquared(other) ) def distanceSquared(self, other): 'Get the square of the Euclidean distance between this vector and other one.' separationX = self.x - other.x separationY = self.y - other.y separationZ = self.z - other.z return separationX * separationX + separationY * separationY + separationZ * separationZ def dot(self, other): 'Calculate the dot product of this vector with other one.' return self.x * other.x + self.y * other.y + self.z * other.z def dropAxis( self, which = 2 ): 'Get a complex by removing one axis of the vector3.' if which == 0: return complex( self.y, self.z ) if which == 1: return complex( self.x, self.z ) if which == 2: return complex( self.x, self.y ) def getFloatList(self): 'Get the vector as a list of floats.' return [ float( self.x ), float( self.y ), float( self.z ) ] def getIsDefault(self): 'Determine if this is the zero vector.' if self.x != 0.0: return False if self.y != 0.0: return False return self.z == 0.0 def getNormalized(self): 'Get the normalized Vector3.' magnitude = abs(self) if magnitude == 0.0: return self.copy() return self / magnitude def magnitudeSquared(self): 'Get the square of the magnitude of the Vector3.' return self.x * self.x + self.y * self.y + self.z * self.z def maximize(self, other): 'Maximize the Vector3.' self.x =max(other.x, self.x) self.y =max(other.y, self.y) self.z =max(other.z, self.z) def minimize(self, other): 'Minimize the Vector3.' self.x =min(other.x, self.x) self.y =min(other.y, self.y) self.z =min(other.z, self.z) def normalize(self): 'Scale each component of this Vector3 so that it has a magnitude of 1. If this Vector3 has a magnitude of 0, this method has no effect.' magnitude = abs(self) if magnitude != 0.0: self /= magnitude def reflect( self, normal ): 'Reflect the Vector3 across the normal, which is assumed to be normalized.' distance = 2 * ( self.x * normal.x + self.y * normal.y + self.z * normal.z ) return Vector3Index( self.index, self.x - distance * normal.x, self.y - distance * normal.y, self.z - distance * normal.z ) def setToVector3(self, other): 'Set this Vector3 to be identical to other one.' self.x = other.x self.y = other.y self.z = other.z def setToXYZ( self, x, y, z ): 'Set the x, y, and z components of this Vector3.' self.x = x self.y = y self.z = z globalGetAccessibleAttributeSet = 'x y z'.split() globalSetAccessibleAttributeSet = globalGetAccessibleAttributeSet sfact-2011.12.18/fabmetheus_utilities/version.txt000066400000000000000000000000701167321211700216510ustar00rootroot0000000000000018.12.11 if SFACT Daily refer to date you downloaded itsfact-2011.12.18/fabmetheus_utilities/xml_simple_reader.py000066400000000000000000000627651167321211700235130ustar00rootroot00000000000000""" The xml_simple_reader.py script is an xml parser that can parse a line separated xml text. This xml parser will read a line seperated xml text and produce a tree of the xml with a document element. Each element can have an attribute table, childNodes, a class name, parentNode, text and a link to the document element. This example gets an xml tree for the xml file boolean.xml. This example is run in a terminal in the folder which contains boolean.xml and xml_simple_reader.py. > python Python 2.5.1 (r251:54863, Sep 22 2007, 01:43:31) [GCC 4.2.1 (SUSE Linux)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> fileName = 'boolean.xml' >>> file = open(fileName, 'r') >>> xmlText = file.read() >>> file.close() >>> from xml_simple_reader import DocumentNode >>> xmlParser = DocumentNode(fileName, xmlText) >>> print( xmlParser ) ?xml, {'version': '1.0'} ArtOfIllusion, {'xmlns:bf': '//babelfiche/codec', 'version': '2.0', 'fileversion': '3'} Scene, {'bf:id': 'theScene'} materials, {'bf:elem-type': 'java.lang.Object', 'bf:list': 'collection', 'bf:id': '1', 'bf:type': 'java.util.Vector'} .. many more lines of the xml tree .. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.geometry.geometry_utilities import evaluate from fabmetheus_utilities.geometry.geometry_utilities import matrix from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import xml_simple_writer import cStringIO __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' globalGetAccessibleAttributeSet = set('getPaths getPreviousVertex getPreviousElementNode getVertexes parentNode'.split()) def createAppendByText(parentNode, xmlText): 'Create and append the child nodes from the xmlText.' monad = OpenMonad(parentNode) for character in xmlText: monad = monad.getNextMonad(character) def createAppendByTextb(parentNode, xmlText): 'Create and append the child nodes from the xmlText.' monad = OpenMonad(parentNode) for character in xmlText: monad = monad.getNextMonad(character) def getChildElementsByLocalName(childNodes, localName): 'Get the childNodes which have the given local name.' childElementsByLocalName = [] for childNode in childNodes: if localName.lower() == childNode.getNodeName(): childElementsByLocalName.append(childNode) return childElementsByLocalName def getDocumentNode(fileName): 'Get the document from the file name.' xmlText = getFileText('test.xml') return DocumentNode(fileName, xmlText) def getElementsByLocalName(childNodes, localName): 'Get the descendents which have the given local name.' elementsByLocalName = getChildElementsByLocalName(childNodes, localName) for childNode in childNodes: if childNode.getNodeType() == 1: elementsByLocalName += childNode.getElementsByLocalName(localName) return elementsByLocalName def getFileText(fileName, printWarning=True, readMode='r'): 'Get the entire text of a file.' try: file = open(fileName, readMode) fileText = file.read() file.close() return fileText except IOError: if printWarning: print('The file ' + fileName + ' does not exist.') return '' class CDATASectionMonad: 'A monad to handle a CDATASection node.' def __init__(self, input, parentNode): 'Initialize.' self.input = input self.parentNode = parentNode def getNextMonad(self, character): 'Get the next monad.' self.input.write(character) if character == '>': inputString = self.input.getvalue() if inputString.endswith(']]>'): textContent = '<%s\n' % inputString self.parentNode.childNodes.append(CDATASectionNode(self.parentNode, textContent)) return OpenMonad(self.parentNode) return self class CDATASectionNode: 'A CDATASection node.' def __init__(self, parentNode, textContent=''): 'Initialize.' self.parentNode = parentNode self.textContent = textContent def __repr__(self): 'Get the string representation of this CDATASection node.' return self.textContent def addToIdentifierDictionaries(self): 'Add the element to the owner document identifier dictionaries.' pass def addXML(self, depth, output): 'Add xml for this CDATASection node.' output.write(self.textContent) def appendSelfToParent(self): 'Append self to the parentNode.' self.parentNode.appendChild(self) def copyXMLChildNodes(self, idSuffix, parentNode): 'Copy the xml childNodes.' pass def getAttributes(self): 'Get the attributes.' return {} def getChildNodes(self): 'Get the empty set.' return [] def getCopy(self, idSuffix, parentNode): 'Copy the xml element, set its dictionary and add it to the parentNode.' copy = self.getCopyShallow() copy.parentNode = parentNode copy.appendSelfToParent() return copy def getCopyShallow(self, attributes=None): 'Copy the node and set its parentNode.' return CDATASectionNode(self.parentNode, self.textContent) def getNodeName(self): 'Get the node name.' return '#cdata-section' def getNodeType(self): 'Get the node type.' return 4 def getOwnerDocument(self): 'Get the owner document.' return self.parentNode.getOwnerDocument() def getTextContent(self): 'Get the text content.' return self.textContent def removeChildNodesFromIDNameParent(self): 'Remove the childNodes from the id and name dictionaries and the childNodes.' pass def removeFromIDNameParent(self): 'Remove this from the id and name dictionaries and the childNodes of the parentNode.' if self.parentNode is not None: self.parentNode.childNodes.remove(self) def setParentAddToChildNodes(self, parentNode): 'Set the parentNode and add this to its childNodes.' self.parentNode = parentNode if self.parentNode is not None: self.parentNode.childNodes.append(self) attributes = property(getAttributes) childNodes = property(getChildNodes) nodeName = property(getNodeName) nodeType = property(getNodeType) ownerDocument = property(getOwnerDocument) class CommentMonad(CDATASectionMonad): 'A monad to handle a comment node.' def getNextMonad(self, character): 'Get the next monad.' self.input.write(character) if character == '>': inputString = self.input.getvalue() if inputString.endswith('-->'): textContent = '<%s\n' % inputString self.parentNode.childNodes.append(CommentNode(self.parentNode, textContent)) return OpenMonad(self.parentNode) return self class CommentNode(CDATASectionNode): 'A comment node.' def getCopyShallow(self, attributes=None): 'Copy the node and set its parentNode.' return CommentNode(self.parentNode, self.textContent) def getNodeName(self): 'Get the node name.' return '#comment' def getNodeType(self): 'Get the node type.' return 8 nodeName = property(getNodeName) nodeType = property(getNodeType) class DocumentNode: 'A class to parse an xml text and store the elements.' def __init__(self, fileName, xmlText): 'Initialize.' self.childNodes = [] self.fileName = fileName self.idDictionary = {} self.nameDictionary = {} self.parentNode = None self.tagDictionary = {} self.xmlText = xmlText createAppendByText(self, xmlText) def __repr__(self): 'Get the string representation of this xml document.' output = cStringIO.StringIO() for childNode in self.childNodes: childNode.addXML(0, output) return output.getvalue() def appendChild(self, elementNode): 'Append child elementNode to the child nodes.' self.childNodes.append(elementNode) elementNode.addToIdentifierDictionaries() return elementNode def getAttributes(self): 'Get the attributes.' return {} def getCascadeBoolean(self, defaultBoolean, key): 'Get the cascade boolean.' return defaultBoolean def getCascadeFloat(self, defaultFloat, key): 'Get the cascade float.' return defaultFloat def getDocumentElement(self): 'Get the document element.' if len(self.childNodes) == 0: return None return self.childNodes[-1] def getElementsByLocalName(self, localName): 'Get the descendents which have the given local name.' return getElementsByLocalName(self.childNodes, localName) def getImportNameChain(self, suffix=''): 'Get the import name chain with the suffix at the end.' return suffix def getNodeName(self): 'Get the node name.' return '#document' def getNodeType(self): 'Get the node type.' return 9 def getOriginalRoot(self): 'Get the original reparsed document element.' if evaluate.getEvaluatedBoolean(True, self.documentElement, 'getOriginalRoot'): return DocumentNode(self.fileName, self.xmlText).documentElement return None def getOwnerDocument(self): 'Get the owner document.' return self attributes = property(getAttributes) documentElement = property(getDocumentElement) nodeName = property(getNodeName) nodeType = property(getNodeType) ownerDocument = property(getOwnerDocument) class DocumentTypeMonad(CDATASectionMonad): 'A monad to handle a document type node.' def getNextMonad(self, character): 'Get the next monad.' self.input.write(character) if character == '>': inputString = self.input.getvalue() if inputString.endswith('?>'): textContent = '%s\n' % inputString self.parentNode.childNodes.append(DocumentTypeNode(self.parentNode, textContent)) return OpenMonad(self.parentNode) return self class DocumentTypeNode(CDATASectionNode): 'A document type node.' def getCopyShallow(self, attributes=None): 'Copy the node and set its parentNode.' return DocumentTypeNode(self.parentNode, self.textContent) def getNodeName(self): 'Get the node name.' return '#forNowDocumentType' def getNodeType(self): 'Get the node type.' return 10 nodeName = property(getNodeName) nodeType = property(getNodeType) class ElementEndMonad: 'A monad to look for the end of an ElementNode tag.' def __init__(self, parentNode): 'Initialize.' self.parentNode = parentNode def getNextMonad(self, character): 'Get the next monad.' if character == '>': return TextMonad(self.parentNode) return self class ElementLocalNameMonad: 'A monad to set the local name of an ElementNode.' def __init__(self, character, parentNode): 'Initialize.' self.input = cStringIO.StringIO() self.input.write(character) self.parentNode = parentNode def getNextMonad(self, character): 'Get the next monad.' if character == '[': if (self.input.getvalue() + character).startswith('![CDATA['): self.input.write(character) return CDATASectionMonad(self.input, self.parentNode) if character == '-': if (self.input.getvalue() + character).startswith('!--'): self.input.write(character) return CommentMonad(self.input, self.parentNode) if character.isspace(): self.setLocalName() return ElementReadMonad(self.elementNode) if character == '/': self.setLocalName() self.elementNode.appendSelfToParent() return ElementEndMonad(self.elementNode.parentNode) if character == '>': self.setLocalName() self.elementNode.appendSelfToParent() return TextMonad(self.elementNode) self.input.write(character) return self def setLocalName(self): 'Set the class name.' self.elementNode = ElementNode(self.parentNode) self.elementNode.localName = self.input.getvalue().lower().strip() class ElementNode: 'An xml element.' def __init__(self, parentNode=None): 'Initialize.' self.attributes = {} self.childNodes = [] self.localName = '' self.parentNode = parentNode self.xmlObject = None def __repr__(self): 'Get the string representation of this xml document.' return '%s\n%s\n%s' % (self.localName, self.attributes, self.getTextContent()) def _getAccessibleAttribute(self, attributeName): 'Get the accessible attribute.' global globalGetAccessibleAttributeSet if attributeName in globalGetAccessibleAttributeSet: return getattr(self, attributeName, None) return None def addSuffixToID(self, idSuffix): 'Add the suffix to the id.' if 'id' in self.attributes: self.attributes['id'] += idSuffix def addToIdentifierDictionaries(self): 'Add the element to the owner document identifier dictionaries.' ownerDocument = self.getOwnerDocument() importNameChain = self.getImportNameChain() idKey = self.getStrippedAttributesValue('id') if idKey is not None: ownerDocument.idDictionary[importNameChain + idKey] = self nameKey = self.getStrippedAttributesValue('name') if nameKey is not None: euclidean.addElementToListDictionaryIfNotThere(self, importNameChain + nameKey, ownerDocument.nameDictionary) for tagKey in self.getTagKeys(): euclidean.addElementToListDictionaryIfNotThere(self, tagKey, ownerDocument.tagDictionary) def addXML(self, depth, output): 'Add xml for this elementNode.' innerOutput = cStringIO.StringIO() xml_simple_writer.addXMLFromObjects(depth + 1, self.childNodes, innerOutput) innerText = innerOutput.getvalue() xml_simple_writer.addBeginEndInnerXMLTag(self.attributes, depth, innerText, self.localName, output, self.getTextContent()) def appendChild(self, elementNode): 'Append child elementNode to the child nodes.' self.childNodes.append(elementNode) elementNode.addToIdentifierDictionaries() return elementNode def appendSelfToParent(self): 'Append self to the parentNode.' self.parentNode.appendChild(self) def copyXMLChildNodes(self, idSuffix, parentNode): 'Copy the xml childNodes.' for childNode in self.childNodes: childNode.getCopy(idSuffix, parentNode) def getCascadeBoolean(self, defaultBoolean, key): 'Get the cascade boolean.' if key in self.attributes: value = evaluate.getEvaluatedBoolean(None, self, key) if value is not None: return value return self.parentNode.getCascadeBoolean(defaultBoolean, key) def getCascadeFloat(self, defaultFloat, key): 'Get the cascade float.' if key in self.attributes: value = evaluate.getEvaluatedFloat(None, self, key) if value is not None: return value return self.parentNode.getCascadeFloat(defaultFloat, key) def getChildElementsByLocalName(self, localName): 'Get the childNodes which have the given local name.' return getChildElementsByLocalName(self.childNodes, localName) def getCopy(self, idSuffix, parentNode): 'Copy the xml element, set its dictionary and add it to the parentNode.' matrix4X4 = matrix.getBranchMatrixSetElementNode(self) attributesCopy = self.attributes.copy() attributesCopy.update(matrix4X4.getAttributes('matrix.')) copy = self.getCopyShallow(attributesCopy) copy.setParentAddToChildNodes(parentNode) copy.addSuffixToID(idSuffix) copy.addToIdentifierDictionaries() self.copyXMLChildNodes(idSuffix, copy) return copy def getCopyShallow(self, attributes=None): 'Copy the xml element and set its dictionary and parentNode.' if attributes is None: # to evade default initialization bug where a dictionary is initialized to the last dictionary attributes = {} copyShallow = ElementNode(self.parentNode) copyShallow.attributes = attributes copyShallow.localName = self.localName return copyShallow def getDocumentElement(self): 'Get the document element.' return self.getOwnerDocument().getDocumentElement() def getElementNodeByID(self, idKey): 'Get the xml element by id.' idDictionary = self.getOwnerDocument().idDictionary idKey = self.getImportNameChain() + idKey if idKey in idDictionary: return idDictionary[idKey] return None def getElementNodesByName(self, nameKey): 'Get the xml elements by name.' nameDictionary = self.getOwnerDocument().nameDictionary nameKey = self.getImportNameChain() + nameKey if nameKey in nameDictionary: return nameDictionary[nameKey] return None def getElementNodesByTag(self, tagKey): 'Get the xml elements by tag.' tagDictionary = self.getOwnerDocument().tagDictionary if tagKey in tagDictionary: return tagDictionary[tagKey] return None def getElementsByLocalName(self, localName): 'Get the descendents which have the given local name.' return getElementsByLocalName(self.childNodes, localName) def getFirstChildByLocalName(self, localName): 'Get the first childNode which has the given class name.' for childNode in self.childNodes: if localName.lower() == childNode.getNodeName(): return childNode return None def getIDSuffix(self, elementIndex=None): 'Get the id suffix from the dictionary.' suffix = self.localName if 'id' in self.attributes: suffix = self.attributes['id'] if elementIndex is None: return '_%s' % suffix return '_%s_%s' % (suffix, elementIndex) def getImportNameChain(self, suffix=''): 'Get the import name chain with the suffix at the end.' importName = self.getStrippedAttributesValue('_importName') if importName is not None: suffix = '%s.%s' % (importName, suffix) return self.parentNode.getImportNameChain(suffix) def getNodeName(self): 'Get the node name.' return self.localName def getNodeType(self): 'Get the node type.' return 1 def getOwnerDocument(self): 'Get the owner document.' return self.parentNode.getOwnerDocument() def getParser(self): 'Get the parser.' return self.getOwnerDocument() def getPaths(self): 'Get all paths.' if self.xmlObject is None: return [] return self.xmlObject.getPaths() def getPreviousElementNode(self): 'Get previous ElementNode if it exists.' if self.parentNode is None: return None previousElementNodeIndex = self.parentNode.childNodes.index(self) - 1 if previousElementNodeIndex < 0: return None return self.parentNode.childNodes[previousElementNodeIndex] def getPreviousVertex(self, defaultVector3=None): 'Get previous vertex if it exists.' if self.parentNode is None: return defaultVector3 if self.parentNode.xmlObject is None: return defaultVector3 if len(self.parentNode.xmlObject.vertexes) < 1: return defaultVector3 return self.parentNode.xmlObject.vertexes[-1] def getStrippedAttributesValue(self, keyString): 'Get the stripped attribute value if the length is at least one, otherwise return None.' if keyString in self.attributes: strippedAttributesValue = self.attributes[keyString].strip() if len(strippedAttributesValue) > 0: return strippedAttributesValue return None def getSubChildWithID( self, idReference ): 'Get the childNode which has the idReference.' for childNode in self.childNodes: if 'bf:id' in childNode.attributes: if childNode.attributes['bf:id'] == idReference: return childNode subChildWithID = childNode.getSubChildWithID( idReference ) if subChildWithID is not None: return subChildWithID return None def getTagKeys(self): 'Get stripped tag keys.' if 'tags' not in self.attributes: return [] tagKeys = [] tagString = self.attributes['tags'] if tagString.startswith('='): tagString = tagString[1 :] if tagString.startswith('['): tagString = tagString[1 :] if tagString.endswith(']'): tagString = tagString[: -1] for tagWord in tagString.split(','): tagKey = tagWord.strip() if tagKey != '': tagKeys.append(tagKey) return tagKeys def getTextContent(self): 'Get the text from the child nodes.' if len(self.childNodes) == 0: return '' firstNode = self.childNodes[0] if firstNode.nodeType == 3: return firstNode.textContent return '' def getValueByKey( self, key ): 'Get value by the key.' if key in evaluate.globalElementValueDictionary: return evaluate.globalElementValueDictionary[key](self) if key in self.attributes: return evaluate.getEvaluatedLinkValue(self, self.attributes[key]) return None def getVertexes(self): 'Get the vertexes.' if self.xmlObject is None: return [] return self.xmlObject.getVertexes() def getXMLProcessor(self): 'Get the xmlProcessor.' return self.getDocumentElement().xmlProcessor def linkObject(self, xmlObject): 'Link self to xmlObject and add xmlObject to archivableObjects.' self.xmlObject = xmlObject self.xmlObject.elementNode = self self.parentNode.xmlObject.archivableObjects.append(self.xmlObject) def printAllVariables(self): 'Print all variables.' print('attributes') print(self.attributes) print('childNodes') print(self.childNodes) print('localName') print(self.localName) print('parentNode') print(self.parentNode.getNodeName()) print('text') print(self.getTextContent()) print('xmlObject') print(self.xmlObject) print('') def printAllVariablesRoot(self): 'Print all variables and the document element variables.' self.printAllVariables() documentElement = self.getDocumentElement() if documentElement is not None: print('') print('Root variables:') documentElement.printAllVariables() def removeChildNodesFromIDNameParent(self): 'Remove the childNodes from the id and name dictionaries and the childNodes.' childNodesCopy = self.childNodes[:] for childNode in childNodesCopy: childNode.removeFromIDNameParent() def removeFromIDNameParent(self): 'Remove this from the id and name dictionaries and the childNodes of the parentNode.' self.removeChildNodesFromIDNameParent() idKey = self.getStrippedAttributesValue('id') if idKey is not None: idDictionary = self.getOwnerDocument().idDictionary idKey = self.getImportNameChain() + idKey if idKey in idDictionary: del idDictionary[idKey] nameKey = self.getStrippedAttributesValue('name') if nameKey is not None: euclidean.removeElementFromListTable(self, self.getImportNameChain() + nameKey, self.getOwnerDocument().nameDictionary) for tagKey in self.getTagKeys(): euclidean.removeElementFromListTable(self, tagKey, self.getOwnerDocument().tagDictionary) if self.parentNode is not None: self.parentNode.childNodes.remove(self) def setParentAddToChildNodes(self, parentNode): 'Set the parentNode and add this to its childNodes.' self.parentNode = parentNode if self.parentNode is not None: self.parentNode.childNodes.append(self) def setTextContent(self, textContent=''): 'Get the text from the child nodes.' if len(self.childNodes) == 0: self.childNodes.append(TextNode(self, textContent)) return firstNode = self.childNodes[0] if firstNode.nodeType == 3: firstNode.textContent = textContent self.childNodes.append(TextNode(self, textContent)) nodeName = property(getNodeName) nodeType = property(getNodeType) ownerDocument = property(getOwnerDocument) textContent = property(getTextContent) class ElementReadMonad: 'A monad to read the attributes of the ElementNode tag.' def __init__(self, elementNode): 'Initialize.' self.elementNode = elementNode def getNextMonad(self, character): 'Get the next monad.' if character.isspace(): return self if character == '/': self.elementNode.appendSelfToParent() return ElementEndMonad(self.elementNode.parentNode) if character == '>': self.elementNode.appendSelfToParent() return TextMonad(self.elementNode) return KeyMonad(character, self.elementNode) class KeyMonad: 'A monad to set the key of an attribute of an ElementNode.' def __init__(self, character, elementNode): 'Initialize.' self.input = cStringIO.StringIO() self.input.write(character) self.elementNode = elementNode def getNextMonad(self, character): 'Get the next monad.' if character == '=': return ValueMonad(self.elementNode, self.input.getvalue().strip()) self.input.write(character) return self class OpenChooseMonad(ElementEndMonad): 'A monad to choose the next monad.' def getNextMonad(self, character): 'Get the next monad.' if character.isspace(): return self if character == '?': input = cStringIO.StringIO() input.write(' 0: self.parentNode.childNodes.append(TextNode(self.parentNode, inputString)) return OpenChooseMonad(self.parentNode) self.input.write(character) return self class TextNode(CDATASectionNode): 'A text node.' def addXML(self, depth, output): 'Add xml for this text node.' pass def getCopyShallow(self, attributes=None): 'Copy the node and set its parentNode.' return TextNode(self.parentNode, self.textContent) def getNodeName(self): 'Get the node name.' return '#text' def getNodeType(self): 'Get the node type.' return 3 nodeName = property(getNodeName) nodeType = property(getNodeType) class ValueMonad: 'A monad to set the value of an attribute of an ElementNode.' def __init__(self, elementNode, key): 'Initialize.' self.elementNode = elementNode self.input = cStringIO.StringIO() self.key = key self.quoteCharacter = None def getNextMonad(self, character): 'Get the next monad.' if self.quoteCharacter is None: if character == '"' or character == "'": self.quoteCharacter = character return self if self.quoteCharacter == character: self.elementNode.attributes[self.key] = self.input.getvalue() return ElementReadMonad(self.elementNode) self.input.write(character) return self sfact-2011.12.18/fabmetheus_utilities/xml_simple_writer.py000066400000000000000000000105431167321211700235500ustar00rootroot00000000000000""" XML tag writer utilities. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ import cStringIO __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead \nArt of Illusion ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addBeginEndInnerXMLTag(attributes, depth, innerText, localName, output, text=''): 'Add the begin and end xml tag and the inner text if any.' if len( innerText ) > 0: addBeginXMLTag(attributes, depth, localName, output, text) output.write( innerText ) addEndXMLTag(depth, localName, output) else: addClosedXMLTag(attributes, depth, localName, output, text) def addBeginXMLTag(attributes, depth, localName, output, text=''): 'Add the begin xml tag.' depthStart = '\t' * depth output.write('%s<%s%s>%s\n' % (depthStart, localName, getAttributesString(attributes), text)) def addClosedXMLTag(attributes, depth, localName, output, text=''): 'Add the closed xml tag.' depthStart = '\t' * depth attributesString = getAttributesString(attributes) if len(text) > 0: output.write('%s<%s%s >%s\n' % (depthStart, localName, attributesString, text, localName)) else: output.write('%s<%s%s />\n' % (depthStart, localName, attributesString)) def addEndXMLTag(depth, localName, output): 'Add the end xml tag.' depthStart = '\t' * depth output.write('%s\n' % (depthStart, localName)) def addXMLFromLoopComplexZ(attributes, depth, loop, output, z): 'Add xml from loop.' addBeginXMLTag(attributes, depth, 'path', output) for pointComplexIndex in xrange(len(loop)): pointComplex = loop[pointComplexIndex] addXMLFromXYZ(depth + 1, pointComplexIndex, output, pointComplex.real, pointComplex.imag, z) addEndXMLTag(depth, 'path', output) def addXMLFromObjects(depth, objects, output): 'Add xml from objects.' for object in objects: object.addXML(depth, output) def addXMLFromVertexes(depth, output, vertexes): 'Add xml from loop.' for vertexIndex in xrange(len(vertexes)): vertex = vertexes[vertexIndex] addXMLFromXYZ(depth + 1, vertexIndex, output, vertex.x, vertex.y, vertex.z) def addXMLFromXYZ(depth, index, output, x, y, z): 'Add xml from x, y & z.' attributes = {'index' : str(index)} if x != 0.0: attributes['x'] = str(x) if y != 0.0: attributes['y'] = str(y) if z != 0.0: attributes['z'] = str(z) addClosedXMLTag(attributes, depth, 'vertex', output) def compareAttributeKeyAscending(key, otherKey): 'Get comparison in order to sort attribute keys in ascending order, with the id key first and name second.' if key == 'id': return - 1 if otherKey == 'id': return 1 if key == 'name': return - 1 if otherKey == 'name': return 1 if key < otherKey: return - 1 return int(key > otherKey) def getAttributesString(attributes): 'Add the closed xml tag.' attributesString = '' attributesKeys = attributes.keys() attributesKeys.sort(compareAttributeKeyAscending) for attributesKey in attributesKeys: valueString = str(attributes[attributesKey]) if "'" in valueString: attributesString += ' %s="%s"' % (attributesKey, valueString) else: attributesString += " %s='%s'" % (attributesKey, valueString) return attributesString def getBeginGeometryXMLOutput(elementNode=None): 'Get the beginning of the string representation of this boolean geometry object info.' output = getBeginXMLOutput() attributes = {} if elementNode is not None: documentElement = elementNode.getDocumentElement() attributes = documentElement.attributes addBeginXMLTag(attributes, 0, 'fabmetheus', output) return output def getBeginXMLOutput(): 'Get the beginning of the string representation of this object info.' output = cStringIO.StringIO() output.write("\n") return output def getDictionaryWithoutList(dictionary, withoutList): 'Get the dictionary without the keys in the list.' dictionaryWithoutList = {} for key in dictionary: if key not in withoutList: dictionaryWithoutList[key] = dictionary[key] return dictionaryWithoutList def getEndGeometryXMLString(output): 'Get the string representation of this object info.' addEndXMLTag(0, 'fabmetheus', output) return output.getvalue() sfact-2011.12.18/models/000077500000000000000000000000001167321211700144735ustar00rootroot00000000000000sfact-2011.12.18/models/Screw Holder Bottom.stl000066400000000000000000002252011167321211700207270ustar00rootroot00000000000000solid "Screw_Holder_Bottom"; Produced by Art of Illusion 2.4, Fri Oct 16 16:42:04 PDT 2009 facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.804173569059 0.110046151702 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 24.730643081307 0 vertex 14.883210818105 25.830303993361 0 vertex 15.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 23 0 vertex 54.002309837942 24.730643081307 0 vertex 60 40 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 54.002309837942 15.269356918694 0 vertex 48.011309837942 15.269356918694 0 vertex 54.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 15.830303993361 11.883210818105 0 vertex 16.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 43.737436867076 27.737436867076 0 vertex 43.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 43.169696006639 15.116789181895 0 vertex 42.5 15.25 0 vertex 41.422110817733 17 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 48.011309837942 24.730643081307 0 vertex 54.002309837942 24.730643081307 0 vertex 48.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 43.169696006639 28.116789181895 0 vertex 42.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 40 0 vertex 52 30 0 vertex 52 40 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 14.169696006639 0 vertex 14.75 13.5 0 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 27.169696006639 0 vertex 14.042553191489 30 0 vertex 15.262563132924 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 16.5 11.75 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 48.011309837942 15.195826430941 0.110046151702 vertex 54.002309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 17.169696006639 28.116789181895 0 vertex 16.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 14.75 13.5 0 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 17 0 vertex 60 17 0 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 42.5 11.75 0 vertex 43.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 15.262563132924 14.737436867076 0 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 14.464705848856 10 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 15.830303993361 28.116789181895 0 vertex 15.262563132924 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 15.262563132924 12.262563132924 0 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 16.5 28.25 0 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 24.730643081307 0 vertex 60 23 0 vertex 54.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 23 0 vertex 16.5 24.75 0 vertex 17.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 15.195826430941 0.110046151702 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.75 26.5 0 vertex 12.002309837942 24.730643081307 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 60 40 0 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.422110817733 17 0 vertex 48.011309837942 17 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 13.5 0 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 6.011309837942 17 0 vertex 6.011309837942 15.269356918694 0 vertex 0 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.422110817733 17 0 vertex 41.830303993361 15.116789181895 0 vertex 41.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 11.883210818105 0 vertex 17.737436867076 12.262563132924 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 15.269356918694 0 vertex 0 10 0 vertex 0 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 25.830303993361 0 vertex 12.002309837942 24.730643081307 0 vertex 14.75 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 52 30 0 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 17 0 vertex 43.737436867076 14.737436867076 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 15.25 0 vertex 41.830303993361 15.116789181895 0 vertex 41.422110817733 17 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 14.883210818105 12.830303993361 0 vertex 6.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 23 0 vertex 0 30 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 12.002309837942 15.269356918694 0 vertex 6.011309837942 15.269356918694 0 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 60 17 0 vertex 52 10 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 23 0 vertex 0 23 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 48.011309837942 15.269356918694 0 vertex 44.25 13.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 27.169696006639 0 vertex 41.262563132924 25.262563132924 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 25.830303993361 0 vertex 18.25 26.5 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 14.737436867076 0 vertex 41.262563132924 14.737436867076 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.830303993361 24.883210818105 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 25.262563132924 0 vertex 18.116789181895 25.830303993361 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 12.262563132924 0 vertex 18.116789181895 12.830303993361 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 12.262563132924 0 vertex 41.262563132924 12.262563132924 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 17.169696006639 28.116789181895 0 vertex 41.830303993361 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 11.75 0 vertex 14.464705848856 10 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.25 26.5 0 vertex 44.116789181895 27.169696006639 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 12.830303993361 0 vertex 41.262563132924 12.262563132924 0 vertex 17.737436867076 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 17.737436867076 25.262563132924 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 12.830303993361 0 vertex 44.25 13.5 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 12.830303993361 0 vertex 40.75 13.5 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.25 13.5 0 vertex 18.116789181895 14.169696006639 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 14.737436867076 0 vertex 17.737436867076 14.737436867076 0 vertex 17.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 14.169696006639 0 vertex 17.737436867076 14.737436867076 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 44.25 26.5 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 14.75 13.5 0.77775 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.75 13.5 0.77775 vertex 14.75 13.5 0 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 41.830303993361 28.116789181895 0 vertex 42.5 28.25 0.77775 vertex 41.830303993361 28.116789181895 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.830303993361 24.883210818105 0.77775 vertex 15.830303993361 24.883210818105 0 vertex 15.262563132924 25.262563132924 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 16.5 28.25 0 vertex 17.169696006639 28.116789181895 0.77775 vertex 16.5 28.25 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 43.169696006639 24.883210818105 0 vertex 42.5 24.75 0.77775 vertex 43.169696006639 24.883210818105 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 28.25 0.77775 vertex 15.830303993361 28.116789181895 0.77775 vertex 16.5 28.25 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 15.830303993361 28.116789181895 0.77775 vertex 15.830303993361 28.116789181895 0 vertex 16.5 28.25 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 23 0 vertex 6.011309837942 23 0.77775 vertex 0 23 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 60 0 0.77775 vertex 52 10 0.77775 vertex 52 0 0.77775 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 27.169696006639 0 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.75 26.5 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.169696006639 24.883210818105 0 vertex 16.5 24.75 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 0 0 vertex 52 0 0.77775 vertex 52 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.883210818105 12.830303993361 0.77775 vertex 40.75 13.5 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 42.5 24.75 0 vertex 41.830303993361 24.883210818105 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 0 0 vertex 60 0 0.77775 vertex 52 0 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 28.116789181895 0.77775 vertex 15.262563132924 27.737436867076 0.77775 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.262563132924 27.737436867076 0.77775 vertex 15.262563132924 27.737436867076 0 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0 1 0 outer loop vertex 6.011309837942 17 0.77775 vertex 6.011309837942 17 0 vertex 0 17 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 17 0 vertex 48.011309837942 17 0.77775 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 18.25 26.5 0 vertex 18.25 26.5 0.77775 vertex 18.116789181895 27.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.455907969142 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 54.002309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 44.25 26.5 0 vertex 44.25 26.5 0.77775 vertex 44.116789181895 27.169696006639 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 10 0 vertex 15.306548743796 10 0.77775 vertex 14.464705848856 10 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 26.5 0.77775 vertex 40.883210818105 25.830303993361 0 vertex 40.75 26.5 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 48.011309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 43.737436867076 27.737436867076 0.77775 vertex 44.116789181895 27.169696006639 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 43.737436867076 27.737436867076 0 vertex 44.116789181895 27.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 10 0 vertex 52 10 0.77775 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 23 0.77775 vertex 6.011309837942 23 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.883210818105 14.169696006639 0.77775 vertex 41.262563132924 14.737436867076 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 26.5 0 vertex 14.883210818105 25.830303993361 0.77775 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 6.011309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 18.116789181895 14.169696006639 0.77775 vertex 17.737436867076 14.737436867076 0.77775 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 17.737436867076 14.737436867076 0 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 42.5 15.25 0.77775 vertex 41.830303993361 15.116789181895 0.77775 vertex 42.5 15.25 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 41.830303993361 15.116789181895 0.77775 vertex 41.830303993361 15.116789181895 0 vertex 42.5 15.25 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 14.883210818105 14.169696006639 0.77775 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 14.883210818105 14.169696006639 0 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 43.169696006639 15.116789181895 0 vertex 43.737436867076 14.737436867076 0.77775 vertex 43.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 13.5 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.75 13.5 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 40.883210818105 14.169696006639 0.77775 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 11.75 0.77775 vertex 43.169696006639 11.883210818105 0.77775 vertex 43.169696006639 11.883210818105 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 17.169696006639 15.116789181895 0 vertex 17.737436867076 14.737436867076 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.730643081307 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 6.011309837942 23 0.77775 vertex 0 23 0 vertex 6.011309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 48.011309837942 23 0 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.195826430941 0.110046151702 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 10 0 vertex 6.011309837942 15.269356918694 0 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 -0 outer loop vertex 17.169696006639 28.116789181895 0.77775 vertex 16.5 28.25 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 44.116789181895 27.169696006639 0 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.25 26.5 0.77775 vertex 44.25 26.5 0 vertex 44.116789181895 25.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 40.75 26.5 0.77775 vertex 37.474084379442 23 0.77775 vertex 40.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.75 13.5 0.77775 vertex 40.883210818105 14.169696006639 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 17.169696006639 11.883210818105 0 vertex 16.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 52 30 0.77775 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 15.063011877768 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.75 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 48.011309837942 15.063011877768 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 24.883210818105 0.77775 vertex 42.5 24.75 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 24.730643081307 0 vertex 14.883210818105 27.169696006639 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.737436867076 14.737436867076 0.77775 vertex 43.169696006639 15.116789181895 0 vertex 43.737436867076 14.737436867076 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 41.866228156844 30 0.77775 vertex 43.169696006639 28.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 41.830303993361 15.116789181895 0.77775 vertex 42.5 15.25 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 11.75 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 0 23 0.77775 vertex 0 30 0 vertex 0 23 0 endloop endfacet facet normal -1 0 0 outer loop vertex 0 30 0 vertex 0 23 0.77775 vertex 0 30 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 52 10 0 vertex 52 0 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 11.883210818105 0 vertex 17.169696006639 11.883210818105 0.77775 vertex 17.737436867076 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 43.169696006639 28.116789181895 0.77775 vertex 41.866228156844 30 0.77775 vertex 42.5 28.25 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 14.042553191489 30 0 vertex 41.866228156844 30 0.77775 vertex 52 30 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 42.5 11.75 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 12.262563132924 0.77775 vertex 15.830303993361 11.883210818105 0 vertex 15.262563132924 12.262563132924 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 40.75 26.5 0.77775 vertex 40.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 27.169696006639 0 vertex 40.883210818105 25.830303993361 0 vertex 41.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 17.169696006639 28.116789181895 0 vertex 14.042553191489 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 15.262563132924 27.737436867076 0.77775 vertex 15.830303993361 28.116789181895 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 25.830303993361 0.77775 vertex 15.262563132924 25.262563132924 0.77775 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 15.262563132924 25.262563132924 0.77775 vertex 15.262563132924 25.262563132924 0 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 24.804173569059 0.110046151702 vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 43.737436867076 27.737436867076 0 vertex 52 30 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 25.830303993361 0 vertex 18.116789181895 25.830303993361 0.77775 vertex 18.25 26.5 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.195826430941 0.110046151702 vertex 54.002309837942 15.063011877768 0.77775 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 15.116789181895 0 vertex 41.830303993361 15.116789181895 0.77775 vertex 41.262563132924 14.737436867076 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 43.169696006639 28.116789181895 0.77775 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.169696006639 28.116789181895 0.77775 vertex 43.169696006639 28.116789181895 0 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 42.5 11.75 0.77775 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 23 0.77775 vertex 15.830303993361 24.883210818105 0.77775 vertex 15.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 41.262563132924 14.737436867076 0 vertex 41.830303993361 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 17 0 vertex 60 0 0 vertex 52 0 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 25.262563132924 0 vertex 15.262563132924 25.262563132924 0.77775 vertex 15.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 23 0 vertex 17.379510917074 23 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 6.011309837942 23 0.77775 vertex 6.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 11.883210818105 0 vertex 41.830303993361 11.883210818105 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 14.042553191489 30 0 vertex 52 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 43.169696006639 15.116789181895 0.77775 vertex 43.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 17 0.77775 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 18.116789181895 27.169696006639 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.75 26.5 0 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.75 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 0 30 0.77775 vertex 14.883210818105 27.169696006639 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 11.75 0.77775 vertex 43.169696006639 11.883210818105 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 15.830303993361 28.116789181895 0.77775 vertex 16.5 28.25 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 52 30 0.77775 vertex 52 30 0 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 17 0 vertex 52 0 0 vertex 52 10 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 0 outer loop vertex 44.116789181895 14.169696006639 0.77775 vertex 43.737436867076 14.737436867076 0.77775 vertex 43.737436867076 14.737436867076 0 endloop endfacet facet normal 0 1 0 outer loop vertex 14.607403236621 30 0.77775 vertex 41.866228156844 30 0.77775 vertex 14.042553191489 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 15.306548743796 10 0.77775 vertex 17.737436867076 12.262563132924 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.269356918694 0 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 17 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 16.5 24.75 0 vertex 16.5 24.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 43.169696006639 24.883210818105 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 6.011309837942 17 0.77775 vertex 0 17 0 vertex 0 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 16.5 28.25 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 17.737436867076 25.262563132924 0 vertex 17.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 24.75 0.77775 vertex 17.379510917074 23 0.77775 vertex 17.169696006639 24.883210818105 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 44.116789181895 27.169696006639 0 vertex 44.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.75 13.5 0 vertex 18.25 13.5 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 48.011309837942 24.730643081307 0 vertex 48.011309837942 23 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 10 0.77775 vertex 0 10 0 vertex 14.464705848856 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 15.306548743796 10 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.262563132924 12.262563132924 0.77775 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 28.116789181895 0 vertex 43.169696006639 28.116789181895 0.77775 vertex 42.5 28.25 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 16.5 11.75 0 vertex 16.5 11.75 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 18.25 13.5 0.77775 vertex 18.116789181895 14.169696006639 0.77775 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.737436867076 25.262563132924 0 vertex 17.169696006639 24.883210818105 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 10 0.77775 vertex 14.464705848856 10 0 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 17.737436867076 14.737436867076 0 vertex 17.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.866228156844 30 0.77775 vertex 41.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 16.5 11.75 0.77775 vertex 15.830303993361 11.883210818105 0 vertex 15.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.75 26.5 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 44.116789181895 14.169696006639 0.77775 vertex 43.737436867076 14.737436867076 0 vertex 44.116789181895 14.169696006639 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 60 17 0.77775 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 12.002309837942 15.195826430941 0.110046151702 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 23 0.77775 vertex 17.379510917074 23 0.77775 vertex 15.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.830303993361 24.883210818105 0.77775 vertex 17.379510917074 23 0.77775 vertex 16.5 24.75 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.25 26.5 0.77775 vertex 18.25 26.5 0 vertex 18.116789181895 25.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 25.262563132924 0.77775 vertex 37.474084379442 23 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 14.883210818105 27.169696006639 0.77775 vertex 15.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 15.455907969142 17 0.77775 vertex 17.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 34.416922535211 17 0.77775 vertex 15.455907969142 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.306548743796 10 0.77775 vertex 15.262563132924 12.262563132924 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.737436867076 25.262563132924 0.77775 vertex 17.737436867076 25.262563132924 0 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 15.25 0.77775 vertex 15.455907969142 17 0.77775 vertex 15.830303993361 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 42.5 28.25 0.77775 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 18.25 13.5 0.77775 vertex 18.25 13.5 0 endloop endfacet facet normal 0 1 0 outer loop vertex 60 17 0.77775 vertex 60 17 0 vertex 54.002309837942 17 0 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 12.002309837942 17 0 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 11.883210818105 0 vertex 43.737436867076 12.262563132924 0.77775 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 11.883210818105 0 vertex 43.169696006639 11.883210818105 0.77775 vertex 43.737436867076 12.262563132924 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 18.25 13.5 0.77775 vertex 18.116789181895 14.169696006639 0 vertex 18.25 13.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 41.830303993361 28.116789181895 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 23 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 15.455907969142 17 0.77775 vertex 16.5 15.25 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 17.737436867076 12.262563132924 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 52 40 0.77775 vertex 60 23 0.77775 vertex 60 40 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.75 13.5 0 vertex 18.116789181895 12.830303993361 0 vertex 18.25 13.5 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 28.116789181895 0 vertex 42.5 28.25 0.77775 vertex 42.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 12.002309837942 23 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 23 0.77775 vertex 60 23 0.77775 vertex 54.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 23 0.77775 vertex 6.011309837942 24.730643081307 0 vertex 6.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 17.169696006639 15.116789181895 0 vertex 16.5 15.25 0.77775 vertex 16.5 15.25 0 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 17 0.77775 vertex 6.011309837942 15.063011877768 0.77775 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 1 0 0 outer loop vertex 60 17 0.77775 vertex 60 0 0 vertex 60 17 0 endloop endfacet facet normal 1 0 0 outer loop vertex 60 0 0.77775 vertex 60 0 0 vertex 60 17 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 12.262563132924 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 43.737436867076 12.262563132924 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 12.002309837942 15.063011877768 0.77775 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.379510917074 23 0.77775 vertex 17.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 43.737436867076 12.262563132924 0.77775 vertex 43.169696006639 11.883210818105 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 42.5 28.25 0.77775 vertex 41.830303993361 28.116789181895 0 vertex 42.5 28.25 0 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 17 0 vertex 6.011309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 25.830303993361 0.77775 vertex 37.474084379442 23 0.77775 vertex 41.262563132924 25.262563132924 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 18.25 13.5 0 vertex 18.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 25.262563132924 0.77775 vertex 17.379510917074 23 0.77775 vertex 18.116789181895 25.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 41.262563132924 14.737436867076 0.77775 vertex 41.830303993361 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 30 0.77775 vertex 6.011309837942 24.936988122232 0.77775 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 17.379510917074 23 0.77775 vertex 37.474084379442 23 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 43.169696006639 11.883210818105 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 40.883210818105 14.169696006639 0 vertex 41.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 43.169696006639 24.883210818105 0 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.25 26.5 0.77775 vertex 44.116789181895 25.830303993361 0 vertex 44.116789181895 25.830303993361 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 60 17 0.77775 vertex 54.002309837942 17 0 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 42.5 24.75 0 vertex 43.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 44.116789181895 27.169696006639 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 18.116789181895 25.830303993361 0 vertex 17.737436867076 25.262563132924 0 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.195826430941 0.110046151702 vertex 54.002309837942 17 0.77775 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 14.75 26.5 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 0 0.77775 vertex 52 0 0 vertex 60 0 0.77775 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 14.75 26.5 0.77775 vertex 14.75 26.5 0 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.269356918694 0 vertex 54.002309837942 17 0.77775 vertex 54.002309837942 17 0 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 11.75 0.77775 vertex 15.306548743796 10 0.77775 vertex 17.169696006639 11.883210818105 0.77775 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 17.169696006639 15.116789181895 0 vertex 17.169696006639 15.116789181895 0.77775 vertex 16.5 15.25 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.195826430941 0.110046151702 vertex 12.002309837942 15.063011877768 0.77775 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 48.011309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 16.5 11.75 0.77775 vertex 16.5 11.75 0 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 48.011309837942 15.269356918694 0 vertex 48.011309837942 17 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 52 30 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 24.75 0.77775 vertex 43.169696006639 24.883210818105 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 26.5 0 vertex 14.75 26.5 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 43.737436867076 14.737436867076 0 vertex 48.011309837942 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 48.011309837942 17 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 41.830303993361 24.883210818105 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 42.5 24.75 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 1 0 outer loop vertex 52 40 0 vertex 52 40 0.77775 vertex 60 40 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 52 40 0 vertex 60 40 0.77775 vertex 60 40 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0.77775 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 15.830303993361 24.883210818105 0 vertex 15.830303993361 24.883210818105 0.77775 vertex 16.5 24.75 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 15.830303993361 24.883210818105 0 vertex 16.5 24.75 0.77775 vertex 16.5 24.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 24.936988122232 0.77775 vertex 12.002309837942 23 0.77775 vertex 15.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 24.936988122232 0.77775 vertex 15.262563132924 25.262563132924 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 60 40 0.77775 vertex 60 23 0.77775 vertex 60 23 0 endloop endfacet facet normal 1 0 0 outer loop vertex 60 40 0.77775 vertex 60 23 0 vertex 60 40 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 27.737436867076 0 vertex 15.262563132924 27.737436867076 0.77775 vertex 14.883210818105 27.169696006639 0.77775 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 27.737436867076 0 vertex 14.883210818105 27.169696006639 0.77775 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 1 outer loop vertex 37.474084379442 23 0.77775 vertex 48.011309837942 23 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 37.474084379442 23 0.77775 vertex 42.5 24.75 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 14.737436867076 0 vertex 12.002309837942 17 0 vertex 41.422110817733 17 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 15.116789181895 0.77775 vertex 42.5 15.25 0.77775 vertex 42.5 15.25 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 -0 outer loop vertex 43.169696006639 15.116789181895 0.77775 vertex 42.5 15.25 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 52 10 0.77775 vertex 60 0 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 60 0 0.77775 vertex 60 17 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 13.5 0.77775 vertex 40.883210818105 12.830303993361 0.77775 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 13.5 0.77775 vertex 40.883210818105 12.830303993361 0 vertex 40.75 13.5 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.737436867076 27.737436867076 0 vertex 17.737436867076 27.737436867076 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.737436867076 27.737436867076 0 vertex 17.169696006639 28.116789181895 0.77775 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 0 30 0.77775 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 14.75 26.5 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 12.262563132924 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 12.262563132924 0.77775 vertex 44.116789181895 12.830303993361 0 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 48.011309837942 23 0.77775 vertex 37.474084379442 23 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 15.25 0.77775 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.830303993361 15.116789181895 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 15.25 0.77775 vertex 15.830303993361 15.116789181895 0 vertex 16.5 15.25 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 41.262563132924 12.262563132924 0.77775 vertex 41.262563132924 12.262563132924 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 41.262563132924 12.262563132924 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 16.5 15.25 0 vertex 15.830303993361 15.116789181895 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 25.262563132924 0 vertex 43.737436867076 25.262563132924 0.77775 vertex 44.116789181895 25.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 25.262563132924 0 vertex 44.116789181895 25.830303993361 0.77775 vertex 44.116789181895 25.830303993361 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 14.169696006639 0.77775 vertex 40.75 13.5 0.77775 vertex 40.75 13.5 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 14.169696006639 0.77775 vertex 40.75 13.5 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 23 0 vertex 60 23 0.77775 vertex 54.002309837942 23 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 23 0 vertex 54.002309837942 23 0.77775 vertex 54.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 30 0 vertex 14.042553191489 30 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 30 0 vertex 14.883210818105 27.169696006639 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.262563132924 25.262563132924 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.830303993361 24.883210818105 0.77775 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.262563132924 27.737436867076 0.77775 vertex 41.262563132924 27.737436867076 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.262563132924 27.737436867076 0 vertex 41.830303993361 28.116789181895 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 24.883210818105 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 24.883210818105 0.77775 vertex 43.737436867076 25.262563132924 0 vertex 43.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 43.169696006639 11.883210818105 0 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 43.737436867076 12.262563132924 0 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 60 23 0.77775 vertex 52 40 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 52 40 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 34.416922535211 17 0.77775 vertex 41.422110817733 17 0 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 41.422110817733 17 0 vertex 12.002309837942 17 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 12.002309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 12.002309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.730643081307 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 15.455907969142 17 0.77775 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 12.002309837942 17 0.77775 vertex 14.883210818105 14.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 25.830303993361 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 17 0.77775 vertex 0 10 0.77775 vertex 6.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 17 0.77775 vertex 6.011309837942 15.063011877768 0.77775 vertex 6.011309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 34.416922535211 17 0.77775 vertex 42.5 15.25 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 42.5 15.25 0.77775 vertex 43.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 12.002309837942 15.063011877768 0.77775 vertex 14.75 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 0 30 0.77775 vertex 0 23 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 0 23 0.77775 vertex 6.011309837942 23 0.77775 endloop endfacet facet normal -0 -0 -1 outer loop vertex 40.75 26.5 0 vertex 40.883210818105 25.830303993361 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 44.25 13.5 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 44.116789181895 14.169696006639 0 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 44.25 13.5 0.77775 vertex 44.116789181895 14.169696006639 0 vertex 44.25 13.5 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 17.737436867076 12.262563132924 0 vertex 17.737436867076 12.262563132924 0.77775 vertex 18.116789181895 12.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 17.737436867076 12.262563132924 0 vertex 18.116789181895 12.830303993361 0.77775 vertex 18.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 0 10 0.77775 vertex 15.306548743796 10 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 54.002309837942 24.936988122232 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.936988122232 0.77775 vertex 48.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 12.830303993361 0 vertex 14.883210818105 12.830303993361 0.77775 vertex 15.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 12.830303993361 0 vertex 15.262563132924 12.262563132924 0.77775 vertex 15.262563132924 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 43.737436867076 12.262563132924 0 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 44.116789181895 12.830303993361 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 1 0 outer loop vertex 0 30 0 vertex 0 30 0.77775 vertex 14.607403236621 30 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 0 30 0 vertex 14.607403236621 30 0.77775 vertex 14.042553191489 30 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 12.262563132924 0 vertex 41.262563132924 12.262563132924 0.77775 vertex 41.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 12.262563132924 0 vertex 41.830303993361 11.883210818105 0.77775 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal -1 0 0 outer loop vertex 0 10 0 vertex 0 10 0.77775 vertex 0 17 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 0 10 0 vertex 0 17 0.77775 vertex 0 17 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.116789181895 12.830303993361 0.77775 vertex 44.25 13.5 0.77775 vertex 44.25 13.5 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.116789181895 12.830303993361 0.77775 vertex 44.25 13.5 0 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal 0 1 0 outer loop vertex 41.422110817733 17 0 vertex 34.416922535211 17 0.77775 vertex 48.011309837942 17 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 41.422110817733 17 0 vertex 48.011309837942 17 0.77775 vertex 48.011309837942 17 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 30 0.77775 vertex 52 40 0.77775 vertex 52 40 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 30 0.77775 vertex 52 40 0 vertex 52 30 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.830303993361 24.883210818105 0 vertex 16.5 24.75 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 40.883210818105 27.169696006639 0 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 17.737436867076 27.737436867076 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 0 10 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 12.002309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 43.737436867076 14.737436867076 0.77775 vertex 44.116789181895 14.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.262563132924 25.262563132924 0 vertex 15.830303993361 24.883210818105 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.262563132924 25.262563132924 0 vertex 12.002309837942 23 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 44.25 26.5 0.77775 vertex 44.116789181895 25.830303993361 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 27.169696006639 0 vertex 40.75 26.5 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 27.169696006639 0 vertex 18.116789181895 27.169696006639 0 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 41.262563132924 14.737436867076 0 vertex 17.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 17.169696006639 15.116789181895 0 vertex 16.5 15.25 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 15.116789181895 0 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.262563132924 14.737436867076 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 15.116789181895 0 vertex 15.262563132924 14.737436867076 0.77775 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.883210818105 27.169696006639 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0 vertex 41.262563132924 27.737436867076 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 37.474084379442 23 0.77775 vertex 17.379510917074 23 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 17.379510917074 23 0.77775 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 15.830303993361 15.116789181895 0 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 15.262563132924 14.737436867076 0 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 40.883210818105 25.830303993361 0.77775 vertex 41.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 41.262563132924 25.262563132924 0.77775 vertex 41.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 12.830303993361 0 vertex 15.262563132924 12.262563132924 0 vertex 14.464705848856 10 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 12.830303993361 0 vertex 14.464705848856 10 0 vertex 0 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 41.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 17.169696006639 28.116789181895 0.77775 vertex 17.737436867076 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.936988122232 0.77775 vertex 43.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 43.169696006639 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 44.25 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 44.25 26.5 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 48.011309837942 24.936988122232 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 23 0.77775 vertex 54.002309837942 24.936988122232 0.77775 vertex 54.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 41.866228156844 30 0.77775 vertex 14.607403236621 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 14.607403236621 30 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.25 13.5 0.77775 vertex 44.116789181895 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 14.169696006639 0.77775 vertex 18.25 13.5 0.77775 vertex 41.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.25 26.5 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 18.116789181895 27.169696006639 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 24.730643081307 0 vertex 54.002309837942 23 0 vertex 54.002309837942 23 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 24.730643081307 0 vertex 54.002309837942 23 0.77775 vertex 54.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 41.262563132924 12.262563132924 0.77775 vertex 18.25 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 18.25 13.5 0.77775 vertex 18.116789181895 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 17.737436867076 12.262563132924 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 42.5 11.75 0.77775 vertex 41.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 15.306548743796 10 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 52 10 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 18.116789181895 14.169696006639 0.77775 vertex 41.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.25 26.5 0.77775 vertex 40.75 26.5 0.77775 vertex 40.883210818105 27.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 37.474084379442 23 0.77775 vertex 40.75 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 40.75 26.5 0.77775 vertex 18.25 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 34.416922535211 17 0.77775 vertex 17.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 17.737436867076 14.737436867076 0.77775 vertex 18.116789181895 14.169696006639 0.77775 endloop endfacet endsolid sfact-2011.12.18/models/Screw Holder.gts000066400000000000000000002202261167321211700174770ustar00rootroot00000000000000737 2253 1502 Number of Vertices,Number of Edges,Number of Faces -6.859863212247494 0.22628773741583247 9.642249999999999 Vertex Coordinates XYZ -6.649863212247495 0.946287737415833 9.642249999999999 -6.319863212247495 1.396287737415833 9.642249999999999 -5.809863212247494 1.726287737415833 9.642249999999999 -5.2998632122474945 1.8462877374158326 9.642249999999999 -4.519863212247495 1.8462877374158326 9.642249999999999 -4.009863212247495 1.636287737415833 9.642249999999999 -3.6798632122474944 1.2762877374158328 9.642249999999999 -3.4698632122474935 0.7962877374158329 9.642249999999999 -3.3498632122474934 0.016287737415832892 9.642249999999999 -3.3498632122474934 -0.37371226258416745 9.642249999999999 -5.689863212247494 -0.4037122625841675 9.642249999999999 -5.509863212247495 -0.9437122625841673 9.642249999999999 -5.179863212247494 -1.2437122625841672 9.642249999999999 -4.699863212247494 -1.3937122625841676 9.642249999999999 -3.949863212247494 -1.3637122625841673 9.642249999999999 -3.319863212247494 -1.1837122625841672 9.642249999999999 -3.3498632122474934 -1.9637122625841674 9.642249999999999 -4.279863212247495 -2.143712262584168 9.642249999999999 -5.209863212247494 -2.143712262584168 9.642249999999999 -5.929863212247494 -1.9037122625841678 9.642249999999999 -6.409863212247495 -1.4837122625841674 9.642249999999999 -6.679863212247494 -1.0337122625841673 9.642249999999999 -6.829863212247495 -0.4337122625841675 9.642249999999999 -5.4473632122474935 0.8687877374158329 9.642249999999999 -4.457363212247493 0.8387877374158327 9.642249999999999 -4.367363212247493 0.26878773741583245 9.642249999999999 -5.627363212247492 0.3887877374158325 9.642249999999999 -4.667363212247494 1.1087877374158324 9.642249999999999 -5.627363212247492 0.2987877374158325 9.642249999999999 -5.177363212247494 1.1087877374158324 9.642249999999999 -4.009863212247495 1.636287737415833 11.322250000000002 -4.519863212247496 1.8462877374158326 11.322250000000002 -3.6798632122474944 1.276287737415834 11.32225 -3.3498632122474934 -0.37371226258416734 11.32225 -3.3498632122474934 0.016287737415832892 11.32225 -5.689863212247495 -0.4037122625841676 11.32225 -3.9498632122474935 -1.3637122625841673 11.32225 -3.319863212247494 -1.1837122625841672 11.32225 -3.3498632122474943 -1.9637122625841679 11.32225 -6.859863212247496 0.2262877374158324 11.322249999999999 -6.829863212247496 -0.4337122625841676 11.32225 -6.319863212247493 1.396287737415832 11.322249999999999 -5.809863212247494 1.726287737415833 11.32225 -6.649863212247495 0.9462877374158329 11.32225 -5.209863212247495 -2.143712262584168 11.32225 -5.929863212247496 -1.9037122625841687 11.32225 -5.179863212247494 -1.2437122625841672 11.32225 -4.699863212247494 -1.3937122625841676 11.32225 -4.279863212247495 -2.1437122625841676 11.32225 -6.4098632122474966 -1.483712262584167 11.32225 -6.679863212247495 -1.0337122625841677 11.32225 -5.299863212247494 1.846287737415833 11.32225 -3.4698632122474944 0.796287737415833 11.32225 -5.509863212247496 -0.9437122625841675 11.32225 -4.667363212247494 1.1087877374158326 11.32225 -5.177363212247494 1.1087877374158317 11.32225 -4.457363212247494 0.8387877374158329 11.32225 -5.627363212247493 0.38878773741583256 11.32225 -4.367363212247493 0.2687877374158326 11.32225 -5.627363212247492 0.2987877374158324 11.32225 -5.4473632122474935 0.8687877374158326 11.32225 11.759863212247497 1.8856484886916096 9.64225 12.899863212247496 1.8556484886916098 9.64225 12.929863212247495 1.22564848869161 9.64225 13.439863212247495 1.6756484886916105 9.64225 13.889863212247496 1.8556484886916098 9.64225 14.519863212247497 1.8556484886916098 9.64225 14.999863212247497 1.5856484886916102 9.64225 15.359863212247497 1.0756484886916096 9.64225 15.539863212247496 0.3556484886916095 9.64225 15.539863212247496 -0.60435151130839 9.64225 15.329863212247497 -1.23435151130839 9.64225 14.999863212247497 -1.6843515113083907 9.64225 14.609863212247497 -1.9543515113083907 9.64225 14.039863212247496 -2.1343515113083904 9.64225 12.899863212247496 -2.194351511308391 9.64225 12.869863212247497 -3.5143515113083907 9.64225 11.759863212247497 -3.484351511308391 9.64225 12.899863212247496 -1.3843515113083904 9.64225 13.079863212247497 -1.4443515113083905 9.64225 14.279863212247497 -0.9043515113083903 9.64225 12.899863212247496 0.4456484886916098 9.64225 13.379863212247496 0.8956484886916104 9.64225 13.769863212247497 1.0156484886916095 9.64225 14.369863212247497 -0.21435151130839014 9.64225 14.279863212247497 0.5056484886916098 9.64225 14.009863212247497 -1.2943515113083905 9.64225 14.099863212247497 0.8656484886916099 9.64225 13.649863212247496 -1.4443515113083905 9.64225 11.759863212247497 1.8856484886916096 11.32225 12.899863212247498 1.8556484886916098 11.32225 12.929863212247488 1.2256484886916095 11.32225 13.439863212247495 1.6756484886916105 11.32225 13.889863212247494 1.8556484886916107 11.32225 14.519863212247497 1.8556484886916098 11.32225 14.999863212247497 1.5856484886916107 11.32225 15.359863212247493 1.0756484886916098 11.32225 15.5398632122475 0.35564848869160914 11.32225 15.539863212247498 -0.6043515113083899 11.32225 15.329863212247494 -1.234351511308391 11.32225 14.999863212247503 -1.684351511308392 11.32225 14.609863212247497 -1.9543515113083898 11.32225 14.039863212247498 -2.1343515113083895 11.32225 12.899863212247496 -2.194351511308391 11.32225 12.869863212247498 -3.514351511308391 11.32225 11.759863212247494 -3.4843515113083914 11.32225 14.279863212247493 -0.9043515113083888 11.322250000000002 14.009863212247494 -1.2943515113083883 11.322250000000002 13.379863212247498 0.8956484886916118 11.32225 13.769863212247497 1.0156484886916093 11.322249999999997 12.899863212247496 0.4456484886916098 11.32225 12.899863212247496 -1.38435151130839 11.32225 14.36986321224749 -0.2143515113083907 11.32225 14.279863212247497 0.5056484886916095 11.32225 14.099863212247497 0.8656484886916107 11.32225 13.649863212247496 -1.4443515113083905 11.32225 13.0798632122475 -1.4443515113083896 11.32225 2.270136787752506 3.2862877374158317 9.64225 5.210136787752507 3.256287737415831 9.64225 5.7801367877525065 3.0462877374158315 9.64225 6.110136787752507 2.716287737415832 9.64225 6.260136787752507 2.356287737415831 9.64225 6.320136787752506 1.6662877374158316 9.64225 6.140136787752507 1.0962877374158313 9.64225 5.600136787752507 0.5562877374158314 9.64225 5.270136787752507 0.3462877374158312 9.64225 7.040136787752506 -2.1737122625841687 9.64225 5.720136787752507 -2.143712262584169 9.64225 4.220136787752507 0.04628773741583159 9.64225 3.380136787752506 0.01628773741583156 9.64225 3.350136787752507 -2.1737122625841687 9.64225 2.270136787752506 -2.143712262584169 9.64225 3.3801367877525057 2.5062877374158314 9.64225 3.3801367877525057 0.8562877374158319 9.64225 5.120136787752506 1.9962877374158312 9.64225 4.520136787752507 0.9162877374158317 9.64225 5.120136787752506 1.4562877374158316 9.64225 3.920136787752506 0.8262877374158316 9.64225 4.580136787752507 2.476287737415832 9.64225 4.940136787752506 2.296287737415832 9.64225 4.880136787752506 1.0962877374158313 9.64225 2.2701367877525054 3.286287737415832 11.32225 5.210136787752507 3.256287737415833 11.322250000000004 5.780136787752506 3.046287737415832 11.32225 6.1101367877525075 2.7162877374158323 11.32225 6.260136787752506 2.356287737415831 11.32225 6.320136787752505 1.6662877374158316 11.32225 6.140136787752509 1.0962877374158313 11.32225 5.600136787752508 0.5562877374158319 11.32225 5.270136787752508 0.3462877374158302 11.32225 7.040136787752505 -2.1737122625841687 11.32225 5.7201367877525096 -2.143712262584169 11.32225 4.220136787752508 0.046287737415831476 11.32225 3.3801367877525066 0.01628773741583056 11.32225 3.3501367877525063 -2.1737122625841683 11.32225 2.2701367877525063 -2.143712262584169 11.322250000000002 3.9201367877525066 0.8262877374158334 11.32225 4.520136787752508 0.9162877374158318 11.32225 4.880136787752507 1.096287737415831 11.32225 5.120136787752507 1.9962877374158317 11.32225 4.940136787752505 2.296287737415833 11.32225 5.120136787752507 1.4562877374158316 11.32225 3.380136787752506 0.8562877374158319 11.32225 4.580136787752508 2.476287737415833 11.32225 3.3801367877525057 2.506287737415832 11.32225 -2.4198632122474937 1.876287737415832 9.64225 -1.279863212247494 1.8462877374158322 9.64225 -1.2498632122474946 1.2162877374158323 9.64225 -0.7398632122474949 1.666287737415833 9.64225 -0.2898632122474938 1.8462877374158322 9.64225 0.3401367877525061 1.8462877374158322 9.64225 0.8201367877525065 1.5762877374158326 9.64225 1.1801367877525069 1.066287737415832 9.64225 1.3601367877525057 0.34628773741583185 9.64225 1.3601367877525057 -0.6137122625841677 9.64225 1.1501367877525075 -1.2437122625841677 9.64225 0.8201367877525065 -1.6937122625841683 9.64225 0.43013678775250686 -1.9637122625841683 9.64225 -0.13986321224749437 -2.143712262584168 9.64225 -1.279863212247494 -2.2037122625841685 9.64225 -1.3098632122474934 -3.5237122625841684 9.64225 -2.4198632122474937 -3.4937122625841686 9.64225 -1.0998632122474925 -1.453712262584168 9.64225 0.10013678775250578 -0.9137122625841679 9.64225 -1.279863212247494 0.43628773741583216 9.64225 -0.7998632122474936 0.8862877374158328 9.64225 -0.40986321224749395 1.0062877374158319 9.64225 -1.279863212247494 -1.393712262584168 9.64225 0.19013678775250686 -0.22371226258416776 9.64225 0.10013678775250612 0.4962877374158322 9.64225 -0.16986321224749384 -1.3037122625841682 9.64225 -0.07986321224749288 0.8562877374158323 9.64225 -0.5298632122474941 -1.453712262584168 9.64225 -2.4198632122474937 1.876287737415832 11.32225 -1.2798632122474942 1.8462877374158313 11.32225 -1.2498632122474944 1.2162877374158318 11.32225 -0.7398632122474951 1.6662877374158342 11.322249999999999 -0.28986321224749373 1.8462877374158322 11.32225 0.340136787752506 1.8462877374158322 11.32225 0.8201367877525063 1.5762877374158322 11.32225 1.180136787752507 1.0662877374158315 11.32225 1.3601367877525052 0.34628773741583185 11.32225 1.3601367877525052 -0.6137122625841679 11.32225 1.1501367877525073 -1.2437122625841677 11.32225 0.8201367877525064 -1.6937122625841687 11.322250000000002 0.43013678775250686 -1.9637122625841683 11.32225 -0.13986321224749487 -2.143712262584167 11.32225 -1.2798632122474942 -2.203712262584169 11.32225 -1.3098632122474934 -3.5237122625841684 11.32225 -2.4198632122474937 -3.493712262584169 11.32225 0.10013678775250634 -0.9137122625841673 11.32225 -0.16986321224749368 -1.3037122625841677 11.32225 -0.40986321224749384 1.0062877374158323 11.32225 -1.2798632122474942 0.43628773741583216 11.32225 -1.2798632122474942 -1.393712262584168 11.32225 0.19013678775250709 -0.22371226258416776 11.32225 0.10013678775250609 0.4962877374158318 11.32225 -0.07986321224749288 0.8562877374158324 11.32225 -0.5298632122474942 -1.453712262584168 11.32225 -1.0998632122474927 -1.453712262584168 11.32225 -0.7998632122474936 0.8862877374158331 11.32225 -11.929863212247497 3.2862877374158317 9.64225 -8.989863212247496 3.256287737415831 9.64225 -8.419863212247495 3.0462877374158315 9.64225 -8.089863212247495 2.716287737415832 9.64225 -7.939863212247495 2.356287737415831 9.64225 -7.879863212247496 1.6662877374158316 9.64225 -8.059863212247494 1.0962877374158313 9.64225 -8.599863212247495 0.5562877374158314 9.64225 -8.929863212247495 0.3462877374158312 9.64225 -7.159863212247496 -2.1737122625841687 9.64225 -8.479863212247496 -2.143712262584169 9.64225 -9.979863212247496 0.04628773741583159 9.64225 -10.819863212247496 0.01628773741583156 9.64225 -10.849863212247495 -2.1737122625841687 9.64225 -11.929863212247497 -2.143712262584169 9.64225 -10.819863212247496 2.5062877374158314 9.64225 -10.819863212247496 0.8562877374158319 9.64225 -9.079863212247496 1.9962877374158312 9.64225 -9.679863212247495 0.9162877374158317 9.64225 -9.079863212247496 1.4562877374158316 9.64225 -10.279863212247495 0.8262877374158316 9.64225 -9.619863212247495 2.476287737415832 9.64225 -9.259863212247495 2.296287737415832 9.64225 -9.319863212247496 1.0962877374158313 9.64225 -11.9298632122475 3.2862877374158317 11.32225 -8.989863212247498 3.2562877374158314 11.32225 -8.419863212247495 3.046287737415831 11.32225 -8.089863212247495 2.7162877374158314 11.32225 -7.939863212247496 2.3562877374158306 11.322250000000002 -7.879863212247495 1.666287737415833 11.32225 -8.059863212247494 1.096287737415831 11.32225 -8.599863212247495 0.5562877374158306 11.32225 -8.929863212247497 0.3462877374158324 11.32225 -7.159863212247495 -2.1737122625841683 11.32225 -8.479863212247496 -2.143712262584169 11.32225 -9.979863212247498 0.04628773741582992 11.32225 -10.819863212247498 0.016287737415831227 11.32225 -10.849863212247497 -2.1737122625841687 11.32225 -11.929863212247499 -2.1437122625841694 11.32225 -9.679863212247495 0.9162877374158314 11.32225 -9.319863212247498 1.096287737415831 11.322250000000002 -9.079863212247496 1.4562877374158316 11.32225 -9.079863212247496 1.996287737415832 11.322250000000002 -9.259863212247495 2.2962877374158324 11.32225 -10.819863212247496 0.8562877374158329 11.322250000000002 -9.619863212247497 2.476287737415832 11.32225 -10.279863212247498 0.8262877374158322 11.32225 -10.819863212247494 2.5062877374158314 11.32225 30.0 15.073000000000004 7.822250000000002 30.0 15.206210818105248 8.491946006638905 30.0 15.585563132923546 9.059686867076463 30.0 16.153303993361096 9.43903918189475 30.0 16.823 9.572249999999997 30.0 17.49269600663891 9.43903918189475 30.0 18.06043686707646 9.059686867076458 30.0 18.439789181894753 8.49194600663891 30.0 18.573000000000004 7.822250000000006 30.0 18.439789181894753 7.152553993361098 22.000000000000007 18.43978918189476 7.152553993361091 30.0 18.06043686707646 6.5848131329235455 30.0 17.492696006638916 6.205460818105249 30.0 16.823 6.072249999999999 30.0 16.153303993361092 6.205460818105249 30.0 15.585563132923546 6.584813132923542 30.0 15.206210818105244 7.152553993361091 22.000000000000007 15.073000000000006 7.822250000000001 22.000000000000007 15.206210818105252 8.491946006638905 22.000000000000007 15.585563132923546 9.05968686707646 22.000000000000007 16.823000000000008 9.572249999999997 22.000000000000007 16.153303993361096 9.439039181894755 22.000000000000014 17.492696006638912 9.439039181894753 22.000000000000007 18.060436867076454 9.059686867076454 22.000000000000007 18.439789181894753 8.491946006638907 22.0 18.57300000000001 7.822250000000001 22.000000000000007 18.060436867076465 6.584813132923542 22.000000000000007 17.492696006638912 6.20546081810525 22.000000000000007 16.823 6.0722499999999995 22.000000000000007 16.1533039933611 6.205460818105244 22.000000000000007 15.585563132923546 6.584813132923544 22.000000000000007 15.206210818105255 7.152553993361091 22.000000000000007 15.073000000000002 -0.17774999999999785 22.000000000000007 15.585563132923546 1.0596868670764614 22.000000000000007 15.206210818105255 0.49194600663890586 22.000000000000007 16.153303993361096 1.439039181894751 22.000000000000007 16.823000000000004 1.5722499999999995 22.000000000000007 17.492696006638912 1.4390391818947483 22.000000000000007 18.06043686707646 1.059686867076457 22.000000000000014 18.573000000000004 -0.1777500000000014 22.000000000000007 18.43978918189476 0.49194600663890853 22.000000000000007 18.060436867076458 -1.4151868670764545 22.000000000000007 18.43978918189476 -0.8474460066389078 22.000000000000007 17.492696006638912 -1.7945391818947485 22.000000000000007 16.153303993361092 -1.7945391818947503 22.000000000000007 16.823000000000004 -1.9277499999999996 22.000000000000007 15.585563132923546 -1.4151868670764598 22.000000000000007 15.206210818105253 -0.8474460066389087 30.0 15.072999999999999 -0.17774999999999785 30.0 15.206210818105257 0.49194600663890586 30.0 15.58556313292355 1.0596868670764596 30.0 16.153303993361096 1.4390391818947554 30.0 16.823000000000004 1.5722499999999995 30.0 18.060436867076465 1.0596868670764579 30.0 17.492696006638912 1.4390391818947492 30.0 18.439789181894753 0.49194600663890586 30.0 18.573 -0.1777500000000014 30.0 18.43978918189476 -0.8474460066389105 30.0 17.492696006638912 -1.7945391818947511 30.0 18.06043686707646 -1.4151868670764562 30.0 16.823000000000004 -1.9277499999999996 30.0 16.153303993361096 -1.7945391818947494 30.0 15.585563132923548 -1.4151868670764598 30.0 15.20621081810525 -0.8474460066389096 29.999999999999993 -17.927 -0.1777500000000014 22.000000000000007 -17.793789181894752 0.491946006638905 30.0 -17.414436867076454 1.0596868670764552 30.0 -16.846696006638904 1.4390391818947492 30.0 -16.176999999999996 1.5722499999999995 30.0 -15.507303993361093 1.4390391818947545 30.0 -14.939563132923539 1.059686867076457 29.999999999999993 -14.560210818105249 0.4919460066389041 29.999999999999993 -14.427 -0.17774999999999963 30.0 -14.560210818105247 -0.8474460066389069 30.0 -14.93956313292354 -1.4151868670764562 30.0 -15.507303993361088 -1.794539181894752 30.0 -16.177 -1.9277500000000023 30.0 -16.846696006638904 -1.7945391818947556 30.0 -17.414436867076454 -1.4151868670764527 29.999999999999993 -17.793789181894756 -0.8474460066389087 30.0 -17.793789181894756 0.4919460066389023 22.000000000000007 -17.927000000000003 -0.17774999999999785 22.000000000000007 -17.414436867076454 1.059686867076456 22.000000000000007 -16.846696006638904 1.4390391818947519 22.000000000000007 -16.176999999999996 1.5722499999999995 22.000000000000007 -15.507303993361091 1.4390391818947519 22.000000000000007 -14.939563132923539 1.0596868670764579 22.000000000000007 -14.560210818105244 0.49194600663890764 22.000000000000007 -14.427000000000001 -0.1777500000000023 22.000000000000007 -14.560210818105245 -0.8474460066389105 22.000000000000007 -14.939563132923539 -1.4151868670764625 22.000000000000007 -15.507303993361091 -1.7945391818947538 22.000000000000007 -16.177 -1.9277500000000014 22.000000000000007 -16.846696006638904 -1.79453918189476 22.000000000000007 -17.414436867076454 -1.415186867076459 22.000000000000007 -17.79378918189475 -0.8474460066389069 22.0 -17.92699999999999 7.822249999999998 22.0 -17.793789181894745 8.491946006638901 22.0 -17.414436867076454 9.059686867076454 22.000000000000007 -16.8466960066389 9.43903918189475 22.000000000000007 -16.177 9.572249999999999 22.000000000000007 -15.507303993361091 9.439039181894753 22.000000000000007 -14.939563132923539 9.059686867076458 22.000000000000007 -14.560210818105242 8.491946006638909 22.0 -14.426999999999989 7.822249999999997 22.0 -14.560210818105247 7.152553993361094 22.000000000000007 -14.939563132923539 6.584813132923543 22.000000000000007 -15.50730399336109 6.205460818105245 22.000000000000007 -16.177 6.072249999999999 22.000000000000007 -16.846696006638904 6.205460818105244 22.000000000000007 -17.414436867076454 6.584813132923531 22.0 -17.793789181894745 7.15255399336109 30.0 -17.92699999999999 7.822249999999999 29.999999999999993 -17.79378918189475 8.491946006638901 30.0 -16.8466960066389 9.439039181894747 29.999999999999993 -17.41443686707645 9.059686867076447 30.0 -16.177000000000003 9.572249999999999 30.0 -15.507303993361093 9.439039181894755 30.0 -14.939563132923542 9.05968686707646 29.999999999999993 -14.560210818105244 8.49194600663891 30.0 -14.426999999999994 7.822249999999999 30.0 -14.560210818105247 7.15255399336109 30.0 -15.507303993361091 6.205460818105246 30.0 -14.939563132923539 6.58481313292354 30.0 -16.846696006638908 6.20546081810525 30.0 -16.177000000000003 6.072249999999999 30.0 -17.414436867076454 6.5848131329235375 29.999999999999993 -17.793789181894738 7.152553993361091 22.000000000000007 20.323 11.32225 -15.957446808510642 10.323 -3.6777500000000014 22.000000000000007 10.323 -3.677749999999998 22.000000000000007 20.323 -3.6777499999999996 -30.0 10.323 11.32225 22.000000000000007 10.323 11.32225 18.512888012183033 10.323 -3.6777500000000014 3.649215653894089 10.323 11.32225 -30.0 10.323 -3.6777500000000014 22.000000000000007 -19.677 -3.677750000000003 -15.535294151144047 -9.677 -3.677749999999998 -15.551298997002412 -9.677 11.32225 -30.0 -9.677 11.32225 22.000000000000007 -9.677 -3.677749999999998 22.000000000000007 -9.677 11.32225 14.771385376467595 -9.677000000000001 11.322249999999997 -30.0 -9.677 -3.6777500000000014 22.000000000000007 -19.677 11.32225 14.25 -6.1770000000000005 11.32225 14.116789181894752 -6.846696006638907 11.32225 13.737436867076458 -7.414436867076454 11.32225 13.169696006638908 -7.793789181894753 11.32225 12.5 -7.927000000000002 11.32225 11.830303993361095 -7.793789181894753 -3.677749999999998 10.883210818105248 -6.846696006638907 11.32225 10.750000000000002 -6.177000000000002 11.32225 10.883210818105248 -5.507303993361092 11.32225 11.262563132923546 -4.939563132923541 11.32225 11.830303993361092 -4.56021081810525 11.32225 12.5 -4.4270000000000005 11.32225 13.169696006638912 -4.560210818105252 11.32225 13.737436867076458 -4.939563132923545 11.32225 14.116789181894745 -5.507303993361094 11.32225 11.262563132923546 -7.414436867076459 -3.677749999999998 14.116789181894752 -6.846696006638906 -3.677749999999998 14.250000000000004 -6.177000000000001 -3.677749999999998 13.737436867076454 -7.414436867076457 -3.677749999999998 12.5 -7.9270000000000005 -3.677749999999998 13.169696006638908 -7.793789181894753 -3.677749999999998 11.262563132923546 -7.4144368670764615 11.322250000000004 11.830303993361099 -7.793789181894749 11.322249999999997 10.883210818105246 -6.846696006638908 -3.6777500000000014 10.749999999999998 -6.177000000000003 -3.6777500000000014 10.883210818105246 -5.50730399336109 -3.677749999999998 11.262563132923546 -4.939563132923544 -3.677749999999998 11.830303993361092 -4.560210818105249 -3.677749999999998 12.5 -4.427 -3.6777500000000014 13.169696006638912 -4.560210818105251 -3.6777500000000014 13.737436867076458 -4.939563132923547 -3.6777500000000014 14.116789181894745 -5.507303993361091 -3.677749999999998 14.25 6.823000000000001 11.32225 14.116789181894752 6.153303993361095 11.32225 13.737436867076458 5.585563132923542 11.32225 13.169696006638908 5.206210818105249 11.32225 12.5 5.0729999999999995 11.32225 11.830303993361092 5.206210818105249 11.32225 11.262563132923542 5.58556313292354 11.32225 10.88321081810525 6.153303993361093 11.32225 10.75 6.823000000000001 11.32225 10.88321081810525 7.4926960066389094 11.32225 11.262563132923542 8.060436867076458 11.32225 11.830303993361092 8.439789181894751 11.32225 12.500000000000004 8.572999999999997 11.32225 13.169696006638908 8.43978918189475 11.32225 13.737436867076454 8.060436867076458 11.32225 14.116789181894745 7.492696006638908 11.32225 14.116789181894756 6.153303993361094 -3.677749999999998 14.250000000000004 6.822999999999999 -3.677749999999998 13.169696006638908 5.206210818105248 -3.677749999999998 13.737436867076454 5.585563132923541 -3.6777500000000014 11.830303993361092 5.206210818105244 -3.677749999999998 12.500000000000007 5.073 -3.677749999999998 11.262563132923539 5.585563132923539 -3.6777500000000014 10.883210818105248 6.153303993361094 -3.677749999999998 10.75 6.823000000000002 -3.677749999999998 10.88321081810525 7.49269600663891 -3.677749999999998 11.262563132923542 8.060436867076458 -3.677749999999998 11.830303993361092 8.439789181894751 -3.677749999999998 13.169696006638908 8.439789181894747 -3.677749999999998 12.500000000000007 8.572999999999999 -3.677749999999998 13.73743686707645 8.060436867076456 -3.677749999999998 14.116789181894752 7.492696006638909 -3.677749999999998 -11.75 6.8229999999999995 11.32225 -11.883210818105248 6.153303993361091 11.32225 -12.262563132923546 5.585563132923542 11.32225 -12.830303993361092 5.206210818105249 11.32225 -13.5 5.0729999999999995 11.32225 -14.169696006638908 5.206210818105247 11.32225 -14.737436867076461 5.585563132923542 11.32225 -15.116789181894752 6.153303993361095 11.32225 -15.25 6.8229999999999995 11.32225 -15.116789181894749 7.492696006638904 11.32225 -14.737436867076454 8.060436867076458 11.32225 -14.169696006638908 8.439789181894753 11.32225 -13.500000000000007 8.573 11.32225 -12.830303993361099 8.439789181894755 11.32225 -12.262563132923542 8.060436867076463 11.32225 -11.883210818105244 7.492696006638908 11.32225 -11.749999999999996 6.823 -3.6777500000000014 -11.883210818105255 6.153303993361096 -3.677749999999998 -12.830303993361095 5.2062108181052515 -3.677750000000005 -12.262563132923542 5.5855631329235464 -3.677749999999998 -13.5 5.073 -3.6777500000000014 -14.169696006638908 5.20621081810525 -3.677749999999998 -15.116789181894756 6.153303993361094 -3.6777500000000014 -14.737436867076461 5.5855631329235464 -3.6777500000000014 -15.25 6.823000000000004 -3.6777500000000014 -15.116789181894749 7.492696006638907 -3.677749999999998 -14.169696006638908 8.439789181894753 -3.6777500000000014 -14.737436867076454 8.06043686707646 -3.677749999999998 -13.500000000000007 8.573 -3.6777500000000014 -12.830303993361099 8.439789181894756 -3.677749999999998 -12.262563132923546 8.060436867076461 -3.677749999999998 -11.883210818105248 7.492696006638909 -3.6777500000000014 -11.75 -6.177000000000002 11.32225 -11.883210818105248 -6.846696006638909 11.32225 -12.262563132923546 -7.4144368670764615 11.32225 -12.830303993361095 -7.793789181894753 11.32225 -13.5 -7.927000000000004 11.32225 -14.169696006638912 -7.793789181894753 11.32225 -14.737436867076458 -7.414436867076458 11.32225 -15.116789181894752 -6.846696006638909 11.32225 -15.25 -6.177000000000002 11.32225 -15.116789181894752 -5.507303993361099 11.32225 -14.737436867076461 -4.9395631329235465 11.32225 -14.169696006638908 -4.56021081810525 11.32225 -13.5 -4.4270000000000005 11.32225 -12.830303993361095 -4.56021081810525 11.32225 -12.262563132923539 -4.939563132923539 11.32225 -11.88321081810524 -5.507303993361094 11.32225 -11.883210818105248 -6.846696006638911 -3.677749999999998 -11.750000000000004 -6.177 -3.6777500000000014 -12.262563132923546 -7.414436867076457 -3.677749999999998 -12.830303993361095 -7.7937891818947564 -3.677749999999998 -14.169696006638908 -7.793789181894753 -3.6777500000000014 -13.5 -7.927000000000008 -3.677749999999998 -14.737436867076454 -7.414436867076457 -3.677749999999998 -15.116789181894752 -6.846696006638908 -3.677749999999998 -15.250000000000004 -6.177 -3.6777500000000014 -15.116789181894749 -5.507303993361097 -3.6777500000000014 -14.737436867076461 -4.939563132923546 -3.677749999999998 -14.169696006638908 -4.560210818105251 -3.677749999999998 -13.5 -4.427 -3.6777500000000014 -12.830303993361095 -4.560210818105254 -3.6777500000000014 -12.262563132923546 -4.93956313292354 -3.677749999999998 -11.88321081810524 -5.507303993361091 -3.677749999999998 -17.997690162057708 -2.677 2.3222500000000004 -17.997690162057708 3.323 2.3222500000000004 30.0 3.323 2.3222500000000004 30.0 3.323 -3.6777500000000014 -23.988690162057708 3.323 2.3222500000000004 -23.988690162057708 -2.677 2.3222500000000004 30.0 -2.677 -3.6777500000000014 18.011309837942285 -2.677 2.3222500000000004 30.0 -2.677 2.3222500000000004 18.011309837942285 3.323 -3.677749999999998 -30.0 3.323 -3.6777500000000014 -17.997690162057708 3.323 -3.6777500000000014 -23.988690162057708 3.323 -3.677749999999998 11.422110817733461 -2.677 -3.677749999999998 -17.997690162057708 -2.677 -3.6777500000000014 -30.0 -2.677 2.3222500000000004 -23.988690162057708 -2.677 -3.677749999999998 -30.0 3.323 2.3222500000000004 24.002309837942285 -2.677 2.3222500000000004 18.011309837942285 3.323 2.3222500000000004 24.002309837942285 3.323 -3.6777500000000014 -30.0 -2.677 -3.6777500000000014 24.002309837942285 -2.677 -3.6777500000000014 24.002309837942285 3.323 2.3222500000000004 18.011309837942285 -2.677 -3.677749999999998 -17.997690162057708 -4.876999999999995 -1.5777500000000053 -17.997690162057708 -4.481173569058687 0.41220384829846246 -17.997690162057708 -3.3539552621700417 2.099205262170041 -17.997690162057708 -1.6669538482984616 3.226423569058687 -17.997690162057708 0.3230000000000051 3.6222499999999958 -17.997690162057708 2.312953848298472 3.226423569058687 -17.997690162057708 3.9999552621700523 2.099205262170044 -17.997690162057708 5.127173569058697 0.41220384829846424 -17.997690162057708 5.523000000000007 -1.5777500000000053 -17.997690162057708 5.127173569058698 -3.5677038482984695 -17.997690162057708 -4.481173569058685 -3.5677038482984766 -23.988690162057708 -4.876999999999992 -1.5777500000000053 -23.988690162057708 -4.481173569058684 0.41220384829846246 -23.988690162057708 -3.35395526217004 2.099205262170041 -23.988690162057708 -1.6669538482984607 3.226423569058687 -23.988690162057708 0.323000000000006 3.6222499999999958 -23.988690162057708 2.312953848298473 3.226423569058687 -23.988690162057708 3.999955262170054 2.099205262170044 -23.988690162057708 5.127173569058697 0.41220384829846246 -23.988690162057708 5.523000000000007 -1.5777500000000053 -23.988690162057708 5.1271735690587 -3.567703848298473 -23.988690162057708 -4.481173569058683 -3.5677038482984766 -17.997690162057708 5.053643081306509 -3.6777500000000014 -17.997690162057708 -4.4076430813064995 -3.6777500000000014 -23.988690162057708 5.0536430813065145 -3.677749999999998 -23.988690162057708 -4.4076430813064995 -3.677749999999998 30.0 20.323 -3.6777499999999996 30.0 20.323 11.32225 30.0 -19.677 -3.677750000000003 30.0 -19.677 11.32225 24.002309837942285 5.053643081306509 -3.6777500000000014 18.011309837942285 5.053643081306513 -3.677749999999998 24.002309837942285 -4.4076430813064995 -3.6777500000000014 18.011309837942285 -4.407643081306494 -3.677749999999998 24.002309837942285 -4.876999999999995 -1.5777500000000053 24.002309837942285 -4.481173569058687 0.41220384829846246 24.002309837942285 -3.3539552621700417 2.099205262170041 24.002309837942285 -1.6669538482984616 3.226423569058687 24.002309837942285 0.3230000000000051 3.6222499999999958 24.002309837942285 2.312953848298472 3.226423569058687 24.002309837942285 3.9999552621700523 2.099205262170044 24.002309837942285 5.127173569058697 0.41220384829846424 24.002309837942285 5.523000000000007 -1.5777500000000053 24.002309837942285 5.127173569058698 -3.5677038482984695 24.002309837942285 -4.481173569058685 -3.5677038482984766 18.011309837942285 -4.876999999999992 -1.5777500000000053 18.011309837942285 -4.481173569058684 0.41220384829846246 18.011309837942285 -3.35395526217004 2.099205262170041 18.011309837942285 -1.6669538482984607 3.226423569058687 18.011309837942285 0.323000000000006 3.6222499999999958 18.011309837942285 2.312953848298473 3.226423569058687 18.011309837942285 3.999955262170054 2.099205262170044 18.011309837942285 5.127173569058697 0.41220384829846246 18.011309837942285 5.523000000000007 -1.5777500000000053 18.011309837942285 5.1271735690587 -3.567703848298473 18.011309837942285 -4.481173569058683 -3.5677038482984766 -12.919863212247494 1.006287737415828 11.322250000000007 -13.189863212247493 1.4862877374158323 11.32225 -15.109863212247499 3.4362877374158303 11.32225 -16.999863212247483 1.5762877374158215 11.32225 -17.53986321224749 0.19628773741582983 11.322249999999999 -12.739863212247494 -0.3737122625841701 11.322250000000006 -12.739863212247498 0.34628773741582886 11.322250000000004 -12.979863212247494 -1.0937122625841718 11.322250000000004 -13.999863212247496 -2.08371226258417 11.32225 -14.689863212247495 -2.3237122625841695 11.32225 -13.459863212247495 -1.7237122625841699 11.32225 -16.939863212247495 -1.57371226258417 11.32225 -17.35986321224749 0.9762877374158305 11.32225 -16.3398632122475 -2.05371226258417 11.322250000000002 -15.649863212247492 -2.3237122625841677 11.32225 -17.329863212247496 -0.9137122625841699 11.32224999999999 -17.509863212247502 -0.25371226258417345 11.322249999999986 -17.539863212247496 0.1962877374158304 9.64225 -17.359863212247497 0.9762877374158304 9.64225 -16.999863212247497 1.5762877374158304 9.64225 -15.109863212247495 3.43628773741583 9.64225 -13.189863212247493 1.48628773741583 9.64225 -12.919863212247494 1.0062877374158297 9.64225 -12.739863212247494 0.34628773741582985 9.64225 -12.739863212247494 -0.3737122625841701 9.64225 -12.979863212247494 -1.09371226258417 9.64225 -13.459863212247495 -1.7237122625841703 9.64225 -13.999863212247494 -2.08371226258417 9.64225 -14.689863212247495 -2.32371226258417 9.64225 -15.649863212247494 -2.32371226258417 9.64225 -16.339863212247494 -2.05371226258417 9.64225 -16.939863212247495 -1.57371226258417 9.64225 -17.329863212247496 -0.9137122625841699 9.64225 -17.509863212247495 -0.25371226258417 9.64225 7.756738351254477 -1.9418924731182776 11.32225 7.60673835125448 -0.38189247311828 11.32225 7.996738351254475 -0.05189247311827905 11.322249999999997 8.14673835125448 -2.18189247311828 11.32225 10.906738351254479 -1.4618924731182803 11.32225 8.746738351254475 -2.2418924731182805 11.32225 9.226738351254475 -2.0918924731182775 11.322249999999997 7.786738351254477 0.7881075268817213 11.32225 7.426738351254476 -0.891892473118279 11.32225 7.426738351254478 -1.1618924731182783 11.322249999999993 11.146738351254479 -1.4918924731182788 11.32225 11.146738351254477 -2.1518924731182794 11.32225 8.56673835125448 1.7481075268817183 11.322249999999999 7.816738351254481 1.5381075268817215 11.32225 8.05673835125448 0.9081075268817214 11.322249999999999 8.776738351254474 -1.4318924731182783 11.32225 8.536738351254476 0.12810752688172422 11.322249999999997 9.61673835125448 -1.7018924731182792 11.322250000000002 8.83673835125448 1.1181075268817215 11.322249999999997 7.546738351254474 -1.6418924731182787 11.322249999999997 8.536738351254476 -1.1618924731182818 11.32225 9.316738351254479 1.0581075268817208 11.32225 9.256738351254473 -1.4318924731182792 11.322250000000002 10.36673835125448 -2.2418924731182828 11.322249999999997 10.096738351254476 1.6581075268817225 11.322249999999997 8.686738351254476 -0.5618924731182797 11.322249999999997 8.506738351254475 -0.8618924731182792 11.32225 9.946738351254476 -2.091892473118282 11.322249999999997 9.496738351254475 1.8081075268817197 11.32225 9.616738351254476 0.24810752688172077 11.322250000000004 9.586738351254477 -1.1918924731182794 11.322249999999993 10.726738351254475 -1.3118924731182808 11.322249999999993 10.666738351254477 0.8781075268817216 11.32225 9.586738351254478 0.7881075268817216 11.32225 9.706738351254476 -1.7918924731182786 11.32225 9.166738351254473 -0.41189247311827915 11.322249999999997 10.486738351254473 1.3281075268817206 11.32225 9.496738351254475 0.21810752688172008 11.322250000000002 9.61673835125448 -0.44189247311827906 11.322249999999997 7.4267383512544765 -0.891892473118279 9.67725 7.606738351254478 -0.3818924731182791 9.67725 7.996738351254475 -0.05189247311827877 9.67725 8.536738351254474 0.12810752688172145 9.67725 9.496738351254475 0.21810752688172086 9.67725 9.616738351254478 0.24810752688172089 9.67725 9.586738351254478 0.7881075268817215 9.67725 9.316738351254479 1.058107526881721 9.67725 8.836738351254478 1.118107526881721 9.67725 8.056738351254479 0.9081075268817216 9.67725 7.786738351254474 0.7881075268817215 9.67725 7.816738351254479 1.5381075268817215 9.67725 8.566738351254479 1.748107526881721 9.67725 9.496738351254475 1.8081075268817215 9.67725 10.096738351254478 1.6581075268817216 9.67725 10.486738351254475 1.3281075268817215 9.67725 10.666738351254477 0.8781075268817216 9.67725 10.726738351254475 -1.311892473118279 9.67725 10.906738351254477 -1.461892473118279 9.67725 11.146738351254477 -1.4918924731182792 9.67725 11.146738351254477 -2.15189247311828 9.67725 10.366738351254478 -2.241892473118279 9.67725 9.946738351254476 -2.0918924731182797 9.67725 9.706738351254476 -1.7918924731182795 9.67725 9.616738351254478 -1.7018924731182796 9.67725 9.226738351254475 -2.0918924731182797 9.67725 8.746738351254475 -2.241892473118279 9.67725 8.146738351254477 -2.1818924731182796 9.67725 7.756738351254475 -1.9418924731182798 9.67725 7.546738351254474 -1.6418924731182791 9.67725 7.4267383512544765 -1.1618924731182791 9.67725 8.536738351254474 -1.1618924731182791 9.67725 8.686738351254476 -0.5618924731182792 9.67725 8.506738351254475 -0.861892473118279 9.67725 9.586738351254478 -1.1918924731182794 9.67725 9.256738351254475 -1.4318924731182792 9.67725 9.616738351254478 -0.44189247311827906 9.67725 9.166738351254477 -0.41189247311827915 9.67725 8.776738351254474 -1.4318924731182792 9.67725 671 426 Edge Vertex Indices Starting from 1 426 107 647 646 646 645 633 261 672 455 431 417 417 101 193 174 174 172 80 63 627 247 190 176 176 175 191 190 190 175 188 172 172 171 481 143 83 63 18 17 17 16 142 137 137 127 85 67 67 66 85 68 68 67 736 731 731 685 671 107 667 148 661 148 193 191 191 174 20 19 19 14 190 177 177 176 19 15 15 14 448 434 434 431 481 249 249 33 19 18 18 16 19 16 16 15 484 247 665 425 708 674 24 23 23 12 188 171 171 170 694 677 677 666 191 175 175 174 193 172 153 128 142 127 127 126 627 626 626 247 20 14 14 13 30 12 710 673 673 667 366 352 352 335 32 6 597 276 34 7 470 453 34 32 32 7 33 32 195 33 280 279 296 280 300 285 187 170 170 169 295 278 314 312 402 314 639 637 637 522 474 458 389 373 358 342 40 17 646 627 194 181 181 180 328 310 44 43 43 3 44 3 92 63 111 84 401 317 317 315 404 289 289 288 43 2 624 600 45 2 562 549 46 20 510 494 731 702 702 701 38 35 49 38 643 630 348 347 363 348 679 152 44 4 222 219 219 214 402 313 313 310 38 15 683 665 665 426 49 15 363 362 408 363 42 23 323 322 322 306 481 195 195 143 52 23 569 558 558 552 55 12 724 665 55 37 37 12 614 604 604 567 153 152 152 128 434 417 735 733 733 716 673 146 53 5 620 564 621 620 366 365 408 366 494 493 509 494 596 328 251 43 57 56 56 29 57 29 293 291 399 293 287 286 301 287 56 26 30 27 60 30 339 338 354 339 61 59 59 28 61 28 467 453 453 452 509 493 210 209 209 182 615 605 605 604 391 271 357 341 597 274 413 404 404 99 417 100 562 555 555 549 512 497 497 496 569 552 616 569 253 229 254 253 505 489 402 312 658 641 326 309 596 327 292 291 291 274 328 312 330 328 598 349 365 349 610 568 253 41 325 323 323 307 640 639 639 522 324 308 625 615 615 604 412 361 361 360 501 485 659 643 643 642 592 503 399 296 296 295 325 307 408 362 412 408 401 318 318 317 399 281 291 275 275 274 459 458 475 459 295 294 399 295 195 34 325 308 53 6 621 611 611 610 256 51 470 454 454 453 350 349 365 350 323 306 596 329 362 346 607 563 281 280 296 281 326 324 324 309 597 275 332 315 333 332 506 490 278 277 294 278 327 310 328 327 566 560 399 294 294 293 39 35 282 280 485 484 499 485 341 340 356 341 616 615 615 569 497 481 401 305 305 303 554 467 508 491 597 278 412 360 360 359 252 43 638 629 629 488 211 39 554 470 470 467 320 286 299 284 251 53 46 21 47 46 576 546 620 609 642 411 282 281 297 282 623 613 613 612 596 330 330 329 585 574 618 608 608 607 503 489 489 488 582 571 466 449 408 336 366 335 622 611 619 608 36 35 195 36 554 469 61 30 647 626 408 365 365 364 302 287 195 54 54 36 256 47 623 612 55 48 48 37 597 277 479 464 464 463 480 464 597 279 331 314 401 303 346 345 361 346 404 290 290 289 540 524 251 44 598 335 329 312 331 329 329 314 408 352 328 313 313 312 285 284 299 285 330 312 333 315 404 292 292 290 614 602 284 283 298 284 58 26 638 488 483 247 669 150 246 231 231 230 78 77 79 78 736 685 84 65 86 71 87 86 80 77 81 80 561 560 560 550 534 409 264 262 93 92 92 64 93 64 363 347 430 104 479 477 477 405 93 65 417 414 414 413 94 93 93 66 431 101 96 67 616 605 97 68 446 445 558 446 98 97 97 69 98 69 100 71 445 428 101 72 102 101 101 73 165 163 163 162 362 347 347 346 103 74 451 94 104 75 718 670 670 664 452 94 518 410 105 77 429 428 445 429 451 95 583 550 584 583 79 63 107 79 107 63 446 429 539 523 601 600 624 601 352 336 412 362 362 361 598 348 242 229 229 228 50 20 101 100 100 72 514 210 394 377 102 73 439 410 562 411 411 403 605 567 106 78 108 88 88 82 364 349 349 348 478 405 113 80 413 375 375 374 364 348 109 90 90 88 611 568 608 563 596 401 591 570 592 579 594 592 624 613 599 385 421 420 437 421 374 373 413 374 573 546 546 545 350 335 598 350 463 404 450 95 453 92 605 563 557 549 517 410 599 408 538 537 593 538 582 572 572 571 520 410 505 490 490 489 621 610 598 408 462 404 618 552 619 618 437 420 402 399 596 402 572 545 461 406 117 90 461 404 188 170 113 81 118 113 506 400 508 506 196 167 584 574 574 573 414 412 597 399 494 406 460 406 413 99 534 532 532 409 614 567 515 514 529 515 396 378 438 422 368 367 416 368 588 577 420 414 625 604 414 410 410 409 531 515 591 581 581 570 625 614 614 603 106 79 107 106 419 418 433 419 387 385 385 370 562 560 560 411 406 403 493 406 510 509 509 400 352 351 351 335 382 367 383 382 416 370 370 369 192 180 180 179 427 107 593 537 537 536 567 551 602 567 715 692 437 436 436 421 439 414 586 549 587 586 418 414 453 91 357 342 342 341 476 400 532 517 517 516 491 403 109 88 435 419 599 387 396 379 464 404 366 350 396 393 393 378 524 523 539 524 493 403 534 517 599 384 617 606 437 412 428 107 622 612 612 611 373 372 413 373 491 490 506 491 421 414 439 422 593 539 539 538 490 403 599 386 386 385 553 547 547 391 581 571 571 570 525 524 540 525 420 419 435 420 416 369 369 368 599 416 416 408 412 409 436 412 386 384 384 368 508 400 598 347 387 370 450 96 386 368 606 563 599 413 535 533 533 409 449 98 408 364 364 363 538 523 523 522 398 382 541 525 613 600 600 565 562 550 394 392 392 376 622 554 623 622 618 607 507 493 493 492 573 545 431 102 464 449 449 404 428 427 444 428 562 407 384 367 478 476 476 405 509 507 507 400 429 106 492 403 114 109 109 108 395 379 394 376 519 410 384 383 383 367 428 106 419 414 562 403 587 577 577 576 619 609 609 608 596 399 597 596 355 339 617 552 618 617 480 479 479 405 393 377 599 383 412 359 359 358 594 579 114 110 110 109 115 110 30 24 24 12 632 247 26 8 8 7 129 128 128 127 115 111 111 110 134 120 120 119 135 134 134 119 139 130 140 120 141 136 136 123 144 143 143 119 144 119 334 303 203 175 298 283 145 120 532 516 516 515 502 501 556 502 392 341 600 548 147 122 460 459 475 460 585 584 586 585 418 417 434 418 584 550 550 549 592 400 533 518 534 533 495 458 556 501 501 499 415 409 416 367 154 129 407 400 592 407 399 291 638 489 489 403 351 336 353 351 583 572 592 556 157 133 133 119 260 259 259 236 145 144 144 120 80 79 79 77 147 146 146 122 148 124 616 606 606 605 542 526 526 525 149 125 587 575 162 136 164 135 166 134 479 463 463 462 578 576 166 140 140 134 587 576 576 575 597 388 388 274 548 332 559 540 540 539 570 559 593 570 590 579 519 518 533 519 595 591 591 580 321 304 296 279 279 278 592 506 506 505 598 398 599 598 575 546 389 274 569 446 564 554 622 564 518 517 534 518 612 565 359 343 343 342 516 439 439 438 609 568 621 564 622 621 164 139 354 337 559 541 541 540 322 321 321 306 571 559 118 117 117 113 495 459 402 315 579 556 402 310 160 158 504 486 206 157 594 407 535 519 401 315 402 401 558 542 559 558 201 143 563 553 567 563 334 318 318 303 292 273 296 278 354 338 338 337 316 314 402 316 620 610 610 609 542 525 566 415 595 566 566 561 157 119 583 582 582 550 565 548 548 547 620 619 619 564 398 383 599 398 558 444 444 443 372 371 416 372 613 565 532 515 571 545 475 458 448 430 459 406 494 459 573 572 583 573 479 462 415 411 560 415 611 565 617 607 607 606 520 519 535 520 292 274 274 273 568 565 565 547 412 358 413 412 301 300 304 301 589 578 578 577 556 546 578 556 586 584 584 549 413 372 416 413 165 140 166 165 556 499 205 157 595 415 319 303 153 129 154 153 542 541 559 542 592 505 505 503 575 573 340 339 355 340 457 143 578 546 359 342 584 573 388 387 387 372 588 549 456 144 504 487 487 486 536 535 535 409 569 447 447 446 594 590 590 557 371 370 416 371 595 561 200 143 580 570 593 580 568 563 608 568 445 444 558 445 579 578 589 579 455 454 469 455 555 407 594 555 619 552 590 589 589 557 360 344 344 343 404 399 399 292 589 577 551 345 499 484 500 499 283 282 297 283 356 340 405 400 406 405 202 143 166 135 448 431 431 430 471 455 484 483 500 484 552 545 564 552 595 580 415 410 598 412 457 144 593 559 559 539 564 545 553 551 567 553 302 271 591 561 516 410 288 271 302 288 425 152 476 460 161 136 162 161 599 388 602 551 551 412 404 302 433 418 434 433 458 457 473 458 360 343 353 337 334 333 333 318 557 555 594 557 589 588 588 557 480 466 466 464 603 434 387 371 404 288 320 319 319 305 617 616 616 552 333 317 203 143 587 549 588 587 536 520 470 469 469 454 512 474 474 473 683 666 666 665 174 173 173 172 221 184 183 182 182 181 673 148 187 169 194 180 323 284 270 269 269 262 393 339 389 273 197 168 355 354 379 355 504 502 556 504 196 195 195 167 199 170 354 353 380 354 598 351 673 147 672 456 456 146 510 400 396 395 395 338 404 98 204 203 203 176 597 280 496 458 514 423 423 210 553 342 378 355 379 378 218 190 496 481 481 457 211 210 210 182 211 182 543 443 443 442 302 301 305 302 561 550 582 561 200 199 199 171 200 171 379 354 380 379 670 107 107 91 210 208 438 423 515 438 496 457 298 297 309 298 325 324 324 282 380 353 381 380 322 286 358 357 376 358 392 342 553 392 208 207 207 179 208 179 394 393 393 340 320 287 547 320 297 281 311 297 213 192 192 185 212 192 602 435 435 433 215 187 187 186 390 273 548 333 215 186 397 337 198 196 402 311 311 281 217 212 212 185 217 185 219 193 193 188 214 193 480 405 601 480 376 375 375 358 596 280 599 597 597 413 548 334 334 319 500 498 498 469 597 404 396 338 627 484 353 336 381 353 531 432 432 422 357 356 377 357 325 282 382 381 381 336 398 351 351 337 510 476 476 475 325 283 548 319 322 284 416 336 652 633 436 409 532 436 601 466 531 422 500 469 398 337 327 280 603 433 553 391 323 283 547 319 602 433 603 602 551 344 592 504 322 285 215 189 216 215 377 356 378 377 326 280 356 355 378 356 516 438 598 346 326 282 543 542 542 443 309 297 311 309 222 214 214 187 396 339 222 187 413 358 544 543 543 442 601 465 551 346 598 551 394 340 497 473 473 472 515 423 305 301 581 561 582 581 397 338 558 443 510 475 475 474 304 300 306 304 321 286 416 382 382 336 532 531 531 436 394 341 401 302 554 499 499 469 402 281 210 207 376 357 377 376 308 298 309 308 512 473 472 457 457 456 190 185 185 177 699 668 241 234 234 231 239 238 238 223 243 234 241 231 246 241 220 184 249 248 248 225 712 688 250 249 249 225 250 225 251 250 250 227 90 77 77 76 252 227 253 228 473 457 255 230 234 233 233 231 648 626 257 232 663 660 660 152 258 233 720 719 719 716 259 235 189 181 261 237 237 223 247 237 634 524 635 524 248 224 250 226 252 251 251 227 253 252 252 228 719 717 717 716 254 229 655 639 257 256 256 232 697 689 260 236 630 411 642 630 263 262 262 241 263 241 267 238 243 241 262 243 635 634 654 635 629 628 628 488 257 233 258 257 260 258 628 487 656 639 654 634 647 627 530 441 441 440 111 85 85 84 636 634 634 525 652 636 636 633 270 238 269 243 711 688 688 672 641 411 156 132 209 181 692 670 670 91 113 109 665 663 663 425 711 672 498 472 472 471 710 667 25 3 3 2 704 693 693 689 482 249 668 661 661 149 714 692 718 717 719 718 674 667 667 662 705 693 702 662 720 687 687 683 112 84 84 83 729 669 705 681 202 173 709 708 710 709 245 224 736 735 735 703 707 681 150 149 149 126 62 57 57 31 679 669 669 152 90 76 648 632 632 626 649 632 708 678 669 151 511 510 510 474 736 702 707 678 712 707 707 706 240 228 228 227 165 160 149 148 148 125 544 441 210 157 92 91 91 63 688 684 684 455 691 664 711 707 712 711 136 124 124 123 735 704 704 703 233 232 232 231 713 712 712 706 112 110 110 84 717 664 696 684 714 696 86 82 82 72 498 497 497 472 710 708 711 710 390 389 389 374 737 725 725 724 50 19 714 684 726 663 725 663 717 691 688 455 710 672 692 691 691 670 449 97 729 699 699 669 694 666 698 695 695 690 737 724 736 703 703 702 450 97 711 708 708 707 62 31 31 25 721 687 706 681 242 228 725 665 117 109 514 211 211 46 514 46 25 4 4 3 27 10 10 9 156 155 155 132 214 188 188 187 512 511 511 474 31 4 696 692 692 91 31 5 5 4 33 6 36 11 36 10 40 39 39 17 211 50 50 46 478 477 477 461 477 462 462 461 49 48 48 15 48 14 52 51 51 22 52 22 53 44 44 5 163 161 54 34 34 8 54 8 103 102 102 74 478 460 478 461 461 460 50 40 40 18 50 18 253 45 252 45 45 43 704 689 211 40 528 257 260 257 650 632 650 631 61 60 60 59 60 58 544 442 442 441 195 32 211 195 195 39 195 35 600 401 548 401 596 548 116 111 687 666 290 272 290 273 273 272 294 276 294 277 277 276 361 344 361 345 345 344 327 326 326 310 326 311 311 310 657 641 641 637 289 271 289 272 272 271 301 285 301 286 286 285 500 482 500 483 483 482 332 331 331 316 332 316 316 315 51 47 47 21 51 21 512 495 512 496 496 495 511 494 511 495 495 494 663 152 49 37 49 35 83 65 65 63 218 217 217 190 65 64 64 63 90 81 81 77 96 95 95 67 508 507 507 491 507 492 492 491 105 104 104 76 105 76 106 105 105 78 268 264 386 370 386 369 97 96 96 68 100 99 99 71 202 201 201 173 104 103 103 75 113 112 112 80 112 83 83 80 114 108 108 86 108 82 439 421 422 421 436 422 538 521 538 522 522 521 389 388 388 373 388 372 431 103 430 103 452 92 94 92 397 395 395 381 395 380 521 410 521 411 411 410 398 397 397 382 397 381 543 526 543 527 527 526 414 409 89 70 70 69 544 527 544 528 528 527 586 574 586 575 575 574 443 426 442 426 426 425 537 520 537 521 521 520 417 413 413 100 118 81 117 81 429 104 106 104 133 132 132 131 139 135 135 131 139 131 131 130 456 145 504 503 503 487 503 488 488 487 152 151 151 128 151 127 593 536 536 409 155 131 625 603 615 603 603 569 146 145 145 122 145 121 559 545 558 545 466 465 465 449 465 450 450 449 159 158 158 139 159 139 139 137 160 159 159 142 159 137 441 423 441 424 424 423 624 623 623 601 623 554 637 521 637 411 468 451 465 451 451 450 425 153 444 427 443 427 427 426 407 403 403 400 406 400 442 424 442 425 425 424 293 276 291 276 276 275 596 332 596 331 472 456 471 456 456 455 498 482 497 482 482 481 199 196 199 143 196 143 468 467 467 452 468 452 452 451 204 157 203 157 157 143 321 320 320 304 320 305 305 304 156 154 156 153 603 448 569 448 448 447 194 184 184 181 632 631 631 261 218 216 628 486 498 471 471 469 632 261 261 247 211 167 211 183 183 167 199 198 198 170 203 202 202 175 202 174 659 653 653 643 219 218 218 191 219 191 308 307 307 299 308 299 299 298 197 196 196 168 30 28 28 24 307 306 306 300 307 300 300 299 207 157 481 33 553 343 551 343 391 272 390 272 667 661 86 72 72 71 237 236 236 235 270 267 630 403 256 255 255 232 255 231 636 525 659 658 658 657 157 156 156 133 88 76 76 75 268 265 255 254 254 230 261 260 260 237 718 664 530 440 654 653 656 654 656 655 655 654 653 652 652 650 652 651 651 650 254 41 640 522 26 9 9 8 58 56 683 426 669 668 668 150 668 149 734 723 734 724 724 723 729 679 700 668 700 661 113 110 27 9 673 672 672 146 638 403 702 676 676 662 678 674 676 674 674 662 703 689 721 694 694 687 23 22 22 13 23 13 13 12 636 261 22 21 21 13 21 20 20 13 736 698 736 695 42 1 42 24 24 1 27 12 12 11 27 11 11 10 568 553 568 547 250 33 250 53 53 33 37 35 35 11 37 11 649 648 648 644 245 240 240 226 240 227 227 226 246 229 246 230 230 229 85 66 84 66 66 65 595 593 593 415 593 409 640 523 635 523 95 94 94 67 94 66 45 41 41 1 45 1 447 429 447 430 430 429 116 115 115 89 115 87 115 114 114 87 114 86 116 85 116 89 89 85 644 630 644 638 638 630 696 453 696 91 89 87 87 70 87 71 71 70 148 147 147 124 147 123 728 679 727 679 679 660 99 98 98 70 99 70 163 136 163 138 138 136 502 486 501 486 486 485 544 530 530 528 530 513 406 401 406 404 404 401 438 432 440 438 440 423 601 405 600 405 405 401 28 25 25 2 183 181 189 183 201 200 200 173 200 172 221 216 216 189 221 189 189 184 531 529 529 432 529 440 440 432 601 554 554 468 601 468 468 465 530 529 529 513 529 514 514 513 547 271 547 287 287 271 29 26 26 7 29 7 7 6 697 678 678 676 653 634 652 634 88 74 88 75 75 74 264 263 263 242 263 246 246 242 266 265 265 245 265 240 265 264 264 240 264 242 242 240 268 266 266 244 266 245 245 244 528 260 527 260 735 716 716 715 735 715 715 704 138 124 138 125 125 124 31 29 29 5 29 6 6 5 255 41 255 42 42 41 645 638 645 629 727 660 726 660 723 677 735 698 733 698 698 690 715 714 714 705 715 705 705 704 185 178 178 177 732 730 730 686 730 680 483 249 483 248 142 125 142 126 126 125 89 68 89 69 69 68 724 666 723 666 186 169 169 167 169 168 168 167 734 733 733 690 734 690 690 682 733 723 723 722 733 722 722 716 714 713 713 705 713 706 706 705 716 691 715 691 720 683 719 683 683 671 165 158 82 74 74 73 82 73 73 72 719 671 718 671 671 670 701 662 700 662 662 661 737 726 726 725 155 154 154 130 155 130 696 454 684 454 732 686 731 686 686 685 209 208 208 180 209 180 722 721 721 720 722 720 720 716 39 38 38 17 38 16 54 9 36 9 222 218 392 391 391 375 392 375 602 412 435 412 437 435 133 131 135 133 135 119 137 130 130 127 130 129 129 127 151 150 150 126 151 126 163 160 160 138 160 142 142 138 556 554 564 556 564 546 391 390 390 375 390 374 198 197 197 169 198 169 628 627 627 485 628 485 703 676 703 697 697 676 205 204 204 176 205 176 207 206 206 178 207 178 220 194 213 194 194 192 709 674 709 667 248 247 247 223 248 223 651 631 651 633 633 631 259 258 258 235 258 234 659 657 657 656 659 656 656 653 649 644 644 643 659 642 658 642 642 641 646 629 646 628 210 156 657 639 657 637 713 688 713 684 141 121 140 121 121 120 423 156 528 513 513 257 513 256 732 728 730 728 728 727 28 1 28 2 2 1 722 677 721 677 729 728 732 729 732 699 141 123 123 121 123 122 122 121 636 526 636 527 527 261 62 59 59 58 62 58 58 57 55 14 55 13 62 25 59 25 513 46 256 46 648 647 647 645 648 645 645 644 655 640 654 640 640 635 165 162 162 141 165 141 141 140 189 186 186 183 186 167 206 205 205 177 206 177 256 52 255 52 52 42 697 693 693 681 697 681 681 678 244 224 238 224 224 223 732 731 731 701 737 675 730 675 270 262 268 262 192 178 192 179 179 178 166 158 166 164 164 158 686 682 695 685 690 685 685 682 737 730 730 727 737 727 727 726 60 26 60 27 27 26 222 215 218 215 270 268 268 244 270 244 244 238 237 235 239 237 239 223 243 239 239 235 243 235 235 234 653 650 650 643 650 649 649 643 732 701 701 699 701 700 700 699 221 217 217 216 220 213 213 212 424 153 423 153 737 734 734 675 734 682 682 675 686 680 682 680 680 675 245 226 226 225 245 225 225 224 269 267 267 239 269 239 221 220 220 212 221 212 1 2 31 Face Edge Indices Starting from 1 2161 3 4 1709 2105 5 6 1683 1035 388 7 8 9 10 61 11 419 744 12 50 1126 16 13 14 59 15 16 17 18 55 899 1052 19 11 1569 20 21 22 47 63 23 24 25 26 1842 27 28 25 29 30 366 2027 31 1067 1747 32 33 33 1362 1320 9 34 35 36 37 67 13 38 39 40 41 37 949 42 43 44 45 1742 46 47 48 48 49 40 50 360 952 130 51 1609 52 1801 1351 53 54 682 55 56 496 57 58 1408 35 59 60 17 1111 61 62 686 890 1992 63 64 65 66 12 67 68 1815 1821 171 69 1313 70 71 72 73 312 1933 79 74 1501 329 75 1463 76 685 289 77 178 78 79 76 80 1487 81 82 778 83 84 350 1740 85 86 1016 87 262 237 88 200 89 90 91 215 92 981 1007 1393 93 464 561 1080 94 21 1471 95 96 2083 2119 97 98 1017 347 99 127 102 100 101 1428 123 102 103 1541 377 1382 689 104 105 106 817 994 107 108 1315 101 109 460 110 628 1475 111 109 719 630 112 1814 293 113 160 538 114 115 116 2188 117 1535 118 1272 223 119 120 379 121 1246 1882 122 1441 1460 123 124 125 1175 126 127 811 49 2050 128 1784 129 130 118 131 128 132 228 133 53 1819 134 249 135 136 19 137 138 2179 139 134 195 140 141 1810 2155 142 143 1009 1997 144 145 142 511 146 147 148 149 62 43 150 7 151 152 1958 1034 153 746 1968 241 154 155 797 156 157 320 158 159 180 160 161 207 302 100 341 162 165 163 164 1965 1344 165 166 731 167 168 1515 169 1930 164 170 171 2208 172 173 828 174 177 175 176 1735 318 177 1691 178 179 180 636 648 1054 181 182 183 184 218 1513 1745 185 1131 186 273 234 257 187 508 188 189 8 190 433 112 191 192 1528 193 194 195 998 196 197 1265 198 307 895 199 200 348 126 1759 201 1509 1174 1507 202 203 264 161 868 204 205 206 351 207 247 469 208 321 209 445 210 796 833 1853 1473 211 227 212 213 214 215 1780 1212 256 216 217 218 520 282 219 220 271 725 221 222 223 2115 224 1626 1159 238 225 226 1729 240 227 228 427 229 230 231 105 232 254 225 205 233 234 235 854 236 237 266 238 1462 323 239 1075 240 216 241 1442 1829 242 243 484 1456 2177 244 77 245 246 247 209 248 1737 213 249 344 1680 250 428 251 337 252 617 865 253 83 254 202 255 256 257 1678 75 258 352 259 781 260 482 261 1500 262 263 99 264 265 372 837 167 266 267 2048 268 117 253 298 269 270 940 271 272 944 273 196 274 275 1051 194 276 277 278 335 1690 1920 279 500 280 588 779 333 281 675 282 283 284 162 1259 285 286 359 1445 1477 287 279 288 289 168 1089 290 291 357 1732 292 1828 1233 293 1525 294 295 784 764 843 296 664 2117 297 1302 298 1091 299 300 301 326 302 303 250 714 304 502 305 306 635 1628 307 308 1191 309 598 640 991 310 426 346 311 468 572 312 798 313 242 488 314 305 315 1490 316 1004 288 317 318 172 1482 319 65 1289 622 320 321 1058 322 169 323 324 316 1524 244 325 634 326 583 327 328 144 261 281 329 758 330 331 671 332 330 82 1043 333 830 1521 334 825 230 335 336 1503 337 107 338 339 576 769 340 1459 292 341 342 541 1033 345 343 88 334 344 345 158 346 72 206 347 348 349 291 350 303 351 343 106 999 352 338 353 354 1157 527 355 356 703 357 358 170 1783 359 308 732 1990 360 2100 1352 361 2067 362 363 1840 364 745 365 366 2200 1817 367 1536 1331 368 1875 369 370 1543 371 1060 372 373 620 722 374 375 1273 1941 378 376 377 1540 383 378 379 404 132 380 1617 1858 672 381 382 387 383 1844 1613 384 385 1852 386 387 400 639 388 28 1559 389 274 390 183 1996 395 391 392 924 393 396 394 395 1600 1884 396 1749 434 397 643 923 398 2024 401 399 400 401 437 2167 402 403 251 404 405 1940 1565 406 1850 416 407 1551 408 1763 1769 409 410 407 1693 411 475 789 412 364 1554 413 414 398 415 416 471 1665 417 718 418 419 421 420 1068 421 1367 422 415 392 423 624 592 424 110 425 734 540 426 219 427 428 446 208 429 430 431 1421 113 1448 432 399 433 434 1424 435 1053 1087 436 673 2022 1466 437 521 556 438 661 439 440 441 147 184 528 442 365 1572 443 444 451 445 446 382 1449 447 371 497 448 449 450 465 451 121 623 567 452 453 210 243 454 455 252 306 456 818 491 457 919 776 458 677 459 1658 460 300 461 532 569 462 489 463 464 586 465 466 467 638 468 342 469 486 759 470 1544 615 471 472 1584 179 473 823 441 192 986 474 967 565 475 476 485 783 477 549 478 479 480 309 656 866 481 199 482 483 156 484 832 229 958 485 495 1452 486 487 931 488 2059 489 603 490 666 491 853 480 492 507 1469 493 494 452 1423 1896 493 495 1434 496 85 497 1615 498 499 612 500 501 2002 1734 502 503 902 873 385 504 936 1124 505 537 159 506 856 712 507 1614 508 1560 374 509 510 552 355 511 512 1925 513 570 514 1049 1130 1898 515 516 727 517 1002 518 662 660 602 519 520 146 526 521 522 1598 1915 523 513 524 525 457 526 527 1636 528 420 529 530 978 531 532 533 614 534 535 439 536 577 537 1037 538 539 73 540 541 542 658 543 544 545 604 546 547 2194 548 2 1669 549 550 1633 551 975 552 1980 553 1321 463 554 555 589 1573 556 557 1001 558 559 384 716 560 1366 472 186 561 562 563 945 647 705 564 565 593 587 566 567 443 653 531 1097 568 569 903 974 1038 570 654 470 331 571 572 248 157 514 573 574 575 423 576 651 637 577 578 564 509 610 594 579 997 580 749 609 554 581 582 548 642 583 584 313 585 882 586 587 260 588 519 462 589 795 590 515 591 592 478 733 483 593 594 595 461 596 597 1153 598 599 525 600 340 601 602 568 603 604 605 517 606 607 476 608 1145 609 616 610 611 649 1546 612 120 429 613 915 993 614 1414 615 1558 605 1557 616 617 473 750 618 883 606 910 619 620 621 1040 641 622 623 133 1577 624 625 626 543 845 601 802 627 851 628 629 630 373 534 655 631 632 633 1660 634 670 635 864 1548 636 637 638 492 858 1465 1582 639 571 640 641 642 1667 643 929 191 644 516 611 645 447 646 647 539 648 649 650 659 414 566 1549 651 652 653 1570 1066 1588 654 1210 436 655 412 773 656 645 657 658 529 582 659 559 530 660 1670 644 661 662 663 763 664 665 314 666 505 667 668 174 1024 669 487 670 1113 671 672 574 673 1164 657 579 674 675 676 872 772 913 677 678 679 652 678 1862 680 681 682 69 1349 683 66 1931 684 685 686 687 2066 680 688 689 693 690 691 692 693 2062 2063 1651 694 762 695 690 2143 696 697 698 699 700 691 743 700 1121 701 889 1042 702 14 703 943 1073 1641 704 2127 705 706 852 707 724 708 709 562 1082 710 841 629 2145 1879 711 712 236 713 714 880 715 716 150 717 718 719 881 720 499 780 721 790 722 235 808 723 724 725 886 726 522 957 727 542 1199 2065 2034 728 729 720 730 731 204 937 732 733 1798 734 1127 735 839 736 479 737 810 458 838 738 739 740 741 1270 704 742 743 744 745 370 711 746 747 1964 1363 748 749 750 390 751 752 834 1993 1342 753 558 754 1605 696 2168 755 1621 799 756 692 948 757 758 759 860 877 760 663 757 761 762 763 764 754 187 765 766 767 259 1101 768 769 961 770 960 771 772 926 932 773 721 774 775 776 956 777 1197 804 778 779 827 894 780 781 782 846 783 784 466 896 766 1579 785 140 786 393 787 633 788 789 578 790 791 863 584 792 793 901 1168 794 795 796 922 665 797 788 798 799 1649 2198 1031 800 983 801 802 768 803 804 136 599 805 770 498 806 807 857 1532 808 1523 831 809 810 879 925 811 1508 1105 1648 1652 812 1026 813 1889 814 887 2174 815 730 459 816 774 619 817 809 818 819 893 820 918 1908 821 822 964 823 824 825 701 354 826 1497 226 827 87 828 829 800 830 89 831 832 833 296 892 834 627 835 862 265 917 836 837 838 699 1696 839 840 417 841 842 871 843 844 155 845 674 846 847 848 1193 849 916 850 851 791 301 1201 852 523 853 1642 805 92 1195 854 1705 855 1857 856 506 857 858 736 859 381 860 1451 861 535 862 870 454 863 864 865 580 866 816 867 868 869 826 870 871 1826 872 1179 873 874 1196 875 876 877 938 878 900 879 880 881 557 882 850 883 884 761 885 2074 886 1205 1694 2089 887 888 835 836 889 278 996 890 728 891 892 801 893 224 894 895 1606 896 503 897 668 898 698 959 899 900 295 760 676 901 94 902 859 418 903 904 1581 905 474 989 906 742 1625 907 908 813 909 910 1634 911 912 786 913 914 987 915 544 916 917 966 775 1688 1062 918 919 771 920 921 455 922 923 847 924 925 876 926 927 1005 928 929 815 930 931 955 844 932 933 914 934 935 982 936 937 353 988 938 518 336 1183 939 940 953 941 942 299 943 944 898 1166 945 1672 946 821 1562 947 948 756 2197 949 950 855 951 928 1713 952 1518 953 954 962 955 1845 956 920 861 957 1591 1184 958 976 906 1215 959 960 961 591 467 2076 962 963 551 964 1929 322 965 966 1190 524 967 438 794 968 965 969 1666 970 148 713 1139 971 972 755 973 1118 974 765 975 976 2057 1897 977 1204 978 717 979 980 1239 981 283 982 792 1137 735 983 984 985 824 986 930 987 988 989 933 332 990 991 1703 992 42 993 849 904 994 969 977 995 996 1699 669 997 998 999 231 985 1000 947 1721 1001 905 1002 1003 867 909 245 1004 1005 1006 1007 1213 1008 1009 129 1010 1011 10 2251 1012 1226 1906 1013 1014 32 71 1015 1016 1999 1099 1017 546 2097 135 1018 1142 1019 1020 2191 1021 897 1088 869 785 1022 2001 2081 1023 1024 1065 1025 1026 708 1027 1028 1029 501 56 1063 1030 1031 1077 1032 1033 1136 782 1015 1034 1877 1035 1036 1797 1037 563 1138 1038 1039 1125 189 1040 1883 2090 1041 1042 1043 1117 667 723 1529 1044 435 1045 1046 793 1743 1047 1048 1025 1049 1050 15 1727 1072 1051 1052 1055 1053 1054 1013 1717 1055 1056 1057 1181 1058 1189 1059 1060 840 1061 1064 1062 1063 18 1910 1064 1065 1032 1066 1067 1068 1306 1069 2041 181 1070 1188 1071 980 1044 1072 1073 1173 1074 1075 1076 1133 1077 1128 1078 803 1079 1198 1080 1209 1081 1082 1047 1083 1086 1084 1085 547 2042 1086 1087 1088 1185 1089 1928 1090 1091 1106 1092 1095 2234 1093 1094 1108 1095 1156 1096 1097 1102 1098 1099 1022 1392 1100 1101 984 1120 1161 1102 2171 1103 829 1192 2080 1104 1733 1105 1106 1207 1109 1107 1108 1216 1539 1109 1112 125 1110 1111 1433 1112 1113 1901 1114 1081 1115 1116 1117 1151 203 1118 1119 618 1120 1121 1141 1122 1123 1149 1124 188 1119 1125 173 1177 2084 1126 270 1127 1135 1128 1129 1130 1148 1131 1163 1132 1133 942 1140 1134 1135 1200 1136 1137 1150 1194 1138 1139 212 1140 1154 842 1141 1155 1142 349 1160 607 1143 311 1144 2104 1777 1145 510 1146 990 1114 1147 1148 1575 1202 941 1149 1206 1592 1150 1103 1165 1505 1151 979 992 1152 2054 1083 1153 1154 356 1018 995 1090 1155 1156 1152 1157 1504 939 1158 1159 1027 737 1160 1516 1079 1161 1912 1162 1163 1167 1164 1165 269 1170 1166 1048 1167 1168 1071 706 405 613 1169 255 1170 1076 1056 1171 1172 1173 1092 1174 1178 1175 1176 573 1177 1021 1178 1098 2210 1179 1116 449 1180 1181 1485 1644 1147 1182 1183 1169 1184 1185 272 1203 1186 1187 1389 512 1188 1045 875 1700 1189 1190 1061 1191 1586 1192 1039 1193 1172 819 1354 1194 1195 1196 1738 1197 1697 1198 290 1199 1200 1143 1201 1202 1146 631 1203 709 1204 1059 277 1205 1206 317 490 1207 232 1069 1208 1084 1209 1132 1210 1211 1074 1212 193 1213 1186 1214 1215 1681 1216 1217 38 1218 1785 1407 1224 1219 1220 1221 1222 2218 1219 1277 1223 1224 362 1225 1226 1706 2095 1231 1227 1228 1372 1229 1300 1232 1230 1231 2245 1258 1232 1260 1233 1234 1235 1236 1347 1360 1262 1237 431 197 1238 1187 1239 1214 363 1756 1240 1220 1241 1242 2160 1243 319 1377 1283 1244 1245 1246 1533 1241 2108 1247 2047 1248 1249 1751 741 1250 1914 1251 1707 1715 1252 1254 1253 2101 1254 1295 1255 600 1279 1256 1255 2247 1228 1257 1838 1234 1258 1237 1259 1260 1238 1261 1262 1249 1263 1264 1841 1766 1265 214 2164 1266 1244 1267 1268 1269 1317 2180 1750 1768 1270 1271 297 1272 1275 1273 1274 1225 1943 1275 1221 2249 1276 1277 1274 1278 1279 1288 1280 1281 1282 286 1283 1247 1284 740 1285 2106 1282 1286 1629 1287 1266 1773 1288 1936 1771 1289 96 3 1770 1290 1291 104 1292 1293 1294 1295 1757 1296 1297 1144 1298 1276 1752 1299 1278 1020 1300 1301 1310 1510 1302 1662 1761 1303 1619 182 1304 1014 1305 1306 1439 1794 1307 679 1308 1309 51 1391 1310 1402 1311 1312 1712 2099 1336 1313 1905 1314 1315 1316 1317 1476 44 1686 1318 1319 1320 1787 1321 1438 1385 1322 1263 1323 1324 1325 1803 1983 1326 1316 116 1327 2028 1328 1329 2017 1330 1331 1568 1791 1332 1345 1333 2181 1326 1334 1010 1723 1335 1390 1336 2184 1955 1337 1338 1339 1412 1340 1420 1358 1341 1342 2068 1343 1344 1417 122 1345 1346 453 1347 1762 1348 1349 1243 1833 1350 1348 1416 1351 1356 1346 1352 1630 1353 1354 1436 115 29 1355 1356 2183 1340 1380 1357 1358 1359 1360 1837 1361 2070 402 1362 1363 753 1290 1892 1364 1365 1741 1208 1366 1367 103 1368 1369 1401 1404 1370 410 1371 1357 1372 1373 1374 697 1339 1375 1376 1242 1377 1378 1379 1380 2013 1381 1382 1330 1370 1400 1383 1384 1397 1385 1386 1387 1748 1388 1389 1311 1390 1415 1391 2079 1392 1393 1411 1394 1395 432 1396 36 2011 1397 2124 2032 1398 1399 1422 1399 1308 1264 1400 2015 6 1301 1401 1402 1796 70 1305 1403 1404 1405 394 621 1406 1407 1332 1806 1408 1495 1409 1410 1979 1789 2237 1411 1355 1412 1413 1647 1414 1405 1371 1415 1416 1417 1418 2156 2045 1419 1328 2014 1420 1333 1359 1951 1421 1395 1422 143 807 1423 1307 1426 1424 1425 2158 1926 1426 1314 1427 1428 1429 1430 1795 1303 1431 1432 1176 1433 1434 1435 1436 1006 1418 1437 1427 1438 1439 1872 1440 1441 1437 80 1442 74 1831 315 1443 1443 1444 1824 1445 1446 95 1425 1447 1448 1468 1449 1450 1450 1451 1452 131 1453 1454 1454 1455 41 1456 1457 1458 1458 1807 139 154 1459 1460 403 1461 973 1462 1463 1464 1464 1782 2051 406 1465 1466 971 646 1467 1467 1468 1469 1470 1471 1472 1472 46 1396 1261 1473 1474 1474 1475 284 1376 1476 1804 1447 1477 1470 1956 1478 1479 1479 1284 1285 1350 2225 1480 1480 1481 1708 175 1482 1483 1483 1484 2151 1364 1485 1486 239 1487 78 287 1488 1489 1489 1490 268 710 1491 1492 1492 456 1493 1859 1494 688 1329 1495 1008 1512 339 1496 1496 1497 1498 1676 267 1499 1499 1500 1501 934 220 1502 1502 1503 1504 263 1505 1506 1506 1507 1508 1509 1510 2122 968 108 1511 1511 1512 1513 84 874 1514 1514 1515 1516 1684 1122 1517 1517 1518 1519 1520 1521 1522 1522 1523 258 1524 1525 1526 1526 1812 1457 1531 1435 1527 1527 1528 1529 114 1353 1530 1530 1531 1532 1533 970 1309 328 1453 1534 1534 1535 1830 20 1536 1537 1538 1539 1050 1537 1540 1541 1542 1543 1235 1544 1545 389 280 1546 1547 1547 1548 1549 1550 1551 1552 1552 1236 413 442 1553 1554 1948 1764 1555 533 595 1556 1556 1557 545 391 1558 1559 397 1560 1561 1562 1563 1334 408 1564 1565 448 1566 1567 1567 1568 1569 1864 1570 1571 1571 1572 1386 590 1573 1574 1574 555 1575 1611 477 1576 1576 1577 1578 93 1579 1580 1580 1581 585 950 1582 1583 1583 1564 380 411 1584 1585 1585 376 386 1594 1586 1587 1587 1588 1078 481 1612 1589 1589 1590 1591 626 1592 1593 1593 1594 1134 751 1171 1595 1595 1596 1597 504 1598 608 1599 1600 1995 1596 1180 1601 1601 1602 1603 304 715 1604 1604 1605 1606 1057 1607 1608 1608 1609 1674 1003 550 1610 1610 1611 1612 190 1613 1614 806 1615 1616 1616 1542 494 650 1617 1618 1618 1550 1553 2060 1619 1620 1621 1622 1623 1623 1624 694 1036 1625 1639 907 1626 1627 1627 1628 1629 149 1630 1631 1631 1632 687 1847 1633 1634 1432 1635 1620 217 1636 1637 1637 1638 275 747 1639 1640 1640 1641 2146 820 1642 1643 1643 954 141 310 1644 1645 1645 1646 1647 1648 1649 1650 1650 1651 1654 2072 1652 1653 1653 1654 23 1900 1291 1655 1655 1656 1657 425 1658 1659 1659 1660 1919 1578 91 1661 1661 1662 1590 1922 1663 1664 1664 1665 1646 1675 1666 2235 848 1667 1668 1668 1669 1607 729 1670 1671 1671 536 1672 1656 1486 1673 1673 1674 1675 166 1676 1677 1677 1678 233 767 1493 1679 1679 1680 1520 1312 1681 1682 1682 1683 951 1388 1684 1685 1685 1686 276 1104 1719 1687 1687 1688 1689 138 1028 1689 1690 1691 1692 1692 1693 1663 1041 1694 1695 1695 1696 1000 777 1697 1698 1698 1699 1700 2033 1431 1701 1701 1702 891 1638 1703 1704 1704 1705 911 1706 1707 97 1708 1709 1714 1538 1710 2232 1711 908 1286 1712 1713 1123 1714 1715 683 1029 1488 1716 1716 1717 1718 1030 1719 1720 702 1721 1722 1722 1723 60 1724 1725 222 1726 1727 1728 1728 34 1110 1729 1730 1731 1731 1732 1211 1733 1734 1023 681 1735 1736 1737 1738 1739 1739 1740 1730 1741 814 2092 1742 81 137 963 1743 1744 1744 935 1158 2077 1745 1746 1746 1498 1100 2030 1325 1747 1748 1749 368 2216 1750 1751 1019 1752 2248 1753 440 1271 1268 1754 1755 1755 1756 1378 2147 1757 752 2109 1758 1759 738 1760 1761 1762 1763 1939 1945 1952 1764 1765 1766 1240 1767 1768 1252 1383 1322 1769 1917 1923 1770 1771 2112 1772 1772 1773 1774 2223 1775 1776 1776 1777 1778 1779 211 198 1848 1780 625 684 1781 1782 2153 1783 163 1 2019 1784 361 1785 1786 1786 1787 1341 2007 2003 1788 1788 1789 1790 1880 2140 1791 1218 2230 1792 1792 1793 1319 1381 1566 1794 2209 1795 1781 153 1796 1797 1870 1798 1753 1799 1800 1327 1935 1801 1802 1802 1803 1800 1804 1269 2087 1805 1806 1419 1807 1808 1809 1809 1810 54 5 1297 1811 1808 1812 1813 1813 1814 1815 1977 1338 1816 1816 1817 1409 1854 1971 1818 1818 1819 1820 1821 1822 1823 1823 1824 1429 822 921 1825 1825 1826 596 45 1230 1827 1827 1828 1829 1830 1831 1832 1832 1822 145 2113 1833 1834 2244 1835 1836 1836 1837 1838 430 1944 1839 1839 1840 1841 1293 1842 1843 1843 1844 367 888 1845 1846 1846 1847 726 2166 1848 1849 1849 575 1256 1545 1850 1851 1851 1852 26 1853 1854 1855 1855 2137 111 422 912 1856 1856 1857 1858 1866 1859 1860 1860 1861 1873 1861 1862 1863 1863 1864 369 1292 1494 1865 1865 1866 1867 119 2114 1868 1868 1869 1870 246 2036 1871 1871 1872 560 1599 1873 1874 1874 1875 1876 748 1877 1878 1878 1879 1374 2134 1880 1881 1881 1882 1974 1883 1884 1885 1885 1876 1561 972 1461 1886 1886 1887 1888 707 1889 1890 1890 1891 221 1602 1892 1893 1893 1894 2129 1903 946 1895 1895 1896 1897 1898 1918 1899 1899 1900 1070 424 1901 1902 1902 1903 1491 1904 1905 2136 1906 1251 1907 1563 1908 1909 1909 1910 1011 1911 1912 1913 1913 1914 1012 1129 1915 1916 1916 1917 1918 1919 1920 1921 1921 1922 1182 1894 1923 1924 1924 1925 1926 185 597 1927 1927 1928 1929 1930 1931 1932 1932 1933 1967 1934 1935 2088 1775 1936 1937 1937 1294 1296 2021 444 1938 1938 1939 1940 1950 1941 1942 1942 1943 1944 1954 1945 1946 1946 1947 1835 1947 1948 1949 1949 1950 1951 2213 1952 1953 1953 1954 1955 1603 1956 1957 1957 1767 2149 1958 1959 1960 1960 1961 1375 1373 1888 1962 1962 1963 1964 1440 1965 1966 1966 1967 1968 1779 1765 1969 1969 1970 1971 1869 2163 1972 1972 1973 285 2206 1974 1975 1975 1245 1398 2008 1976 2138 151 1977 1978 1978 1979 2004 1980 1981 1982 1982 1983 1961 1984 1985 1217 2038 1986 1987 1987 1988 2241 1318 1519 1989 1989 1990 1227 1963 2073 1991 1991 1992 1993 27 1867 1994 1994 1995 1996 1790 1997 1998 1998 58 1976 2173 1999 2000 2000 2001 2002 2003 2004 2005 2005 2006 2239 2007 2008 2009 2009 2010 152 1981 2011 2012 2012 2013 2014 1959 2015 2016 2016 1403 553 1248 2017 2018 2018 2019 2025 2020 812 1361 2021 2022 2023 2023 2024 1387 1323 2025 2026 2026 2027 409 2229 2028 2029 2029 2030 1793 2031 2032 1394 2033 2034 2035 2035 1624 1635 1384 2036 2037 2037 927 1369 2187 2038 2039 2039 2040 30 2041 2042 2043 2043 98 1304 2044 2045 2046 2046 2047 2010 1446 2048 2049 2049 2050 22 324 2051 2052 2052 1430 1444 1726 124 2053 2054 2055 2056 2056 1115 632 1096 2057 2058 2058 581 2059 2060 1622 2061 2061 2062 739 24 2063 2064 2064 2065 2066 2067 2068 2069 2069 64 1632 1887 2070 2071 2071 2072 2073 2074 787 2075 2075 2076 878 2055 2077 2078 2078 2079 450 2080 2081 2082 2082 86 1720 2083 2084 2085 2085 1891 1711 1799 1413 2086 2086 2087 2088 2089 2090 2091 2091 39 2175 2092 2093 2094 2094 2195 1085 2233 2095 2096 2096 2097 1093 52 1335 2098 2098 2099 1324 2100 2101 2102 2102 2186 1257 1481 1778 2103 2103 2104 2105 1250 2106 2107 2107 2108 2222 2109 2110 2111 2111 2112 1724 2226 2113 2114 1758 2115 2116 2116 2117 201 1973 4 2118 2118 2119 1281 2120 1760 1365 1287 2110 2121 2121 2122 90 1229 1379 2123 2123 2124 1368 2170 2125 2126 2126 2127 695 2128 2120 1046 1478 2129 2130 2130 2131 1267 1986 2132 2133 2133 2134 2204 1820 1736 2135 2135 2136 2137 2044 2138 2139 2139 57 1805 2140 2132 2141 2141 2142 1406 2125 2143 2144 2144 2145 2146 2147 1597 2148 2148 2149 1811 2150 2151 2152 2152 2153 1343 1455 327 2154 2154 2155 68 2150 2156 2157 2157 1904 176 2131 2158 2159 2159 294 325 2160 2161 2162 2162 2163 1834 1774 2164 2165 2165 2166 1280 2167 2168 2169 2169 2170 884 1907 2171 2172 2172 2173 1718 2174 2175 2176 2176 1985 2093 1754 2177 2178 2178 2179 1970 2180 2181 2182 2182 2183 1934 2215 2184 2185 2185 2186 1222 2187 2188 2227 2203 2189 2190 2190 2243 1988 2212 2191 2192 2192 375 1555 1984 1094 2193 2193 2194 2195 2020 885 2196 2196 2197 2198 2202 2040 2199 1410 2200 2201 2201 2202 2006 2203 2204 2205 2205 2206 2031 358 1484 2207 2207 2208 2209 2053 2210 2211 2211 1162 1710 2212 2213 2214 2214 2215 1298 2216 2220 2217 2217 2218 1253 2219 2220 2221 2221 2222 1223 1725 2223 2224 2224 2225 2226 2142 2227 2228 2228 2229 2230 2231 2232 1911 2252 2233 2234 1657 2235 2236 2236 1702 2128 2189 2237 2238 2238 2239 2240 2199 2241 2242 2242 2243 2240 2244 2245 2246 2246 2247 1337 2248 2249 2250 2250 2219 1299 2251 2252 2253 2253 1107 2231 sfact-2011.12.18/models/box.obj000066400000000000000000000035441167321211700157650ustar00rootroot00000000000000# ----------------- # Start of obj file g Box01 mtllib box.mat usemtl box v -62.0579 -41.4791 0.0 v 58.8424 -41.4791 0.0 v -62.0579 22.1865 0.0 v 58.8424 22.1865 0.0 v -62.0579 -41.4791 39.8714 v 58.8424 -41.4791 39.8714 v -62.0579 22.1865 39.8714 v 58.8424 22.1865 39.8714 vt 0.843206 0.405444 0.000499517 vt 0.482802 0.71377 0.9995 vt 0.478066 0.404023 0.000499636 vt 0.482802 0.716612 0.9995 vt 0.841627 0.688332 0.000499517 vt 0.482013 0.981029 0.9995 vt 0.480434 0.688332 0.000499636 vt 0.485959 0.978188 0.9995 vt 0.450102 0.00618343 0.000499547 vt 0.45247 0.509304 0.000499547 vt 0.000499517 0.512146 0.000499547 vt 0.000499517 0.512146 0.000499547 vt -0.0010791 0.00618302 0.000499547 vt 0.450102 0.00618343 0.000499547 vt 0.000499517 0.512009 0.9995 vt 0.450891 0.510588 0.9995 vt 0.45247 0.995237 0.9995 vt 0.45247 0.996658 0.9995 vt 0.000499636 0.9995 0.9995 vt 0.000499517 0.51343 0.9995 vt 0.478855 0.405444 0.000500023 vt 0.841627 0.408286 0.000499576 vt 0.83847 0.688332 0.000499576 vt 0.83847 0.688332 0.000499576 vt 0.477276 0.694016 0.000500023 vt 0.478855 0.405444 0.000500023 vt 0.482802 0.71377 0.9995 vt 0.845574 0.71377 0.999501 vt 0.844784 0.976767 0.999501 vt 0.844784 0.976767 0.999501 vt 0.482802 0.716612 0.9995 vt 0.842417 0.710929 0.9995 vt 0.843995 0.975346 0.9995 vt 0.843995 0.975346 0.9995 vt 0.478066 0.404023 0.000499636 vt 0.841627 0.688332 0.000499517 vn 0.0 0.0 -1.0 vn 0.0 0.0 -1.0 vn 0.0 0.0 1.0 vn 0.0 0.0 1.0 vn 0.0 -1.0 0.0 vn 0.0 -1.0 0.0 vn 1.0 0.0 0.0 vn 1.0 0.0 0.0 vn 0.0 1.0 0.0 vn 0.0 1.0 0.0 vn -1.0 0.0 0.0 vn -1.0 0.0 0.0 f 1/9/1 3/10/1 4/11/1 f 4/12/2 2/13/2 1/14/2 f 5/15/3 6/16/3 8/17/3 f 8/18/4 7/19/4 5/20/4 f 1/21/5 2/22/5 6/23/5 f 6/24/6 5/25/6 1/26/6 f 2/27/7 4/28/7 8/29/7 f 8/30/8 6/6/8 2/2/8 f 4/31/9 3/32/9 7/33/9 f 7/34/10 8/8/10 4/4/10 f 3/35/11 1/1/11 5/36/11 f 5/5/12 7/7/12 3/3/12 # end of obj file # --------------- sfact-2011.12.18/models/inkscape_star.svg000066400000000000000000000052051167321211700200440ustar00rootroot00000000000000 image/svg+xml sfact-2011.12.18/models/xml_models/000077500000000000000000000000001167321211700166365ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/art_of_illusion/000077500000000000000000000000001167321211700220265ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/art_of_illusion/art_of_illusion_boolean.xml000066400000000000000000000623661167321211700274540ustar00rootroot00000000000000 Default Texture Camera 1 Weight Position Weight Rotation Light 1 Weight Position Weight Rotation Cube 1 Weight Position Weight Rotation Cube 2 Weight Position Weight Rotation Boolean1 Weight Position Weight Rotation sfact-2011.12.18/models/xml_models/art_of_illusion/art_of_illusion_cylinder.xml000066400000000000000000000370561167321211700276440ustar00rootroot00000000000000 Default Texture Camera 1 Weight Position Weight Rotation Light 1 Weight Position Weight Rotation Cylinder 1 Weight Position Weight Rotation sfact-2011.12.18/models/xml_models/art_of_illusion/art_of_illusion_group.xml000066400000000000000000000641411167321211700271620ustar00rootroot00000000000000 Default Texture Camera 1 Weight Position Weight Rotation Light 1 Weight Position Weight Rotation Array of Cylinder 1 Cylinder 1 Weight Position Weight Rotation Cylinder 2 Weight Position Weight Rotation Weight Position Weight Rotation Cylinder 2 Cylinder 1 sfact-2011.12.18/models/xml_models/art_of_illusion/art_of_illusion_sphere.xml000066400000000000000000000367361167321211700273250ustar00rootroot00000000000000 Default Texture Camera 1 Weight Position Weight Rotation Light 1 Weight Position Weight Rotation Sphere1 Weight Position Weight Rotation sfact-2011.12.18/models/xml_models/art_of_illusion/art_of_illusion_tetrahedron.xml000066400000000000000000000463001167321211700303420ustar00rootroot00000000000000 Default Texture Camera 1 Weight Position Weight Rotation Light 1 Weight Position Weight Rotation tetrahedron Weight Position Weight Rotation sfact-2011.12.18/models/xml_models/combined.xml000066400000000000000000000034721167321211700211460ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/000077500000000000000000000000001167321211700204425ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/creation/circle.xml000066400000000000000000000002611167321211700224240ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/concatenate.xml000066400000000000000000000005441167321211700234530ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/drill.xml000066400000000000000000000003651167321211700222760ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/extrude.xml000066400000000000000000000036741167321211700226560ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/000077500000000000000000000000001167321211700213605ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/creation/gear/bevel.svg000066400000000000000000011036371167321211700232110ustar00rootroot00000000000000 bevel.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Layer 25, z:10.2 Layer 26, z:10.6 Layer 27, z:11.0 Layer 28, z:11.4 Layer 29, z:11.8 Layer 30, z:12.2 Layer 31, z:12.6 Layer 32, z:13.0 Layer 33, z:13.4 Layer 34, z:13.8 Layer 35, z:14.2 Layer 36, z:14.6 Layer 37, z:15.0 Layer 38, z:15.4 Latitude < > Longitude < > Scale 1 < > Min X: -49.2741 mm Y: -148.9752 mm Z: 0.0 mm Max X: 49.2741 mm Y: 21.6669 mm Z: 15.6 mm Dimension X: 98.5482 mm Y: 170.6421 mm Z: 15.6 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 39 Volume: 262.5277 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -49.2741 mm Y: -148.9752 mm Z: 0.0 mm Max X: 49.2741 mm Y: 21.6669 mm Z: 15.6 mm Dimension X: 98.5482 mm Y: 170.6421 mm Z: 15.6 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 39 Volume: 262.5277 cm3 Y X Scale : 1 < > Min X: -49.2741 mm Y: -148.9752 mm Z: 0.0 mm Max X: 49.2741 mm Y: 21.6669 mm Z: 15.6 mm Dimension X: 98.5482 mm Y: 170.6421 mm Z: 15.6 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 39 Volume: 262.5277 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/bevel.xml000066400000000000000000000001171167321211700231760ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/collar.svg000066400000000000000000011054051167321211700233630ustar00rootroot00000000000000 collar.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Layer 25, z:10.2 Layer 26, z:10.6 Layer 27, z:11.0 Layer 28, z:11.4 Layer 29, z:11.8 Layer 30, z:12.2 Layer 31, z:12.6 Layer 32, z:13.0 Layer 33, z:13.4 Layer 34, z:13.8 Layer 35, z:14.2 Layer 36, z:14.6 Layer 37, z:15.0 Layer 38, z:15.4 Layer 39, z:15.8 Layer 40, z:16.2 Layer 41, z:16.6 Layer 42, z:17.0 Layer 43, z:17.4 Layer 44, z:17.8 Layer 45, z:18.2 Layer 46, z:18.6 Layer 47, z:19.0 Layer 48, z:19.4 Layer 49, z:19.8 Latitude < > Longitude < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 20.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 20.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 50 Volume: 164.3011 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 20.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 20.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 50 Volume: 164.3011 cm3 Y X Scale : 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 20.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 20.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 50 Volume: 164.3011 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/collar.xml000066400000000000000000000002271167321211700233570ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/default_gear.svg000066400000000000000000006312621167321211700245350ustar00rootroot00000000000000 default_gear.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Latitude < > Longitude < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: 0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.0364 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: 0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.0364 cm3 Y X Scale : 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: 0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.0364 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/gear.svg000066400000000000000000006332671167321211700230400ustar00rootroot00000000000000 gear.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Latitude < > Longitude < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.0364 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.0364 cm3 Y X Scale : 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.0364 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/gear.xml000066400000000000000000000000731167321211700230200ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/keyway.svg000066400000000000000000011047611167321211700234240ustar00rootroot00000000000000 keyway.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Layer 25, z:10.2 Layer 26, z:10.6 Layer 27, z:11.0 Layer 28, z:11.4 Layer 29, z:11.8 Layer 30, z:12.2 Layer 31, z:12.6 Layer 32, z:13.0 Layer 33, z:13.4 Layer 34, z:13.8 Layer 35, z:14.2 Layer 36, z:14.6 Layer 37, z:15.0 Layer 38, z:15.4 Layer 39, z:15.8 Layer 40, z:16.2 Layer 41, z:16.6 Layer 42, z:17.0 Layer 43, z:17.4 Layer 44, z:17.8 Layer 45, z:18.2 Layer 46, z:18.6 Layer 47, z:19.0 Layer 48, z:19.4 Layer 49, z:19.8 Latitude < > Longitude < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 20.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 20.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 50 Volume: 164.533 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 20.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 20.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 50 Volume: 164.533 cm3 Y X Scale : 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 20.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 20.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 50 Volume: 164.533 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/keyway.xml000066400000000000000000000002501167321211700234100ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/rack.svg000066400000000000000000003576371167321211700230460ustar00rootroot00000000000000 rack.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Latitude < > Longitude < > Scale 1 < > Min X: -62.8319 mm Y: -54.0 mm Z: -0.0 mm Max X: 62.8319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 125.6637 mm Y: 75.8248 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 55.6493 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -62.8319 mm Y: -54.0 mm Z: -0.0 mm Max X: 62.8319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 125.6637 mm Y: 75.8248 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 55.6493 cm3 Y X Scale : 1 < > Min X: -62.8319 mm Y: -54.0 mm Z: -0.0 mm Max X: 62.8319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 125.6637 mm Y: 75.8248 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 55.6493 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/rack.xml000066400000000000000000000001171167321211700230210ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/rack_hole.svg000066400000000000000000004535451167321211700240500ustar00rootroot00000000000000 rack_hole.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Latitude < > Longitude < > Scale 1 < > Min X: -62.8319 mm Y: -64.0 mm Z: -0.0 mm Max X: 62.8319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 125.6637 mm Y: 85.8248 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 81.0238 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -62.8319 mm Y: -64.0 mm Z: -0.0 mm Max X: 62.8319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 125.6637 mm Y: 85.8248 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 81.0238 cm3 Y X Scale : 1 < > Min X: -62.8319 mm Y: -64.0 mm Z: -0.0 mm Max X: 62.8319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 125.6637 mm Y: 85.8248 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 81.0238 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/rack_hole.xml000066400000000000000000000002101167321211700240220ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/ring.svg000066400000000000000000007537311167321211700230600ustar00rootroot00000000000000 ring.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Layer 25, z:10.2 Layer 26, z:10.6 Layer 27, z:11.0 Layer 28, z:11.4 Layer 29, z:11.8 Layer 30, z:12.2 Layer 31, z:12.6 Layer 32, z:13.0 Layer 33, z:13.4 Layer 34, z:13.8 Layer 35, z:14.2 Layer 36, z:14.6 Layer 37, z:15.0 Latitude < > Longitude < > Scale 1 < > Min X: -73.4936 mm Y: -191.9792 mm Z: -0.0 mm Max X: 73.4936 mm Y: 21.8248 mm Z: 15.2 mm Dimension X: 146.9872 mm Y: 213.804 mm Z: 15.2 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 38 Volume: 230.2172 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -73.4936 mm Y: -191.9792 mm Z: -0.0 mm Max X: 73.4936 mm Y: 21.8248 mm Z: 15.2 mm Dimension X: 146.9872 mm Y: 213.804 mm Z: 15.2 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 38 Volume: 230.2172 cm3 Y X Scale : 1 < > Min X: -73.4936 mm Y: -191.9792 mm Z: -0.0 mm Max X: 73.4936 mm Y: 21.8248 mm Z: 15.2 mm Dimension X: 146.9872 mm Y: 213.804 mm Z: 15.2 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 38 Volume: 230.2172 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/ring.xml000066400000000000000000000001211167321211700230330ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/shaft.svg000066400000000000000000007741571167321211700232330ustar00rootroot00000000000000 shaft.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Latitude < > Longitude < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.8979 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.8979 cm3 Y X Scale : 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.8979 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/shaft.xml000066400000000000000000000001131167321211700232020ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/shaft_top.svg000066400000000000000000010072471167321211700241030ustar00rootroot00000000000000 shaft_top.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Latitude < > Longitude < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.1382 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.1382 cm3 Y X Scale : 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: -0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 10.0 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.1382 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/shaft_top.xml000066400000000000000000000001551167321211700240720ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/spur_helix.svg000066400000000000000000006626461167321211700243070ustar00rootroot00000000000000 spur_helix.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Latitude < > Longitude < > Scale 1 < > Min X: -50.4346 mm Y: -150.4247 mm Z: -0.0 mm Max X: 50.4288 mm Y: 22.1224 mm Z: 10.0 mm Dimension X: 100.8635 mm Y: 172.5471 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 150.9144 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -50.4346 mm Y: -150.4247 mm Z: -0.0 mm Max X: 50.4288 mm Y: 22.1224 mm Z: 10.0 mm Dimension X: 100.8635 mm Y: 172.5471 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 150.9144 cm3 Y X Scale : 1 < > Min X: -50.4346 mm Y: -150.4247 mm Z: -0.0 mm Max X: 50.4288 mm Y: 22.1224 mm Z: 10.0 mm Dimension X: 100.8635 mm Y: 172.5471 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 150.9144 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/spur_helix.xml000066400000000000000000000001141167321211700242600ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/spur_herringbone.svg000066400000000000000000006534631167321211700254750ustar00rootroot00000000000000 spur_herringbone.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Latitude < > Longitude < > Scale 1 < > Min X: -50.4225 mm Y: -150.4395 mm Z: -0.0 mm Max X: 50.4306 mm Y: 22.1224 mm Z: 10.0 mm Dimension X: 100.8531 mm Y: 172.5619 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 150.9346 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -50.4225 mm Y: -150.4395 mm Z: -0.0 mm Max X: 50.4306 mm Y: 22.1224 mm Z: 10.0 mm Dimension X: 100.8531 mm Y: 172.5619 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 150.9346 cm3 Y X Scale : 1 < > Min X: -50.4225 mm Y: -150.4395 mm Z: -0.0 mm Max X: 50.4306 mm Y: 22.1224 mm Z: 10.0 mm Dimension X: 100.8531 mm Y: 172.5619 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 150.9346 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/spur_herringbone.xml000066400000000000000000000001441167321211700254540ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/spur_parabolic.svg000066400000000000000000006350501167321211700251170ustar00rootroot00000000000000 spur_parabolic.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Layer 2, z:1.0 Layer 3, z:1.4 Layer 4, z:1.8 Layer 5, z:2.2 Layer 6, z:2.6 Layer 7, z:3.0 Layer 8, z:3.4 Layer 9, z:3.8 Layer 10, z:4.2 Layer 11, z:4.6 Layer 12, z:5.0 Layer 13, z:5.4 Layer 14, z:5.8 Layer 15, z:6.2 Layer 16, z:6.6 Layer 17, z:7.0 Layer 18, z:7.4 Layer 19, z:7.8 Layer 20, z:8.2 Layer 21, z:8.6 Layer 22, z:9.0 Layer 23, z:9.4 Layer 24, z:9.8 Latitude < > Longitude < > Scale 1 < > Min X: -50.4272 mm Y: -150.3492 mm Z: -0.0 mm Max X: 50.4412 mm Y: 22.1077 mm Z: 10.0 mm Dimension X: 100.8684 mm Y: 172.4569 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.0364 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -50.4272 mm Y: -150.3492 mm Z: -0.0 mm Max X: 50.4412 mm Y: 22.1077 mm Z: 10.0 mm Dimension X: 100.8684 mm Y: 172.4569 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.0364 cm3 Y X Scale : 1 < > Min X: -50.4272 mm Y: -150.3492 mm Z: -0.0 mm Max X: 50.4412 mm Y: 22.1077 mm Z: 10.0 mm Dimension X: 100.8684 mm Y: 172.4569 mm Z: 10.0 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 25 Volume: 151.0364 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/spur_parabolic.xml000066400000000000000000000001421167321211700251040ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/spur_profile.svg000066400000000000000000001056561167321211700246270ustar00rootroot00000000000000 spur_profile.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Latitude < > Longitude < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: 0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 0.8 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 16.6701 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: 0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 0.8 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 16.6701 cm3 Y X Scale : 1 < > Min X: -50.4319 mm Y: -150.126 mm Z: 0.0 mm Max X: 50.4319 mm Y: 21.8248 mm Z: 0.8 mm Dimension X: 100.8638 mm Y: 171.9508 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 16.6701 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/creation/gear/spur_profile.xml000066400000000000000000000002251167321211700246120ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/gear/test_gear.xml000066400000000000000000000024261167321211700240630ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/grid.xml000066400000000000000000000006121167321211700221100ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/heightmap.xml000066400000000000000000000002101167321211700231230ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/heightmap_1.pgm000066400000000000000000000000711167321211700233330ustar00rootroot00000000000000P1 # CREATOR: GIMP PNM Filter Version 1.1 3 2 1 0 1 1 0 1sfact-2011.12.18/models/xml_models/creation/heightmap_255.pgm000066400000000000000000000013021167321211700235040ustar00rootroot00000000000000P2 # CREATOR: GIMP PNM Filter Version 1.1 20 10 255 255 255 255 255 229 120 19 0 0 0 0 0 0 19 120 229 255 255 255 255 255 255 255 255 197 70 0 0 0 0 0 0 0 0 70 197 255 255 255 255 255 255 255 255 140 12 0 0 0 0 0 0 0 0 12 140 255 255 255 255 255 255 255 255 128 0 0 0 0 0 0 0 0 0 0 128 255 255 255 255 255 255 255 255 128 0 0 0 0 0 0 0 0 0 0 128 255 255 255 255 255 255 255 255 179 51 0 0 0 0 0 0 0 0 51 179 255 255 255 255 255 255 255 255 217 89 0 0 0 0 0 0 0 0 89 217 255 255 255 255 255 255 255 255 249 198 77 0 0 0 0 0 0 77 198 249 255 255 255 255 255 255 255 255 255 249 198 128 51 0 0 51 128 198 249 255 255 255 255 255 255 255 255 255 255 255 249 236 218 205 205 218 236 249 255 255 255 255 255 255 sfact-2011.12.18/models/xml_models/creation/lathe.xml000066400000000000000000000003141167321211700222570ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/line.xml000066400000000000000000000003001167321211700221040ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/linear_bearing_cage.xml000066400000000000000000000001101167321211700250740ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/lineation.xml000066400000000000000000000002441167321211700231460ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/mechaslab.xml000066400000000000000000000001741167321211700231050ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/peg.xml000066400000000000000000000000721167321211700217360ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/polygon.xml000066400000000000000000000011111167321211700226450ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/shaft.xml000066400000000000000000000003771167321211700223000ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/sponge.xml000066400000000000000000000003041167321211700224540ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/sponge_slice.xml000066400000000000000000000003111167321211700236310ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/square.xml000066400000000000000000000002341167321211700224630ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/svg.xml000066400000000000000000000007671167321211700217750ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/teardrop.xml000066400000000000000000000003471167321211700230100ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/creation/text.xml000066400000000000000000000001771167321211700221550ustar00rootroot00000000000000 hi sfact-2011.12.18/models/xml_models/geometry.csv000066400000000000000000000005501167321211700212060ustar00rootroot00000000000000Format is tab separated boolean geometry. Name Value _object booleangeometry version 2010-03-29 _object trianglemesh id tetrahedron _object matrix4x4 m11 0.0 m13 1.0 m21 -1.0 m22 0.0 m32 -1.0 m33 0.0 _table vertex x y z -5.0 2.89 -5.77 5.0 2.89 8.66 _table face vertex0 vertex1 vertex2 3 0 1 3 1 2 3 2 0 0 2 1 sfact-2011.12.18/models/xml_models/geometry_tools/000077500000000000000000000000001167321211700217115ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/geometry_tools/path_elements/000077500000000000000000000000001167321211700245415ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/geometry_tools/path_elements/arc.xml000066400000000000000000000022341167321211700260310ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_tools/path_elements/cubic.xml000066400000000000000000000006741167321211700263570ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_tools/path_elements/quadratic.xml000066400000000000000000000006461167321211700272460ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/000077500000000000000000000000001167321211700225645ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate.xml000066400000000000000000000063021167321211700251150ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_elements/000077500000000000000000000000001167321211700262665ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_elements/creation.xml000066400000000000000000000001611167321211700306120ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_elements/document.xml000066400000000000000000000022611167321211700306270ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_elements/setting.xml000066400000000000000000000012211167321211700304610ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_enumerables/000077500000000000000000000000001167321211700267545ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_enumerables/dictionary.xml000066400000000000000000000017301167321211700316440ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_enumerables/list.xml000066400000000000000000000015141167321211700304520ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_enumerables/string.xml000066400000000000000000000020331167321211700310020ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_fundamentals/000077500000000000000000000000001167321211700271335ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_fundamentals/euclid.xml000066400000000000000000000020201167321211700311140ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_fundamentals/math.xml000066400000000000000000000013251167321211700306070ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_fundamentals/measure.xml000066400000000000000000000013511167321211700313160ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/geometry_utilities/evaluate_fundamentals/print.xml000066400000000000000000000005171167321211700310140ustar00rootroot00000000000000 hello sfact-2011.12.18/models/xml_models/manipulation_matrix/000077500000000000000000000000001167321211700227225ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/manipulation_matrix/rotate.xml000066400000000000000000000012321167321211700247400ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_matrix/scale.xml000066400000000000000000000002571167321211700245370ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_matrix/transform.xml000066400000000000000000000003121167321211700254530ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_matrix/translate.xml000066400000000000000000000002621167321211700254410ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_meta/000077500000000000000000000000001167321211700223445ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/manipulation_meta/array.xml000066400000000000000000000006131167321211700242040ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_meta/carve.xml000066400000000000000000000004511167321211700241660ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_meta/copy.xml000066400000000000000000000011461167321211700240420ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_meta/disjoin.xml000066400000000000000000000012531167321211700245260ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_meta/import.xml000066400000000000000000000012221167321211700243750ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_meta/pathTest.svg000066400000000000000000000604201167321211700246630ustar00rootroot00000000000000 write.xml - Slice Layers Layer 0, z:0.0 Layer 1, z:5.0 Latitude < > Longitude < > Scale 1 < > Min X: -9.0 mm Y: -9.0 mm Z: -1.5 mm Max X: 9.0 mm Y: 15.0 mm Z: 6.5 mm Dimension X: 18.0 mm Y: 24.0 mm Z: 8.0 mm Statistics Layer Thickness: 3.0 mm Number of Layers: 2 Volume: 0.33 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -9.0 mm Y: -9.0 mm Z: -1.5 mm Max X: 9.0 mm Y: 15.0 mm Z: 6.5 mm Dimension X: 18.0 mm Y: 24.0 mm Z: 8.0 mm Statistics Layer Thickness: 3.0 mm Number of Layers: 2 Volume: 0.33 cm3 Y X Scale : 1 < > Min X: -9.0 mm Y: -9.0 mm Z: -1.5 mm Max X: 9.0 mm Y: 15.0 mm Z: 6.5 mm Dimension X: 18.0 mm Y: 24.0 mm Z: 8.0 mm Statistics Layer Thickness: 3.0 mm Number of Layers: 2 Volume: 0.33 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/manipulation_meta/write.xml000066400000000000000000000010601167321211700242150ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_meta/writeTest.xml000066400000000000000000000207431167321211700250660ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_meta/writeTest_2.xml000066400000000000000000000207431167321211700253070ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/000077500000000000000000000000001167321211700225355ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/manipulation_paths/bevel.xml000066400000000000000000000002531167321211700243540ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/bevel/000077500000000000000000000000001167321211700236325ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/manipulation_paths/bevel/bevel.xml000066400000000000000000000002531167321211700254510ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/bevel/bevel_element.xml000066400000000000000000000003311167321211700271570ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/convex.xml000066400000000000000000000002771167321211700245670ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/inset.xml000066400000000000000000000002411167321211700243760ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/outline.xml000066400000000000000000000002461167321211700247400ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/outset.xml000066400000000000000000000002401167321211700245760ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/overhang.xml000066400000000000000000000006101167321211700250650ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/round.xml000066400000000000000000000002531167321211700244060ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/segment.xml000066400000000000000000000005451167321211700247250ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_paths/wedge.xml000066400000000000000000000003201167321211700243450ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_shapes/000077500000000000000000000000001167321211700227015ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/manipulation_shapes/bottom.xml000066400000000000000000000010511167321211700247240ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_shapes/equation.xml000066400000000000000000000004641167321211700252540ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_shapes/flip/000077500000000000000000000000001167321211700236335ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/manipulation_shapes/flip/flip_element.svg000066400000000000000000000625161167321211700270310ustar00rootroot00000000000000 flip_element.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Latitude < > Longitude < > Scale 1 < > Min X: -9.5508 mm Y: 0.0 mm Z: 0.0 mm Max X: -0.3223 mm Y: 9.082 mm Z: 0.8 mm Dimension X: 9.2285 mm Y: 9.082 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 0.0475 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -9.5508 mm Y: 0.0 mm Z: 0.0 mm Max X: -0.3223 mm Y: 9.082 mm Z: 0.8 mm Dimension X: 9.2285 mm Y: 9.082 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 0.0475 cm3 Y X Scale : 1 < > Min X: -9.5508 mm Y: 0.0 mm Z: 0.0 mm Max X: -0.3223 mm Y: 9.082 mm Z: 0.8 mm Dimension X: 9.2285 mm Y: 9.082 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 0.0475 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/manipulation_shapes/flip/flip_element.xml000066400000000000000000000003051167321211700270160ustar00rootroot00000000000000 hi sfact-2011.12.18/models/xml_models/manipulation_shapes/flip/flip_path.svg000066400000000000000000000554261167321211700263360ustar00rootroot00000000000000 flip_path.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Latitude < > Longitude < > Scale 1 < > Min X: -20.0 mm Y: 0.0 mm Z: 0.0 mm Max X: -10.0 mm Y: 30.0 mm Z: 0.8 mm Dimension X: 10.0 mm Y: 30.0 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 0.1 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -20.0 mm Y: 0.0 mm Z: 0.0 mm Max X: -10.0 mm Y: 30.0 mm Z: 0.8 mm Dimension X: 10.0 mm Y: 30.0 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 0.1 cm3 Y X Scale : 1 < > Min X: -20.0 mm Y: 0.0 mm Z: 0.0 mm Max X: -10.0 mm Y: 30.0 mm Z: 0.8 mm Dimension X: 10.0 mm Y: 30.0 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 0.1 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/manipulation_shapes/flip/flip_path.xml000066400000000000000000000002631167321211700263240ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_shapes/flip/flip_solid.svg000066400000000000000000000553161167321211700265120ustar00rootroot00000000000000 flip_solid.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Latitude < > Longitude < > Scale 1 < > Min X: -20.0 mm Y: 0.0 mm Z: 0.0 mm Max X: -10.0 mm Y: 30.0 mm Z: 0.8 mm Dimension X: 10.0 mm Y: 30.0 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 0.1 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -20.0 mm Y: 0.0 mm Z: 0.0 mm Max X: -10.0 mm Y: 30.0 mm Z: 0.8 mm Dimension X: 10.0 mm Y: 30.0 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 0.1 cm3 Y X Scale : 1 < > Min X: -20.0 mm Y: 0.0 mm Z: 0.0 mm Max X: -10.0 mm Y: 30.0 mm Z: 0.8 mm Dimension X: 10.0 mm Y: 30.0 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 0.1 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/manipulation_shapes/flip/flip_solid.xml000066400000000000000000000001531167321211700265000ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_shapes/inset/000077500000000000000000000000001167321211700240235ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/manipulation_shapes/inset/inset_element.xml000066400000000000000000000006401167321211700274000ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_shapes/inset/inset_path.xml000066400000000000000000000002411167321211700267000ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_shapes/inset/inset_solid.xml000066400000000000000000000003501167321211700270570ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_shapes/mirror/000077500000000000000000000000001167321211700242135ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/manipulation_shapes/mirror/mirror_element.xml000066400000000000000000000002411167321211700277550ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_shapes/mirror/mirror_path.svg000066400000000000000000000555541167321211700273000ustar00rootroot00000000000000 mirror_path.xml - Slice Layers Layer 0, z:0.2 Layer 1, z:0.6 Latitude < > Longitude < > Scale 1 < > Min X: -20.0 mm Y: 0.0 mm Z: 0.0 mm Max X: 20.0 mm Y: 30.0 mm Z: 0.8 mm Dimension X: 40.0 mm Y: 30.0 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 2.0 cm3 Y X 0 1 Layer < > Scale 1 < > Min X: -20.0 mm Y: 0.0 mm Z: 0.0 mm Max X: 20.0 mm Y: 30.0 mm Z: 0.8 mm Dimension X: 40.0 mm Y: 30.0 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 2.0 cm3 Y X Scale : 1 < > Min X: -20.0 mm Y: 0.0 mm Z: 0.0 mm Max X: 20.0 mm Y: 30.0 mm Z: 0.8 mm Dimension X: 40.0 mm Y: 30.0 mm Z: 0.8 mm Statistics Layer Thickness: 0.4 mm Number of Layers: 2 Volume: 2.0 cm3 [Iso View] Iso View [Layer View] Layer View [Scroll View] Scroll View sfact-2011.12.18/models/xml_models/manipulation_shapes/mirror/mirror_path.xml000066400000000000000000000002651167321211700272660ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/manipulation_shapes/mirror/mirror_solid.xml000066400000000000000000000001551167321211700274420ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/slab.xml000066400000000000000000000001361167321211700203010ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/solids/000077500000000000000000000000001167321211700201335ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/solids/cube.xml000066400000000000000000000002071167321211700215720ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/solids/cylinder.xml000066400000000000000000000002121167321211700224610ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/solids/difference.xml000066400000000000000000000003071167321211700227470ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/solids/group.xml000066400000000000000000000010251167321211700220070ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/solids/intersection.xml000066400000000000000000000003531167321211700233640ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/solids/sphere.xml000066400000000000000000000001611167321211700221410ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/solids/triangle_mesh.xml000066400000000000000000000010771167321211700235030ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/solids/union.xml000066400000000000000000000011651167321211700220100ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/statements/000077500000000000000000000000001167321211700210255ustar00rootroot00000000000000sfact-2011.12.18/models/xml_models/statements/class.xml000066400000000000000000000017271167321211700226630ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/statements/elif.xml000066400000000000000000000006431167321211700224710ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/statements/else.xml000066400000000000000000000006171167321211700225030ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/statements/for.xml000066400000000000000000000005241167321211700223360ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/statements/function.xml000066400000000000000000000003071167321211700233740ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/statements/if.xml000066400000000000000000000005321167321211700221450ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/statements/print.xml000066400000000000000000000003571167321211700227100ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/statements/return.xml000066400000000000000000000002641167321211700230700ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/statements/statement.xml000066400000000000000000000003321167321211700235510ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/statements/while.xml000066400000000000000000000004611167321211700226600ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/support_test_box.xml000066400000000000000000000002711167321211700230030ustar00rootroot00000000000000 sfact-2011.12.18/models/xml_models/tetra.xml000066400000000000000000002105611167321211700205040ustar00rootroot00000000000000 Default Texture Camera 1 Weight Position Weight Rotation Light 1 Weight Position Weight Rotation tetrax20 Weight Position Weight Rotation tetray40 Weight Position Weight Rotation tetraz30 Weight Position Weight Rotation tetrax20y40 Weight Position Weight Rotation tetrax20z30 Weight Position Weight Rotation tetray40z30 Weight Position Weight Rotation tetrax20y40z30 Weight Position Weight Rotation sfact-2011.12.18/models/xml_models/tetrawedge.xml000066400000000000000000000455621167321211700215270ustar00rootroot00000000000000 Default Texture Camera 1 Weight Position Weight Rotation Light 1 Weight Position Weight Rotation tetrawedge Weight Position Weight Rotation sfact-2011.12.18/sfact changes.txt000066400000000000000000000026241167321211700164460ustar00rootroot00000000000000CARVE: Extrusion width ratio changed to absolute value in mm. CHAMBER: Added options for setting Initial Extruder Nozzle Temperature, it is issued only at the beginning and with M109 code so printer wont try extruding if a min temp has not beeen reached. option checkbox for turning Extruder Heater Off at Shut Down Commented out options and function for Chamber Temperature and Holding Force as it is only confusing and I am not sure if anone uses it. CLIP: Changed internal formulation to calculate the clip amount automatically based on extrusion width by using 0.5*(1/4pi). The value still can be altered using the clip scaler which defaults to 1. COOL: Added option for a minimum feedrate in case of layertime approaching 0, feedrate gets tooo low. INSET: Removed the Temperature read option. Add Custom Code for Temperature Reading Turn Extruder Heater Off at Shut Down is now removed and moved to Chamber SPEED: Perimeter Feedrate is entered as absolute value in mm/sec. The Flowrates are directly dependent on the feedrate and default to 1 (scaled up in background) Option to send Acceleration setting for Fill, perimeter and bridges differently. Setting for bridges is relative to the perimeter. Bridge feedrateis still relative but to the Perimeter feedrate setting now. Flowrate for bridge is now reduced to the native flowrate of the extruder. (for explanation of the native flowrate see my blog) sfact-2011.12.18/sfact_profiles/000077500000000000000000000000001167321211700162135ustar00rootroot00000000000000sfact-2011.12.18/sfact_profiles/profiles/000077500000000000000000000000001167321211700200365ustar00rootroot00000000000000sfact-2011.12.18/sfact_profiles/profiles/cutting.csv000066400000000000000000000002011167321211700222210ustar00rootroot00000000000000Format is tab separated cutting settings. _Name Value WindowPosition 0+400 Profile Selection: end_mill sfact-2011.12.18/sfact_profiles/profiles/extrusion.csv000066400000000000000000000002021167321211700226050ustar00rootroot00000000000000Format is tab separated extrusion settings. _Name Value WindowPosition 0+400 Profile Selection: Default sfact-2011.12.18/sfact_profiles/profiles/milling.csv000066400000000000000000000002011167321211700221770ustar00rootroot00000000000000Format is tab separated milling settings. _Name Value WindowPosition 0+400 Profile Selection: end_mill sfact-2011.12.18/sfact_profiles/profiles/skeinforge_profile.csv000066400000000000000000000002511167321211700244250ustar00rootroot00000000000000Format is tab separated skeinforge profile settings. _Name Value WindowPosition 0+200 cutting False extrusion True milling False winding False sfact-2011.12.18/sfact_profiles/profiles/winding.csv000066400000000000000000000002021167321211700222040ustar00rootroot00000000000000Format is tab separated winding settings. _Name Value WindowPosition 0+400 Profile Selection: free_wire sfact-2011.12.18/skeinforge_application/000077500000000000000000000000001167321211700177275ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/__init__.py000066400000000000000000000006571167321211700220500ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 1 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/skeinforge_application/alterations/000077500000000000000000000000001167321211700222545ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/alterations/end.gmc000066400000000000000000000011511167321211700235100ustar00rootroot00000000000000G91 ; Make coordinates relative G92 E0 ; reset Extruder counter G1 E-2 F900 ;Retract extuder 2mm at 900mm/min G1 Z2 F400 ;Move up two mm (from current position because it is all relative now) G1 Z2 F5000 ; Move Z another 2mm up G90 ; Use absolute coordinates again G1 X5 Y5 F3000.0 ;go to almost home M84 ;disable steppers so they dont get hot during idling... ;or you can use this one comment out ;G1 X10.0 F4000 ;home (almost) x ;G1 Y170 F4000 ; move the print to the front. ;M104 S0 ; make sure the extuder is turned off. ;M140 S0 ; make sure the bed is turned off. ;M84 ; shut down motors. sfact-2011.12.18/skeinforge_application/alterations/example_end.gmc000066400000000000000000000001421167321211700252220ustar00rootroot00000000000000(this is a sample gcode end file, it must be renamed end.gcode for skeinforge to recognize it) M2 sfact-2011.12.18/skeinforge_application/alterations/example_homing.gmc000066400000000000000000000002331167321211700257360ustar00rootroot00000000000000(this is a sample gcode homing file, it must be renamed homing.gcode for skeinforge to recognize it) G1 X-250.0 G92 X0 ;set x 0 G1 Y-250.0 G92 Y0 ;set y 0 sfact-2011.12.18/skeinforge_application/alterations/example_replace.csv000066400000000000000000000000131167321211700261110ustar00rootroot00000000000000M101 M103 sfact-2011.12.18/skeinforge_application/alterations/example_replace_M108.csv000066400000000000000000000000341167321211700266210ustar00rootroot00000000000000M108 S M108 P M113 S M108 S sfact-2011.12.18/skeinforge_application/alterations/replace.csv000066400000000000000000000001311167321211700243770ustar00rootroot00000000000000"M101 "; M103; "M108 S*.* ";" " "M108 "; "G1 F0.0 "; "M113 S0.0 "; "M113 "; G4 P100.0; sfact-2011.12.18/skeinforge_application/alterations/start.gmc000066400000000000000000000001261167321211700241000ustar00rootroot00000000000000G1 Z1 F3000 ;Move Z 1mm up to avid head crashing into printbed G92 E0 ;reset extrudersfact-2011.12.18/skeinforge_application/profiles/000077500000000000000000000000001167321211700215525ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/profiles/cutting/000077500000000000000000000000001167321211700232275ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/profiles/cutting/End_Mill/000077500000000000000000000000001167321211700247125ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/profiles/cutting/End_Mill/chop.csv000066400000000000000000000006151167321211700263620ustar00rootroot00000000000000Format is tab separated chop preferences. Name Value Add Extra Top Layer if Necessary True Open File to be Chopped Import Coarseness (ratio): 1.0 Correct Mesh True Unproven Mesh False Layer Thickness (mm): 0.4 Layer Thickness over Precision (ratio): 10.0 Layers From (index): 0 Layers To (index): 999999999 Perimeter Width (mm): 2.0 windowPositionChop Preferences 600+0 sfact-2011.12.18/skeinforge_application/profiles/cutting/End_Mill/lift.csv000066400000000000000000000005361167321211700263710ustar00rootroot00000000000000Format is tab separated lift preferences. Name Value Activate Lift: True Cutting Lift over Layer Step (ratio): -0.5 Open File to be Lifted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/Screw Holder Bottom.stl Clearance above Top (mm): 5.0 windowPositionLift Preferences 440+53 sfact-2011.12.18/skeinforge_application/profiles/cutting/Laser/000077500000000000000000000000001167321211700242755ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/profiles/cutting/Laser/chop.csv000066400000000000000000000006151167321211700257450ustar00rootroot00000000000000Format is tab separated chop preferences. Name Value Add Extra Top Layer if Necessary True Open File to be Chopped Import Coarseness (ratio): 1.0 Correct Mesh True Unproven Mesh False Layer Thickness (mm): 0.4 Layer Thickness over Precision (ratio): 10.0 Layers From (index): 0 Layers To (index): 999999999 Perimeter Width (mm): 0.2 windowPositionChop Preferences 600+0 sfact-2011.12.18/skeinforge_application/profiles/cutting/Laser/lift.csv000066400000000000000000000005351167321211700257530ustar00rootroot00000000000000Format is tab separated lift preferences. Name Value Activate Lift: True Cutting Lift over Layer Step (ratio): 0.0 Open File to be Lifted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/Screw Holder Bottom.stl Clearance above Top (mm): 5.0 windowPositionLift Preferences 440+53 sfact-2011.12.18/skeinforge_application/profiles/milling/000077500000000000000000000000001167321211700232055ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/profiles/milling/End_Mill/000077500000000000000000000000001167321211700246705ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/profiles/milling/End_Mill/chop.csv000066400000000000000000000006151167321211700263400ustar00rootroot00000000000000Format is tab separated chop preferences. Name Value Add Extra Top Layer if Necessary True Open File to be Chopped Import Coarseness (ratio): 1.0 Correct Mesh True Unproven Mesh False Layer Thickness (mm): 0.4 Layer Thickness over Precision (ratio): 10.0 Layers From (index): 0 Layers To (index): 999999999 Perimeter Width (mm): 2.0 windowPositionChop Preferences 600+0 sfact-2011.12.18/skeinforge_application/profiles/milling/End_Mill/lift.csv000066400000000000000000000005361167321211700263470ustar00rootroot00000000000000Format is tab separated lift preferences. Name Value Activate Lift: True Cutting Lift over Layer Step (ratio): -0.5 Open File to be Lifted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/Screw Holder Bottom.stl Clearance above Top (mm): 5.0 windowPositionLift Preferences 440+53 sfact-2011.12.18/skeinforge_application/profiles/milling/Laser/000077500000000000000000000000001167321211700242535ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/profiles/milling/Laser/chop.csv000066400000000000000000000006151167321211700257230ustar00rootroot00000000000000Format is tab separated chop preferences. Name Value Add Extra Top Layer if Necessary True Open File to be Chopped Import Coarseness (ratio): 1.0 Correct Mesh True Unproven Mesh False Layer Thickness (mm): 0.4 Layer Thickness over Precision (ratio): 10.0 Layers From (index): 0 Layers To (index): 999999999 Perimeter Width (mm): 0.2 windowPositionChop Preferences 600+0 sfact-2011.12.18/skeinforge_application/profiles/milling/Laser/lift.csv000066400000000000000000000005351167321211700257310ustar00rootroot00000000000000Format is tab separated lift preferences. Name Value Activate Lift: True Cutting Lift over Layer Step (ratio): 0.0 Open File to be Lifted /home/enrique/Desktop/backup/babbleold/script/reprap/pyRepRap/skeinforge_tools/craft_plugins/Screw Holder Bottom.stl Clearance above Top (mm): 5.0 windowPositionLift Preferences 440+53 sfact-2011.12.18/skeinforge_application/runskeinforge.sh000066400000000000000000000012421167321211700231430ustar00rootroot00000000000000#!/bin/sh # # Utility script for keeping track of which preference settings a file was processed # with, by copying the current preferences to a date-tagged directory together # with the output files. # # Usage: runskeinforge.sh # dir=`dirname $1` file=`basename $1` for s in .gts .GTS .stl .STL; do if [ ! `basename $file $s` = $file ]; then suffix=$s; fi done if [ -n $suffix ]; then filename=`basename $file $suffix` newdir=$filename-`date +%m%d%H%M` mkdir -p $newdir/skeinforge-prefs cp $1 $newdir cp ~/.skeinforge/*.csv $newdir/skeinforge-prefs python skeinforge.py $newdir/$filename$suffix echo $PWD/$newdir/${filename}_export.gcode fi sfact-2011.12.18/skeinforge_application/sfact_profiles/000077500000000000000000000000001167321211700227325ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/sfact_profiles/profiles/000077500000000000000000000000001167321211700245555ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/sfact_profiles/profiles/milling.csv000066400000000000000000000002011167321211700267160ustar00rootroot00000000000000Format is tab separated milling settings. _Name Value WindowPosition 0+400 Profile Selection: end_mill sfact-2011.12.18/skeinforge_application/sfact_profiles/profiles/skeinforge_profile.csv000066400000000000000000000002511167321211700311440ustar00rootroot00000000000000Format is tab separated skeinforge profile settings. _Name Value WindowPosition 0+200 cutting False extrusion True milling False winding False sfact-2011.12.18/skeinforge_application/sfact_profiles/profiles/winding.csv000066400000000000000000000002021167321211700267230ustar00rootroot00000000000000Format is tab separated winding settings. _Name Value WindowPosition 0+400 Profile Selection: free_wire sfact-2011.12.18/skeinforge_application/show_skeinforge.sh000066400000000000000000000003031167321211700234530ustar00rootroot00000000000000#!/usr/bin/python # # Script to show the skeinforge dialog. # # Usage: set the executable property to true if it isn't already. Then double click the file. # import skeinforge skeinforge.main() sfact-2011.12.18/skeinforge_application/skeinforge.py000066400000000000000000000745371167321211700224550ustar00rootroot00000000000000#!/usr/bin/python """ This page is in the table of contents. ==Overview== ===Introduction=== Skeinforge is a GPL tool chain to forge a gcode skein for a model. The tool chain starts with carve, which carves the model into layers, then the layers are modified by other tools in turn like fill, comb, tower, raft, stretch, hop, wipe, fillet & export. Each tool automatically gets the gcode from the previous tool. So if you want a carved & filled gcode, call the fill tool and it will call carve, then it will fill and output the gcode. If you want to use all the tools, call export and it will call in turn all the other tools down the chain to produce the gcode file. If you do not want a tool after preface to modify the output, deselect the Activate checkbox for that tool. When the Activate checkbox is off, the tool will just hand off the gcode to the next tool without modifying it. The skeinforge module provides a single place to call up all the setting dialogs. When the 'Skeinforge' button is clicked, skeinforge calls export, since that is the end of the chain. The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight. There are also tools which handle settings for the chain, like polyfile. The analyze tool calls plugins in the analyze_plugins folder, which will analyze the gcode in some way when it is generated if their Activate checkbox is selected. The interpret tool accesses and displays the import plugins. The default settings are similar to those on Nophead's machine. A setting which is often different is the 'Layer Thickness' in carve. ===Command Line Interface=== To bring up the skeinforge dialog without a file name, type: python skeinforge_application/skeinforge.py Slicing a file from skeinforge_utilities/skeinforge_craft.py, for example: python skeinforge_application/skeinforge_utilities/skeinforge_craft.py test.stl will slice the file and exit. This is the correct option for programs which use skeinforge to only generate a gcode file. Slicing a file from skeinforge.py, for example: python skeinforge_application/skeinforge.py test.stl will slice the file and bring up the skeinforge window and the analyze windows and then skeinforge will wait for user input. Slicing a file from skeinforge_plugins/craft.py, for example: python skeinforge_application/skeinforge_plugins/craft.py test.stl will slice the file and bring up the analyze windows only and then skeinforge will wait for user input. ===Contribute=== You can contribute by helping develop the manual at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge There is also a forum thread about how to contribute to skeinforge development at: http://dev.forums.reprap.org/read.php?12,27562 I will only reply to emails from contributors or to complete bug reports. ===Documentation=== There is a manual at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge There is also documentation is in the documentation folder, in the doc strings for each module and it can be called from the '?' button or the menu or by clicking F1 in each setting dialog. A list of other tutorials is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge#Tutorials Skeinforge tagged pages on thingiverse can be searched for at: http://www.thingiverse.com/search?cx=015525747728168968820%3Arqnsgx1xxcw&cof=FORID%3A9&ie=UTF-8&q=skeinforge&sa=Search&siteurl=www.thingiverse.com%2F#944 ===Fabrication=== To fabricate a model with gcode and the Arduino you can use the send.py in the fabricate folder. The documentation for it is in the folder as send.html and at: http://reprap.org/bin/view/Main/ArduinoSend Another way is to use an EMC2 or similar computer controlled milling machine, as described in the "ECM2 based repstrap" forum thread at: http://forums.reprap.org/read.php?1,12143 using the M-Apps package, which is at: http://forums.reprap.org/file.php?1,file=772 Another way is to use Zach's ReplicatorG at: http://replicat.org/ There is also an older Processing script at: http://reprap.svn.sourceforge.net/viewvc/reprap/trunk/users/hoeken/arduino/GCode_Host/ Yet another way is to use the reprap host, written in Java, to load and print gcode: http://dev.www.reprap.org/bin/view/Main/DriverSoftware#Load_GCode For jogging, the Metalab group wrote their own exerciser, also in Processing: http://reprap.svn.sourceforge.net/viewvc/reprap/trunk/users/metalab/processing/GCode_Exerciser/ The Metalab group has descriptions of skeinforge in action and their adventures are described at: http://reprap.soup.io/ There is a board about printing issues at: http://www.bitsfrombytes.com/fora/user/index.php?board=5.0 You can buy the Rapman (an improved Darwin) from Bits from Bytes at: http://www.bitsfrombytes.com/ You can buy the Makerbot from Makerbot Industries at: http://www.makerbot.com/ ===File Formats=== An explanation of the gcodes is at: http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter and at: http://reprap.org/bin/view/Main/MCodeReference A gode example is at: http://forums.reprap.org/file.php?12,file=565 The settings are saved as tab separated .csv files in the .skeinforge folder in your home directory. The settings can be set in the tool dialogs. The .csv files can also be edited with a text editor or a spreadsheet program set to separate tabs. The Scalable Vector Graphics file produced by vectorwrite can be opened by an SVG viewer or an SVG capable browser like Mozilla: http://www.mozilla.com/firefox/ A good triangle surface format is the GNU Triangulated Surface format, which is supported by Mesh Viewer and described at: http://gts.sourceforge.net/reference/gts-surfaces.html#GTS-SURFACE-WRITE You can export GTS files from Art of Illusion with the Export GNU Triangulated Surface.bsh script in the Art of Illusion Scripts folder. STL is an inferior triangle surface format, described at: http://en.wikipedia.org/wiki/STL_(file_format) If you're using an STL file and you can't even carve it, try converting it to a GNU Triangulated Surface file in Art of Illusion. If it still doesn't carve, then follow the advice in the troubleshooting section. ===Getting Skeinforge=== The latest version is at: http://members.axion.net/~enrique/reprap_python_beanshell.zip a sometimes out of date version is in the last reprap_python_beanshell.zip attachment in the last post of the Fabmetheus blog at: http://fabmetheus.blogspot.com/ another sometimes out of date version is at: https://reprap.svn.sourceforge.net/svnroot/reprap/trunk/reprap/miscellaneous/python-beanshell-scripts/ ===Getting Started=== For skeinforge to run, install python 2.x on your machine, which is available from: http://www.python.org/download/ To use the settings dialog you'll also need Tkinter, which probably came with the python installation. If it did not, look for it at: http://www.tcl.tk/software/tcltk/ If you want python and Tkinter together on MacOS, you can try: http://www.astro.washington.edu/users/rowen/ROPackage/Overview.html If you want python and Tkinter together on all platforms and don't mind filling out forms, you can try the ActivePython package from Active State at: http://www.activestate.com/Products/activepython/feature_list.mhtml The computation intensive python modules will use psyco if it is available and run about twice as fast. Psyco is described at: http://psyco.sourceforge.net/index.html The psyco download page is: http://psyco.sourceforge.net/download.html Skeinforge imports Stereolithography (.stl) files or GNU Triangulated Surface (.gts) files. If importing an STL file directly doesn't work, an indirect way to import an STL file is by turning it into a GTS file is by using the Export GNU Triangulated Surface script at: http://members.axion.net/~enrique/Export%20GNU%20Triangulated%20Surface.bsh The Export GNU Triangulated Surface script is also in the Art of Illusion folder, which is in the same folder as skeinforge.py. To bring the script into Art of Illusion, drop it into the folder ArtOfIllusion/Scripts/Tools/. Then import the STL file using the STL import plugin in the import submenu of the Art of Illusion file menu. Then from the Scripts submenu in the Tools menu, choose 'Export GNU Triangulated Surface' and select the imported STL shape. Click the 'Export Selected' checkbox and click OK. Once you've created the GTS file, you can turn it into gcode by typing in a shell in the same folder as skeinforge: > python skeinforge.py When the skeinforge dialog pops up, click 'Skeinforge', choose the file which you exported in 'Export GNU Triangulated Surface' and the gcode file will be saved with the suffix '_export.gcode'. Or you can turn files into gcode by adding the file name, for example: > python skeinforge.py Screw Holder Bottom.stl ===License=== GNU Affero General Public License http://www.gnu.org/licenses/agpl.html ===Motto=== I may be slow, but I get there in the end. ===Troubleshooting=== If there's a bug, try downloading the very latest version because skeinforge is often updated without an announcement. The very latest version is at: http://members.axion.net/~enrique/reprap_python_beanshell.zip If there is still a bug, then first prepare the following files: 1. stl file 2. pictures explaining the problem 3. your settings (pack the whole .skeinforge directory with all your settings) 4. alterations folder, if you have any active alterations files Then zip all the files. Second, write a description of the error, send the description and the archive to the developer, enrique ( perez_enrique AT yahoo.com.removethispart ). After a bug fix is released, test the new version and report the results to enrique, whether the fix was successful or not. If the dialog window is too big for the screen, on most Linux window managers you can move a window by holding down the Alt key and then drag the window with the left mouse button to get to the off screen widgets. If you can't use the graphical interface, you can change the settings for skeinforge by using a text editor or spreadsheet to change the settings in the profiles folder in the .skeinforge folder in your home directory. Comments and suggestions are welcome, however, I won't reply unless you are a contributor. Likewise, I will only answer your questions if you contribute to skeinforge in some way. Some ways of contributing to skeinforge are in the contributions thread at: http://dev.forums.reprap.org/read.php?12,27562 You could also contribute articles to demozendium on any topic: http://fabmetheus.crsndoo.com/wiki/index.php/Main_Page If you contribute in a significant way to another open source project, I will consider that also. When I answered everyone's questions, eventually I received more questions than I had time to answer, so now I only answer questions from contributors. I reserve the right to make any correspondence public. Do not send me any correspondence marked confidential. If you do I will delete it. ==Examples== The following examples forge the STL file Screw Holder.stl. The examples are run in a terminal in the folder which contains Screw Holder.gts and skeinforge.py. > python skeinforge.py This brings up the dialog, after clicking 'Skeinforge', the following is printed: The exported file is saved as Screw Holder_export.gcode > python skeinforge.py Screw Holder.stl The exported file is saved as Screw Holder_export.gcode To run only fill for example, type in the craft_plugins folder which fill is in: > python fill.py """ from __future__ import absolute_import import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from optparse import OptionParser from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import os import sys # document raft, stretch, then carve, comb, fill, inset, oozebane, splodge, temperature, speed once they are updated # wiki document help, description, polyfile # subplugins like export static, maybe later mill cut and coil plugins, maybe later still export plugins & change file extension to output file extension http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge # # some kind of gradual bed temperature Bed Temperature Begin Change Height, End Change Height, End # backup demozendium links # replace layer thickness with layer height, replace baseLayerThickness.. with baseLayerHeightMultiplier, consolidate Object First Layer Flow # announce # question, should 'Infill Odd Layer Extra Rotation' be dropped # # unimportant # minor outline problem when an end path goes through a path, like in the letter A # view profile 1 mm thickness # analyze doesn't save skeinlayer settings, remember xy in skeiniso # # # # comb -> maybe add back running jump look at outside loops only for jump, find closest points, find slightly away inside points, link # global simplify pathBetween # comb documentation # retraction step leave # melt _extrusion # resolve getGcodeWithoutDuplication, make better consolidate gcode command function, remove comments from addRaftedLine # think about http://code.google.com/p/skeinarchiver/ and/or undo # add volume fraction to fill # consider removing tower # use fileSettingName to change perimeter width to extrusion width, globalSubstitutionDictionary # check globalExecutionOrder, ensure that bottom order is really high # set temperature in temperature # contract wipe titles # maybe rename geometry_plugins xml # dwindle or dawdle or taper # voronoi average location intersection looped inset intercircles # skin layers without something over the infill # check for last existing then remove unneeded fill code (getLastExistingFillLoops) from euclidean, add fill in penultimate loops, if there is no fill it should not use perimeter - skin should work # delete commented addInfillPerimeter # unpause slow flow rate instead of speeding feed rate # maybe in svgReader if loop intersection with previous union else add # add links download manual svg_writer, add left right arrow keys to layer # delete location from wipe, in other words Arrival X instead of Location Arrival X, also convert Location Arrival to Arrival Location # command # manipulation derivations # cutting ahmet # # When opening a file for craft I wondered if there is an option to set the file type to .stl as it currently defaults to .xml # then add Retraction Scaling Exponent # check inset loop for intersection with loopLayer.loops # maybe make vectorwrite prominent, not skeiniso, probably not because it doesn't work on Mac # close, getPillarByLoopLists, addConcave, polymorph original graph section, loop, add step object, add continuous object # chamber: heated bed off at a layer http://blog.makerbot.com/2011/03/17/if-you-cant-stand-the-heat/ # profile copy / rename / delete, maybe move craft type to profile # think about rectangular getVector3RemoveByPre.. # del previous, add begin & end if far get actual path # bridge infill modifiers only in the bridge infill loop # linearbearingexample 15 x 1 x 2, linearbearingcage # polling # connectionfrom, to, connect, xaxis # move replace from export to alterations # lathe, transform normal in getRemaining, getConnection # add overview link to crnsdoo index and svg page # getConnection of some kind like getConnectionVertexes, getConnection # incorporate actual thickness from feed rate and flow rate in statistics for dimension # update stretch pictures By design, distance between parallel sides in hexagonal hole are 13mm, 7mm, 6.5mm, round hole diameter's are 8mm, 4mm and 3mm. http://fabmetheus.crsndoo.com/wiki/images/Stretch.png http://fabmetheus.crsndoo.com/wiki/images/thumb/NormalHole.png/180px-NormalHole.png http://fabmetheus.crsndoo.com/wiki/images/thumb/StretchDeformedHole.png/180px-StretchDeformedHole.png # xml_creation # 'fileName, text, repository' commandLineInterface # delete: text = text.replace(('\nName %sValue\n' % globalSpreadsheetSeparator), ('\n_Name %sValue\n' % globalSpreadsheetSeparator)) # comment search from home panel when there is an input field # # # multiply to table + boundary bedBound bedWidth bedHeight bedFile.csv # getNormal, getIsFlat? # info statistics, procedures, xml if any # test solid arguments # combine xmlelement with csvelement using example.csv & geometry.csv, csv _format, _column, _row, _text # pixel, voxel, surfaxel/boxel, lattice, mesh # probably not replace getOverlapRatio with getOverlap if getOverlapRatio is never small, always 0.0 # mesh. for cube, then cylinder, then sphere after lathe # dimension extrude diameter, density # superformula http://www.thingiverse.com/thing:12419 # maybe get rid of testLoops once they are no longer needed # thermistor lookup table # stretch maybe add back addAlong # import, write, copy examples # maybe remove default warnings from scale, rotate, translate, transform # easy helix # write tool; maybe write one deep # # # tube # rotor # coin # demozendium privacy policy, maybe thumbnail logo # pymethe # test translate # full lathe # pyramid # round extrusion ?, fillet # make html statistics, move statistics to folder # manipulate solid, maybe manipulate around elements # boolean loop corner outset # mechaslab advanced drainage, shingles # dovetail # maybe not getNewObject, getNew, addToBoolean # work out close and radius # maybe have add function as well as append for list and string # maybe move and give geometryOutput to cube, cylinder, sphere # # maybe move widen before bottom # maybe add 1 to max layer input to iso in layer_template.svg # maybe save all generated_files option # table to dictionary # remove cool set at end of layer # add fan on when hot in chamber # maybe measuring rod # getLayerThickness from xml # maybe center for xy plane # remove comments from clip, bend # winding into coiling, coil into wind & weave # later, precision # documentation # http://wiki.makerbot.com/configuring-skeinforge # # # remove index from CircleIntersection remove ahead or behind from CircleIntersection _speed # probably not speed up CircleIntersection by performing isWithinCircles before creation _speed # don't remove brackets in early craft tools _speed # check bounding box when subtracting or intersecting boolean geometry # get arounds in inset, the inside become extrude loops and the outside below loops _speed # # # add hook _extrusion # integral thin width _extrusion # layer color, for multilayer start http://reprap.org/pub/Main/MultipleMaterialsFiles/legend.xml _extrusion # maybe raft triple layer base, middle interface with hot loop or ties # somehow, add pattern to outside, http://blog.makerbot.com/2010/09/03/lampshades/ # implement acceleration & collinear removal in penultimate viewers _extrusion # # rename skeinforge_profile.addListsToCraftTypeRepository to skeinforge_profile.addToCraftTypeRepository after skirt # basic basedit tool # arch, ceiling # meta setting, rename setting _setting # add polish, has perimeter, has cut first layer (False) # probably not set addedLocation in distanceFeedRate after arc move # maybe horizontal bridging and/or check to see if the ends are standing on anything # thin self? check when removing intersecting paths in inset # save all analyze viewers of the same name except itself, update help menu self.wikiManualPrimary.setUpdateFunction # check alterations folder first, if there is something copy it to the home directory, if not check the home directory # add links to demozendium in help # maybe add hop only if long option # # # # help primary menu item refresh # add plugin help menu, add craft below menu # give option of saving when switching profiles # xml & svg more forgiving, svg make defaults for layerThickness # option of surrounding lines in display # maybe add connecting line in display line # maybe check inset loops to see if they are smaller, but this would be slow # maybe status bar # maybe measurement ruler mouse tool # search rss from blogs, add search links for common materials, combine created on or progress bar with searchable help # boundaries, center radius z bottom top, alterations file, circular or rectangular, polygon, put cool minimum radius orbits within boundaries, bound.. # move & rotate model # possible jitter bug http://cpwebste.blogspot.com/2010/04/hydras-first-print.html # trial, meta in a grid settings # maybe interpret svg_convex_mesh #laminate tool head #maybe use 5x5 radius search in circle node #maybe add layer updates in behold, skeinlayer and maybe others #lathe winding, extrusion and cutting; synonym for rotation or turning, loop angle # maybe split into source code and documentation sections # transform plugins, start with sarrus http://www.thingiverse.com/thing:1425 # maybe make setting backups # move skeinforge_utilities to fabmetheus_utilities # maybe lathe cutting # maybe lathe extrusion # maybe lathe milling # maybe lathe winding & weaving # # # # pick and place # search items, search links, choice entry field # svg triangle mesh, svg polygon mesh # simulate #transform # juricator # probably not run along sparse infill to avoid stops #custom inclined plane, inclined plane from model, screw, fillet travel as well maybe # probably not stretch single isLoop #maybe much afterwards make congajure multistep view #maybe stripe although model colors alone can handle it #stretch fiber around shape, maybe modify winding for asymmetric shapes #multiple heads around edge #maybe add rarely used tool option #angle shape for overhang extrusions #maybe m111? countdown #first time tool tip #individual tool tip to place in text # maybe try to simplify raft layer start # maybe make temp directory # maybe carve aoi xml testing and check xml gcode # maybe cross hatch support polishing??? # maybe print svg view from current layer or zero layer in single view # maybe check if tower is picking the closest island # maybe combine skein classes in fillet # maybe isometric svg option #Manual #10,990 #11,1776,786 #12,3304,1528 #1,4960,1656 #2, 7077,2117 #3, 9598,2521 #4 12014,2305 #5 14319,2536 #6 16855,3226 #7 20081, 2189 #8 22270, 2625 #9 24895, 2967, 98 #10 27862, 3433, 110 #11 31295, 3327 #12 34622 #85 jan7, 86jan11, 87 jan13, 88 jan15, 91 jan21, 92 jan23, 95 jan30, 98 feb6 #make one piece electromagnet spool #stepper rotor with ceramic disk magnet in middle, electromagnet with long thin spool line? #stepper motor #make plastic coated thread in vat with pulley #tensile stuart platform #kayak #gear vacuum pump #gear turbine #heat engine #solar power #sailboat #yacht #house #condo with reflected gardens in between buildings #medical equipment #cell counter, etc.. #pipe clamp lathe # square tube driller & cutter # archihedrongagglevoteindexium # outline images # look from top of intersection circle plane to look for next, add a node; tree out until all are stepped on then connect, when more than three intersections are close # when loading a file, we should have a preview of the part and orientation in space # second (and most important in my opinion) would be the ability to rotate the part on X/Y/Z axis to chose it's orientation # third, a routine to detect the largest face and orient the part accordingly. Mat http://reprap.kumy.net/ # concept, three perpendicular slices to get display spheres # extend lines around short segment after cross hatched boolean # concept, donation, postponement, rotate ad network, cached search options # concept, local ad server, every time the program runs it changes the iamge which all the documentation points to from a pool of ads # concept, join cross slices, go from vertex to two orthogonal edges, then from edges to each other, if not to a common point, then simplify polygons by removing points which do not change the area much # concept, each node is fourfold, use sorted intersectionindexes to find close, connect each double sided edge, don't overlap more than two triangles on an edge # concept, diamond cross section loops # concept, in file, store polygon mesh and centers # concept, display spheres or polygons would have original triangle for work plane # .. then again no point with slices # concept, filled slices, about 2 mm thick # concept, rgb color triangle switch to get inside color, color golden ratio on 5:11 slope with a modulo 3 face # concept, interlaced bricks at corners ( length proportional to corner angle ) # concept, new links to archi, import links to archi and adds skeinforge tool menu item, back on skeinforge named execute tool is added # concept, trnsnt # concept, indexium expand condense remove, single text, pymetheus # concept, inscribed key silencer # concept, spreadsheet to python and/or javascript # concept, range voting for posters, informative, complainer, funny, insightful, rude, spammer, literacy, troll? # concept, intermittent cloud with multiple hash functions __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = """ Adrian Bowyer Brendan Erwin Greenarrow Ian England John Gilmore Jonwise Kyle Corbitt Michael Duffin Marius Kintel Nophead PJR Reece.Arnott Wade Xsainnz Zach Hoeken Organizations: Art of Illusion """ __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addToProfileMenu(profileSelection, profileType, repository): 'Add a profile menu.' pluginFileNames = skeinforge_profile.getPluginFileNames() craftTypeName = skeinforge_profile.getCraftTypeName() pluginModule = skeinforge_profile.getCraftTypePluginModule() profilePluginSettings = settings.getReadRepository(pluginModule.getNewRepository()) for pluginFileName in pluginFileNames: skeinforge_profile.ProfileTypeMenuRadio().getFromMenuButtonDisplay(profileType, pluginFileName, repository, craftTypeName == pluginFileName) for profileName in profilePluginSettings.profileList.value: skeinforge_profile.ProfileSelectionMenuRadio().getFromMenuButtonDisplay(profileSelection, profileName, repository, profileName == profilePluginSettings.profileListbox.value) def getNewRepository(): 'Get new repository.' return SkeinforgeRepository() def getPluginFileNames(): 'Get skeinforge plugin fileNames.' return archive.getPluginFileNamesFromDirectoryPath(archive.getSkeinforgePluginsPath()) def getRadioPluginsAddPluginGroupFrame(directoryPath, importantFileNames, names, repository): 'Get the radio plugins and add the plugin frame.' repository.pluginGroupFrame = settings.PluginGroupFrame() radioPlugins = [] for name in names: radioPlugin = settings.RadioPlugin().getFromRadio(name in importantFileNames, repository.pluginGroupFrame.latentStringVar, name, repository, name == importantFileNames[0]) radioPlugin.updateFunction = repository.pluginGroupFrame.update radioPlugins.append( radioPlugin ) defaultRadioButton = settings.getSelectedRadioPlugin(importantFileNames + [radioPlugins[0].name], radioPlugins) repository.pluginGroupFrame.getFromPath(defaultRadioButton, directoryPath, repository) return radioPlugins def writeOutput(fileName): 'Craft a file, display dialog.' repository = getNewRepository() repository.fileNameInput.value = fileName repository.execute() settings.startMainLoopFromConstructor(repository) class SkeinforgeRepository: 'A class to handle the skeinforge settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Skeinforge', self, '') self.profileType = settings.MenuButtonDisplay().getFromName('Profile Type: ', self ) self.profileType.columnspan = 6 self.profileSelection = settings.MenuButtonDisplay().getFromName('Profile Selection: ', self) self.profileSelection.columnspan = 6 addToProfileMenu( self.profileSelection, self.profileType, self ) settings.LabelDisplay().getFromName('', self) importantFileNames = ['craft', 'profile'] getRadioPluginsAddPluginGroupFrame(archive.getSkeinforgePluginsPath(), importantFileNames, getPluginFileNames(), self) self.executeTitle = 'Skeinforge' def execute(self): 'Skeinforge button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: skeinforge_craft.writeOutput(fileName) def save(self): 'Profile has been saved and profile menu should be updated.' self.profileType.removeMenus() self.profileSelection.removeMenus() addToProfileMenu(self.profileSelection, self.profileType, self) self.profileType.addRadiosToDialog(self.repositoryDialog) self.profileSelection.addRadiosToDialog(self.repositoryDialog) def main(): 'Display the skeinforge dialog.' parser = OptionParser() parser.add_option( '-p', '--prefdir', help='set path to preference directory', action='store', type='string', dest='preferencesDirectory') parser.add_option( '-s', '--start', help='set start file to use', action='store', type='string', dest='startFile') parser.add_option( '-e', '--end', help='set end file to use', action='store', type='string', dest='endFile') parser.add_option( '-o', '--option', help='set an individual option in the format "module:preference=value"', action='append', type='string', dest='preferences') (options, args) = parser.parse_args() if options.preferencesDirectory: archive.globalTemporarySettingsPath = options.preferencesDirectory if options.preferences: for prefSpec in options.preferences: (moduleName, prefSpec) = prefSpec.split(':', 1) (prefName, valueName) = prefSpec.split('=', 1) settings.addPreferenceOverride(moduleName, prefName, valueName) sys.argv = [sys.argv[0]] + args if len( args ) > 0: writeOutput( ' '.join(args) ) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/000077500000000000000000000000001167321211700236245ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/__init__.py000066400000000000000000000006571167321211700257450ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 2 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze.py000066400000000000000000000035111167321211700256410ustar00rootroot00000000000000""" This page is in the table of contents. Analyze is a script to access the plugins which analyze a gcode file. The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight. ==Gcodes== An explanation of the gcodes is at: http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter and at: http://reprap.org/bin/view/Main/MCodeReference A gode example is at: http://forums.reprap.org/file.php?12,file=565 """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_analyze import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addToMenu(master, menu, repository, window): "Add a tool plugin menu." analyzeFilePath = archive.getSkeinforgePluginsPath('analyze.py') pluginsDirectoryPath = skeinforge_analyze.getPluginsDirectoryPath() settings.addPluginsParentToMenu(pluginsDirectoryPath, menu, analyzeFilePath, skeinforge_analyze.getPluginFileNames()) def getNewRepository(): 'Get new repository.' return skeinforge_analyze.AnalyzeRepository() def writeOutput(fileName): "Analyze a gcode file." repository = getNewRepository() repository.fileNameInput.value = fileName repository.execute() settings.startMainLoopFromConstructor(repository) def main(): "Display the analyze dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/000077500000000000000000000000001167321211700270305ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/__init__.py000066400000000000000000000006571167321211700311510ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities/000077500000000000000000000000001167321211700325665ustar00rootroot00000000000000__init__.py000066400000000000000000000006571167321211700346300ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 4 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) display_line.py000066400000000000000000000123511167321211700355370ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities""" This page is in the table of contents. Display line is a mouse tool to select and display information about the line. When a line is clicked, the line will be selected and information about the line will be displayed. If a gcode line is clicked, the information will be file line count of the line clicked, counting from one, and the line itself. When the display line tool is chosen and the canvas has the focus, display line will listen to the arrow keys. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. When the right arrow key is pressed, display line will increase the line index of the layer by one, and change the selection accordingly. If the line index of the layer goes over the index of the last line, the layer index will be increased by one and the new line index will be zero. When the left arrow key is pressed, the index will be decreased. If the line index goes below the index of the first line, the layer index will be decreased by one and the new line index will be at the last line. The up arrow key increases the layer index by one and the down arow key decreases the line index. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base import MouseToolBase from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewMouseTool(): "Get a new mouse tool." return DisplayLine() class DisplayLine( MouseToolBase ): "Display the line when it is clicked." def button1( self, event, shift = False ): "Print line text and connection line." self.destroyEverythingGetFocus() x = self.canvas.canvasx(event.x) y = self.canvas.canvasy(event.y) tags = self.getTagsGivenXY(x, y) if tags == '': return if tags.startswith('colored_line_index:'): splitLine = tags.split() coloredLineIndex = int(splitLine[1]) self.repository.line.value = coloredLineIndex tags = self.getSelectedColoredLine().displayString self.drawLineText( complex( float(x), float(y) ), tags ) def destroyEverything(self): "Destroy items." self.canvas.delete('mouse_item') self.canvas.delete('selection_line') def drawLineText( self, location, tags ): "Draw the line text." self.window.getDrawnLineText( location, 'mouse_item', tags ) def drawSelectedColoredLineText(self): "Draw the selected line and text." selectedColoredLine = self.getSelectedColoredLine() if len( self.canvas.find_withtag('selection_line') ) < 1 or selectedColoredLine is None: return tags = selectedColoredLine.displayString lineCoordinates = self.canvas.coords( self.canvas.find_withtag('selection_line')[-1] ) begin = complex( lineCoordinates[0], lineCoordinates[1] ) end = complex( lineCoordinates[2], lineCoordinates[3] ) segment = end - begin segmentLength = abs(segment) if segmentLength <= 0.0: return towardEnd = 0.75 * segment segmentClockwise = 20.0 * complex( segment.imag, - segment.real ) / segmentLength location = begin + towardEnd + segmentClockwise self.drawLineText( location, tags ) def getSelectedColoredLine(self): "Draw the selected line, add it to the items and return the colored line." self.window.cancelTimerResetButtons() coloredLines = self.window.getColoredLines() self.repository.line.value = max(0, self.repository.line.value) if len(coloredLines) < 1: return None self.repository.line.value = min(len(coloredLines) - 1, self.repository.line.value) self.window.setLineButtonsState() coloredLine = coloredLines[self.repository.line.value] lineCoordinates = self.canvas.coords(self.window.getDrawnSelectedColoredLine(coloredLine)) end = complex(lineCoordinates[2], lineCoordinates[3]) radiusComplex = complex(16.0, 16.0) upperLeft = end - radiusComplex lowerRight = end + radiusComplex self.canvas.create_oval (int(upperLeft.real), int(upperLeft.imag), int(lowerRight.real), int(lowerRight.imag), tags = 'mouse_item') return coloredLine def isSelectionTool(self): "Return if this mouse tool is a selection tool." return True def keyPressDown(self, event): "The down arrow was pressed." self.destroyEverything() self.window.setLayerIndex( self.repository.layer.value - 1 ) def keyPressLeft(self, event): "The left arrow was pressed." self.destroyEverything() self.repository.line.value -= 1 if self.window.isLineBelowZeroSetLayer(): return self.drawSelectedColoredLineText() def keyPressRight(self, event): "The right arrow was pressed." self.destroyEverything() self.repository.line.value += 1 if self.window.isLineBeyondListSetLayer(): return self.drawSelectedColoredLineText() def keyPressUp(self, event): "The up arrow was pressed." self.destroyEverything() self.window.setLayerIndex( self.repository.layer.value + 1 ) def update(self): "Update the mouse tool." self.destroyEverything() self.drawSelectedColoredLineText() mouse_tool_base.py000066400000000000000000000041711167321211700362430ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities""" Display line is a mouse tool to display the line index of the line clicked, counting from one, and the line itself. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' class MouseToolBase: "The mouse tool base class, which does nothing." def button1(self, event): "The left button was clicked, function." pass def buttonRelease1(self, event): "The left button was released, function." pass def destroyEverything(self): "Destroy items." self.canvas.delete('mouse_item') def destroyEverythingGetFocus(self): "Destroy items and get the focus for the canvas." self.destroyEverything() self.canvas.focus_set() def getReset( self, window ): "Reset the mouse tool to default." self.setWindowItems( window ) self.destroyEverything() return self def getTagsGivenXY( self, x, y ): "Get the tag for the x and y." tags = self.canvas.itemcget( self.canvas.find_closest(x, y), 'tags') currentEnd = ' current' if tags.find( currentEnd ) != - 1: return tags[ : - len( currentEnd ) ] return tags def isSelectionTool(self): "Return if this mouse tool is a selection tool." return False def keyPressDown(self, event): "The down arrow was pressed." pass def keyPressLeft(self, event): "The left arrow was pressed." pass def keyPressReturn(self, event): "The return key was pressed." pass def keyPressRight(self, event): "The right arrow was pressed." pass def keyPressUp(self, event): "The up arrow was pressed." pass def motion( self, event, shift = False ): "The mouse moved, function." pass def setWindowItems( self, window ): "Set the canvas and items." self.canvas = window.canvas self.repository = window.repository self.window = window def update(self): "Update the mouse tool." pass tableau.py000066400000000000000000001044021167321211700344770ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities""" Tableau has a couple of base classes for analyze viewers. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities import zoom_in from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities import zoom_out import math import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getGeometricDifference( first, second ): 'Get the geometric difference of the two numbers.' return max( first, second ) / min( first, second ) def getGridHorizontalFrame(gridPosition): 'Get the grid horizontal object with a frame from the grid position.' gridHorizontal = settings.GridHorizontal( 0, 0 ) gridHorizontal.master = settings.Tkinter.Frame( gridPosition.master, borderwidth = 1, padx = 3, relief = 'raised') gridHorizontal.master.grid( row = gridPosition.row, column = gridPosition.column, sticky = settings.Tkinter.E ) return gridHorizontal def getIsLayerStart(firstWord, skein, splitLine): 'Determine if the line is the start of a layer.' if skein.isThereALayerStartWord: return firstWord == '(' if firstWord != 'G1' and firstWord != 'G2' and firstWord != 'G3': return False location = gcodec.getLocationFromSplitLine(skein.oldLocation, splitLine) if location.z - skein.oldZ > 0.1: skein.oldZ = location.z return True return False def getLengthMinusOneMinimumOne( elementList ): 'Get the length of the length minus one, minimum one.' return max( 1, len( elementList ) - 1 ) def getPluginsDirectoryPath(): 'Get the plugins directory path.' return archive.getAnalyzePluginsDirectoryPath('export_canvas_plugins') def getScrollbarCanvasPortion( scrollbar ): 'Get the canvas portion of the scrollbar.' scrollbarBeginEnd = scrollbar.get() return scrollbarBeginEnd[1] - scrollbarBeginEnd[0] def setStateNormalDisabled( active, widget ): 'Set the state of the widget to normal if active and disabled if inactive.' if active: widget.config( state = settings.Tkinter.NORMAL ) else: widget.config( state = settings.Tkinter.DISABLED ) class ColoredLine: 'A colored index line.' def __init__( self, begin, colorName, displayString, end, tagString ): 'Set the color name and corners.' self.begin = begin self.colorName = colorName self.displayString = displayString self.end = end self.tagString = tagString def __repr__(self): 'Get the string representation of this colored index line.' return '%s, %s, %s, %s' % ( self.colorName, self.begin, self.end, self.tagString ) class ExportCanvasDialog: 'A class to display the export canvas repository dialog.' def addPluginToMenu( self, canvas, fileName, menu, name, suffix ): 'Add the display command to the menu.' self.canvas = canvas self.fileName = fileName self.name = name self.suffix = suffix menu.add_command( label = settings.getEachWordCapitalized( self.name ), command = self.display ) def display(self): 'Display the export canvas repository dialog.' for repositoryDialog in settings.globalRepositoryDialogListTable: if repositoryDialog.repository.lowerName == self.name: repositoryDialog.setCanvasFileNameSuffix(self.canvas, self.skein.fileName, self.suffix) settings.liftRepositoryDialogs(settings.globalRepositoryDialogListTable[repositoryDialog]) return pluginModule = archive.getModuleWithDirectoryPath(getPluginsDirectoryPath(), self.name) if pluginModule is None: return None pluginRepository = pluginModule.getNewRepository() pluginRepository.setCanvasFileNameSuffix(self.canvas, self.fileName, self.suffix) settings.getDisplayedDialogFromConstructor(pluginRepository) class TableauRepository: 'The viewer base repository class.' def addAnimation(self): 'Add the animation settings.' self.frameList = settings.FrameList().getFromValue('Frame List', self, [] ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Animation -', self ) self.animationLineQuickening = settings.FloatSpinUpdate().getFromValue( 0.5, 'Animation Line Quickening (ratio):', self, 4.5, 1.0 ) self.animationSlideShowRate = settings.FloatSpinUpdate().getFromValue( 1.0, 'Animation Slide Show Rate (layers/second):', self, 5.0, 2.0 ) settings.LabelSeparator().getFromRepository(self) def addScaleScreenSlide(self): 'Add the scale, screen and slide show settings.' self.scale = settings.FloatSpinNotOnMenu().getFromValue( 10.0, 'Scale (pixels per millimeter):', self, 50.0, 15.0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Screen Inset -', self ) self.screenHorizontalInset = settings.IntSpin().getFromValue( 80, 'Screen Horizontal Inset (pixels):', self, 1000, 100 ) self.screenVerticalInset = settings.IntSpin().getFromValue( 120, 'Screen Vertical Inset (pixels):', self, 1000, 220 ) settings.LabelSeparator().getFromRepository(self) self.showGcode = settings.BooleanSetting().getFromValue('Show Gcode', self, True ) def setToDisplaySave(self, event=None): 'Set the setting values to the display, save the new values.' for menuEntity in self.menuEntities: if menuEntity in self.preferences: menuEntity.setToDisplay() settings.writeSettings(self) class TableauWindow: def activateMouseModeTool(self): 'Activate the mouse mode tool.' self.repository.setToDisplaySave() self.canvas.focus_set() self.createMouseModeTool() self.mouseTool.update() def addCanvasMenuRootScrollSkein(self, repository, skein, suffix, title): 'Add the canvas, menu bar, scroll bar, skein panes, tableau repository, root and skein.' self.imagesDirectoryPath = archive.getFabmetheusUtilitiesPath('images') self.movementTextID = None self.mouseInstantButtons = [] self.photoImages = {} self.repository = repository self.root = settings.Tkinter.Tk() self.gridPosition = settings.GridVertical(0, 1) self.gridPosition.master = self.root self.highlightThickness = 3 self.root.title(os.path.basename(skein.fileName) + ' - ' + title) self.rulingExtent = 24 self.rulingTargetSeparation = 150.0 self.screenSize = skein.screenSize self.skein = skein self.skeinPanes = skein.skeinPanes self.suffix = suffix self.timerID = None repository.animationSlideShowRate.value = max(repository.animationSlideShowRate.value, 0.01) repository.animationSlideShowRate.value = min(repository.animationSlideShowRate.value, 85.0) repository.drawArrows.setUpdateFunction(self.setWindowToDisplaySaveUpdate) repository.goAroundExtruderOffTravel.setUpdateFunction(self.setWindowToDisplaySavePhoenixUpdate) repository.layerExtraSpan.setUpdateFunction(self.setWindowToDisplaySaveUpdate) repository.showGcode.setUpdateFunction(self.setWindowToDisplaySaveUpdate) repository.widthOfSelectionThread.setUpdateFunction(self.setWindowToDisplaySaveUpdate) repository.widthOfTravelThread.setUpdateFunction(self.setWindowToDisplaySaveUpdate) repository.window = self for menuRadio in repository.mouseMode.menuRadios: fileName = menuRadio.name.lower() fileName = fileName.replace(' ', '_') + '.ppm' menuRadio.mouseButton = self.getPhotoButtonGridIncrement(menuRadio.invoke, fileName, self.gridPosition) self.gridPosition = settings.GridHorizontal(2, 99) self.gridPosition.master = self.root self.gcodeStringVar = settings.Tkinter.StringVar(self.root) self.gcodeLabel = settings.Tkinter.Label(self.root, anchor = settings.Tkinter.W, textvariable = self.gcodeStringVar) self.gcodeLabel.grid(row = 0, column = 5, columnspan = 93, sticky = settings.Tkinter.W) from fabmetheus_utilities.hidden_scrollbar import HiddenScrollbar self.xScrollbar = HiddenScrollbar(self.root, orient = settings.Tkinter.HORIZONTAL) self.xScrollbar.grid(row = 98, column = 2, columnspan = 96, sticky = settings.Tkinter.E + settings.Tkinter.W) self.yScrollbar = HiddenScrollbar(self.root) self.yScrollbar.grid(row = 2, rowspan = 96, column = 99, sticky = settings.Tkinter.N + settings.Tkinter.S) self.canvasHeight = self.root.winfo_screenheight() - repository.screenVerticalInset.value self.canvasWidth = self.root.winfo_screenwidth() - repository.screenHorizontalInset.value scrollRegionBoundingBox = (0, 0, int(skein.screenSize.real), int(skein.screenSize.imag)) self.canvas = settings.Tkinter.Canvas(self.root, highlightthickness = self.highlightThickness, width = self.canvasWidth, height = self.canvasHeight, scrollregion = scrollRegionBoundingBox) self.canvas.grid(row = 2, rowspan = 96, column = 2, columnspan = 96, sticky = settings.Tkinter.E + settings.Tkinter.W + settings.Tkinter.N + settings.Tkinter.S) self.fileHelpMenuBar = settings.FileHelpMenuBar(self.root) self.exportMenu = settings.Tkinter.Menu(self.fileHelpMenuBar.fileMenu, tearoff = 0) self.fileHelpMenuBar.fileMenu.add_cascade(label = 'Export', menu = self.exportMenu, underline = 0) exportCanvasPluginFileNames = archive.getPluginFileNamesFromDirectoryPath(getPluginsDirectoryPath()) for exportCanvasPluginFileName in exportCanvasPluginFileNames: ExportCanvasDialog().addPluginToMenu(self.canvas, skein.fileName, self.exportMenu, exportCanvasPluginFileName, suffix) self.fileHelpMenuBar.fileMenu.add_separator() self.fileHelpMenuBar.completeMenu(self.close, repository, self.save, self) def addLayer( self, gridPosition ): 'Add the layer frame items.' self.diveButton = self.getPhotoButtonGridIncrement( self.dive, 'dive.ppm', gridPosition ) self.soarButton = self.getPhotoButtonGridIncrement( self.soar, 'soar.ppm', gridPosition ) gridPosition.increment() settings.Tkinter.Label( gridPosition.master, text = 'Layer:').grid( row = gridPosition.row, column = gridPosition.column, sticky = settings.Tkinter.W ) gridPosition.increment() self.limitIndex() self.layerEntry = settings.Tkinter.Spinbox( gridPosition.master, command = self.layerEntryReturnPressed, from_ = 0, increment = 1, to = getLengthMinusOneMinimumOne( self.skeinPanes ) ) self.layerEntry.bind('', self.layerEntryReturnPressed ) self.layerEntry.grid( row = gridPosition.row, column = gridPosition.column, sticky = settings.Tkinter.W ) def addLine( self, gridPosition ): 'Add the line frame items.' self.lineDiveButton = self.getPhotoButtonGridIncrement( self.lineDive, 'dive.ppm', gridPosition ) self.lineSoarButton = self.getPhotoButtonGridIncrement( self.lineSoar, 'soar.ppm', gridPosition ) gridPosition.increment() settings.Tkinter.Label( gridPosition.master, text = 'Line:').grid( row = gridPosition.row, column = gridPosition.column, sticky = settings.Tkinter.W ) gridPosition.increment() self.lineEntry = settings.Tkinter.Spinbox( gridPosition.master, command = self.lineEntryReturnPressed, from_ = 0, increment = 1, to = getLengthMinusOneMinimumOne( self.getColoredLines() ) ) self.lineEntry.bind('', self.lineEntryReturnPressed ) self.lineEntry.grid( row = gridPosition.row, column = gridPosition.column, sticky = settings.Tkinter.W ) def addMouseInstantTool( self, fileName, gridPosition, mouseInstantTool ): 'Add the mouse instant tool and derived photo button.' mouseInstantTool.getReset(self) photoButton = self.getPhotoButtonGridIncrement( mouseInstantTool.click, fileName, gridPosition ) mouseInstantTool.mouseButton = photoButton self.mouseInstantButtons.append( photoButton ) def addMouseToolsBind(self): 'Add the mouse tool and bind button one clicked, button one released and motion.' self.xScrollbar.config( command = self.relayXview ) self.yScrollbar.config( command = self.relayYview ) self.canvas['xscrollcommand'] = self.xScrollbar.set self.canvas['yscrollcommand'] = self.yScrollbar.set settings.CloseListener( self, self.destroyAllDialogWindows ).listenToWidget( self.canvas ) self.canvasScreenCenter = 0.5 * complex( float( self.canvasWidth ) / float( self.screenSize.real ), float( self.canvasHeight ) / float( self.screenSize.imag ) ) self.addPhotoImage('stop.ppm', self.gridPosition ) self.gridPosition.increment() self.addLayer( getGridHorizontalFrame( self.gridPosition ) ) self.gridPosition.increment() self.addLine( getGridHorizontalFrame( self.gridPosition ) ) self.gridPosition.increment() self.addScale( getGridHorizontalFrame( self.gridPosition ) ) self.gridPosition = settings.GridVertical( self.gridPosition.columnStart + 1, self.gridPosition.row ) self.gridPosition.master = self.root for name in self.repository.frameList.value: entity = self.getEntityFromName( name ) if entity is not None: self.gridPosition.incrementGivenNumberOfColumns(3) entity.addToDialog( getGridHorizontalFrame( self.gridPosition ) ) for menuRadio in self.repository.mouseMode.menuRadios: menuRadio.mouseTool = menuRadio.getNewMouseToolFunction().getReset(self) self.mouseTool = menuRadio.mouseTool self.createMouseModeTool() self.canvas.bind('', self.button1) self.canvas.bind('', self.buttonRelease1) self.canvas.bind('', self.setInsetToCanvas) self.canvas.bind('', self.keyPressDown) self.canvas.bind('', self.keyPressLeft) self.canvas.bind('', self.keyPressRight) self.canvas.bind('', self.keyPressUp) self.canvas.bind('', self.motion) self.canvas.bind('', self.keyPressReturn) self.canvas.bind('', self.shiftButtonRelease1) self.canvas.bind('', self.shiftMotion) self.layerEntry.bind('', self.cancelTimer) self.root.grid_columnconfigure(44, weight = 1) self.root.grid_rowconfigure(44, weight = 1) self.resetPeriodicButtonsText() self.repository.animationLineQuickening.setUpdateFunction( self.repository.setToDisplaySave ) self.repository.animationSlideShowRate.setUpdateFunction( self.repository.setToDisplaySave ) self.repository.screenHorizontalInset.setUpdateFunction( self.redisplayWindowUpdate ) self.repository.screenVerticalInset.setUpdateFunction( self.redisplayWindowUpdate ) rankZeroSeperation = self.getRulingSeparationWidthPixels( 0 ) zoom = self.rulingTargetSeparation / rankZeroSeperation self.rank = euclidean.getRank( zoom ) rankTop = self.rank + 1 seperationBottom = self.getRulingSeparationWidthPixels( self.rank ) seperationTop = self.getRulingSeparationWidthPixels( rankTop ) bottomDifference = getGeometricDifference( self.rulingTargetSeparation, seperationBottom ) topDifference = getGeometricDifference( self.rulingTargetSeparation, seperationTop ) if topDifference < bottomDifference: self.rank = rankTop self.rulingSeparationWidthMillimeters = euclidean.getIncrementFromRank( self.rank ) self.canvas.focus_set() def addPhotoImage( self, fileName, gridPosition ): 'Get a PhotoImage button, grid the button and increment the grid position.' photoImage = None try: photoImage = settings.Tkinter.PhotoImage( file = os.path.join( self.imagesDirectoryPath, fileName ), master = gridPosition.master ) except: print('Image %s was not found in the images directory, so a text button will be substituted.' % fileName ) untilDotFileName = archive.getUntilDot(fileName) self.photoImages[ untilDotFileName ] = photoImage return untilDotFileName def addScale( self, gridPosition ): 'Add the line frame items.' self.addMouseInstantTool('zoom_out.ppm', gridPosition, zoom_out.getNewMouseTool() ) self.addMouseInstantTool('zoom_in.ppm', gridPosition, zoom_in.getNewMouseTool() ) gridPosition.increment() settings.Tkinter.Label( gridPosition.master, text = 'Scale:').grid( row = gridPosition.row, column = gridPosition.column, sticky = settings.Tkinter.W ) gridPosition.increment() self.scaleEntry = settings.Tkinter.Spinbox( gridPosition.master, command = self.scaleEntryReturnPressed, from_ = 10.0, increment = 5.0, to = 100.0 ) self.scaleEntry.bind('', self.scaleEntryReturnPressed ) self.scaleEntry.grid( row = gridPosition.row, column = gridPosition.column, sticky = settings.Tkinter.W ) def addSettingsMenuSetWindowGeometry( self, center ): 'Add the settings menu, center the scroll region, update, and set the window geometry.' self.settingsMenu = settings.Tkinter.Menu( self.fileHelpMenuBar.menuBar, tearoff = 0 ) self.fileHelpMenuBar.addMenuToMenuBar( 'Settings', self.settingsMenu ) settings.addMenuEntitiesToMenuFrameable( self.settingsMenu, self.repository.menuEntities ) self.relayXview( settings.Tkinter.MOVETO, center.real - self.canvasScreenCenter.real ) self.relayYview( settings.Tkinter.MOVETO, center.imag - self.canvasScreenCenter.imag ) self.root.withdraw() self.root.update_idletasks() movedGeometryString = '%sx%s+%s' % ( self.root.winfo_reqwidth(), self.root.winfo_reqheight(), '0+0') self.root.geometry( movedGeometryString ) def button1(self, event): 'The button was clicked.' self.mouseTool.button1(event) def buttonRelease1(self, event): 'The button was released.' self.mouseTool.buttonRelease1(event) def cancel(self, event=None): 'Set all entities to their saved state.' settings.cancelRepository(self.repository) def cancelTimer(self, event=None): 'Cancel the timer and set it to none.' if self.timerID is not None: self.canvas.after_cancel(self.timerID) self.timerID = None def cancelTimerResetButtons(self): 'Cancel the timer and set it to none.' self.cancelTimer() self.resetPeriodicButtonsText() def close(self, event=None): 'The dialog was closed.' try: self.root.after( 1, self.root.destroy ) # to get around 'Font Helvetica -12 still in cache.' segmentation bug, instead of simply calling self.root.destroy() except: pass def createMouseModeTool(self): 'Create the mouse mode tool.' self.destroyMouseToolRaiseMouseButtons() for menuRadio in self.repository.mouseMode.menuRadios: if menuRadio.value: self.mouseTool = menuRadio.mouseTool menuRadio.mouseButton['relief'] = settings.Tkinter.SUNKEN def destroyAllDialogWindows(self): 'Destroy all the dialog windows.' settings.writeSettings(self.repository) return for menuEntity in self.repository.menuEntities: lowerName = menuEntity.name.lower() if lowerName in settings.globalRepositoryDialogListTable: globalRepositoryDialogValues = settings.globalRepositoryDialogListTable[ lowerName ] for globalRepositoryDialogValue in globalRepositoryDialogValues: settings.quitWindow( globalRepositoryDialogValue.root ) def destroyMouseToolRaiseMouseButtons(self): 'Destroy the mouse tool and raise the mouse buttons.' self.mouseTool.destroyEverything() for menuRadio in self.repository.mouseMode.menuRadios: menuRadio.mouseButton['relief'] = settings.Tkinter.RAISED for mouseInstantButton in self.mouseInstantButtons: mouseInstantButton['relief'] = settings.Tkinter.RAISED def dive(self): 'Dive, go down periodically.' oldDiveButtonText = self.diveButton['text'] self.cancelTimerResetButtons() if oldDiveButtonText == 'stop': return self.diveCycle() def diveCycle(self): 'Start the dive cycle.' self.setLayerIndex(self.repository.layer.value - 1) if self.repository.layer.value < 1: self.resetPeriodicButtonsText() return self.setButtonImageText( self.diveButton, 'stop') self.timerID = self.canvas.after( self.getSlideShowDelay(), self.diveCycle ) def getAnimationLineDelay( self, coloredLine ): 'Get the animation line delay in milliseconds.' # maybe later, add animation along line # nextLayerIndex = self.repository.layer.value # nextLineIndex = self.repository.line.value + 1 # coloredLinesLength = len( self.getColoredLines() ) # self.skein.feedRateMinute # if nextLineIndex >= coloredLinesLength: # if nextLayerIndex + 1 < len( self.skeinPanes ): # nextLayerIndex += 1 # nextLineIndex = 0 # else: # nextLineIndex = self.repository.line.value splitLine = gcodec.getSplitLineBeforeBracketSemicolon( coloredLine.displayString ) self.skein.feedRateMinute = gcodec.getFeedRateMinute( self.skein.feedRateMinute, splitLine ) feedRateSecond = self.skein.feedRateMinute / 60.0 coloredLineLength = abs( coloredLine.end - coloredLine.begin ) / self.repository.scale.value duration = coloredLineLength / feedRateSecond animationLineDelay = int( round( 1000.0 * duration / self.repository.animationLineQuickening.value ) ) return max( animationLineDelay, 1 ) def getDrawnLineText( self, location, tags, text ): 'Get the line text drawn on the canvas.' anchorTowardCenter = settings.Tkinter.N if location.imag > float( self.canvasHeight ) * 0.1: anchorTowardCenter = settings.Tkinter.S if location.real > float( self.canvasWidth ) * 0.7: anchorTowardCenter += settings.Tkinter.E else: anchorTowardCenter += settings.Tkinter.W return self.canvas.create_text( int( location.real ), int( location.imag ), anchor = anchorTowardCenter, tags = tags, text = text ) def getEntityFromName(self, name): 'Get the entity of the given name.' for entity in self.repository.displayEntities: if entity.name == name: return entity return None def getPhotoButtonGridIncrement( self, commandFunction, fileName, gridPosition ): 'Get a PhotoImage button, grid the button and increment the grid position.' gridPosition.increment() untilDotFileName = self.addPhotoImage( fileName, gridPosition ) photoImage = self.photoImages[ untilDotFileName ] photoButton = settings.Tkinter.Button( gridPosition.master, activebackground = 'black', activeforeground = 'white', command = commandFunction, text = untilDotFileName ) if photoImage is not None: photoButton['image'] = photoImage photoButton.grid( row = gridPosition.row, column = gridPosition.column, sticky = settings.Tkinter.W ) return photoButton def getRoundedRulingText( self, extraDecimalPlaces, number ): 'Get the rounded ruling text.' rulingText = euclidean.getRoundedToPlacesString( extraDecimalPlaces - math.floor( math.log10( self.rulingSeparationWidthMillimeters ) ), number ) if self.rulingSeparationWidthMillimeters < .99: return rulingText if rulingText[ - len('.0') : ] == '.0': return rulingText[ : - len('.0') ] return rulingText def getRulingSeparationWidthPixels( self, rank ): 'Get the separation width in pixels.' return euclidean.getIncrementFromRank( rank ) * self.skein.scale def getScrollPaneCenter(self): 'Get the center of the scroll pane.' return self.getScrollPaneFraction() + self.canvasScreenCenter def getScrollPaneFraction(self): 'Get the scroll pane top left.' return complex( self.xScrollbar.get()[0], self.yScrollbar.get()[0] ) def getSlideShowDelay(self): 'Get the slide show delay in milliseconds.' slideShowDelay = int( round( 1000.0 / self.repository.animationSlideShowRate.value ) ) return max( slideShowDelay, 1 ) def getUpdateSkeinPanes(self): 'Get the update skein panes.' layerPlusExtraSpan = self.repository.layer.value + self.repository.layerExtraSpan.value layersFrom = max( 0, min( self.repository.layer.value, layerPlusExtraSpan ) ) layersTo = min( len( self.skeinPanes ), max( self.repository.layer.value, layerPlusExtraSpan ) + 1 ) return self.skeinPanes[ layersFrom : layersTo ] def isLineBelowZeroSetLayer(self): 'Determine if the line index is below zero, and if so set the layer index.' if self.repository.line.value >= 0: return False self.repository.line.value = 0 if self.repository.layer.value > 0: self.setLayerIndex( self.repository.layer.value - 1 ) return True return False def isLineBeyondListSetLayer(self): 'Determine if the line index is beyond the end of the list, and if so set the layer index.' coloredLinesLength = len( self.getColoredLines() ) if self.repository.line.value < coloredLinesLength: return False self.repository.line.value = coloredLinesLength - 1 if self.repository.layer.value < len( self.skeinPanes ) - 1: self.setLayerIndex( self.repository.layer.value + 1 ) return True return False def keyPressDown(self, event): 'The down arrow was pressed.' self.mouseTool.keyPressDown(event) def keyPressLeft(self, event): 'The left arrow was pressed.' self.mouseTool.keyPressLeft(event) def keyPressReturn(self, event): 'The return key was pressed.' self.mouseTool.keyPressReturn(event) def keyPressRight(self, event): 'The right arrow was pressed.' self.mouseTool.keyPressRight(event) def keyPressUp(self, event): 'The up arrow was pressed.' self.mouseTool.keyPressUp(event) def layerEntryReturnPressed(self, event=None): 'The layer index entry return was pressed.' self.setLayerIndex( int( self.layerEntry.get() ) ) def limitIndex(self): 'Limit the index so it is not below zero or above the top.' self.repository.layer.value = max( 0, self.repository.layer.value ) self.repository.layer.value = min( len( self.skeinPanes ) - 1, self.repository.layer.value ) def limitIndexSetArrowMouseDeleteCanvas(self): 'Limit the index, set the arrow type, and delete all the canvas items.' self.limitIndex() self.arrowType = None if self.repository.drawArrows.value: self.arrowType = 'last' self.canvas.delete( settings.Tkinter.ALL ) def lineDive(self): 'Line dive, go down periodically.' oldLineDiveButtonText = self.lineDiveButton['text'] self.cancelTimerResetButtons() if oldLineDiveButtonText == 'stop': return self.lineDiveCycle() def lineDiveCycle(self): 'Start the line dive cycle.' self.cancelTimer() self.repository.line.value -= 1 if self.repository.line.value < 0: self.repository.line.value = 0 if self.repository.layer.value == 0: self.resetPeriodicButtonsText() self.setLineButtonsState() return self.setLayerIndex( self.repository.layer.value - 1 ) else: self.updateMouseToolIfSelection() self.setLineButtonsState() self.setButtonImageText( self.lineDiveButton, 'stop') coloredLine = self.getColoredLines()[ self.repository.line.value ] self.timerID = self.canvas.after( self.getAnimationLineDelay( coloredLine ), self.lineDiveCycle ) def lineEntryReturnPressed(self, event=None): 'The line index entry return was pressed.' self.repository.line.value = int( self.lineEntry.get() ) if self.isLineBelowZeroSetLayer(): return if self.isLineBeyondListSetLayer(): return self.cancelTimerResetButtons() self.updateMouseToolIfSelection() self.setLineButtonsState() def lineSoar(self): 'Line soar, go up periodically.' oldLineSoarButtonText = self.lineSoarButton['text'] self.cancelTimerResetButtons() if oldLineSoarButtonText == 'stop': return self.lineSoarCycle() def lineSoarCycle(self): 'Start the line soar cycle.' self.cancelTimer() self.repository.line.value += 1 coloredLinesLength = len( self.getColoredLines() ) if self.repository.line.value >= coloredLinesLength: self.repository.line.value = coloredLinesLength - 1 if self.repository.layer.value > len( self.skeinPanes ) - 2: self.resetPeriodicButtonsText() self.setLineButtonsState() return self.setLayerIndex( self.repository.layer.value + 1 ) else: self.updateMouseToolIfSelection() self.setLineButtonsState() self.setButtonImageText( self.lineSoarButton, 'stop') coloredLine = self.getColoredLines()[ self.repository.line.value ] self.timerID = self.canvas.after( self.getAnimationLineDelay( coloredLine ), self.lineSoarCycle ) def motion(self, event): 'The mouse moved.' self.mouseTool.motion(event) def phoenixUpdate(self): 'Update the skein, and deiconify a new window and destroy the old.' self.updateNewDestroyOld( self.getScrollPaneCenter() ) def redisplayWindowUpdate(self, event=None): 'Deiconify a new window and destroy the old.' self.repository.setToDisplaySave() self.getCopy().updateDeiconify( self.getScrollPaneCenter() ) self.root.after( 1, self.root.destroy ) # to get around 'Font Helvetica -12 still in cache.' segmentation bug, instead of simply calling self.root.destroy() def relayXview( self, *args ): 'Relay xview changes.' self.canvas.xview( *args ) def relayYview( self, *args ): 'Relay yview changes.' self.canvas.yview( *args ) def resetPeriodicButtonsText(self): 'Reset the text of the periodic buttons.' self.setButtonImageText( self.diveButton, 'dive') self.setButtonImageText( self.soarButton, 'soar') self.setButtonImageText( self.lineDiveButton, 'dive') self.setButtonImageText( self.lineSoarButton, 'soar') def save(self): 'Set the setting values to the display, save the new values.' for menuEntity in self.repository.menuEntities: if menuEntity in self.repository.preferences: menuEntity.setToDisplay() settings.writeSettings(self.repository) def scaleEntryReturnPressed(self, event=None): 'The scale entry return was pressed.' self.repository.scale.value = float( self.scaleEntry.get() ) self.phoenixUpdate() def setButtonImageText( self, button, text ): 'Set the text of the e periodic buttons.' photoImage = self.photoImages[ text ] if photoImage is not None: button['image'] = photoImage button['text'] = text def setDisplayLayerIndex(self): 'Set the display of the layer index entry field and buttons.' coloredLines = self.getColoredLines() isAboveFloor = self.repository.layer.value > 0 isBelowCeiling = self.repository.layer.value < len( self.skeinPanes ) - 1 setStateNormalDisabled( isAboveFloor, self.diveButton ) setStateNormalDisabled( isBelowCeiling, self.soarButton ) self.setLineButtonsState() settings.setEntryText( self.layerEntry, self.repository.layer.value ) settings.setEntryText( self.lineEntry, self.repository.line.value ) settings.setEntryText( self.scaleEntry, self.repository.scale.value ) self.mouseTool.update() def setInsetToCanvas(self, event=None): 'Set the repository insets to the canvas.' if self.root.state() != 'normal': return excessExtent = self.highlightThickness + self.highlightThickness screenHorizontalInset = self.repository.screenHorizontalInset screenVerticalInset = self.repository.screenVerticalInset oldHorizontalValue = screenHorizontalInset.value oldVerticalValue = screenVerticalInset.value screenHorizontalInset.value = self.root.winfo_screenwidth() - self.canvas.winfo_width() + excessExtent if not self.yScrollbar.visible: screenHorizontalInset.value += self.yScrollbar.winfo_reqwidth() screenHorizontalInset.setStateToValue() screenVerticalInset.value = self.root.winfo_screenheight() - self.canvas.winfo_height() + excessExtent if not self.xScrollbar.visible: screenVerticalInset.value += self.xScrollbar.winfo_reqheight() screenVerticalInset.setStateToValue() if oldHorizontalValue != screenHorizontalInset.value or oldVerticalValue != screenVerticalInset.value: self.repository.setToDisplaySave() def setLayerIndex( self, layerIndex ): 'Set the layer index.' self.cancelTimerResetButtons() oldLayerIndex = self.repository.layer.value self.repository.layer.value = layerIndex self.limitIndex() coloredLines = self.getColoredLines() if self.repository.layer.value < oldLayerIndex: self.repository.line.value = len( coloredLines ) - 1 self.lineEntry['to'] = getLengthMinusOneMinimumOne( coloredLines ) if self.repository.layer.value > oldLayerIndex: self.repository.line.value = 0 self.lineEntry['to'] = getLengthMinusOneMinimumOne( coloredLines ) self.update() def setLineButtonsState(self): 'Set the state of the line buttons.' coloredLines = self.getColoredLines() if len(coloredLines) < 1: print('Warning, there are no coloredLines in setLineButtonsState in tableau for the layer:') print(self.repository.layer.value) return isAboveFloor = self.repository.layer.value > 0 isBelowCeiling = self.repository.layer.value < len( self.skeinPanes ) - 1 setStateNormalDisabled( isAboveFloor or self.repository.line.value > 0, self.lineDiveButton ) setStateNormalDisabled( isBelowCeiling or self.repository.line.value < len( coloredLines ) - 1, self.lineSoarButton ) self.repository.line.value = max(self.repository.line.value, 0) self.repository.line.value = min(self.repository.line.value, len(coloredLines) - 1) gcodeString = '' if self.repository.showGcode.value: gcodeString = 'Gcode: ' + coloredLines[self.repository.line.value].displayString self.gcodeStringVar.set(gcodeString) self.canvas.delete('selection_line') self.getDrawnSelectedColoredLine(coloredLines[self.repository.line.value]) settings.setEntryText(self.lineEntry, self.repository.line.value) def setWindowNewMouseTool( self, getNewMouseToolFunction, mouseTool ): 'Set the getNewMouseTool function and the update function.' mouseTool.getNewMouseToolFunction = getNewMouseToolFunction mouseTool.setUpdateFunction( self.activateMouseModeTool ) def setWindowToDisplaySavePhoenixUpdate(self, event=None): 'Set the setting values to the display, save the new values, then call the update function.' self.repository.setToDisplaySave() self.phoenixUpdate() def setWindowToDisplaySaveUpdate(self, event=None): 'Set the setting values to the display, save the new values, then call the update function.' self.repository.setToDisplaySave() self.update() def shiftButtonRelease1(self, event): 'The button was released while the shift key was pressed.' self.mouseTool.buttonRelease1( event, True ) def shiftMotion(self, event): 'The mouse moved.' self.mouseTool.motion( event, True ) def soar(self): 'Soar, go up periodically.' oldSoarButtonText = self.soarButton['text'] self.cancelTimerResetButtons() if oldSoarButtonText == 'stop': return self.soarCycle() def soarCycle(self): 'Start the soar cycle.' self.setLayerIndex(self.repository.layer.value + 1) if self.repository.layer.value > len( self.skeinPanes ) - 2: self.resetPeriodicButtonsText() return self.setButtonImageText( self.soarButton, 'stop') self.timerID = self.canvas.after( self.getSlideShowDelay(), self.soarCycle ) def updateDeiconify( self, center = complex( 0.5, 0.5 ) ): 'Update and deiconify the window.' self.addSettingsMenuSetWindowGeometry( center ) self.update() self.root.deiconify() def updateMouseToolIfSelection(self): 'Update the mouse tool if it is a selection tool.' if self.mouseTool is None: return if self.mouseTool.isSelectionTool(): self.mouseTool.update() def updateNewDestroyOld( self, scrollPaneCenter ): 'Update and deiconify a window and destroy the old.' self.getCopyWithNewSkein().updateDeiconify( scrollPaneCenter ) self.root.after(1, self.root.destroy) # to get around 'Font Helvetica -12 still in cache.' segmentation bug, instead of simply calling self.root.destroy() view_move.py000066400000000000000000000071201167321211700350610ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities""" This page is in the table of contents. Viewpoint move is a mouse tool to move the viewpoint in the xy plane. When the mouse is clicked and dragged on the canvas, viewpoint move will drag the scroll pane accordingly. If the shift key is also pressed, the scroll pane will be moved only in the x or y direction, whichever is largest. When the viewpoint move tool is chosen and the canvas has the focus, viewpoint move will listen to the arrow keys. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. When the right arrow key is pressed, viewpoint move will move the scroll pane to the right by a pixel. When the left arrow key is pressed, the scroll pane will be moved a pixel to the left. The up arrow key moves the scroll pane a pixel up and the down arow key moves the scroll pane a pixel down. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base import MouseToolBase from fabmetheus_utilities import settings __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewMouseTool(): "Get a new mouse tool." return ViewpointMove() class ViewpointMove( MouseToolBase ): "Display the line when it is clicked." def button1( self, event, shift = False ): "Print line text and connection line." self.destroyEverythingGetFocus() self.buttonOnePressedScreenCoordinate = complex( event.x, event.y ) self.scrollPaneFraction = self.window.getScrollPaneFraction() def buttonRelease1( self, event, shift = False ): "The left button was released, function." self.destroyEverything() def destroyEverything(self): "Destroy items." self.buttonOnePressedScreenCoordinate = None def keyPressDown(self, event): "The down arrow was pressed." self.setScrollPaneMove( complex( 0.0, 1.0 ) ) def keyPressLeft(self, event): "The left arrow was pressed." self.setScrollPaneMove( complex( - 1.0, 0.0 ) ) def keyPressRight(self, event): "The right arrow was pressed." self.setScrollPaneMove( complex( 1.0, 0.0 ) ) def keyPressUp(self, event): "The up arrow was pressed." self.setScrollPaneMove( complex(0.0, -1.0) ) def motion( self, event, shift = False ): "The mouse moved, function." if self.buttonOnePressedScreenCoordinate is None: return motionCoordinate = complex( event.x, event.y ) relativeMotion = motionCoordinate - self.buttonOnePressedScreenCoordinate if shift: if abs( relativeMotion.real ) > abs( relativeMotion.imag ): relativeMotion = complex( relativeMotion.real, 0.0 ) else: relativeMotion = complex( 0.0, relativeMotion.imag ) self.relativeMove( relativeMotion ) def relativeMove( self, relativeMotion ): "Move the view given the relative motion." relativeScreenMotion = complex( relativeMotion.real / float( self.window.screenSize.real ), relativeMotion.imag / float( self.window.screenSize.imag ) ) moveTo = self.scrollPaneFraction - relativeScreenMotion self.window.relayXview( settings.Tkinter.MOVETO, moveTo.real ) self.window.relayYview( settings.Tkinter.MOVETO, moveTo.imag ) def setScrollPaneMove( self, relativeMotion ): "The up arrow was pressed." self.scrollPaneFraction = self.window.getScrollPaneFraction() self.relativeMove( relativeMotion ) view_rotate.py000066400000000000000000000233741167321211700354220ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities""" This page is in the table of contents. Viewpoint rotate is a mouse tool to rotate the viewpoint around the origin. When the mouse is clicked, dragged and released on the canvas, viewpoint rotate will rotate the longitude by the amount the mouse is dragged around the origin. If the mouse is moved towards the origin, the latitude will be increased, so the viewpoint will be closer to the top. If the mouse is moved away from the origin, the latitude will be decreased. If the shift key is also pressed, only the latitude or longitude will be changed, whichever is being changed the most. When the viewpoint rotate tool is chosen and the canvas has the focus, viewpoint rotate will listen to the arrow keys. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. When the right arrow key is pressed, viewpoint rotate will increase the preview longitude by one degree. When the left arrow key is pressed, the preview longitude will be decreased. The up arrow key increase the preview latitude by one degree and the down arow decreases the preview latitude. Pressing the key implements the preview. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base import MouseToolBase from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import euclidean from fabmetheus_utilities import settings import math __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getBoundedLatitude( latitude ): "Get the bounded latitude.later get rounded" return round( min( 179.9, max( 0.1, latitude ) ), 1 ) def getNewMouseTool(): "Get a new mouse tool." return ViewpointRotate() class LatitudeLongitude: "A latitude and longitude." def __init__( self, buttonOnePressedCanvasCoordinate, newCoordinate, skeinWindow, shift ): "Set the latitude and longitude." buttonOnePressedCentered = skeinWindow.getCenteredScreened( buttonOnePressedCanvasCoordinate ) buttonOnePressedRadius = abs( buttonOnePressedCentered ) buttonOnePressedComplexMirror = complex( buttonOnePressedCentered.real, - buttonOnePressedCentered.imag ) buttonOneReleasedCentered = skeinWindow.getCenteredScreened( newCoordinate ) buttonOneReleasedRadius = abs( buttonOneReleasedCentered ) pressedReleasedRotationComplex = buttonOneReleasedCentered * buttonOnePressedComplexMirror self.deltaLatitude = math.degrees( buttonOneReleasedRadius - buttonOnePressedRadius ) self.originalDeltaLongitude = math.degrees( math.atan2( pressedReleasedRotationComplex.imag, pressedReleasedRotationComplex.real ) ) self.deltaLongitude = self.originalDeltaLongitude if skeinWindow.repository.viewpointLatitude.value > 90.0: self.deltaLongitude = - self.deltaLongitude if shift: if abs( self.deltaLatitude ) > abs( self.deltaLongitude ): self.deltaLongitude = 0.0 else: self.deltaLatitude = 0.0 self.latitude = getBoundedLatitude( skeinWindow.repository.viewpointLatitude.value + self.deltaLatitude ) self.longitude = round( ( skeinWindow.repository.viewpointLongitude.value + self.deltaLongitude ) % 360.0, 1 ) class ViewpointRotate( MouseToolBase ): "Display the line when it is clicked." def button1( self, event, shift = False ): "Print line text and connection line." self.destroyEverything() x = self.canvas.canvasx(event.x) y = self.canvas.canvasy(event.y) self.buttonOnePressedCanvasCoordinate = complex(x, y) def buttonRelease1( self, event, shift = False ): "The left button was released, function." if self.buttonOnePressedCanvasCoordinate is None: return x = self.canvas.canvasx(event.x) y = self.canvas.canvasy(event.y) buttonOneReleasedCanvasCoordinate = complex(x, y) self.moveViewpointGivenCoordinates( buttonOneReleasedCanvasCoordinate, shift, self.buttonOnePressedCanvasCoordinate ) def destroyEverything(self): "Destroy items." self.buttonOnePressedCanvasCoordinate = None self.keyStartCanvasCoordinate = None self.relativeLatitude = 0.0 self.relativeLongitude = 0.5 * math.pi self.canvas.delete('mouse_item') def getMoveCoordinate(self): "Get the movement coordinate from the class relative latitude and longitude." motionRadius = ( 0.75 + self.relativeLatitude ) * self.window.getCanvasRadius() return self.window.getScreenComplex( motionRadius * euclidean.getWiddershinsUnitPolar( self.relativeLongitude ) ) def keyPressDown(self, event): "The down arrow was pressed." self.keyPressStart() self.relativeLatitude -= math.radians(1.0) self.keyPressMotion() def keyPressLeft(self, event): "The left arrow was pressed." self.keyPressStart() self.relativeLongitude += math.radians(1.0) self.keyPressMotion() def keyPressMotion(self): "Move the motion viewpoint for the class key press coordinates." self.motionGivenCoordinates( self.getMoveCoordinate(), False, self.keyStartCanvasCoordinate ) def keyPressReturn(self, event): "The return key was pressed." if self.keyStartCanvasCoordinate is None: return self.moveViewpointGivenCoordinates( self.getMoveCoordinate(), False, self.keyStartCanvasCoordinate ) def keyPressRight(self, event): "The right arrow was pressed." self.keyPressStart() self.relativeLongitude -= math.radians(1.0) self.keyPressMotion() def keyPressStart(self): "If necessary, destroy everything and calculate the keyStartCanvasCoordinate." if self.keyStartCanvasCoordinate is None: self.destroyEverything() self.keyStartCanvasCoordinate = self.window.getScreenComplex( complex( 0.0, 0.75 * self.window.getCanvasRadius() ) ) def keyPressUp(self, event): "The up arrow was pressed." self.keyPressStart() self.relativeLatitude += math.radians(1.0) self.keyPressMotion() def motion( self, event, shift = False ): "Move the motion viewpoint if the mouse was moved." if self.buttonOnePressedCanvasCoordinate is None: return x = self.canvas.canvasx(event.x) y = self.canvas.canvasy(event.y) motionCoordinate = complex(x, y) self.motionGivenCoordinates( motionCoordinate, shift, self.buttonOnePressedCanvasCoordinate ) def motionGivenCoordinates( self, motionCoordinate, shift, startCoordinate ): "Move the motion viewpoint given the motion coordinates." latitudeLongitude = LatitudeLongitude( startCoordinate, motionCoordinate, self.window, shift ) viewVectors = euclidean.ProjectiveSpace().getByLatitudeLongitude( latitudeLongitude.latitude, latitudeLongitude.longitude ) motionCentered = self.window.getCentered( motionCoordinate ) motionCenteredNormalized = motionCentered / abs( motionCentered ) buttonOnePressedCentered = self.window.getCentered( startCoordinate ) buttonOnePressedAngle = math.degrees( math.atan2( buttonOnePressedCentered.imag, buttonOnePressedCentered.real ) ) buttonOnePressedLength = abs( buttonOnePressedCentered ) buttonOnePressedCorner = complex( buttonOnePressedLength, buttonOnePressedLength ) buttonOnePressedCornerBottomLeft = self.window.getScreenComplex( - buttonOnePressedCorner ) buttonOnePressedCornerUpperRight = self.window.getScreenComplex( buttonOnePressedCorner ) motionPressedStart = buttonOnePressedLength * motionCenteredNormalized motionPressedScreen = self.window.getScreenComplex( motionPressedStart ) motionColorName = '#4B0082' motionWidth = 9 self.canvas.delete('mouse_item') if abs( latitudeLongitude.deltaLongitude ) > 0.0: self.canvas.create_arc( buttonOnePressedCornerBottomLeft.real, buttonOnePressedCornerBottomLeft.imag, buttonOnePressedCornerUpperRight.real, buttonOnePressedCornerUpperRight.imag, extent = latitudeLongitude.originalDeltaLongitude, start = buttonOnePressedAngle, outline = motionColorName, outlinestipple = self.window.motionStippleName, style = settings.Tkinter.ARC, tags = 'mouse_item', width = motionWidth ) if abs( latitudeLongitude.deltaLatitude ) > 0.0: self.canvas.create_line( motionPressedScreen.real, motionPressedScreen.imag, motionCoordinate.real, motionCoordinate.imag, fill = motionColorName, arrow = 'last', arrowshape = self.window.arrowshape, stipple = self.window.motionStippleName, tags = 'mouse_item', width = motionWidth ) self.window.getDrawnLineText( motionCoordinate, 'mouse_item', 'Latitude: %s, Longitude: %s' % ( round( latitudeLongitude.latitude ), round( latitudeLongitude.longitude ) ) ) if self.repository.widthOfAxisPositiveSide.value > 0: self.window.getDrawnColoredLineMotion( self.window.positiveAxisLineX, viewVectors, self.repository.widthOfAxisPositiveSide.value ) self.window.getDrawnColoredLineMotion( self.window.positiveAxisLineY, viewVectors, self.repository.widthOfAxisPositiveSide.value ) self.window.getDrawnColoredLineMotion( self.window.positiveAxisLineZ, viewVectors, self.repository.widthOfAxisPositiveSide.value ) def moveViewpointGivenCoordinates( self, moveCoordinate, shift, startCoordinate ): "Move the viewpoint given the move coordinates." if abs( startCoordinate - moveCoordinate ) < 3: startCoordinate = None self.canvas.delete('mouse_item') return latitudeLongitude = LatitudeLongitude( startCoordinate, moveCoordinate, self.window, shift ) self.repository.viewpointLatitude.value = latitudeLongitude.latitude self.repository.viewpointLatitude.setStateToValue() self.repository.viewpointLongitude.value = latitudeLongitude.longitude self.repository.viewpointLongitude.setStateToValue() startCoordinate = None settings.writeSettings(self.repository) self.window.update() self.destroyEverything() zoom_in.py000066400000000000000000000033571167321211700345430ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities""" This page is in the table of contents. Zoom in is a mouse tool to zoom in the display at the point where the mouse was clicked, increasing the scale by a factor of two. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities.mouse_tool_base import MouseToolBase from fabmetheus_utilities import settings __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewMouseTool(): "Get a new mouse tool." return ZoomIn() class ZoomIn( MouseToolBase ): "The zoom in mouse tool." def button1( self, event, shift = False ): "Print line text and connection line." scaleSetting = self.window.repository.scale scaleSetting.value *= self.getMultiplier() delta = complex( float(event.x) / float( self.window.screenSize.real ), float(event.y) / float( self.window.screenSize.imag ) ) - self.window.canvasScreenCenter delta *= 1.0 - 1.0 / self.getMultiplier() scrollPaneCenter = self.window.getScrollPaneCenter() + delta self.window.updateNewDestroyOld( scrollPaneCenter ) def click(self, event=None): "Set the window mouse tool to this." self.window.destroyMouseToolRaiseMouseButtons() self.window.mouseTool = self self.mouseButton['relief'] = settings.Tkinter.SUNKEN def getMultiplier(self): "Get the scale multiplier." return 2.0 def getReset( self, window ): "Reset the mouse tool to default." self.setWindowItems( window ) self.mouseButton = None return self zoom_out.py000066400000000000000000000016171167321211700347410ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/analyze_utilities""" This page is in the table of contents. Zoom out is a mouse tool to zoom out the display at the point where the mouse was clicked, decreasing the scale by a factor of two. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities import zoom_in from fabmetheus_utilities import settings __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewMouseTool(): "Get a new mouse tool." return ZoomOut() class ZoomOut( zoom_in.ZoomIn ): "The zoom out mouse tool." def getMultiplier(self): "Get the scale multiplier." return 0.5 sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/clairvoyance.py000066400000000000000000000115151167321211700320640ustar00rootroot00000000000000""" This page is in the table of contents. Clairvoyance is an analyze plugin to open the gcode file with an outside program. The clairvoyance manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Clairvoyance ==Operation== The default 'Activate Clairvoyance' checkbox is off. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Clairvoyance' checkbox is on, when clairvoyance is run directly. ==Settings== ===Gcode Program=== Default is webbrowser. If the 'Gcode Program' is set to webbrowser, the gcode file will be sent to the default browser to be opened. If the 'Gcode Program' is set to a program name, the gcode file will be sent to that program to be opened. A good gcode viewer is Pleasant3D, at: http://www.pleasantsoftware.com/developer/pleasant3d/index.shtml ==Examples== Below are examples of clairvoyance being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and clairvoyance.py. > python clairvoyance.py This brings up the clairvoyance dialog. > python clairvoyance.py Screw Holder_penultimate.gcode The file is opened by an outside program """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import subprocess import sys import traceback __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return ClairvoyanceRepository() def getWindowAnalyzeFile(fileName, repository=None): 'Open penultimate file with outside program.' print('') if repository is None: repository = settings.getReadRepository(ClairvoyanceRepository()) gcodeProgram = repository.gcodeProgram.value if gcodeProgram == '': print('Warning, nothing will be done in getWindowAnalyzeFile in clairvoyance because the Gcode Program field is empty.') print('') return if gcodeProgram == 'webbrowser': print('Clairvoyance will use a web browser to open the file:') print(archive.getSummarizedFileName(fileName)) settings.openWebPage(fileName) return try: subprocess.Popen([gcodeProgram, fileName]) print('Clairvoyance has opened the file:') print(archive.getSummarizedFileName(fileName)) print('with the gcode program:') print(gcodeProgram) except: print('Warning, getWindowAnalyzeFile in clairvoyance could not open the file:') print(fileName) print('with the gcode program:') print(gcodeProgram) print('Error traceback is the following:') traceback.print_exc(file=sys.stdout) print('') def writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText=''): 'Open penultimate file with outside program given text.' repository = settings.getReadRepository(ClairvoyanceRepository()) if repository.activateClairvoyance.value: if not filePenultimateWritten: archive.writeFileText(fileNamePenultimate, gcodeText) getWindowAnalyzeFile(fileNamePenultimate, repository) class ClairvoyanceRepository: 'A class to handle the clairvoyance settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.analyze_plugins.clairvoyance.html', self) self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Clairvoyance') self.activateClairvoyance = settings.BooleanSetting().getFromValue('Activate Clairvoyance', self, False) settings.LabelSeparator().getFromRepository(self) self.fileNameInput = settings.FileNameInput().getFromFileName([('Gcode text files', '*.gcode')], 'Open File to Generate Clairvoyances for', self, '') self.gcodeProgram = settings.StringSetting().getFromValue('Gcode Program:', self, 'webbrowser') self.executeTitle = 'Clairvoyance' def execute(self): 'Write button has been clicked.' fileNames = skeinforge_polyfile.getFileOrGcodeDirectory( self.fileNameInput.value, self.fileNameInput.wasCancelled, ['_comment'] ) for fileName in fileNames: getWindowAnalyzeFile(fileName) def main(): 'Display the clairvoyance dialog.' if len(sys.argv) > 1: getWindowAnalyzeFile(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/comment.py000066400000000000000000000146351167321211700310550ustar00rootroot00000000000000""" This page is in the table of contents. Comment is an analyze plugin to comment a gcode file. The comment manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Comment ==Operation== The default 'Activate Comment' checkbox is off. When it is on, the file will be commented when called from the skeinforge toolchain, when it is off, the file will not be commented when called from the toolchain. The file will still be commented, whether or not the 'Activate Comment' checkbox is on, when comment is run directly. ==Gcodes== An explanation of the gcodes is at: http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter and at: http://reprap.org/bin/view/Main/MCodeReference A gode example is at: http://forums.reprap.org/file.php?12,file=565 ==Examples== Below are examples of comment being used. These examples are run in a terminal in the folder which contains Screw_Holder_penultimate.gcode and comment.py. > python comment.py This brings up the comment dialog. > python comment.py Screw Holder_penultimate.gcode The comment file is saved as Screw_Holder_penultimate_comment.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import cStringIO import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return CommentRepository() def getWindowAnalyzeFile(fileName): "Comment a gcode file." gcodeText = archive.getFileText(fileName) return getWindowAnalyzeFileGivenText(fileName, gcodeText) def getWindowAnalyzeFileGivenText(fileName, gcodeText): "Write a commented gcode file for a gcode file." skein = CommentSkein() skein.parseGcode(gcodeText) archive.writeFileMessageEnd('_comment.gcode', fileName, skein.output.getvalue(), 'The commented file is saved as ') def writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText=''): "Write a commented gcode file for a skeinforge gcode file, if 'Write Commented File for Skeinforge Chain' is selected." repository = settings.getReadRepository( CommentRepository() ) if gcodeText == '': gcodeText = archive.getFileText( fileNameSuffix ) if repository.activateComment.value: getWindowAnalyzeFileGivenText( fileNameSuffix, gcodeText ) class CommentRepository: "A class to handle the comment settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.analyze_plugins.comment.html', self) self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Comment') self.activateComment = settings.BooleanSetting().getFromValue('Activate Comment', self, False ) self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File to Write Comments for', self, '') self.executeTitle = 'Write Comments' def execute(self): "Write button has been clicked." fileNames = skeinforge_polyfile.getFileOrGcodeDirectory( self.fileNameInput.value, self.fileNameInput.wasCancelled, ['_comment'] ) for fileName in fileNames: getWindowAnalyzeFile(fileName) class CommentSkein: "A class to comment a gcode skein." def __init__(self): self.oldLocation = None self.output = cStringIO.StringIO() def addComment( self, comment ): "Add a gcode comment and a newline to the output." self.output.write( "( " + comment + " )\n" ) def linearMove( self, splitLine ): "Comment a linear move." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.addComment( "Linear move to " + str( location ) + "." ); self.oldLocation = location def parseGcode( self, gcodeText ): "Parse gcode text and store the commented gcode." lines = archive.getTextLines(gcodeText) for line in lines: self.parseLine(line) def parseLine(self, line): "Parse a gcode line and add it to the commented gcode." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.linearMove(splitLine) elif firstWord == 'G2': self.setHelicalMoveEndpoint(splitLine) self.addComment( "Helical clockwise move to " + str( self.oldLocation ) + "." ) elif firstWord == 'G3': self.setHelicalMoveEndpoint(splitLine) self.addComment( "Helical counterclockwise move to " + str( self.oldLocation ) + "." ) elif firstWord == 'G21': self.addComment( "Set units to mm." ) elif firstWord == 'G28': self.addComment( "Start at home." ) elif firstWord == 'G90': self.addComment( "Set positioning to absolute." ) elif firstWord == 'M101': self.addComment( "Extruder on, forward." ); elif firstWord == 'M102': self.addComment( "Extruder on, reverse." ); elif firstWord == 'M103': self.addComment( "Extruder off." ) elif firstWord == 'M104': self.addComment( "Set temperature to " + str( gcodec.getDoubleAfterFirstLetter(splitLine[1]) ) + " C." ) elif firstWord == 'M105': self.addComment( "Custom code for temperature reading." ) elif firstWord == 'M106': self.addComment( "Turn fan on." ) elif firstWord == 'M107': self.addComment( "Turn fan off." ) elif firstWord == 'M108': self.addComment( "Set extruder speed to " + str( gcodec.getDoubleAfterFirstLetter(splitLine[1]) ) + "." ) self.output.write(line + '\n') def setHelicalMoveEndpoint( self, splitLine ): "Get the endpoint of a helical move." if self.oldLocation is None: print( "A helical move is relative and therefore must not be the first move of a gcode file." ) return location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) location += self.oldLocation self.oldLocation = location def main(): "Display the comment dialog." if len(sys.argv) > 1: getWindowAnalyzeFile(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/export_canvas_plugins/000077500000000000000000000000001167321211700334455ustar00rootroot00000000000000__init__.py000066400000000000000000000006571167321211700355070ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/export_canvas_plugins#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 4 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) postscript.py000066400000000000000000000121251167321211700361530ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/export_canvas_plugins""" This page is in the table of contents. Postscript is an export canvas plugin to export the canvas to a postscript file. When the export menu item in the file menu in an analyze viewer tool, like skeinlayer or skeiniso is clicked, the postscript dialog will be displayed. When the 'Export to Postscript' button on that dialog is clicked, the canvas will be exported as a postscript file. If the 'Postscript Program' is set to a program name, the postscript file will be sent to that program to be opened. The default is gimp, the Gnu Image Manipulation Program (Gimp), which is open source, can open postscript and save in a variety of formats. It is available at: http://www.gimp.org/ If furthermore the 'File Extension' is set to a file extension, the postscript file will be sent to the program, along with the file extension for the converted output. The default is blank because some systems do not have an image conversion program; if you have or will install an image conversion program, a common 'File Extension' is png. A good open source conversion program is Image Magick, which is available at: http://www.imagemagick.org/script/index.php An export canvas plugin is a script in the export_canvas_plugins folder which has the function getNewRepository, and which has a repository class with the functions setCanvasFileNameSuffix to set variables and execute to save the file. It is meant to be run from an analyze viewer tool, like skeinlayer or skeiniso. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile import cStringIO import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return PostscriptRepository() class PostscriptRepository: "A class to handle the export settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository( 'skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins.postscript.html', self) self.fileExtension = settings.StringSetting().getFromValue('File Extension:', self, '') self.postscriptProgram = settings.StringSetting().getFromValue('Postscript Program:', self, 'gimp') def execute(self): "Convert to postscript button has been clicked. Export the canvas as a postscript file." postscriptFileName = archive.getFilePathWithUnderscoredBasename( self.fileName, self.suffix ) boundingBox = self.canvas.bbox( settings.Tkinter.ALL ) # tuple (w, n, e, s) boxW = boundingBox[0] boxN = boundingBox[1] boxWidth = boundingBox[2] - boxW boxHeight = boundingBox[3] - boxN print('Exported postscript file saved as ' + postscriptFileName ) self.canvas.postscript( file = postscriptFileName, height = boxHeight, width = boxWidth, pageheight = boxHeight, pagewidth = boxWidth, x = boxW, y = boxN ) fileExtension = self.fileExtension.value postscriptProgram = self.postscriptProgram.value if postscriptProgram == '': return postscriptFilePath = '"' + os.path.normpath( postscriptFileName ) + '"' # " to send in file name with spaces shellCommand = postscriptProgram print('') if fileExtension == '': shellCommand += ' ' + postscriptFilePath print('Sending the shell command:') print(shellCommand) commandResult = os.system(shellCommand) if commandResult != 0: print('It may be that the system could not find the %s program.' % postscriptProgram ) print('If so, try installing the %s program or look for another one, like the Gnu Image Manipulation Program (Gimp) which can be found at:' % postscriptProgram ) print('http://www.gimp.org/') return shellCommand += ' ' + archive.getFilePathWithUnderscoredBasename( postscriptFilePath, '.' + fileExtension + '"') print('Sending the shell command:') print(shellCommand) commandResult = os.system(shellCommand) if commandResult != 0: print('The %s program could not convert the postscript to the %s file format.' % ( postscriptProgram, fileExtension ) ) print('Try installing the %s program or look for another one, like Image Magick which can be found at:' % postscriptProgram ) print('http://www.imagemagick.org/script/index.php') def setCanvasFileNameSuffix( self, canvas, fileName, suffix ): "Set the canvas and initialize the execute title." self.canvas = canvas self.executeTitle = 'Export to Postscript' self.fileName = fileName self.suffix = suffix + '.ps' def main(): "Display the file or directory dialog." settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() scalable_vector_graphics.py000066400000000000000000000155711167321211700407610ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/export_canvas_plugins""" This page is in the table of contents. Scalable vector graphics is an export canvas plugin to export the canvas to a scalable vector graphics (.svg) file. When the export menu item in the file menu in an analyze viewer tool, like skeinlayer or skeiniso is clicked, the postscript dialog will be displayed. When the 'Export to Scalable Vector Graphics' button on that dialog is clicked, the canvas will be exported as a scalable vector graphics file. If the 'Scalable Vector Graphics Program' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'Scalable Vector Graphics Program' is set to a program name, the scalable vector graphics file will be sent to that program to be opened. If furthermore the 'File Extension' is set to a file extension, the scalable vector graphics file will be sent to the program, along with the file extension for the converted output. The default is blank because some systems do not have an image conversion program; if you have or will install an image conversion program, a common 'File Extension' is png. A good open source conversion program is Image Magick, which is available at: http://www.imagemagick.org/script/index.php An export canvas plugin is a script in the export_canvas_plugins folder which has the function getNewRepository, and which has a repository class with the functions setCanvasFileNameSuffix to set variables and execute to save the file. It is meant to be run from an analyze viewer tool, like skeinlayer or skeiniso. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile import cStringIO import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return ScalableVectorGraphicsRepository() def parseLineReplace( firstWordTable, line, output ): "Parse the line and replace it if the first word of the line is in the first word table." firstWord = gcodec.getFirstWordFromLine(line) if firstWord in firstWordTable: line = firstWordTable[ firstWord ] gcodec.addLineAndNewlineIfNecessary( line, output ) class ScalableVectorGraphicsRepository: "A class to handle the export settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository( 'skeinforge_application.skeinforge_plugins.analyze_plugins.export_canvas_plugins.scalable_vector_graphics.html', self) self.fileExtension = settings.StringSetting().getFromValue('File Extension:', self, '') self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser') def addCanvasLineToOutput( self, canvasLinesOutput, objectIDNumber ): "Add the canvas line to the output." coordinates = self.canvas.coords( objectIDNumber ) xBegin = coordinates[0] - self.boxW xEnd = coordinates[2] - self.boxW yBegin = coordinates[1] - self.boxN yEnd = coordinates[3] - self.boxN west = self.boxW color = self.canvas.itemcget( objectIDNumber, 'fill') width = self.canvas.itemcget( objectIDNumber, 'width') line = '\n' % ( xBegin, yBegin, xEnd, yEnd, color, width ) canvasLinesOutput.write(line + '\n') def execute(self): "Export the canvas as an svg file." svgFileName = archive.getFilePathWithUnderscoredBasename( self.fileName, self.suffix ) boundingBox = self.canvas.bbox( settings.Tkinter.ALL ) # tuple (w, n, e, s) self.boxW = boundingBox[0] self.boxN = boundingBox[1] boxWidth = boundingBox[2] - self.boxW boxHeight = boundingBox[3] - self.boxN print('Exported svg file saved as ' + svgFileName ) svgTemplateText = archive.getFileText(archive.getTemplatesPath('canvas_template.svg')) output = cStringIO.StringIO() lines = archive.getTextLines( svgTemplateText ) firstWordTable = {} firstWordTable['height="999px"'] = ' height="%spx"' % int( round( boxHeight ) ) firstWordTable[''] = self.getCanvasLinesOutput() firstWordTable['replaceLineWithTitle'] = archive.getSummarizedFileName( self.fileName ) firstWordTable['width="999px"'] = ' width="%spx"' % int( round( boxWidth ) ) for line in lines: parseLineReplace( firstWordTable, line, output ) archive.writeFileText( svgFileName, output.getvalue() ) fileExtension = self.fileExtension.value svgViewer = self.svgViewer.value if svgViewer == '': return if svgViewer == 'webbrowser': settings.openWebPage( svgFileName ) return svgFilePath = '"' + os.path.normpath( svgFileName ) + '"' # " to send in file name with spaces shellCommand = svgViewer print('') if fileExtension == '': shellCommand += ' ' + svgFilePath print('Sending the shell command:') print(shellCommand) commandResult = os.system(shellCommand) if commandResult != 0: print('It may be that the system could not find the %s program.' % svgViewer ) print('If so, try installing the %s program or look for another svg viewer, like Netscape which can be found at:' % svgViewer ) print('http://www.netscape.org/') return shellCommand += ' ' + archive.getFilePathWithUnderscoredBasename( svgFilePath, '.' + fileExtension + '"') print('Sending the shell command:') print(shellCommand) commandResult = os.system(shellCommand) if commandResult != 0: print('The %s program could not convert the svg to the %s file format.' % ( svgViewer, fileExtension ) ) print('Try installing the %s program or look for another one, like Image Magick which can be found at:' % svgViewer ) print('http://www.imagemagick.org/script/index.php') def getCanvasLinesOutput(self): "Add the canvas line to the output." canvasLinesOutput = cStringIO.StringIO() objectIDNumbers = self.canvas.find_all() for objectIDNumber in objectIDNumbers: if self.canvas.type( objectIDNumber ) == 'line': self.addCanvasLineToOutput( canvasLinesOutput, objectIDNumber ) return canvasLinesOutput.getvalue() def setCanvasFileNameSuffix( self, canvas, fileName, suffix ): "Set the canvas and initialize the execute title." self.canvas = canvas self.executeTitle = 'Convert to Scalable Vector Graphics' self.fileName = fileName self.suffix = suffix + '.svg' def main(): "Display the file or directory dialog." settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/interpret.py000066400000000000000000000047251167321211700314260ustar00rootroot00000000000000""" This page is in the table of contents. Interpret is an analyze plugin to interpret a file, turning a 2D file into svg and a 3D file into constructive solid geometry xml. The comment manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Interpret ==Operation== The default 'Activate Interpret' checkbox is off. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the tool chain. The functions will still be called, whether or not the 'Activate Interpret' checkbox is on, when interpret is run directly. ==Settings== ===Print Interpretion=== Default is off. When selected, the xml text will be printed to the console. ===Text Program=== Default is webbrowser. If the 'Text Program' is set the default 'webbrowser', the XML file will be sent to the default browser to be opened. If the 'Text Program' is set to a program name, the XML file will be sent to that program to be opened. ==Examples== Below are examples of interpret being used. These examples are run in a terminal in the folder which contains Screw_Holder.stl and interpret.py. > python interpret.py This brings up the interpret dialog. > python interpret.py Screw_Holder.stl The comment file is saved as Screw_Holder_interpret.xml """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import settings from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return fabmetheus_interpret.InterpretRepository() def writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText=''): "Write file interpretation, if activate interpret is selected." repository = settings.getReadRepository(getNewRepository()) if repository.activateInterpret.value: fabmetheus_interpret.getWindowAnalyzeFile(fileName) def main(): "Display the interpret dialog." if len(sys.argv) > 1: fabmetheus_interpret.getWindowAnalyzeFile(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/skeiniso.py000066400000000000000000001264751167321211700312450ustar00rootroot00000000000000""" This page is in the table of contents. Skeiniso is an analyze viewer to display a gcode file in an isometric view. The skeiniso manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skeiniso ==Operation== The default 'Activate Skeiniso' checkbox is off. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Skeiniso' checkbox is on, when skeiniso is run directly. Skeiniso requires skeinforge comments in the gcode file to distinguish the loops and perimeters. If the comments are deleted, all threads will be displayed as generic threads. To get the penultimate file of the tool chain, just before export deletes the comments, select 'Save Penultimate Gcode' in export, and open the gcode file with the suffix '_penultimate.gcode' with skeiniso. The viewer is simple, the viewpoint can only be moved in a sphere around the center of the model by changing the viewpoint latitude and longitude. Different regions of the model can be hidden by setting the width of the thread to zero. The alternating bands act as contour bands and their brightness and width can be changed. ==Settings== ===Animation=== ====Animation Line Quickening==== Default is one. The quickness of the tool animation over the quickness of the actual tool. ====Animation Slide Show Rate==== Default is two layers per second. The rate, in layers per second, at which the layer changes when the soar or dive button is pressed.. ===Axis Rulings=== Default is on. When selected, rulings will be drawn on the axis lines. ===Banding=== ====Band Height==== Default is five layers. Defines the height of the band in layers, a pair of bands is twice that height. ====Bottom Band Brightness==== Default is 0.7. Defines the ratio of the brightness of the bottom band over the brightness of the top band. The higher it is the brighter the bottom band will be. ====Bottom Layer Brightness==== Default is one. Defines the ratio of the brightness of the bottom layer over the brightness of the top layer. With a low bottom layer brightness ratio the bottom of the model will be darker than the top of the model, as if it was being illuminated by a light just above the top. ====Bright Band Start==== Default choice is 'From the Top'. The button group that determines where the bright band starts from. =====From the Bottom===== When selected, the bright bands will start from the bottom. =====From the Top===== When selected, the bright bands will start from the top. ===Draw Arrows=== Default is on. When selected, arrows will be drawn at the end of each line segment. ===Export Menu=== When the submenu in the export menu item in the file menu is clicked, an export canvas dialog will be displayed, which can export the canvas to a file. ===Go Around Extruder Off Travel=== Default is off. When selected, the display will include the travel when the extruder is off, which means it will include the nozzle wipe path if any. ===Layers=== ====Layer==== Default is zero. On the display window, the Up button increases the 'Layer' by one, and the Down button decreases the layer by one. When the layer displayed in the layer spin box is changed then is hit, the layer shown will be set to the spin box, to a mimimum of zero and to a maximum of the highest index layer.The Soar button increases the layer at the 'Animation Slide Show Rate', and the Dive (double left arrow button beside the layer field) button decreases the layer at the slide show rate. ====Layer Extra Span==== Default is a huge number. The viewer will draw the layers in the range including the 'Layer' index and the 'Layer' index plus the 'Layer Extra Span'. If the 'Layer Extra Span' is negative, the layers viewed will start at the 'Layer' index, plus the 'Layer Extra Span', and go up to and include the 'Layer' index. If the 'Layer Extra Span' is zero, only the 'Layer' index layer will be displayed. If the 'Layer Extra Span' is positive, the layers viewed will start at the 'Layer' index, and go up to and include the 'Layer' index plus the 'Layer Extra Span'. ===Line=== Default is zero. The index of the selected line on the layer that is highlighted when the 'Display Line' mouse tool is chosen. The line spin box up button increases the 'Line' by one. If the line index of the layer goes over the index of the last line, the layer index will be increased by one and the new line index will be zero. The down button decreases the line index by one. If the line index goes below the index of the first line, the layer index will be decreased by one and the new line index will be at the last line. When the line displayed in the line field is changed then is hit, the line shown will be set to the line field, to a mimimum of zero and to a maximum of the highest index line. The Soar button increases the line at the speed at which the extruder would move, times the 'Animation Line Quickening' ratio, and the Dive (double left arrow button beside the line field) button decreases the line at the animation line quickening ratio. ===Mouse Mode=== Default is 'Display Line'. The mouse tool can be changed from the 'Mouse Mode' menu button or picture button. The mouse tools listen to the arrow keys when the canvas has the focus. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. ====Display Line==== The 'Display Line' tool will display the highlight the selected line, and display the file line count, counting from one, and the gcode line itself. When the 'Display Line' tool is active, clicking the canvas will select the closest line to the mouse click. ====Viewpoint Move==== The 'Viewpoint Move' tool will move the viewpoint in the xy plane when the mouse is clicked and dragged on the canvas. ====Viewpoint Rotate==== The 'Viewpoint Rotate' tool will rotate the viewpoint around the origin, when the mouse is clicked and dragged on the canvas, or the arrow keys have been used and is pressed. The viewpoint can also be moved by dragging the mouse. The viewpoint latitude will be increased when the mouse is dragged from the center towards the edge. The viewpoint longitude will be changed by the amount around the center the mouse is dragged. This is not very intuitive, but I don't know how to do this the intuitive way and I have other stuff to develop. If the shift key is pressed; if the latitude is changed more than the longitude, only the latitude will be changed, if the longitude is changed more only the longitude will be changed. ===Number of Fill Layers=== ====Number of Fill Bottom Layers==== Default is one. The "Number of Fill Bottom Layers" is the number of layers at the bottom which will be colored olive. ===Number of Fill Top Layers=== Default is one. The "Number of Fill Top Layers" is the number of layers at the top which will be colored blue. ===Scale=== Default is ten. The scale setting is the scale of the image in pixels per millimeter, the higher the number, the greater the size of the display. The zoom in mouse tool will zoom in the display at the point where the mouse was clicked, increasing the scale by a factor of two. The zoom out tool will zoom out the display at the point where the mouse was clicked, decreasing the scale by a factor of two. ===Screen Inset=== ====Screen Horizontal Inset==== Default is one hundred. The "Screen Horizontal Inset" determines how much the canvas will be inset in the horizontal direction from the edge of screen, the higher the number the more it will be inset and the smaller it will be. ====Screen Vertical Inset==== Default is two hundred and twenty. The "Screen Vertical Inset" determines how much the canvas will be inset in the vertical direction from the edge of screen, the higher the number the more it will be inset and the smaller it will be.. ===Viewpoint=== ====Viewpoint Latitude==== Default is fifteen degrees. The "Viewpoint Latitude" is the latitude of the viewpoint, a latitude of zero is the top pole giving a top view, a latitude of ninety gives a side view and a latitude of 180 gives a bottom view. ====Viewpoint Longitude==== Default is 210 degrees. The "Viewpoint Longitude" is the longitude of the viewpoint. ===Width=== The width of each type of thread and of each axis can be changed. If the width is set to zero, the thread will not be visible. ====Width of Axis Negative Side==== Default is two. Defines the width of the negative side of the axis. ====Width of Axis Positive Side==== Default is six. Defines the width of the positive side of the axis. ====Width of Infill Thread==== Default is one. The "Width of Infill Thread" sets the width of the green extrusion threads, those threads which are not loops and not part of the raft. ====Width of Fill Bottom Thread==== Default is two. The "Width of Fill Bottom Thread" sets the width of the olive extrusion threads at the bottom of the model. ====Width of Fill Top Thread==== Default is two. The "Width of Fill Top Thread" sets the width of the blue extrusion threads at the top of the model. ====Width of Loop Thread==== Default is three. The "Width of Loop Thread" sets the width of the yellow loop threads, which are not perimeters. ====Width of Perimeter Inside Thread==== Default is eight. The "Width of Perimeter Inside Thread" sets the width of the orange inside perimeter threads. ====Width of Perimeter Outside Thread==== Default is eight. The "Width of Perimeter Outside Thread" sets the width of the red outside perimeter threads. ====Width of Raft Thread==== Default is one. The "Width of Raft Thread" sets the width of the brown raft threads. ====Width of Selection Thread==== Default is six. The "Width of Selection Thread" sets the width of the selected line. ====Width of Travel Thread==== Default is zero. The "Width of Travel Thread" sets the width of the grey extruder off travel threads. ==Icons== The dive, soar and zoom icons are from Mark James' soarSilk icon set 1.3 at: http://www.famfamfam.com/lab/icons/silk/ ==Gcodes== An explanation of the gcodes is at: http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter and at: http://reprap.org/bin/view/Main/MCodeReference A gode example is at: http://forums.reprap.org/file.php?12,file=565 ==Examples== Below are examples of skeiniso being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and skeiniso.py. > python skeiniso.py This brings up the skeiniso dialog. > python skeiniso.py Screw Holder_penultimate.gcode This brings up the skeiniso viewer to view the gcode file. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities import display_line from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities import tableau from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities import view_move from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities import view_rotate from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def compareLayerSequence( first, second ): "Get comparison in order to sort skein panes in ascending order of layer zone index then sequence index." if first.layerZoneIndex < second.layerZoneIndex: return - 1 if first.layerZoneIndex > second.layerZoneIndex: return 1 if first.sequenceIndex < second.sequenceIndex: return - 1 return int( first.sequenceIndex > second.sequenceIndex ) def getNewRepository(): 'Get new repository.' return SkeinisoRepository() def getWindowAnalyzeFile(fileName): "Skeiniso a gcode file." gcodeText = archive.getFileText(fileName) return getWindowAnalyzeFileGivenText(fileName, gcodeText) def getWindowAnalyzeFileGivenText( fileName, gcodeText, repository=None): "Display a skeiniso gcode file for a gcode file." if gcodeText == '': return None if repository is None: repository = settings.getReadRepository( SkeinisoRepository() ) skeinWindow = getWindowGivenTextRepository( fileName, gcodeText, repository ) skeinWindow.updateDeiconify() return skeinWindow def getWindowGivenTextRepository( fileName, gcodeText, repository ): "Display the gcode text in a skeiniso viewer." skein = SkeinisoSkein() skein.parseGcode( fileName, gcodeText, repository ) return SkeinWindow( repository, skein ) def writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText=''): "Write a skeinisoed gcode file for a skeinforge gcode file, if 'Activate Skeiniso' is selected." try: import Tkinter except: print('Warning, skeiniso will do nothing because Tkinter is not installed.') return repository = settings.getReadRepository( SkeinisoRepository() ) if repository.activateSkeiniso.value: gcodeText = archive.getTextIfEmpty( fileNameSuffix, gcodeText ) return getWindowAnalyzeFileGivenText( fileNameSuffix, gcodeText, repository ) class SkeinisoRepository( tableau.TableauRepository ): "A class to handle the skeiniso settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.analyze_plugins.skeiniso.html', self) self.baseNameSynonym = 'behold.csv' self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File for Skeiniso', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skeiniso') self.activateSkeiniso = settings.BooleanSetting().getFromValue('Activate Skeiniso', self, False) self.addAnimation() self.axisRulings = settings.BooleanSetting().getFromValue('Axis Rulings', self, True ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Banding -', self ) self.bandHeight = settings.IntSpinUpdate().getFromValue( 0, 'Band Height (layers):', self, 10, 5 ) self.bottomBandBrightness = settings.FloatSpinUpdate().getFromValue( 0.0, 'Bottom Band Brightness (ratio):', self, 1.0, 0.7 ) self.bottomLayerBrightness = settings.FloatSpinUpdate().getFromValue( 0.0, 'Bottom Layer Brightness (ratio):', self, 1.0, 1.0 ) self.brightBandStart = settings.MenuButtonDisplay().getFromName('Bright Band Start:', self ) self.fromTheBottom = settings.MenuRadio().getFromMenuButtonDisplay( self.brightBandStart, 'From the Bottom', self, False ) self.fromTheTop = settings.MenuRadio().getFromMenuButtonDisplay( self.brightBandStart, 'From the Top', self, True ) settings.LabelSeparator().getFromRepository(self) self.drawArrows = settings.BooleanSetting().getFromValue('Draw Arrows', self, False ) self.goAroundExtruderOffTravel = settings.BooleanSetting().getFromValue('Go Around Extruder Off Travel', self, False ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Layers -', self ) self.layer = settings.IntSpinNotOnMenu().getSingleIncrementFromValue( 0, 'Layer (index):', self, 912345678, 0 ) self.layerExtraSpan = settings.IntSpinUpdate().getSingleIncrementFromValue( - 912345678, 'Layer Extra Span (integer):', self, 912345678, 912345678 ) settings.LabelSeparator().getFromRepository(self) self.line = settings.IntSpinNotOnMenu().getSingleIncrementFromValue( 0, 'Line (index):', self, 912345678, 0 ) self.mouseMode = settings.MenuButtonDisplay().getFromName('Mouse Mode:', self ) self.displayLine = settings.MenuRadio().getFromMenuButtonDisplay( self.mouseMode, 'Display Line', self, True ) self.viewMove = settings.MenuRadio().getFromMenuButtonDisplay( self.mouseMode, 'View Move', self, False ) self.viewRotate = settings.MenuRadio().getFromMenuButtonDisplay( self.mouseMode, 'View Rotate', self, False ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Number of Fill Layers -', self ) self.numberOfFillBottomLayers = settings.IntSpinUpdate().getFromValue( 0, 'Number of Fill Bottom Layers (integer):', self, 5, 1 ) self.numberOfFillTopLayers = settings.IntSpinUpdate().getFromValue( 0, 'Number of Fill Top Layers (integer):', self, 5, 1 ) settings.LabelSeparator().getFromRepository(self) self.addScaleScreenSlide() settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Viewpoint -', self ) self.viewpointLatitude = settings.FloatSpin().getFromValue( 0.0, 'Viewpoint Latitude (degrees):', self, 180.0, 15.0 ) self.viewpointLongitude = settings.FloatSpin().getFromValue( 0.0, 'Viewpoint Longitude (degrees):', self, 360.0, 210.0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Width -', self ) self.widthOfAxisNegativeSide = settings.IntSpinUpdate().getFromValue( 0, 'Width of Axis Negative Side (pixels):', self, 10, 2 ) self.widthOfAxisPositiveSide = settings.IntSpinUpdate().getFromValue( 0, 'Width of Axis Positive Side (pixels):', self, 10, 6 ) self.widthOfFillBottomThread = settings.IntSpinUpdate().getFromValue( 0, 'Width of Fill Bottom Thread (pixels):', self, 10, 2 ) self.widthOfFillTopThread = settings.IntSpinUpdate().getFromValue( 0, 'Width of Fill Top Thread (pixels):', self, 10, 2 ) self.widthOfInfillThread = settings.IntSpinUpdate().getFromValue( 0, 'Width of Infill Thread (pixels):', self, 10, 1 ) self.widthOfLoopThread = settings.IntSpinUpdate().getFromValue( 0, 'Width of Loop Thread (pixels):', self, 10, 2 ) self.widthOfPerimeterInsideThread = settings.IntSpinUpdate().getFromValue( 0, 'Width of Perimeter Inside Thread (pixels):', self, 10, 8 ) self.widthOfPerimeterOutsideThread = settings.IntSpinUpdate().getFromValue( 0, 'Width of Perimeter Outside Thread (pixels):', self, 10, 8 ) self.widthOfRaftThread = settings.IntSpinUpdate().getFromValue( 0, 'Width of Raft Thread (pixels):', self, 10, 1 ) self.widthOfSelectionThread = settings.IntSpinUpdate().getFromValue( 0, 'Width of Selection Thread (pixels):', self, 10, 6 ) self.widthOfTravelThread = settings.IntSpinUpdate().getFromValue( 0, 'Width of Travel Thread (pixels):', self, 10, 0 ) self.executeTitle = 'Skeiniso' def execute(self): "Write button has been clicked." fileNames = skeinforge_polyfile.getFileOrGcodeDirectory( self.fileNameInput.value, self.fileNameInput.wasCancelled ) for fileName in fileNames: getWindowAnalyzeFile(fileName) class SkeinisoSkein: "A class to write a get a scalable vector graphics text for a gcode skein." def __init__(self): self.coloredThread = [] self.feedRateMinute = 960.1 self.hasANestedRingBeenReached = False self.isLoop = False self.isPerimeter = False self.isOuter = False self.isThereALayerStartWord = False self.layerCount = settings.LayerCount() self.layerTops = [] self.lineIndex = 0 self.oldLayerZoneIndex = 0 self.oldZ = - 999987654321.0 self.skeinPane = None self.skeinPanes = [] self.thirdLayerThickness = 0.133333 def addToPath( self, line, location ): 'Add a point to travel and maybe extrusion.' if self.oldLocation is None: return begin = self.scale * self.oldLocation - self.scaleCenterBottom end = self.scale * location - self.scaleCenterBottom displayString = '%s %s' % ( self.lineIndex + 1, line ) tagString = 'colored_line_index: %s %s' % ( len( self.skeinPane.coloredLines ), len( self.skeinPanes ) - 1 ) coloredLine = tableau.ColoredLine( begin, '', displayString, end, tagString ) coloredLine.z = location.z self.skeinPane.coloredLines.append( coloredLine ) self.coloredThread.append( coloredLine ) def getLayerTop(self): "Get the layer top." if len( self.layerTops ) < 1: return - 9123456789123.9 return self.layerTops[-1] def getLayerZoneIndex( self, z ): "Get the layer zone index." if self.layerTops[ self.oldLayerZoneIndex ] > z: if self.oldLayerZoneIndex == 0: return 0 elif self.layerTops[ self.oldLayerZoneIndex - 1 ] < z: return self.oldLayerZoneIndex for layerTopIndex in xrange( len( self.layerTops ) ): layerTop = self.layerTops[ layerTopIndex ] if layerTop > z: self.oldLayerZoneIndex = layerTopIndex return layerTopIndex self.oldLayerZoneIndex = len( self.layerTops ) - 1 return self.oldLayerZoneIndex def initializeActiveLocation(self): "Set variables to default." self.extruderActive = False self.oldLocation = None def linearCorner( self, splitLine ): "Update the bounding corners." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.extruderActive or self.goAroundExtruderOffTravel: self.cornerMaximum.maximize(location) self.cornerMinimum.minimize(location) self.oldLocation = location def linearMove( self, line, location ): "Get statistics for a linear move." if self.skeinPane is None: return self.addToPath(line, location) def moveColoredThreadToSkeinPane(self): 'Move a colored thread to the skein pane.' if len( self.coloredThread ) <= 0: return layerZoneIndex = self.getLayerZoneIndex( self.coloredThread[0].z ) if not self.extruderActive: self.setColoredThread( ( 190.0, 190.0, 190.0 ), self.skeinPane.travelLines ) #grey return self.skeinPane.layerZoneIndex = layerZoneIndex if self.isPerimeter: if self.isOuter: self.setColoredThread( ( 255.0, 0.0, 0.0 ), self.skeinPane.perimeterOutsideLines ) #red else: self.setColoredThread( ( 255.0, 165.0, 0.0 ), self.skeinPane.perimeterInsideLines ) #orange return if self.isLoop: self.setColoredThread( ( 255.0, 255.0, 0.0 ), self.skeinPane.loopLines ) #yellow return if not self.hasANestedRingBeenReached: self.setColoredThread( ( 165.0, 42.0, 42.0 ), self.skeinPane.raftLines ) #brown return if layerZoneIndex < self.repository.numberOfFillBottomLayers.value: self.setColoredThread( ( 128.0, 128.0, 0.0 ), self.skeinPane.fillBottomLines ) #olive return if layerZoneIndex >= self.firstTopLayer: self.setColoredThread( ( 0.0, 0.0, 255.0 ), self.skeinPane.fillTopLines ) #blue return self.setColoredThread( ( 0.0, 255.0, 0.0 ), self.skeinPane.infillLines ) #green def parseCorner(self, line): "Parse a gcode line and use the location to update the bounding corners." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if tableau.getIsLayerStart(firstWord, self, splitLine): if firstWord == '(': self.layerTopZ = float(splitLine[1]) + self.thirdLayerThickness else: self.layerTopZ = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine).z + self.thirdLayerThickness self.layerTops.append( self.layerTopZ ) if firstWord == 'G1': self.linearCorner(splitLine) elif firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False elif firstWord == '(': self.thirdLayerThickness = 0.33333333333 * float(splitLine[1]) if firstWord == '()': if self.layerTopZ > self.getLayerTop(): self.layerTops.append( self.layerTopZ ) def parseGcode( self, fileName, gcodeText, repository ): "Parse gcode text and store the vector output." self.repository = repository self.fileName = fileName self.gcodeText = gcodeText self.initializeActiveLocation() self.cornerMaximum = Vector3(-987654321.0, -987654321.0, -987654321.0) self.cornerMinimum = Vector3(987654321.0, 987654321.0, 987654321.0) self.goAroundExtruderOffTravel = repository.goAroundExtruderOffTravel.value self.lines = archive.getTextLines(gcodeText) self.isThereALayerStartWord = (gcodec.getFirstWordIndexReverse('(', self.lines, 1) > -1) if self.isThereALayerStartWord: self.parseInitialization() else: print('') print('') print('') print('Warning, there are no skeinforge comments in this text, probably because they have been removed by export.') print('So there is no loop information, and therefore the lines will not be colored.') print('') print('To see the full information in an exported file, either deselect Delete Comments in export, or') print('select Save Penultimate Gcode in export, and open the generated file with the suffix _penultimate.gcode.') print('') print('') print('') for line in self.lines[self.lineIndex :]: self.parseCorner(line) self.oldZ = - 999987654321.0 if len( self.layerTops ) > 0: self.layerTops[-1] += 912345678.9 if len( self.layerTops ) > 1: self.oneMinusBrightnessOverTopLayerIndex = ( 1.0 - repository.bottomLayerBrightness.value ) / float( len( self.layerTops ) - 1 ) self.firstTopLayer = len( self.layerTops ) - self.repository.numberOfFillTopLayers.value self.centerComplex = 0.5 * ( self.cornerMaximum.dropAxis() + self.cornerMinimum.dropAxis() ) self.centerBottom = Vector3( self.centerComplex.real, self.centerComplex.imag, self.cornerMinimum.z ) self.scale = repository.scale.value self.scaleCenterBottom = self.scale * self.centerBottom self.scaleCornerHigh = self.scale * self.cornerMaximum.dropAxis() self.scaleCornerLow = self.scale * self.cornerMinimum.dropAxis() print("The lower left corner of the skeiniso window is at %s, %s" % (self.cornerMinimum.x, self.cornerMinimum.y)) print("The upper right corner of the skeiniso window is at %s, %s" % (self.cornerMaximum.x, self.cornerMaximum.y)) self.cornerImaginaryTotal = self.cornerMaximum.y + self.cornerMinimum.y margin = complex( 5.0, 5.0 ) self.marginCornerLow = self.scaleCornerLow - margin self.screenSize = margin + 2.0 * ( self.scaleCornerHigh - self.marginCornerLow ) self.initializeActiveLocation() for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '()': return elif firstWord == '(': self.feedRateMinute = 60.0 * float(splitLine[1]) def parseLine(self, line): "Parse a gcode line and add it to the vector output." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if tableau.getIsLayerStart(firstWord, self, splitLine): self.layerCount.printProgressIncrement('skeiniso') self.skeinPane = SkeinPane( len( self.skeinPanes ) ) self.skeinPanes.append( self.skeinPane ) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.linearMove(line, location) self.oldLocation = location elif firstWord == 'M101': self.moveColoredThreadToSkeinPane() self.extruderActive = True elif firstWord == 'M103': self.moveColoredThreadToSkeinPane() self.extruderActive = False self.isLoop = False self.isPerimeter = False elif firstWord == '(': self.isLoop = True elif firstWord == '()': self.moveColoredThreadToSkeinPane() self.isLoop = False elif firstWord == '()': self.hasANestedRingBeenReached = True elif firstWord == '(': self.isPerimeter = True self.isOuter = ( splitLine[1] == 'outer') elif firstWord == '()': self.moveColoredThreadToSkeinPane() self.isPerimeter = False if firstWord == 'G2' or firstWord == 'G3': relativeLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) relativeLocation.z = 0.0 location = self.oldLocation + relativeLocation self.linearMove(line, location) self.oldLocation = location def setColoredLineColor( self, coloredLine, colorTuple ): 'Set the color and stipple of the colored line.' layerZoneIndex = self.getLayerZoneIndex( coloredLine.z ) multiplier = self.repository.bottomLayerBrightness.value if len( self.layerTops ) > 1: multiplier += self.oneMinusBrightnessOverTopLayerIndex * float( layerZoneIndex ) bandIndex = layerZoneIndex / self.repository.bandHeight.value if self.repository.fromTheTop.value: brightZoneIndex = len( self.layerTops ) - 1 - layerZoneIndex bandIndex = brightZoneIndex / self.repository.bandHeight.value + 1 if bandIndex % 2 == 0: multiplier *= self.repository.bottomBandBrightness.value red = settings.getWidthHex( int( colorTuple[0] * multiplier ), 2 ) green = settings.getWidthHex( int( colorTuple[1] * multiplier ), 2 ) blue = settings.getWidthHex( int( colorTuple[2] * multiplier ), 2 ) coloredLine.colorName = '#%s%s%s' % ( red, green, blue ) def setColoredThread( self, colorTuple, lineList ): 'Set the colored thread, then move it to the line list and stipple of the colored line.' for coloredLine in self.coloredThread: self.setColoredLineColor( coloredLine, colorTuple ) lineList += self.coloredThread self.coloredThread = [] class SkeinPane: "A class to hold the colored lines for a layer." def __init__( self, sequenceIndex ): "Create empty line lists." self.coloredLines = [] self.fillBottomLines = [] self.fillTopLines = [] self.index = 0 self.infillLines = [] self.layerZoneIndex = 0 self.loopLines = [] self.perimeterInsideLines = [] self.perimeterOutsideLines = [] self.raftLines = [] self.sequenceIndex = sequenceIndex self.travelLines = [] class Ruling: def __init__( self, modelDistance, roundedRulingText ): "Initialize the ruling." self.modelDistance = modelDistance self.roundedRulingText = roundedRulingText class SkeinWindow( tableau.TableauWindow ): def __init__( self, repository, skein ): "Initialize the skein window." self.arrowshape = ( 24, 30, 9 ) self.addCanvasMenuRootScrollSkein( repository, skein, '_skeiniso', 'Skeiniso') self.center = 0.5 * self.screenSize self.motionStippleName = 'gray75' halfCenter = 0.5 * self.center.real negativeHalfCenter = - halfCenter self.halfCenterModel = halfCenter / skein.scale negativeHalfCenterModel = - self.halfCenterModel roundedHalfCenter = euclidean.getThreeSignificantFigures( self.halfCenterModel ) roundedNegativeHalfCenter = euclidean.getThreeSignificantFigures( negativeHalfCenterModel ) self.negativeAxisLineX = tableau.ColoredLine( Vector3(), 'darkorange', None, Vector3( negativeHalfCenter ), 'X Negative Axis: Origin -> %s,0,0' % roundedNegativeHalfCenter ) self.negativeAxisLineY = tableau.ColoredLine( Vector3(), 'gold', None, Vector3( 0.0, negativeHalfCenter ), 'Y Negative Axis: Origin -> 0,%s,0' % roundedNegativeHalfCenter ) self.negativeAxisLineZ = tableau.ColoredLine( Vector3(), 'skyblue', None, Vector3( 0.0, 0.0, negativeHalfCenter ), 'Z Negative Axis: Origin -> 0,0,%s' % roundedNegativeHalfCenter ) self.positiveAxisLineX = tableau.ColoredLine( Vector3(), 'darkorange', None, Vector3( halfCenter ), 'X Positive Axis: Origin -> %s,0,0' % roundedHalfCenter ) self.positiveAxisLineY = tableau.ColoredLine( Vector3(), 'gold', None, Vector3( 0.0, halfCenter ), 'Y Positive Axis: Origin -> 0,%s,0' % roundedHalfCenter ) self.positiveAxisLineZ = tableau.ColoredLine( Vector3(), 'skyblue', None, Vector3( 0.0, 0.0, halfCenter ), 'Z Positive Axis: Origin -> 0,0,%s' % roundedHalfCenter ) self.repository.axisRulings.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.bandHeight.setUpdateFunction( self.setWindowToDisplaySavePhoenixUpdate ) self.repository.bottomBandBrightness.setUpdateFunction( self.setWindowToDisplaySavePhoenixUpdate ) self.repository.bottomLayerBrightness.setUpdateFunction( self.setWindowToDisplaySavePhoenixUpdate ) self.repository.fromTheBottom.setUpdateFunction( self.setWindowToDisplaySavePhoenixUpdate ) self.repository.fromTheTop.setUpdateFunction( self.setWindowToDisplaySavePhoenixUpdate ) self.setWindowNewMouseTool( display_line.getNewMouseTool, self.repository.displayLine ) self.setWindowNewMouseTool( view_move.getNewMouseTool, self.repository.viewMove ) self.setWindowNewMouseTool( view_rotate.getNewMouseTool, self.repository.viewRotate ) self.repository.numberOfFillBottomLayers.setUpdateFunction( self.setWindowToDisplaySavePhoenixUpdate ) self.repository.numberOfFillTopLayers.setUpdateFunction( self.setWindowToDisplaySavePhoenixUpdate ) self.repository.viewpointLatitude.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.viewpointLongitude.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.widthOfAxisNegativeSide.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.widthOfAxisPositiveSide.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.widthOfFillBottomThread.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.widthOfFillTopThread.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.widthOfInfillThread.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.widthOfLoopThread.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.widthOfPerimeterInsideThread.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.widthOfPerimeterOutsideThread.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.repository.widthOfRaftThread.setUpdateFunction( self.setWindowToDisplaySaveUpdate ) self.addMouseToolsBind() self.negativeRulings = [] self.positiveRulings = [] for rulingIndex in xrange( 1, int( math.ceil( self.halfCenterModel / self.rulingSeparationWidthMillimeters ) ) ): modelDistance = rulingIndex * self.rulingSeparationWidthMillimeters self.negativeRulings.append( Ruling( modelDistance, self.getRoundedRulingText( 1, - modelDistance ) ) ) self.positiveRulings.append( Ruling( modelDistance, self.getRoundedRulingText( 1, modelDistance ) ) ) self.rulingExtentHalf = 0.5 * self.rulingExtent def drawRuling( self, projectiveSpace, relativeRulingEnd, ruling, tags, viewBegin, viewEnd ): "Draw ruling." alongWay = ruling.modelDistance / self.halfCenterModel oneMinusAlongWay = 1.0 - alongWay alongScreen = alongWay * viewEnd + oneMinusAlongWay * viewBegin alongScreenEnd = alongScreen + relativeRulingEnd self.canvas.create_line( alongScreen.real, alongScreen.imag, alongScreenEnd.real, alongScreenEnd.imag, fill = 'black', tags = tags, width = 2 ) self.canvas.create_text( int( alongScreenEnd.real ) + 3, alongScreenEnd.imag, anchor = settings.Tkinter.W, text = ruling.roundedRulingText ) def drawRulings( self, axisLine, projectiveSpace, rulings ): "Draw rulings for the axis line." if not self.repository.axisRulings.value: return viewBegin = self.getScreenView( axisLine.begin, projectiveSpace ) viewEnd = self.getScreenView( axisLine.end, projectiveSpace ) viewSegment = viewEnd - viewBegin viewSegmentLength = abs( viewSegment ) if viewSegmentLength < self.rulingExtent: return normalizedViewSegment = viewSegment / viewSegmentLength relativeRulingEnd = complex( - normalizedViewSegment.imag, normalizedViewSegment.real ) if normalizedViewSegment.imag > 0.0: relativeRulingEnd = complex( normalizedViewSegment.imag, - normalizedViewSegment.real ) for ruling in rulings: self.drawRuling( projectiveSpace, relativeRulingEnd * self.rulingExtentHalf, ruling, axisLine.tagString, viewBegin, viewEnd ) def drawSkeinPane( self, projectiveSpace, skeinPane ): "Draw colored lines." self.getDrawnColoredLines( skeinPane.raftLines, projectiveSpace, self.repository.widthOfRaftThread.value ) self.getDrawnColoredLines( skeinPane.travelLines, projectiveSpace, self.repository.widthOfTravelThread.value ) self.getDrawnColoredLines( skeinPane.fillBottomLines, projectiveSpace, self.repository.widthOfFillBottomThread.value ) self.getDrawnColoredLines( skeinPane.fillTopLines, projectiveSpace, self.repository.widthOfFillTopThread.value ) self.getDrawnColoredLines( skeinPane.infillLines, projectiveSpace, self.repository.widthOfInfillThread.value ) self.getDrawnColoredLines( skeinPane.loopLines, projectiveSpace, self.repository.widthOfLoopThread.value ) self.getDrawnColoredLines( skeinPane.perimeterInsideLines, projectiveSpace, self.repository.widthOfPerimeterInsideThread.value ) self.getDrawnColoredLines( skeinPane.perimeterOutsideLines, projectiveSpace, self.repository.widthOfPerimeterOutsideThread.value ) def drawXYAxisLines( self, projectiveSpace ): "Draw the x and y axis lines." if self.repository.widthOfAxisNegativeSide.value > 0: self.getDrawnColoredLineWithoutArrow( self.negativeAxisLineX, projectiveSpace, self.negativeAxisLineX.tagString, self.repository.widthOfAxisNegativeSide.value ) self.getDrawnColoredLineWithoutArrow( self.negativeAxisLineY, projectiveSpace, self.negativeAxisLineY.tagString, self.repository.widthOfAxisNegativeSide.value ) if self.repository.widthOfAxisPositiveSide.value > 0: self.getDrawnColoredLine('last', self.positiveAxisLineX, projectiveSpace, self.positiveAxisLineX.tagString, self.repository.widthOfAxisPositiveSide.value ) self.getDrawnColoredLine('last', self.positiveAxisLineY, projectiveSpace, self.positiveAxisLineY.tagString, self.repository.widthOfAxisPositiveSide.value ) def drawZAxisLine( self, projectiveSpace ): "Draw the z axis line." if self.repository.widthOfAxisNegativeSide.value > 0: self.getDrawnColoredLineWithoutArrow( self.negativeAxisLineZ, projectiveSpace, self.negativeAxisLineZ.tagString, self.repository.widthOfAxisNegativeSide.value ) if self.repository.widthOfAxisPositiveSide.value > 0: self.getDrawnColoredLine('last', self.positiveAxisLineZ, projectiveSpace, self.positiveAxisLineZ.tagString, self.repository.widthOfAxisPositiveSide.value ) def getCanvasRadius(self): "Get half of the minimum of the canvas height and width." return 0.5 * min( float( self.canvasHeight ), float( self.canvasWidth ) ) def getCentered( self, coordinate ): "Get the centered coordinate." relativeToCenter = complex( coordinate.real - self.center.real, self.center.imag - coordinate.imag ) if abs( relativeToCenter ) < 1.0: relativeToCenter = complex( 0.0, 1.0 ) return relativeToCenter def getCenteredScreened( self, coordinate ): "Get the normalized centered coordinate." return self.getCentered( coordinate ) / self.getCanvasRadius() def getColoredLines(self): "Get the colored lines from the skein pane." return self.skeinPanes[ self.repository.layer.value ].coloredLines def getCopy(self): "Get a copy of this window." return SkeinWindow( self.repository, self.skein ) def getCopyWithNewSkein(self): "Get a copy of this window with a new skein." return getWindowGivenTextRepository( self.skein.fileName, self.skein.gcodeText, self.repository ) def getDrawnColoredLine( self, arrowType, coloredLine, projectiveSpace, tags, width ): "Draw colored line." viewBegin = self.getScreenView( coloredLine.begin, projectiveSpace ) viewEnd = self.getScreenView( coloredLine.end, projectiveSpace ) return self.canvas.create_line( viewBegin.real, viewBegin.imag, viewEnd.real, viewEnd.imag, fill = coloredLine.colorName, arrow = arrowType, tags = tags, width = width ) def getDrawnColoredLineMotion( self, coloredLine, projectiveSpace, width ): "Draw colored line with motion stipple and tag." viewBegin = self.getScreenView( coloredLine.begin, projectiveSpace ) viewEnd = self.getScreenView( coloredLine.end, projectiveSpace ) return self.canvas.create_line( viewBegin.real, viewBegin.imag, viewEnd.real, viewEnd.imag, fill = coloredLine.colorName, arrow = 'last', arrowshape = self.arrowshape, stipple = self.motionStippleName, tags = 'mouse_item', width = width + 4 ) def getDrawnColoredLines( self, coloredLines, projectiveSpace, width ): "Draw colored lines." if width <= 0: return drawnColoredLines = [] for coloredLine in coloredLines: drawnColoredLines.append( self.getDrawnColoredLine( self.arrowType, coloredLine, projectiveSpace, coloredLine.tagString, width ) ) return drawnColoredLines def getDrawnColoredLineWithoutArrow( self, coloredLine, projectiveSpace, tags, width ): "Draw colored line without an arrow." viewBegin = self.getScreenView( coloredLine.begin, projectiveSpace ) viewEnd = self.getScreenView( coloredLine.end, projectiveSpace ) return self.canvas.create_line( viewBegin.real, viewBegin.imag, viewEnd.real, viewEnd.imag, fill = coloredLine.colorName, tags = tags, width = width ) def getDrawnSelectedColoredLine( self, coloredLine ): "Get the drawn selected colored line." projectiveSpace = euclidean.ProjectiveSpace().getByLatitudeLongitude( self.repository.viewpointLatitude.value, self.repository.viewpointLongitude.value ) return self.getDrawnColoredLine( self.arrowType, coloredLine, projectiveSpace, 'selection_line', self.repository.widthOfSelectionThread.value ) def getScreenComplex( self, pointComplex ): "Get the point in screen perspective." return complex( pointComplex.real, - pointComplex.imag ) + self.center def getScreenView( self, point, projectiveSpace ): "Get the point in screen view perspective." return self.getScreenComplex( projectiveSpace.getDotComplex(point) ) def printHexadecimalColorName(self, name): "Print the color name in hexadecimal." colorTuple = self.canvas.winfo_rgb( name ) print('#%s%s%s' % ( settings.getWidthHex( colorTuple[0], 2 ), settings.getWidthHex( colorTuple[1], 2 ), settings.getWidthHex( colorTuple[2], 2 ) ) ) def update(self): "Update the screen." if len( self.skeinPanes ) < 1: return self.limitIndexSetArrowMouseDeleteCanvas() self.repository.viewpointLatitude.value = view_rotate.getBoundedLatitude( self.repository.viewpointLatitude.value ) self.repository.viewpointLongitude.value = round( self.repository.viewpointLongitude.value, 1 ) projectiveSpace = euclidean.ProjectiveSpace().getByLatitudeLongitude( self.repository.viewpointLatitude.value, self.repository.viewpointLongitude.value ) skeinPanesCopy = self.getUpdateSkeinPanes()[:] skeinPanesCopy.sort( compareLayerSequence ) if projectiveSpace.basisZ.z > 0.0: self.drawXYAxisLines( projectiveSpace ) else: skeinPanesCopy.reverse() self.drawZAxisLine( projectiveSpace ) for skeinPane in skeinPanesCopy: self.drawSkeinPane( projectiveSpace, skeinPane ) if projectiveSpace.basisZ.z > 0.0: self.drawZAxisLine( projectiveSpace ) else: self.drawXYAxisLines( projectiveSpace ) if self.repository.widthOfAxisNegativeSide.value > 0: self.drawRulings( self.negativeAxisLineX, projectiveSpace, self.negativeRulings ) self.drawRulings( self.negativeAxisLineY, projectiveSpace, self.negativeRulings ) self.drawRulings( self.negativeAxisLineZ, projectiveSpace, self.negativeRulings ) if self.repository.widthOfAxisPositiveSide.value > 0: self.drawRulings( self.positiveAxisLineX, projectiveSpace, self.positiveRulings ) self.drawRulings( self.positiveAxisLineY, projectiveSpace, self.positiveRulings ) self.drawRulings( self.positiveAxisLineZ, projectiveSpace, self.positiveRulings ) self.setDisplayLayerIndex() def main(): "Display the skeiniso dialog." if len(sys.argv) > 1: settings.startMainLoopFromWindow( getWindowAnalyzeFile(' '.join(sys.argv[1 :])) ) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/skeinlayer.py000066400000000000000000000712501167321211700315550ustar00rootroot00000000000000""" This page is in the table of contents. Skeinlayer is an analyze viewer to display each layer of a gcode file. The skeinlayer manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skeinlayer Skeinlayer is derived from Nophead's preview script. The extruded lines are in the resistor colors red, orange, yellow, green, blue, purple & brown. When the extruder is off, the travel line is grey. Skeinlayer is useful for a detailed view of the extrusion, skeiniso is better to see the orientation of the shape. To get an initial overview of the skein, when the skeinlayer display window appears, click the Soar button (double right arrow button beside the layer field). ==Operation== The default 'Activate Skeinlayer' checkbox is on. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Skeinlayer' checkbox is on, when skeinlayer is run directly. Skeinlayer has trouble separating the layers when it reads gcode without comments. ==Settings== ===Animation=== ====Animation Line Quickening==== Default is one. The quickness of the tool animation over the quickness of the actual tool. ====Animation Slide Show Rate==== Default is two layers per second. The rate, in layers per second, at which the layer changes when the soar or dive button is pressed.. ===Draw Arrows=== Default is on. When selected, arrows will be drawn at the end of each line segment. ===Export Menu=== When the submenu in the export menu item in the file menu is clicked, an export canvas dialog will be displayed, which can export the canvas to a file. ===Go Around Extruder Off Travel=== Default is off. When selected, the display will include the travel when the extruder is off, which means it will include the nozzle wipe path if any. ===Layers=== ====Layer==== Default is zero. On the display window, the Up button increases the 'Layer' by one, and the Down button decreases the layer by one. When the layer displayed in the layer spin box is changed then is hit, the layer shown will be set to the spin box, to a mimimum of zero and to a maximum of the highest index layer.The Soar button increases the layer at the 'Animation Slide Show Rate', and the Dive (double left arrow button beside the layer field) button decreases the layer at the slide show rate. ====Layer Extra Span==== Default is zero. The viewer will draw the layers in the range including the 'Layer' index and the 'Layer' index plus the 'Layer Extra Span'. If the 'Layer Extra Span' is negative, the layers viewed will start at the 'Layer' index, plus the 'Layer Extra Span', and go up to and include the 'Layer' index. If the 'Layer Extra Span' is zero, only the 'Layer' index layer will be displayed. If the 'Layer Extra Span' is positive, the layers viewed will start at the 'Layer' index, and go up to and include the 'Layer' index plus the 'Layer Extra Span'. ===Line=== Default is zero. The index of the selected line on the layer that is highlighted when the 'Display Line' mouse tool is chosen. The line spin box up button increases the 'Line' by one. If the line index of the layer goes over the index of the last line, the layer index will be increased by one and the new line index will be zero. The down button decreases the line index by one. If the line index goes below the index of the first line, the layer index will be decreased by one and the new line index will be at the last line. When the line displayed in the line field is changed then is hit, the line shown will be set to the line field, to a mimimum of zero and to a maximum of the highest index line. The Soar button increases the line at the speed at which the extruder would move, times the 'Animation Line Quickening' ratio, and the Dive (double left arrow button beside the line field) button decreases the line at the animation line quickening ratio. ===Mouse Mode=== Default is 'Display Line'. The mouse tool can be changed from the 'Mouse Mode' menu button or picture button. The mouse tools listen to the arrow keys when the canvas has the focus. Clicking in the canvas gives the canvas the focus, and when the canvas has the focus a thick black border is drawn around the canvas. ====Display Line==== The 'Display Line' tool will display the highlight the selected line, and display the file line count, counting from one, and the gcode line itself. When the 'Display Line' tool is active, clicking the canvas will select the closest line to the mouse click. ====Viewpoint Move==== The 'Viewpoint Move' tool will move the viewpoint in the xy plane when the mouse is clicked and dragged on the canvas. ===Numeric Pointer=== Default is on. When selected, the distance along the ruler of the arrow pointers will be drawn next to the pointers. ===Scale=== Default is ten. The scale setting is the scale of the image in pixels per millimeter, the higher the number, the greater the size of the display. The zoom in mouse tool will zoom in the display at the point where the mouse was clicked, increasing the scale by a factor of two. The zoom out tool will zoom out the display at the point where the mouse was clicked, decreasing the scale by a factor of two. ===Screen Inset=== ====Screen Horizontal Inset==== Default is one hundred. The "Screen Horizontal Inset" determines how much the canvas will be inset in the horizontal direction from the edge of screen, the higher the number the more it will be inset and the smaller it will be. ====Screen Vertical Inset==== Default is two hundred and twenty. The "Screen Vertical Inset" determines how much the canvas will be inset in the vertical direction from the edge of screen, the higher the number the more it will be inset and the smaller it will be. ===Width=== The width of each type of thread and of each axis can be changed. If the width is set to zero, the thread will not be visible. ====Width of Extrusion Thread==== Default is three. The "Width of Extrusion Thread" sets the width of the extrusion threads. ====Width of Selection Thread==== Default is six. The "Width of Selection Thread" sets the width of the selected line. ====Width of Travel Thread==== Default is one. The "Width of Travel Thread" sets the width of the grey extruder off travel threads. ==Icons== The dive, soar and zoom icons are from Mark James' soarSilk icon set 1.3 at: http://www.famfamfam.com/lab/icons/silk/ ==Gcodes== An explanation of the gcodes is at: http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter and at: http://reprap.org/bin/view/Main/MCodeReference A gode example is at: http://forums.reprap.org/file.php?12,file=565 ==Examples== Below are examples of skeinlayer being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and skeinlayer.py. > python skeinlayer.py This brings up the skeinlayer dialog. > python skeinlayer.py Screw Holder_penultimate.gcode This brings up the skeinlayer viewer to view each layer of a gcode file. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities import display_line from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities import tableau from skeinforge_application.skeinforge_plugins.analyze_plugins.analyze_utilities import view_move from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return SkeinlayerRepository() def getRankIndex( rulingSeparationWidthMillimeters, screenOrdinate ): "Get rank index." return int( round( screenOrdinate / rulingSeparationWidthMillimeters ) ) def getWindowAnalyzeFile(fileName): "Display a gcode file in a skeinlayer window." gcodeText = archive.getFileText(fileName) return getWindowAnalyzeFileGivenText(fileName, gcodeText) def getWindowAnalyzeFileGivenText( fileName, gcodeText, repository=None): "Display a gcode file in a skeinlayer window given the text." if gcodeText == '': return None if repository is None: repository = settings.getReadRepository( SkeinlayerRepository() ) skeinWindow = getWindowGivenTextRepository( fileName, gcodeText, repository ) skeinWindow.updateDeiconify() return skeinWindow def getWindowGivenTextRepository( fileName, gcodeText, repository ): "Display a gcode file in a skeinlayer window given the text and settings." skein = SkeinlayerSkein() skein.parseGcode( fileName, gcodeText, repository ) return SkeinWindow( repository, skein ) def writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText=''): "Display a skeinlayered gcode file for a skeinforge gcode file, if 'Activate Skeinlayer' is selected." try: import Tkinter except: print('Warning, skeinlayer will do nothing because Tkinter is not installed.') return repository = settings.getReadRepository( SkeinlayerRepository() ) if repository.activateSkeinlayer.value: gcodeText = archive.getTextIfEmpty( fileNameSuffix, gcodeText ) return getWindowAnalyzeFileGivenText( fileNameSuffix, gcodeText, repository ) class SkeinlayerRepository( tableau.TableauRepository ): "A class to handle the skeinlayer settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.analyze_plugins.skeinlayer.html', self) self.baseNameSynonym = 'skeinview.csv' self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File for Skeinlayer', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skeinlayer') self.activateSkeinlayer = settings.BooleanSetting().getFromValue('Activate Skeinlayer', self, True ) self.addAnimation() self.drawArrows = settings.BooleanSetting().getFromValue('Draw Arrows', self, True ) self.goAroundExtruderOffTravel = settings.BooleanSetting().getFromValue('Go Around Extruder Off Travel', self, False ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Layers -', self ) self.layer = settings.IntSpinNotOnMenu().getSingleIncrementFromValue( 0, 'Layer (index):', self, 912345678, 0 ) self.layerExtraSpan = settings.IntSpinUpdate().getSingleIncrementFromValue( - 3, 'Layer Extra Span (integer):', self, 3, 0 ) settings.LabelSeparator().getFromRepository(self) self.line = settings.IntSpinNotOnMenu().getSingleIncrementFromValue( 0, 'Line (index):', self, 912345678, 0 ) self.mouseMode = settings.MenuButtonDisplay().getFromName('Mouse Mode:', self ) self.displayLine = settings.MenuRadio().getFromMenuButtonDisplay( self.mouseMode, 'Display Line', self, True ) self.viewMove = settings.MenuRadio().getFromMenuButtonDisplay( self.mouseMode, 'View Move', self, False ) self.addScaleScreenSlide() self.showPosition = settings.BooleanSetting().getFromValue('Show Position', self, True ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Width -', self ) self.widthOfExtrusionThread = settings.IntSpinUpdate().getSingleIncrementFromValue( 0, 'Width of Extrusion Thread (pixels):', self, 5, 3 ) self.widthOfSelectionThread = settings.IntSpinUpdate().getSingleIncrementFromValue( 0, 'Width of Selection Thread (pixels):', self, 10, 6 ) self.widthOfTravelThread = settings.IntSpinUpdate().getSingleIncrementFromValue( 0, 'Width of Travel Thread (pixels):', self, 5, 1 ) self.executeTitle = 'Skeinlayer' def execute(self): "Write button has been clicked." fileNames = skeinforge_polyfile.getFileOrGcodeDirectory( self.fileNameInput.value, self.fileNameInput.wasCancelled ) for fileName in fileNames: getWindowAnalyzeFile(fileName) class SkeinlayerSkein: "A class to write a get a scalable vector graphics text for a gcode skein." def __init__(self): 'Initialize.' self.extrusionNumber = 0 self.feedRateMinute = 960.1 self.isThereALayerStartWord = False self.layerCount = settings.LayerCount() self.oldZ = - 999987654321.0 self.skeinPane = None self.skeinPanes = [] def addToPath( self, line, location ): "Add a point to travel and maybe extrusion." if self.oldLocation is None: return colorName = 'gray' locationComplex = location.dropAxis() oldLocationComplex = self.oldLocation.dropAxis() begin = self.getScreenCoordinates( oldLocationComplex ) end = self.getScreenCoordinates( locationComplex ) if self.extruderActive: colorName = self.colorNames[ self.extrusionNumber % len( self.colorNames ) ] displayString = '%s %s' % ( self.lineIndex + 1, line ) tagString = 'colored_line_index: %s %s' % ( len( self.skeinPane ), len( self.skeinPanes ) - 1 ) coloredLine = tableau.ColoredLine( begin, colorName, displayString, end, tagString ) coloredLine.isExtrusionThread = self.extruderActive self.skeinPane.append( coloredLine ) def getModelCoordinates( self, screenCoordinates ): "Get the model coordinates." modelCoordinates = ( screenCoordinates + self.marginCornerLow ) / self.scale return complex( modelCoordinates.real, self.cornerImaginaryTotal - modelCoordinates.imag ) def getScreenCoordinates( self, pointComplex ): "Get the screen coordinates." pointComplex = complex( pointComplex.real, self.cornerImaginaryTotal - pointComplex.imag ) return self.scale * pointComplex - self.marginCornerLow def initializeActiveLocation(self): "Set variables to default." self.extruderActive = False self.oldLocation = None def linearCorner( self, splitLine ): "Update the bounding corners." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.extruderActive or self.repository.goAroundExtruderOffTravel.value: self.cornerMaximum.maximize(location) self.cornerMinimum.minimize(location) self.oldLocation = location def linearMove( self, line, location ): "Get statistics for a linear move." if self.skeinPane is not None: self.addToPath(line, location) def parseCorner(self, line): "Parse a gcode line and use the location to update the bounding corners." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.linearCorner(splitLine) elif firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False def parseGcode( self, fileName, gcodeText, repository ): "Parse gcode text and store the vector output." self.fileName = fileName self.gcodeText = gcodeText self.repository = repository self.initializeActiveLocation() self.cornerMaximum = Vector3(-987654321.0, -987654321.0, -987654321.0) self.cornerMinimum = Vector3(987654321.0, 987654321.0, 987654321.0) self.lines = archive.getTextLines(gcodeText) self.isThereALayerStartWord = (gcodec.getFirstWordIndexReverse('(', self.lines, 1) > -1) self.parseInitialization() for line in self.lines[self.lineIndex :]: self.parseCorner(line) self.cornerMaximumComplex = self.cornerMaximum.dropAxis() self.cornerMinimumComplex = self.cornerMinimum.dropAxis() self.scale = repository.scale.value self.scaleCornerHigh = self.scale * self.cornerMaximumComplex self.scaleCornerLow = self.scale * self.cornerMinimumComplex self.cornerImaginaryTotal = self.cornerMaximum.y + self.cornerMinimum.y self.margin = complex( 10.0, 10.0 ) self.marginCornerHigh = self.scaleCornerHigh + self.margin self.marginCornerLow = self.scaleCornerLow - self.margin self.screenSize = self.marginCornerHigh - self.marginCornerLow self.initializeActiveLocation() self.colorNames = ['brown', 'red', 'orange', 'yellow', 'green', 'blue', 'purple'] for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '()': return elif firstWord == '(': self.feedRateMinute = 60.0 * float(splitLine[1]) self.lineIndex = 0 def parseLine(self, line): "Parse a gcode line and add it to the vector output." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if tableau.getIsLayerStart(firstWord, self, splitLine): self.extrusionNumber = 0 self.layerCount.printProgressIncrement('skeinlayer') self.skeinPane = [] self.skeinPanes.append( self.skeinPane ) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.linearMove(line, location) self.oldLocation = location elif firstWord == 'M101': self.extruderActive = True self.extrusionNumber += 1 elif firstWord == 'M103': self.extruderActive = False if firstWord == 'G2' or firstWord == 'G3': relativeLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) relativeLocation.z = 0.0 location = self.oldLocation + relativeLocation self.linearMove(line, location) self.oldLocation = location class SkeinWindow( tableau.TableauWindow ): def __init__(self, repository, skein): "Initialize the skein window.setWindowNewMouseTool" self.addCanvasMenuRootScrollSkein(repository, skein, '_skeinlayer', 'Skeinlayer') horizontalRulerBoundingBox = (0, 0, int( skein.screenSize.real ), self.rulingExtent) self.horizontalRulerCanvas = settings.Tkinter.Canvas(self.root, width = self.canvasWidth, height = self.rulingExtent, scrollregion=horizontalRulerBoundingBox) self.horizontalRulerCanvas.grid(row=1, column=2, columnspan=96, sticky=settings.Tkinter.E+settings.Tkinter.W) self.horizontalRulerCanvas['xscrollcommand'] = self.xScrollbar.set verticalRulerBoundingBox = (0, 0, self.rulingExtent, int(skein.screenSize.imag)) self.verticalRulerCanvas = settings.Tkinter.Canvas(self.root, width=self.rulingExtent, height=self.canvasHeight, scrollregion=verticalRulerBoundingBox) self.verticalRulerCanvas.grid(row=2, rowspan=96, column=1, sticky=settings.Tkinter.N+settings.Tkinter.S) self.verticalRulerCanvas['yscrollcommand'] = self.yScrollbar.set self.xStringVar = settings.Tkinter.StringVar(self.root) self.xLabel = settings.Tkinter.Label(self.root, textvariable=self.xStringVar) self.xLabel.grid(row=0, column=3, sticky=settings.Tkinter.W) self.yStringVar = settings.Tkinter.StringVar(self.root) self.yLabel = settings.Tkinter.Label(self.root, textvariable=self.yStringVar) self.yLabel.grid(row=0, column=4, sticky=settings.Tkinter.W) self.setWindowNewMouseTool(display_line.getNewMouseTool, repository.displayLine) self.setWindowNewMouseTool(view_move.getNewMouseTool, repository.viewMove) repository.showPosition.setUpdateFunction(self.setWindowToDisplaySaveUpdate) repository.widthOfExtrusionThread.setUpdateFunction(self.setWindowToDisplaySaveUpdate) self.addMouseToolsBind() self.createRulers() def addHorizontalRulerRuling( self, xMillimeters ): "Add a ruling to the horizontal ruler." xPixel = self.skein.getScreenCoordinates( complex( xMillimeters, 0.0 ) ).real self.createVerticalLine( 0.0, xPixel ) self.horizontalRulerCanvas.create_text( xPixel + 2, 0, anchor = settings.Tkinter.NW, text = self.getRoundedRulingText( 1, xMillimeters ) ) cumulativeDistance = xMillimeters self.createVerticalLine( self.rulingExtentTiny, self.skein.getScreenCoordinates( complex( xMillimeters + self.separationWidthMillimetersTenth, 0.0 ) ).real ) for subRulingIndex in xrange(4): cumulativeDistance += self.separationWidthMillimetersFifth self.createVerticalLine( self.rulingExtentShort, self.skein.getScreenCoordinates( complex( cumulativeDistance, 0.0 ) ).real ) self.createVerticalLine( self.rulingExtentTiny, self.skein.getScreenCoordinates( complex( cumulativeDistance + self.separationWidthMillimetersTenth, 0.0 ) ).real ) def addVerticalRulerRuling( self, yMillimeters ): "Add a ruling to the vertical ruler." fontHeight = 12 yPixel = self.skein.getScreenCoordinates( complex( 0.0, yMillimeters ) ).imag self.createHorizontalLine( 0.0, yPixel ) yPixel += 2 roundedRulingText = self.getRoundedRulingText( 1, yMillimeters ) effectiveRulingTextLength = len( roundedRulingText ) if roundedRulingText.find('.') != - 1: effectiveRulingTextLength -= 1 cumulativeDistance = yMillimeters self.createHorizontalLine( self.rulingExtentTiny, self.skein.getScreenCoordinates( complex( 0.0, yMillimeters + self.separationWidthMillimetersTenth ) ).imag ) for subRulingIndex in xrange(4): cumulativeDistance += self.separationWidthMillimetersFifth self.createHorizontalLine( self.rulingExtentShort, self.skein.getScreenCoordinates( complex( 0.0, cumulativeDistance ) ).imag ) self.createHorizontalLine( self.rulingExtentTiny, self.skein.getScreenCoordinates( complex( 0.0, cumulativeDistance + self.separationWidthMillimetersTenth ) ).imag ) if effectiveRulingTextLength < 4: self.verticalRulerCanvas.create_text( 0, yPixel, anchor = settings.Tkinter.NW, text = roundedRulingText ) return for character in roundedRulingText: if character == '.': yPixel -= fontHeight * 2 / 3 self.verticalRulerCanvas.create_text( 0, yPixel, anchor = settings.Tkinter.NW, text = character ) yPixel += fontHeight def createHorizontalLine( self, begin, yPixel ): "Create a horizontal line for the horizontal ruler." self.verticalRulerCanvas.create_line( begin, yPixel, self.rulingExtent, yPixel, fill = 'black') def createRulers(self): "Create the rulers.." self.rulingExtentShort = 0.382 * self.rulingExtent self.rulingExtentTiny = 0.764 * self.rulingExtent self.rulingExtentPointer = 0.5 * ( self.rulingExtentShort + self.rulingExtentTiny ) self.rulingPointerRadius = self.rulingExtent - self.rulingExtentPointer self.textBoxHeight = int( 0.8 * self.rulingExtent ) self.textBoxWidth = int( 2.5 * self.rulingExtent ) self.separationWidthMillimetersFifth = 0.2 * self.rulingSeparationWidthMillimeters self.separationWidthMillimetersTenth = 0.1 * self.rulingSeparationWidthMillimeters rulingSeparationWidthPixels = self.getRulingSeparationWidthPixels( self.rank ) marginOverScale = self.skein.margin / self.skein.scale cornerMaximumMargin = self.skein.cornerMaximumComplex + marginOverScale cornerMinimumMargin = self.skein.cornerMinimumComplex - marginOverScale xRankIndexHigh = getRankIndex( self.rulingSeparationWidthMillimeters, cornerMaximumMargin.real ) xRankIndexLow = getRankIndex( self.rulingSeparationWidthMillimeters, cornerMinimumMargin.real ) for xRankIndex in xrange( xRankIndexLow - 2, xRankIndexHigh + 2 ): # 1 is enough, 2 is to be on the safe side self.addHorizontalRulerRuling( xRankIndex * self.rulingSeparationWidthMillimeters ) yRankIndexHigh = getRankIndex( self.rulingSeparationWidthMillimeters, cornerMaximumMargin.imag ) yRankIndexLow = getRankIndex( self.rulingSeparationWidthMillimeters, cornerMinimumMargin.imag ) for yRankIndex in xrange( yRankIndexLow - 2, yRankIndexHigh + 2 ): # 1 is enough, 2 is to be on the safe side self.addVerticalRulerRuling( yRankIndex * self.rulingSeparationWidthMillimeters ) def createVerticalLine( self, begin, xPixel ): "Create a vertical line for the horizontal ruler." self.horizontalRulerCanvas.create_line( xPixel, begin, xPixel, self.rulingExtent, fill = 'black') def getColoredLines(self): "Get the colored lines from the skein pane." return self.skeinPanes[self.repository.layer.value] def getCopy(self): "Get a copy of this window." return SkeinWindow(self.repository, self.skein) def getCopyWithNewSkein(self): "Get a copy of this window with a new skein." return getWindowGivenTextRepository( self.skein.fileName, self.skein.gcodeText, self.repository ) def getDrawnColoredLine( self, coloredLine, tags, width ): "Get the drawn colored line." return self.canvas.create_line( coloredLine.begin.real, coloredLine.begin.imag, coloredLine.end.real, coloredLine.end.imag, fill = coloredLine.colorName, arrow = self.arrowType, tags = tags, width = width ) def getDrawnColoredLineIfThick( self, coloredLine, width ): "Get the drawn colored line if it has a positive thickness." if width > 0: return self.getDrawnColoredLine( coloredLine, coloredLine.tagString, width ) def getDrawnSelectedColoredLine(self, coloredLine): "Get the drawn selected colored line." return self.getDrawnColoredLine(coloredLine, 'selection_line', self.repository.widthOfSelectionThread.value) def motion(self, event): "The mouse moved." self.mouseTool.motion(event) xString = '' yString = '' x = self.canvas.canvasx( event.x ) y = self.canvas.canvasy( event.y ) self.horizontalRulerCanvas.delete('pointer') self.horizontalRulerCanvas.create_polygon( x - self.rulingPointerRadius, self.rulingExtentPointer, x + self.rulingPointerRadius, self.rulingExtentPointer, x, self.rulingExtent, tag = 'pointer') self.verticalRulerCanvas.delete('pointer') self.verticalRulerCanvas.create_polygon( self.rulingExtentPointer, y - self.rulingPointerRadius, self.rulingExtentPointer, y + self.rulingPointerRadius, self.rulingExtent, y, tag = 'pointer') if self.repository.showPosition.value: motionCoordinate = complex(x, y) modelCoordinates = self.skein.getModelCoordinates( motionCoordinate ) roundedXText = self.getRoundedRulingText(3, modelCoordinates.real) roundedYText = self.getRoundedRulingText(3, modelCoordinates.imag) xString = 'X: ' + roundedXText yString = 'Y: ' + roundedYText self.xStringVar.set(xString) self.yStringVar.set(yString) def qqqmotion(self, event): "The mouse moved." self.mouseTool.motion(event) x = self.canvas.canvasx( event.x ) y = self.canvas.canvasy( event.y ) self.horizontalRulerCanvas.delete('pointer') self.horizontalRulerCanvas.create_polygon( x - self.rulingPointerRadius, self.rulingExtentPointer, x + self.rulingPointerRadius, self.rulingExtentPointer, x, self.rulingExtent, tag = 'pointer') self.verticalRulerCanvas.delete('pointer') self.verticalRulerCanvas.create_polygon( self.rulingExtentPointer, y - self.rulingPointerRadius, self.rulingExtentPointer, y + self.rulingPointerRadius, self.rulingExtent, y, tag = 'pointer') if not self.repository.numericPointer.value: return motionCoordinate = complex(x, y) modelCoordinates = self.skein.getModelCoordinates( motionCoordinate ) roundedXText = self.getRoundedRulingText( 3, modelCoordinates.real ) yStart = self.canvas.canvasy( 0 ) self.canvas.create_rectangle( x - 2, yStart, x + self.textBoxWidth, yStart + self.textBoxHeight + 5, fill = self.canvas['background'], tag = 'pointer') self.canvas.create_text( x, yStart + 5, anchor = settings.Tkinter.NW, tag = 'pointer', text = roundedXText ) roundedYText = self.getRoundedRulingText( 3, modelCoordinates.imag ) xStart = self.canvas.canvasx( 0 ) self.canvas.create_rectangle( xStart, y - 2, xStart + self.textBoxWidth + 5, y + self.textBoxHeight, fill = self.canvas['background'], tag = 'pointer') self.canvas.create_text( xStart + 5, y, anchor = settings.Tkinter.NW, tag = 'pointer', text = roundedYText ) xString = '' xString = 'X: ' + roundedXText self.xStringVar.set(xString) def relayXview( self, *args ): "Relay xview changes." self.canvas.xview( *args ) self.horizontalRulerCanvas.xview( *args ) def relayYview( self, *args ): "Relay yview changes." self.canvas.yview( *args ) self.verticalRulerCanvas.yview( *args ) def update(self): "Update the window." if len( self.skeinPanes ) < 1: return self.limitIndexSetArrowMouseDeleteCanvas() for coloredLines in self.getUpdateSkeinPanes(): for coloredLine in coloredLines: if coloredLine.isExtrusionThread: self.getDrawnColoredLineIfThick( coloredLine, self.repository.widthOfExtrusionThread.value ) else: self.getDrawnColoredLineIfThick( coloredLine, self.repository.widthOfTravelThread.value ) self.setDisplayLayerIndex() def main(): "Display the skeinlayer dialog." if len(sys.argv) > 1: settings.startMainLoopFromWindow(getWindowAnalyzeFile(' '.join(sys.argv[1 :]))) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/statistic.py000066400000000000000000000433521167321211700314200ustar00rootroot00000000000000""" This page is in the table of contents. Statistic is an extremely valuable analyze plugin to print and/or save the statistics of the generated gcode. The statistic manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Statistic ==Operation== The default 'Activate Statistic' checkbox is on. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Statistic' checkbox is on, when statistic is run directly. ==Settings== ===Extrusion Diameter over Thickness=== Default is 1.25. The 'Extrusion Diameter over Thickness is the ratio of the extrusion diameter over the layer thickness, the default is 1.25. The extrusion fill density ratio that is printed to the console, ( it is derived quantity not a parameter ) is the area of the extrusion diameter over the extrusion width over the layer thickness. Assuming the extrusion diameter is correct, a high value means the filament will be packed tightly, and the object will be almost as dense as the filament. If the fill density ratio is too high, there could be too little room for the filament, and the extruder will end up plowing through the extra filament. A low fill density ratio means the filaments will be far away from each other, the object will be leaky and light. The fill density ratio with the default extrusion settings is around 0.68. ===Print Statistics=== Default is on. When the 'Print Statistics' checkbox is on, the statistics will be printed to the console. ===Save Statistics=== Default is off. When the 'Save Statistics' checkbox is on, the statistics will be saved as a .txt file. ==Gcodes== An explanation of the gcodes is at: http://reprap.org/bin/view/Main/Arduino_GCode_Interpreter and at: http://reprap.org/bin/view/Main/MCodeReference A gode example is at: http://forums.reprap.org/file.php?12,file=565 ==Examples== Below are examples of statistic being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and statistic.py. The 'Save Statistics' checkbox is selected. > python statistic.py This brings up the statistic dialog. > python statistic.py Screw Holder_penultimate.gcode Statistics are being generated for the file /home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/models/Screw Holder_penultimate.gcode Cost Machine time cost is 0.31$. Material cost is 0.2$. Total cost is 0.51$. Extent X axis extrusion starts at 61 mm and ends at 127 mm, for a width of 65 mm. Y axis extrusion starts at 81 mm and ends at 127 mm, for a depth of 45 mm. Z axis extrusion starts at 0 mm and ends at 15 mm, for a height of 15 mm. Extruder Build time is 18 minutes 47 seconds. Distance extruded is 46558.4 mm. Distance traveled is 58503.3 mm. Extruder speed is 50.0 Extruder was extruding 79.6 percent of the time. Extruder was toggled 1688 times. Operating flow rate is 9.8 mm3/s. Feed rate average is 51.9 mm/s, (3113.8 mm/min). Filament Cross section area is 0.2 mm2. Extrusion diameter is 0.5 mm. Extrusion fill density ratio is 0.68 Material Mass extruded is 9.8 grams. Volume extruded is 9.1 cc. Meta Text has 33738 lines and a size of 1239.0 KB. Version is 11.09.28 Procedures carve bottom preface inset fill multiply speed temperature raft skirt dimension bookend Profile UM-PLA-HighQuality Slice Layer thickness is 0.4 mm. Perimeter width is 0.72 mm. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import cStringIO import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return StatisticRepository() def getWindowAnalyzeFile(fileName): "Write statistics for a gcode file." return getWindowAnalyzeFileGivenText( fileName, archive.getFileText(fileName) ) def getWindowAnalyzeFileGivenText( fileName, gcodeText, repository=None): "Write statistics for a gcode file." print('') print('') print('Statistics are being generated for the file ' + archive.getSummarizedFileName(fileName) ) if repository is None: repository = settings.getReadRepository( StatisticRepository() ) skein = StatisticSkein() statisticGcode = skein.getCraftedGcode(gcodeText, repository) if repository.printStatistics.value: print( statisticGcode ) if repository.saveStatistics.value: archive.writeFileMessageEnd('.txt', fileName, statisticGcode, 'The statistics file is saved as ') def writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText=''): "Write statistics for a skeinforge gcode file, if 'Write Statistics File for Skeinforge Chain' is selected." repository = settings.getReadRepository( StatisticRepository() ) if gcodeText == '': gcodeText = archive.getFileText( fileNameSuffix ) if repository.activateStatistic.value: getWindowAnalyzeFileGivenText( fileNameSuffix, gcodeText, repository ) class StatisticRepository: "A class to handle the statistics settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.analyze_plugins.statistic.html', self) self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Statistic') self.activateStatistic = settings.BooleanSetting().getFromValue('Activate Statistic', self, True ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Cost -', self ) self.machineTime = settings.FloatSpin().getFromValue( 0.0, 'Machine Time ($/hour):', self, 5.0, 1.0 ) self.material = settings.FloatSpin().getFromValue( 0.0, 'Material ($/kg):', self, 40.0, 20.0 ) settings.LabelSeparator().getFromRepository(self) self.density = settings.FloatSpin().getFromValue( 500.0, 'Density (kg/m3):', self, 2000.0, 930.0 ) self.extrusionDiameterOverThickness = settings.FloatSpin().getFromValue( 1.0, 'Extrusion Diameter over Thickness (ratio):', self, 1.5, 1.25 ) self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File to Generate Statistics for', self, '') self.printStatistics = settings.BooleanSetting().getFromValue('Print Statistics', self, True ) self.saveStatistics = settings.BooleanSetting().getFromValue('Save Statistics', self, False ) self.executeTitle = 'Generate Statistics' def execute(self): "Write button has been clicked." fileNames = skeinforge_polyfile.getFileOrGcodeDirectory( self.fileNameInput.value, self.fileNameInput.wasCancelled, ['_comment'] ) for fileName in fileNames: getWindowAnalyzeFile(fileName) class StatisticSkein: "A class to get statistics for a gcode skein." def __init__(self): self.extrusionDiameter = None self.oldLocation = None self.operatingFeedRatePerSecond = None self.output = cStringIO.StringIO() self.profileName = None self.version = None def addLine(self, line): "Add a line of text and a newline to the output." self.output.write(line + '\n') def addToPath(self, location): "Add a point to travel and maybe extrusion." if self.oldLocation is not None: travel = location.distance( self.oldLocation ) if self.feedRateMinute > 0.0: self.totalBuildTime += 60.0 * travel / self.feedRateMinute self.totalDistanceTraveled += travel if self.extruderActive: self.totalDistanceExtruded += travel self.cornerMaximum.maximize(location) self.cornerMinimum.minimize(location) self.oldLocation = location def extruderSet( self, active ): "Maybe increment the number of times the extruder was toggled." if self.extruderActive != active: self.extruderToggled += 1 self.extruderActive = active def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the statistics." self.absolutePerimeterWidth = 0.4 self.characters = 0 self.cornerMaximum = Vector3(-987654321.0, -987654321.0, -987654321.0) self.cornerMinimum = Vector3(987654321.0, 987654321.0, 987654321.0) self.extruderActive = False self.extruderSpeed = None self.extruderToggled = 0 self.feedRateMinute = 600.0 self.layerThickness = 0.4 self.numberOfLines = 0 self.procedures = [] self.repository = repository self.totalBuildTime = 0.0 self.totalDistanceExtruded = 0.0 self.totalDistanceTraveled = 0.0 lines = archive.getTextLines(gcodeText) for line in lines: self.parseLine(line) averageFeedRate = self.totalDistanceTraveled / self.totalBuildTime self.characters += self.numberOfLines kilobytes = round( self.characters / 1024.0 ) halfPerimeterWidth = 0.5 * self.absolutePerimeterWidth halfExtrusionCorner = Vector3( halfPerimeterWidth, halfPerimeterWidth, halfPerimeterWidth ) self.cornerMaximum += halfExtrusionCorner self.cornerMinimum -= halfExtrusionCorner extent = self.cornerMaximum - self.cornerMinimum roundedHigh = euclidean.getRoundedPoint( self.cornerMaximum ) roundedLow = euclidean.getRoundedPoint( self.cornerMinimum ) roundedExtent = euclidean.getRoundedPoint( extent ) axisString = " axis extrusion starts at " crossSectionArea = 0.9 * self.absolutePerimeterWidth * self.layerThickness # 0.9 if from the typical fill density if self.extrusionDiameter is not None: crossSectionArea = math.pi / 4.0 * self.extrusionDiameter * self.extrusionDiameter volumeExtruded = 0.001 * crossSectionArea * self.totalDistanceExtruded mass = volumeExtruded / repository.density.value machineTimeCost = repository.machineTime.value * self.totalBuildTime / 3600.0 materialCost = repository.material.value * mass self.addLine(' ') self.addLine('Cost') self.addLine( "Machine time cost is %s$." % round( machineTimeCost, 2 ) ) self.addLine( "Material cost is %s$." % round( materialCost, 2 ) ) self.addLine( "Total cost is %s$." % round( machineTimeCost + materialCost, 2 ) ) self.addLine(' ') self.addLine('Extent') self.addLine( "X%s%s mm and ends at %s mm, for a width of %s mm." % ( axisString, int( roundedLow.x ), int( roundedHigh.x ), int( extent.x ) ) ) self.addLine( "Y%s%s mm and ends at %s mm, for a depth of %s mm." % ( axisString, int( roundedLow.y ), int( roundedHigh.y ), int( extent.y ) ) ) self.addLine( "Z%s%s mm and ends at %s mm, for a height of %s mm." % ( axisString, int( roundedLow.z ), int( roundedHigh.z ), int( extent.z ) ) ) self.addLine(' ') self.addLine('Extruder') self.addLine( "Build time is %s." % euclidean.getDurationString( self.totalBuildTime ) ) self.addLine( "Distance extruded is %s mm." % euclidean.getThreeSignificantFigures( self.totalDistanceExtruded ) ) self.addLine( "Distance traveled is %s mm." % euclidean.getThreeSignificantFigures( self.totalDistanceTraveled ) ) if self.extruderSpeed is not None: self.addLine( "Extruder speed is %s" % euclidean.getThreeSignificantFigures( self.extruderSpeed ) ) self.addLine( "Extruder was extruding %s percent of the time." % euclidean.getThreeSignificantFigures( 100.0 * self.totalDistanceExtruded / self.totalDistanceTraveled ) ) self.addLine( "Extruder was toggled %s times." % self.extruderToggled ) if self.operatingFeedRatePerSecond is not None: flowRate = crossSectionArea * self.operatingFeedRatePerSecond self.addLine( "Operating flow rate is %s mm3/s." % euclidean.getThreeSignificantFigures( flowRate ) ) self.addLine( "Feed rate average is %s mm/s, (%s mm/min)." % ( euclidean.getThreeSignificantFigures( averageFeedRate ), euclidean.getThreeSignificantFigures( 60.0 * averageFeedRate ) ) ) self.addLine(' ') self.addLine('Filament') self.addLine( "Cross section area is %s mm2." % euclidean.getThreeSignificantFigures( crossSectionArea ) ) if self.extrusionDiameter is not None: self.addLine( "Extrusion diameter is %s mm." % euclidean.getThreeSignificantFigures( self.extrusionDiameter ) ) self.addLine('Extrusion fill density ratio is %s' % euclidean.getThreeSignificantFigures( crossSectionArea / self.absolutePerimeterWidth / self.layerThickness ) ) self.addLine(' ') self.addLine('Material') self.addLine( "Mass extruded is %s grams." % euclidean.getThreeSignificantFigures( 1000.0 * mass ) ) self.addLine( "Volume extruded is %s cc." % euclidean.getThreeSignificantFigures( volumeExtruded ) ) self.addLine(' ') self.addLine('Meta') self.addLine( "Text has %s lines and a size of %s KB." % ( self.numberOfLines, kilobytes ) ) if self.version is not None: self.addLine( "Version is " + self.version ) self.addLine(' ') self.addLine( "Procedures" ) for procedure in self.procedures: self.addLine(procedure) if self.profileName is not None: self.addLine(' ') self.addLine( 'Profile' ) self.addLine(self.profileName) self.addLine(' ') self.addLine('Slice') self.addLine( "Layer thickness is %s mm." % euclidean.getThreeSignificantFigures( self.layerThickness ) ) self.addLine( "Perimeter width is %s mm." % euclidean.getThreeSignificantFigures( self.absolutePerimeterWidth ) ) self.addLine(' ') return self.output.getvalue() def getLocationSetFeedRateToSplitLine( self, splitLine ): "Get location ans set feed rate to the plsit line." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) indexOfF = gcodec.getIndexOfStartingWithSecond( "F", splitLine ) if indexOfF > 0: self.feedRateMinute = gcodec.getDoubleAfterFirstLetter( splitLine[indexOfF] ) return location def helicalMove( self, isCounterclockwise, splitLine ): "Get statistics for a helical move." if self.oldLocation is None: return location = self.getLocationSetFeedRateToSplitLine(splitLine) location += self.oldLocation center = self.oldLocation.copy() indexOfR = gcodec.getIndexOfStartingWithSecond( "R", splitLine ) if indexOfR > 0: radius = gcodec.getDoubleAfterFirstLetter( splitLine[ indexOfR ] ) halfLocationMinusOld = location - self.oldLocation halfLocationMinusOld *= 0.5 halfLocationMinusOldLength = halfLocationMinusOld.magnitude() centerMidpointDistanceSquared = radius * radius - halfLocationMinusOldLength * halfLocationMinusOldLength centerMidpointDistance = math.sqrt( max( centerMidpointDistanceSquared, 0.0 ) ) centerMinusMidpoint = euclidean.getRotatedWiddershinsQuarterAroundZAxis( halfLocationMinusOld ) centerMinusMidpoint.normalize() centerMinusMidpoint *= centerMidpointDistance if isCounterclockwise: center.setToVector3( halfLocationMinusOld + centerMinusMidpoint ) else: center.setToVector3( halfLocationMinusOld - centerMinusMidpoint ) else: center.x = gcodec.getDoubleForLetter( "I", splitLine ) center.y = gcodec.getDoubleForLetter( "J", splitLine ) curveSection = 0.5 center += self.oldLocation afterCenterSegment = location - center beforeCenterSegment = self.oldLocation - center afterCenterDifferenceAngle = euclidean.getAngleAroundZAxisDifference( afterCenterSegment, beforeCenterSegment ) absoluteDifferenceAngle = abs( afterCenterDifferenceAngle ) steps = int( round( 0.5 + max( absoluteDifferenceAngle * 2.4, absoluteDifferenceAngle * beforeCenterSegment.magnitude() / curveSection ) ) ) stepPlaneAngle = euclidean.getWiddershinsUnitPolar( afterCenterDifferenceAngle / steps ) zIncrement = ( afterCenterSegment.z - beforeCenterSegment.z ) / float( steps ) for step in xrange( 1, steps ): beforeCenterSegment = euclidean.getRoundZAxisByPlaneAngle( stepPlaneAngle, beforeCenterSegment ) beforeCenterSegment.z += zIncrement arcPoint = center + beforeCenterSegment self.addToPath( arcPoint ) self.addToPath( location ) def linearMove( self, splitLine ): "Get statistics for a linear move." location = self.getLocationSetFeedRateToSplitLine(splitLine) self.addToPath( location ) def parseLine(self, line): "Parse a gcode line and add it to the statistics." self.characters += len(line) self.numberOfLines += 1 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.linearMove(splitLine) elif firstWord == 'G2': self.helicalMove( False, splitLine ) elif firstWord == 'G3': self.helicalMove( True, splitLine ) elif firstWord == 'M101': self.extruderSet( True ) elif firstWord == 'M102': self.extruderSet( False ) elif firstWord == 'M103': self.extruderSet( False ) elif firstWord == 'M108': self.extruderSpeed = gcodec.getDoubleAfterFirstLetter(splitLine[1]) elif firstWord == '(': self.layerThickness = float(splitLine[1]) self.extrusionDiameter = self.repository.extrusionDiameterOverThickness.value * self.layerThickness elif firstWord == '(': self.operatingFeedRatePerSecond = float(splitLine[1]) elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.absolutePerimeterWidth = abs(float(splitLine[1])) elif firstWord == '(': self.procedures.append(splitLine[1]) elif firstWord == '(': self.profileName = line.replace('(', '').replace(')', '').strip() elif firstWord == '(': self.version = splitLine[1] def main(): "Display the statistics dialog." if len(sys.argv) > 1: getWindowAnalyzeFile(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/synopsis.py000066400000000000000000000221071167321211700312730ustar00rootroot00000000000000""" This page is in the table of contents. Synopsis is an analyze plugin to export the profile from a skeinforge gcode file as a csv or zip file. The synopsis manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Synopsis ==Operation== The default 'Activate Synopsis' checkbox is off. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Synopsis' checkbox is on, when synopsis is run directly. ==Settings== ===Export Profile As CSV File=== Default is on. If 'Export Profile As CSV File' is selected, the profile from a skeinforge gcode file with comments will be exported as a csv (comma separated values) file. ===Export Profile As Zip File=== Default is off. If 'Export Profile As Zip File' is selected, the profile from a skeinforge gcode file with comments will be exported as a zip file. ==Examples== Below are examples of synopsis being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and synopsis.py. > python synopsis.py This brings up the synopsis dialog. > python synopsis.py Screw Holder_penultimate.gcode The synopsis file is saved as Screw_Holder_penultimate_synopsis.csv """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import os import sys import time import zipfile __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Gary Hodgson ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addAbridgedSettings(abridgedSettings, repositoryWriter): 'Add the abridged settings to a repository writer.' for abridgedSetting in abridgedSettings: repositoryWriter.write('%s\n' % abridgedSetting.__repr__()) def exportProfileAsCSVFile(abridgedSettings, suffixFileNameWithoutExtension): 'Export the profile from the gcode text as a csv file.' if len(abridgedSettings) < 1: print('Warning, the synopsis csv file could not be generated because there are no setting comments in the file.') return repositoryWriter = settings.getRepositoryWriter('profile') suffixFileName = suffixFileNameWithoutExtension + 'csv' addAbridgedSettings(abridgedSettings, repositoryWriter) archive.writeFileText(suffixFileName, repositoryWriter.getvalue()) print('The synopsis csv file is saved as ' + archive.getSummarizedFileName(suffixFileName)) def exportProfileAsZipFile(abridgedSettings, suffixDirectoryPath, suffixFileNameWithoutExtension): 'Export the profile from the gcode text as a zip file.' if len(abridgedSettings) < 1: print('Warning, the synopsis zip file could not be generated because there are no setting comments in the file.') return suffixFileName = suffixFileNameWithoutExtension + 'zip' abridgedSettingsDictionary = {} for abridgedSetting in abridgedSettings: euclidean.addElementToListDictionary(abridgedSetting, abridgedSetting.procedure, abridgedSettingsDictionary) abridgedSettingFileNamePaths = [] for abridgedSettingsKey in abridgedSettingsDictionary: abridgedSettings = abridgedSettingsDictionary[abridgedSettingsKey] repositoryWriter = settings.getRepositoryWriter(abridgedSettingsKey) addAbridgedSettings(abridgedSettings, repositoryWriter) abridgedSettingFileNamePath = FileNamePath(suffixDirectoryPath, abridgedSettingsKey + '.csv') abridgedSettingFileNamePaths.append(abridgedSettingFileNamePath) archive.writeFileText(abridgedSettingFileNamePath.path, repositoryWriter.getvalue()) time.sleep(0.2) # the sleep is so that the file system is sure to be consistent zipArchive = zipfile.ZipFile(suffixFileName, 'w', compression=zipfile.ZIP_DEFLATED) for abridgedSettingFileNamePath in abridgedSettingFileNamePaths: zipArchive.write(abridgedSettingFileNamePath.path, abridgedSettingFileNamePath.fileName) zipArchive.close() time.sleep(0.2) # the sleep is so that the file system is sure to be consistent for abridgedSettingFileNamePath in abridgedSettingFileNamePaths: os.remove(abridgedSettingFileNamePath.path) print('The synopsis zip file is saved as ' + archive.getSummarizedFileName(suffixFileName)) def getAbridgedSettings(gcodeText): 'Get the abridged settings from the gcode text.' abridgedSettings = [] lines = archive.getTextLines(gcodeText) settingsStart = False for line in lines: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '(' and settingsStart: if len(splitLine) > 4: abridgedSettings.append(AbridgedSetting(splitLine)) elif firstWord == '()': settingsStart = True elif firstWord == '()': return abridgedSettings return [] def getNewRepository(): 'Get new repository.' return SynopsisRepository() def getWindowAnalyzeFile(fileName): 'Write scalable vector graphics for a gcode file.' gcodeText = archive.getFileText(fileName) return getWindowAnalyzeFileGivenText(fileName, gcodeText) def getWindowAnalyzeFileGivenText(fileName, gcodeText, repository=None): 'Write scalable vector graphics for a gcode file given the settings.' if gcodeText == '': return None if repository is None: repository = settings.getReadRepository(SynopsisRepository()) startTime = time.time() suffixFileNameWithoutExtension = fileName[: fileName.rfind('.')] + '_synopsis.' suffixDirectoryPath = os.path.dirname(suffixFileNameWithoutExtension) suffixReplacedBaseNameWithoutExtension = os.path.basename(suffixFileNameWithoutExtension).replace(' ', '_') suffixFileNameWithoutExtension = os.path.join(suffixDirectoryPath, suffixReplacedBaseNameWithoutExtension) abridgedSettings = getAbridgedSettings(gcodeText) if repository.exportProfileAsCSVFile.value: exportProfileAsCSVFile(abridgedSettings, suffixFileNameWithoutExtension) if repository.exportProfileAsZipFile.value: exportProfileAsZipFile(abridgedSettings, suffixDirectoryPath, suffixFileNameWithoutExtension) print('It took %s for synopsis to analyze the file.' % euclidean.getDurationString(time.time() - startTime)) def writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText=''): 'Write scalable vector graphics for a skeinforge gcode file, if activate synopsis is selected.' repository = settings.getReadRepository( SynopsisRepository() ) if not repository.activateSynopsis.value: return gcodeText = archive.getTextIfEmpty( fileNameSuffix, gcodeText ) getWindowAnalyzeFileGivenText( fileNameSuffix, gcodeText, repository ) class AbridgedSetting: 'A class to handle an abridged setting.' def __init__(self, splitLine): 'Initialize.' self.procedure = splitLine[1] self.name = splitLine[2].replace('_', ' ') self.value = ' '.join(splitLine[3 : -1]) def __repr__(self): 'Get the tab separated representation of this AbridgedSetting.' return '%s\t%s\t%s' % (self.procedure, self.name, self.value) class FileNamePath: 'A class to handle a file name and path.' def __init__(self, directoryName, fileName): 'Initialize.' self.fileName = fileName self.path = os.path.join(directoryName, fileName) def __repr__(self): 'Get the tab separated representation of this FileNamePath.' return '%s\t%s' % (self.fileName, self.path) class SynopsisRepository: 'A class to handle the synopsis settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.analyze_plugins.synopsis.html', self ) self.activateSynopsis = settings.BooleanSetting().getFromValue('Activate Synopsis', self, False ) self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File to Write Synopsis for', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Synopsis') self.exportProfileAsCSVFile = settings.BooleanSetting().getFromValue('Export Profile As CSV File', self, True) self.exportProfileAsZipFile = settings.BooleanSetting().getFromValue('Export Profile As Zip File', self, False) self.executeTitle = 'Synopsis' def execute(self): 'Write button has been clicked.' fileNames = skeinforge_polyfile.getFileOrGcodeDirectory( self.fileNameInput.value, self.fileNameInput.wasCancelled ) for fileName in fileNames: getWindowAnalyzeFile(fileName) def main(): 'Display the synopsis dialog.' if len(sys.argv) > 1: getWindowAnalyzeFile(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/analyze_plugins/vectorwrite.py000066400000000000000000000360211167321211700317610ustar00rootroot00000000000000""" This page is in the table of contents. Vectorwrite is a very interesting analyze plugin that will create an SVG vector image for each layer that you can then use in some other printing system. The Scalable Vector Graphics file can be opened by an SVG viewer or an SVG capable browser like Mozilla: http://www.mozilla.com/firefox/ The vectorwrite manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Vectorwrite ==Operation== The default 'Activate Vectorwrite' checkbox is off. When it is on, the functions described below will work when called from the skeinforge toolchain, when it is off, the functions will not be called from the toolchain. The functions will still be called, whether or not the 'Activate Vectorwrite' checkbox is on, when vectorwrite is run directly. ==Settings== ===Add Loops=== Default is on. If 'Add Loops' is selected, the loops will be added in yellow to the the scalable vector graphics output. ===Add Paths=== Default is on. If 'Add Paths' is selected, the paths will be added in pink to the the scalable vector graphics output. ===Add Perimeters=== Default is on. If 'Add Perimeters' is selected, the perimeters will be added to the the scalable vector graphics output. The outer perimeters will be red and the inner perimeters will be orange. ===Layers=== ====Layers From==== Default is zero. The "Layers From" is the index of the bottom layer that will be displayed. If the layer from is the default zero, the display will start from the lowest layer. If the the layer from index is negative, then the display will start from the layer from index below the top layer. ====Layers To==== Default is a huge number, which will be limited to the highest index layer. The "Layers To" is the index of the top layer that will be displayed. If the layer to index is a huge number like the default, the display will go to the top of the model, at least until we model habitats:) If the layer to index is negative, then the display will go to the layer to index below the top layer. The layer from until layer to index is a python slice. ===SVG Viewer=== Default is webbrowser. If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened. ==Examples== Below are examples of vectorwrite being used. These examples are run in a terminal in the folder which contains Screw Holder_penultimate.gcode and vectorwrite.py. > python vectorwrite.py This brings up the vectorwrite dialog. > python vectorwrite.py Screw Holder_penultimate.gcode The vectorwrite file is saved as Screw_Holder_penultimate_vectorwrite.svg """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from fabmetheus_utilities import svg_writer from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import cStringIO import os import sys import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Nophead ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return VectorwriteRepository() def getWindowAnalyzeFile(fileName): 'Write scalable vector graphics for a gcode file.' gcodeText = archive.getFileText(fileName) return getWindowAnalyzeFileGivenText(fileName, gcodeText) def getWindowAnalyzeFileGivenText( fileName, gcodeText, repository=None): 'Write scalable vector graphics for a gcode file given the settings.' if gcodeText == '': return None if repository is None: repository = settings.getReadRepository( VectorwriteRepository() ) startTime = time.time() vectorwriteGcode = VectorwriteSkein().getCarvedSVG( fileName, gcodeText, repository ) if vectorwriteGcode == '': return None suffixFileName = fileName[ : fileName.rfind('.') ] + '_vectorwrite.svg' suffixDirectoryName = os.path.dirname(suffixFileName) suffixReplacedBaseName = os.path.basename(suffixFileName).replace(' ', '_') suffixFileName = os.path.join( suffixDirectoryName, suffixReplacedBaseName ) archive.writeFileText( suffixFileName, vectorwriteGcode ) print('The vectorwrite file is saved as ' + archive.getSummarizedFileName(suffixFileName) ) print('It took %s to vectorwrite the file.' % euclidean.getDurationString( time.time() - startTime ) ) settings.openSVGPage( suffixFileName, repository.svgViewer.value ) def writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText=''): 'Write scalable vector graphics for a skeinforge gcode file, if activate vectorwrite is selected.' repository = settings.getReadRepository( VectorwriteRepository() ) if not repository.activateVectorwrite.value: return gcodeText = archive.getTextIfEmpty( fileNameSuffix, gcodeText ) getWindowAnalyzeFileGivenText( fileNameSuffix, gcodeText, repository ) class SVGWriterVectorwrite( svg_writer.SVGWriter ): 'A class to vectorwrite a carving.' def addPaths( self, colorName, paths, transformString ): 'Add paths to the output.' pathString = '' for path in paths: pathString += self.getSVGStringForPath(path) + ' ' if len( pathString ) < 1: return pathElementNodeCopy = self.pathElementNode.getCopy('', self.pathElementNode.parentNode ) pathCopyDictionary = pathElementNodeCopy.attributes pathCopyDictionary['d'] = pathString[ : - 1 ] pathCopyDictionary['fill'] = 'none' pathCopyDictionary['stroke'] = colorName pathCopyDictionary['transform'] = transformString def addLoopLayerToOutput( self, layerIndex, threadLayer ): 'Add rotated boundary layer to the output.' settings.printProgress(self.layerIndex, 'vectorwrite') self.addLayerBegin( layerIndex, threadLayer ) transformString = self.getTransformString() self.pathDictionary['d'] = self.getSVGStringForLoops( threadLayer.boundaryLoops ) self.pathDictionary['transform'] = transformString self.addPaths('#fa0', threadLayer.innerPerimeters, transformString ) #orange self.addPaths('#ff0', threadLayer.loops, transformString ) #yellow self.addPaths('#f00', threadLayer.outerPerimeters, transformString ) #red self.addPaths('#f5c', threadLayer.paths, transformString ) #light violetred class ThreadLayer: 'Threads with a z.' def __init__( self, z ): self.boundaryLoops = [] self.innerPerimeters = [] self.loops = [] self.outerPerimeters = [] self.paths = [] self.z = z def __repr__(self): 'Get the string representation of this loop layer.' return str(self.__dict__) def getTotalNumberOfThreads(self): 'Get the total number of loops, paths and perimeters.' return len(self.boundaryLoops) + len(self.innerPerimeters) + len(self.loops) + len(self.outerPerimeters) + len(self.paths) def maximize(self, vector3): 'Maximize the vector3 over the loops, paths and perimeters.' pointComplex = vector3.dropAxis() pointComplex = euclidean.getMaximum(euclidean.getMaximumByComplexPaths(self.boundaryLoops), pointComplex) pointComplex = euclidean.getMaximum(euclidean.getMaximumByComplexPaths(self.innerPerimeters), pointComplex) pointComplex = euclidean.getMaximum(euclidean.getMaximumByComplexPaths(self.loops), pointComplex) pointComplex = euclidean.getMaximum(euclidean.getMaximumByComplexPaths(self.outerPerimeters), pointComplex) pointComplex = euclidean.getMaximum(euclidean.getMaximumByComplexPaths(self.paths), pointComplex) vector3.setToXYZ(pointComplex.real, pointComplex.imag, max(self.z, vector3.z)) def minimize(self, vector3): 'Minimize the vector3 over the loops, paths and perimeters.' pointComplex = vector3.dropAxis() pointComplex = euclidean.getMinimum(euclidean.getMinimumByComplexPaths(self.boundaryLoops), pointComplex) pointComplex = euclidean.getMinimum(euclidean.getMinimumByComplexPaths(self.innerPerimeters), pointComplex) pointComplex = euclidean.getMinimum(euclidean.getMinimumByComplexPaths(self.loops), pointComplex) pointComplex = euclidean.getMinimum(euclidean.getMinimumByComplexPaths(self.outerPerimeters), pointComplex) pointComplex = euclidean.getMinimum(euclidean.getMinimumByComplexPaths(self.paths), pointComplex) vector3.setToXYZ(pointComplex.real, pointComplex.imag, min(self.z, vector3.z)) class VectorwriteRepository: 'A class to handle the vectorwrite settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.analyze_plugins.vectorwrite.html', self ) self.activateVectorwrite = settings.BooleanSetting().getFromValue('Activate Vectorwrite', self, False ) self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File to Write Vector Graphics for', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Vectorwrite') self.addLoops = settings.BooleanSetting().getFromValue('Add Loops', self, True) self.addPaths = settings.BooleanSetting().getFromValue('Add Paths', self, True) self.addPerimeters = settings.BooleanSetting().getFromValue('Add Perimeters', self, True) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Layers -', self ) self.layersFrom = settings.IntSpin().getFromValue( 0, 'Layers From (index):', self, 20, 0 ) self.layersTo = settings.IntSpin().getSingleIncrementFromValue( 0, 'Layers To (index):', self, 912345678, 912345678 ) settings.LabelSeparator().getFromRepository(self) self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser') settings.LabelSeparator().getFromRepository(self) self.executeTitle = 'Vectorwrite' def execute(self): 'Write button has been clicked.' fileNames = skeinforge_polyfile.getFileOrGcodeDirectory( self.fileNameInput.value, self.fileNameInput.wasCancelled ) for fileName in fileNames: getWindowAnalyzeFile(fileName) class VectorwriteSkein: 'A class to vectorwrite a carving.' def __init__(self): 'Initialize.' self.layerCount = settings.LayerCount() def addLoopLayer(self, z): 'Add loop layer.' self.layerCount.printProgressIncrement('vectorwrite') self.threadLayer = ThreadLayer(z) self.threadLayers.append(self.threadLayer) def addToLoops(self): 'Add the thread to the loops.' self.isLoop = False if len(self.thread) < 1: return if self.repository.addLoops.value: self.threadLayer.loops.append(self.thread) self.thread = [] def addToPerimeters(self): 'Add the thread to the perimeters.' self.isPerimeter = False if len(self.thread) < 1: return if self.repository.addPerimeters.value: if self.isOuter: self.threadLayer.outerPerimeters.append(self.thread) else: self.threadLayer.innerPerimeters.append(self.thread) self.thread = [] def getCarvedSVG(self, fileName, gcodeText, repository): 'Parse gnu triangulated surface text and store the vectorwrite gcode.' cornerMaximum = Vector3(-987654321.0, -987654321.0, -987654321.0) cornerMinimum = Vector3(987654321.0, 987654321.0, 987654321.0) self.boundaryLoop = None self.extruderActive = False self.isLoop = False self.isOuter = False self.isPerimeter = False self.lines = archive.getTextLines(gcodeText) self.oldLocation = None self.thread = [] self.threadLayers = [] self.repository = repository self.parseInitialization() for line in self.lines[self.lineIndex :]: self.parseLine(line) self.removeEmptyLayers() for threadLayer in self.threadLayers: threadLayer.maximize(cornerMaximum) threadLayer.minimize(cornerMinimum) halfLayerThickness = 0.5 * self.layerThickness cornerMaximum.z += halfLayerThickness cornerMinimum.z -= halfLayerThickness svgWriter = SVGWriterVectorwrite( True, cornerMaximum, cornerMinimum, self.decimalPlacesCarried, self.layerThickness, self.perimeterWidth) return svgWriter.getReplacedSVGTemplate(fileName, 'vectorwrite', self.threadLayers) def getCarveLayerThickness(self): 'Get the layer thickness.' return self.layerThickness def linearMove( self, splitLine ): 'Get statistics for a linear move.' location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.extruderActive: if len(self.thread) == 0: self.thread = [ self.oldLocation.dropAxis() ] self.thread.append(location.dropAxis()) self.oldLocation = location def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '(': self.decimalPlacesCarried = int(splitLine[1]) elif firstWord == '(': self.layerThickness = float(splitLine[1]) elif firstWord == '()': return elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) def parseLine(self, line): 'Parse a gcode line and add it to the outset skein.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.linearMove(splitLine) elif firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False if self.isLoop: self.addToLoops() return if self.isPerimeter: self.addToPerimeters() return if self.repository.addPaths.value: self.threadLayer.paths.append(self.thread) self.thread = [] elif firstWord == '()': self.boundaryLoop = None elif firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) if self.boundaryLoop is None: self.boundaryLoop = [] self.threadLayer.boundaryLoops.append( self.boundaryLoop ) self.boundaryLoop.append(location.dropAxis()) elif firstWord == '(': self.addLoopLayer(float(splitLine[1])) elif firstWord == '()': self.addToLoops() elif firstWord == '(': self.isLoop = True elif firstWord == '(': self.isPerimeter = True self.isOuter = ( splitLine[1] == 'outer') elif firstWord == '()': self.addToPerimeters() def removeEmptyLayers(self): 'Remove empty layers.' for threadLayerIndex, threadLayer in enumerate(self.threadLayers): if threadLayer.getTotalNumberOfThreads() > 0: self.threadLayers = self.threadLayers[threadLayerIndex :] return def main(): 'Display the vectorwrite dialog.' if len(sys.argv) > 1: getWindowAnalyzeFile(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft.py000066400000000000000000000112551167321211700253010ustar00rootroot00000000000000""" This page is in the table of contents. Craft is a script to access the plugins which craft a gcode file. The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_profile import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addSubmenus( menu, pluginFileName, pluginFolderPath, pluginPath ): "Add a tool plugin menu." submenu = settings.Tkinter.Menu( menu, tearoff = 0 ) menu.add_cascade( label = pluginFileName.capitalize(), menu = submenu ) settings.ToolDialog().addPluginToMenu( submenu, pluginPath ) submenu.add_separator() submenuFileNames = archive.getPluginFileNamesFromDirectoryPath( pluginFolderPath ) for submenuFileName in submenuFileNames: settings.ToolDialog().addPluginToMenu( submenu, os.path.join( pluginFolderPath, submenuFileName ) ) def addToCraftMenu( menu ): "Add a craft plugin menu." settings.ToolDialog().addPluginToMenu(menu, archive.getUntilDot(archive.getSkeinforgePluginsPath('craft.py'))) menu.add_separator() directoryPath = skeinforge_craft.getPluginsDirectoryPath() directoryFolders = settings.getFolders(directoryPath) pluginFileNames = skeinforge_craft.getPluginFileNames() for pluginFileName in pluginFileNames: pluginFolderName = pluginFileName + '_plugins' pluginPath = os.path.join( directoryPath, pluginFileName ) if pluginFolderName in directoryFolders: addSubmenus( menu, pluginFileName, os.path.join( directoryPath, pluginFolderName ), pluginPath ) else: settings.ToolDialog().addPluginToMenu( menu, pluginPath ) def addToMenu( master, menu, repository, window ): "Add a tool plugin menu." CraftMenuSaveListener( menu, window ) def getNewRepository(): 'Get new repository.' return skeinforge_craft.CraftRepository() def writeOutput(fileName): "Craft a gcode file." return skeinforge_craft.writeOutput(fileName) class CraftMenuSaveListener: "A class to update a craft menu." def __init__( self, menu, window ): "Set the menu." self.menu = menu addToCraftMenu( menu ) euclidean.addElementToListDictionaryIfNotThere( self, window, settings.globalProfileSaveListenerListTable ) def save(self): "Profile has been saved and profile menu should be updated." settings.deleteMenuItems( self.menu ) addToCraftMenu( self.menu ) class CraftRadioButtonsSaveListener: "A class to update the craft radio buttons." def addToDialog( self, gridPosition ): "Add this to the dialog." euclidean.addElementToListDictionaryIfNotThere( self, self.repository.repositoryDialog, settings.globalProfileSaveListenerListTable ) self.gridPosition = gridPosition.getCopy() self.gridPosition.increment() self.gridPosition.row = gridPosition.rowStart self.setRadioButtons() def getFromRadioPlugins( self, radioPlugins, repository ): "Initialize." self.name = 'CraftRadioButtonsSaveListener' self.radioPlugins = radioPlugins self.repository = repository repository.displayEntities.append(self) return self def save(self): "Profile has been saved and craft radio plugins should be updated." self.setRadioButtons() def setRadioButtons(self): "Profile has been saved and craft radio plugins should be updated." craftSequence = skeinforge_profile.getCraftTypePluginModule().getCraftSequence() gridPosition = self.gridPosition.getCopy() maximumValue = False activeRadioPlugins = [] for radioPlugin in self.radioPlugins: if radioPlugin.name in craftSequence: activeRadioPlugins.append( radioPlugin ) radioPlugin.incrementGridPosition(gridPosition) maximumValue = max( radioPlugin.value, maximumValue ) else: radioPlugin.radiobutton.grid_remove() if not maximumValue: selectedRadioPlugin = settings.getSelectedRadioPlugin( self.repository.importantFileNames + [ activeRadioPlugins[0].name ], activeRadioPlugins ).setSelect() self.repository.pluginFrame.update() def main(): "Display the craft dialog." if len(sys.argv) > 1: settings.startMainLoopFromWindow(writeOutput(' '.join(sys.argv[1 :]))) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/000077500000000000000000000000001167321211700264645ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/__init__.py000066400000000000000000000006571167321211700306050ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/alteration.py000066400000000000000000000226571167321211700312140ustar00rootroot00000000000000#! /usr/bin/env python """ This page is in the table of contents. The alteration plugin adds the start and end files to the gcode. This plugin also removes the alteration prefix tokens from the alteration lines. Alteration lines have a prefix token so they can go through the craft plugins without being modified. However, the tokens are not recognized by the firmware so they have to be removed before export. The alteration token is: () The alteration manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Alteration ==Operation== The default 'Activate Alteration' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== Alteration looks for alteration files in the alterations folder in the .skeinforge folder in the home directory. Alteration does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder. ===Name of End File=== Default is 'end.gcode'. If there is a file with the name of the "Name of End File" setting, it will be added to the very end of the gcode. ===Name of Start File=== Default is 'start.gcode'. If there is a file with the name of the "Name of Start File" setting, it will be added to the very beginning of the gcode. ===Replace Variable with Setting=== Default: True If 'Replace Variable with Setting' is selected and there is an alteration line with a setting token, the token will be replaced by the value. For example, if there is an alteration line like: M140 S the token would be replaced with the value and assuming the bed chamber was 60.0, the output would be: M140 S60.0 ==Examples== The following examples add the alteration information to the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and alteration.py. > python alteration.py This brings up the alteration dialog. > python alteration.py Screw Holder Bottom.stl The alteration tool is parsing the file: Screw Holder Bottom.stl .. The alteration tool has created the file: .. Screw Holder Bottom_alteration.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, text='', repository=None): 'Alteration a gcode linear move text.' return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): 'Alteration a gcode linear move text.' if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'alteration'): return gcodeText if repository is None: repository = settings.getReadRepository(AlterationRepository()) if not repository.activateAlteration.value: return gcodeText return AlterationSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return AlterationRepository() def writeOutput(fileName, shouldAnalyze=True): 'Alteration a gcode linear move file. Chain alteration the gcode if the alteration procedure has not been done.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'alteration', shouldAnalyze) class AlterationRepository: "A class to handle the alteration settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.alteration.html', self ) self.baseNameSynonym = 'bookend.csv' self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Alteration', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Alteration') self.activateAlteration = settings.BooleanSetting().getFromValue('Activate Alteration', self, True) self.nameOfEndFile = settings.StringSetting().getFromValue('Name of End File:', self, 'end.gmc') self.nameOfStartFile = settings.StringSetting().getFromValue('Name of Start File:', self, 'start.gmc') self.replaceVariableWithSetting = settings.BooleanSetting().getFromValue('Replace Variable with Setting', self, True) self.executeTitle = 'Alteration' def execute(self): 'Alteration button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class AlterationSkein: "A class to alteration a skein of extrusions." def __init__(self): 'Initialize.' self.distanceFeedRate = gcodec.DistanceFeedRate() self.lineIndex = 0 self.settingDictionary = None def addFromUpperLowerFile(self, fileName): "Add lines of text from the fileName or the lowercase fileName, if there is no file by the original fileName in the directory." alterationFileLines = settings.getAlterationFileLines(fileName) self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(alterationFileLines) def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the bevel gcode." self.lines = archive.getTextLines(gcodeText) if repository.replaceVariableWithSetting.value: self.setSettingDictionary() self.addFromUpperLowerFile(repository.nameOfStartFile.value) # Add a start file if it exists. self.parseInitialization() for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.distanceFeedRate.addLine(line) self.addFromUpperLowerFile(repository.nameOfEndFile.value) # Add an end file if it exists. return self.getReplacedAlterationText() def getReplacedAlterationLine(self, alterationFileLine, searchIndex=0): 'Get the alteration file line with variables replaced with the settings.' settingIndex = alterationFileLine.find('setting.', searchIndex) beginIndex = settingIndex - 1 if beginIndex < 0: return alterationFileLine endBracketIndex = alterationFileLine.find('>', settingIndex) if alterationFileLine[beginIndex] != '<' or endBracketIndex == -1: return alterationFileLine endIndex = endBracketIndex + 1 innerToken = alterationFileLine[settingIndex + len('setting.'): endIndex].replace('>', '').replace(' ', '').replace('_', '').lower() if innerToken in self.settingDictionary: replacedSetting = self.settingDictionary[innerToken] replacedAlterationLine = alterationFileLine[: beginIndex] + replacedSetting + alterationFileLine[endIndex :] return self.getReplacedAlterationLine(replacedAlterationLine, beginIndex + len(replacedSetting)) return alterationFileLine def getReplacedAlterationText(self): 'Replace the alteration lines if there are settings.' if self.settingDictionary is None: return self.distanceFeedRate.output.getvalue().replace('()', '') lines = archive.getTextLines(self.distanceFeedRate.output.getvalue()) distanceFeedRate = gcodec.DistanceFeedRate() for line in lines: if line.startswith('()'): line = self.getReplacedAlterationLine(line[len('()') :]) distanceFeedRate.addLine(line) return distanceFeedRate.output.getvalue() def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('alteration') return self.distanceFeedRate.addLine(line) def setSettingDictionary(self): 'Set the setting dictionary from the gcode text.' for line in self.lines: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '(' and self.settingDictionary is not None: if len(splitLine) > 4: procedure = splitLine[1] name = splitLine[2].replace('_', ' ').replace(' ', '') if '(' in name: name = name[: name.find('(')] value = ' '.join(splitLine[3 : -1]) self.settingDictionary[(procedure + '.' + name).lower()] = value elif firstWord == '()': self.settingDictionary = {} elif firstWord == '()': return def main(): "Display the alteration dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/bottom.py000066400000000000000000000155151167321211700303510ustar00rootroot00000000000000#! /usr/bin/env python """ This page is in the table of contents. Bottom sets the bottom of the carving to the defined altitude. The bottom manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Bottom ==Operation== The default 'Activate Bottom' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Additional Height over Layer Thickness=== Default is half. The layers will start at the altitude plus the 'Additional Height over Layer Thickness' times the layer thickness. The default value of half means that the bottom layer is at the height of the bottom slice, because each slice is made through the middle of each layer. Raft expects the layers to start at an additional half layer thickness. You should only change 'Additional Height over Layer Thickness' if you are manipulating the skeinforge output with your own program which does not use the raft tool. ===Altitude=== Default is zero. Defines the altitude of the bottom of the model. The bottom slice has a z of the altitude plus the 'Additional Height over Layer Thickness' times the layer thickness. ===SVG Viewer=== Default is webbrowser. If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened. ==Examples== The following examples bottom the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and bottom.py. > python bottom.py This brings up the bottom dialog. > python bottom.py Screw Holder Bottom.stl The bottom tool is parsing the file: Screw Holder Bottom.stl .. The bottom tool has created the file: .. Screw Holder Bottom_bottom.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from datetime import date from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.svg_reader import SVGReader from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from fabmetheus_utilities import svg_writer from fabmetheus_utilities import xml_simple_writer from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import cStringIO import os import sys import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, svgText='', repository=None): "Bottom and convert an svg file or svgText." return getCraftedTextFromText(fileName, archive.getTextIfEmpty(fileName, svgText), repository) def getCraftedTextFromText(fileName, svgText, repository=None): "Bottom and convert an svgText." if gcodec.isProcedureDoneOrFileIsEmpty(svgText, 'bottom'): return svgText if repository is None: repository = settings.getReadRepository(BottomRepository()) if not repository.activateBottom.value: return svgText return BottomSkein().getCraftedGcode(fileName, repository, svgText) def getNewRepository(): 'Get new repository.' return BottomRepository() def writeOutput(fileName, shouldAnalyze=True): 'Bottom the carving.' skeinforge_craft.writeSVGTextWithNounMessage(fileName, BottomRepository(), shouldAnalyze) class BottomRepository: "A class to handle the bottom settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository( 'skeinforge_application.skeinforge_plugins.craft_plugins.bottom.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Bottom', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Bottom') self.activateBottom = settings.BooleanSetting().getFromValue('Activate Bottom... and dont change anything else here!!!', self, True) self.additionalHeightOverLayerThickness = settings.FloatSpin().getFromValue( 0.0, 'Additional Height (ratio):', self, 1.0, 0.5) self.altitude = settings.FloatSpin().getFromValue(-1.0, 'Altitude (mm):', self, 1.0, 0.0) self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser') self.executeTitle = 'Bottom' def execute(self): "Bottom button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class BottomSkein: "A class to bottom a skein of extrusions." def getCraftedGcode(self, fileName, repository, svgText): "Parse svgText and store the bottom svgText." svgReader = SVGReader() svgReader.parseSVG('', svgText) if svgReader.sliceDictionary is None: print('Warning, nothing will be done because the sliceDictionary could not be found getCraftedGcode in preface.') return '' decimalPlacesCarried = int(svgReader.sliceDictionary['decimalPlacesCarried']) layerThickness = float(svgReader.sliceDictionary['layerThickness']) perimeterWidth = float(svgReader.sliceDictionary['perimeterWidth']) loopLayers = svgReader.loopLayers zMinimum = 987654321.0 for loopLayer in loopLayers: zMinimum = min(loopLayer.z, zMinimum) deltaZ = repository.altitude.value + repository.additionalHeightOverLayerThickness.value * layerThickness - zMinimum for loopLayer in loopLayers: loopLayer.z += deltaZ cornerMaximum = Vector3(-912345678.0, -912345678.0, -912345678.0) cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0) svg_writer.setSVGCarvingCorners(cornerMaximum, cornerMinimum, layerThickness, loopLayers) svgWriter = svg_writer.SVGWriter( True, cornerMaximum, cornerMinimum, decimalPlacesCarried, layerThickness, perimeterWidth) commentElement = svg_writer.getCommentElement(svgReader.documentElement) procedureNameString = svgReader.sliceDictionary['procedureName'] + ',bottom' return svgWriter.getReplacedSVGTemplate(fileName, loopLayers, procedureNameString, commentElement) def main(): "Display the bottom dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/carve.py000066400000000000000000000273661167321211700301540ustar00rootroot00000000000000""" This page is in the table of contents. Carve is the most important plugin to define for your printer. It carves a shape into svg slice layers. It also sets the layer thickness and perimeter width for the rest of the tool chain. The carve manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Carve On the Arcol Blog a method of deriving the layer thickness is posted. That article "Machine Calibrating" is at: http://blog.arcol.hu/?p=157 ==Settings== ===Add Layer Template to SVG=== Default is on. When selected, the layer template will be added to the svg output, which adds javascript control boxes. So 'Add Layer Template to SVG' should be selected when the svg will be viewed in a browser. When off, no controls will be added, the svg output will only include the fabrication paths. So 'Add Layer Template to SVG' should be deselected when the svg will be used by other software, like Inkscape. ===Extra Decimal Places=== Default is two. Defines the number of extra decimal places export will output compared to the number of decimal places in the layer thickness. The higher the 'Extra Decimal Places', the more significant figures the output numbers will have. ===Import Coarseness=== Default is one. When a triangle mesh has holes in it, the triangle mesh slicer switches over to a slow algorithm that spans gaps in the mesh. The higher the 'Import Coarseness' setting, the wider the gaps in the mesh it will span. An import coarseness of one means it will span gaps of the perimeter width. ===Layer Thickness=== Default is 0.4 mm. Defines the the thickness of the layers skeinforge will cut your object into, in the z direction. This is the most important carve setting, many values in the toolchain are derived from the layer thickness. For a 0.5 mm nozzle usable values are 0.3 mm to 0.5 mm. Note; if you are using thinner layers make sure to adjust the extrusion speed as well. ===Layers=== Carve slices from bottom to top. To get a single layer, set the "Layers From" to zero and the "Layers To" to one. The 'Layers From' until 'Layers To' range is a python slice. ====Layers From==== Default is zero. Defines the index of the bottom layer that will be carved. If the 'Layers From' is the default zero, the carving will start from the lowest layer. If the 'Layers From' index is negative, then the carving will start from the 'Layers From' index below the top layer. For example if your object is 5 mm tall and your layer thicknes is 1 mm if you set layers from to 3 you will ignore the first 3 mm and start from 3 mm. ====Layers To==== Default is a huge number, which will be limited to the highest index layer. Defines the index of the top layer that will be carved. If the 'Layers To' index is a huge number like the default, the carving will go to the top of the model. If the 'Layers To' index is negative, then the carving will go to the 'Layers To' index below the top layer. This is the same as layers from, only it defines when to end the generation of gcode. ===Mesh Type=== Default is 'Correct Mesh'. ====Correct Mesh==== When selected, the mesh will be accurately carved, and if a hole is found, carve will switch over to the algorithm that spans gaps. ====Unproven Mesh==== When selected, carve will use the gap spanning algorithm from the start. The problem with the gap spanning algothm is that it will span gaps, even if there is not actually a gap in the model. ===Perimeter Width over Thickness=== Default is 1.8. Defines the ratio of the extrusion perimeter width to the layer thickness. This parameter tells skeinforge how wide the perimeter wall is expected to be in relation to the layer thickness. Default value of 1.8 for the default layer thickness of 0.4 states that a single filament perimeter wall should be 0.4 mm * 1.8 = 0.72 mm wide. The higher the value the more the perimeter will be inset. A ratio of one means the extrusion is a circle, the default ratio of 1.8 means the extrusion is a wide oval. This is an important value because if you are calibrating your machine you need to ensure that the speed of the head and the extrusion rate in combination produce a wall that is 'Layer Thickness' * 'Perimeter Width over Thickness' wide. To start with 'Perimeter Width over Thickness' is probably best left at the default of 1.8 and the extrusion rate adjusted to give the correct calculated wall thickness. Adjustment is in the 'Speed' section with 'Feed Rate' controlling speed of the head in X & Y and 'Flow Rate' controlling the extrusion rate. Initially it is probably easier to start adjusting the flow rate only a little at a time until you get a single filament of the correct width. If you change too many parameters at once you can get in a right mess. ===SVG Viewer=== Default is webbrowser. If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened. ==Examples== The following examples carve the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and carve.py. > python carve.py This brings up the carve dialog. > python carve.py Screw Holder Bottom.stl The carve tool is parsing the file: Screw Holder Bottom.stl .. The carve tool has created the file: .. Screw Holder Bottom_carve.svg """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from fabmetheus_utilities import svg_writer from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import os import sys import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, gcodeText = '', repository=None): "Get carved text." if fileName.endswith('.svg'): gcodeText = archive.getTextIfEmpty(fileName, gcodeText) if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'carve'): return gcodeText carving = svg_writer.getCarving(fileName) if carving is None: return '' if repository is None: repository = CarveRepository() settings.getReadRepository(repository) return CarveSkein().getCarvedSVG( carving, fileName, repository ) def getNewRepository(): 'Get new repository.' return CarveRepository() def writeOutput(fileName, shouldAnalyze=True): "Carve a GNU Triangulated Surface file." startTime = time.time() print('File ' + archive.getSummarizedFileName(fileName) + ' is being carved.') repository = CarveRepository() settings.getReadRepository(repository) carveGcode = getCraftedText(fileName, '', repository) if carveGcode == '': return suffixFileName = archive.getFilePathWithUnderscoredBasename(fileName, '_carve.svg') archive.writeFileText(suffixFileName, carveGcode) print('The carved file is saved as ' + archive.getSummarizedFileName(suffixFileName)) print('It took %s to carve the file.' % euclidean.getDurationString(time.time() - startTime)) if shouldAnalyze: settings.openSVGPage(suffixFileName, repository.svgViewer.value) class CarveRepository: "A class to handle the carve settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.carve.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getTranslatorFileTypeTuples(), 'Open File for Carve', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Carve') settings.LabelDisplay().getFromName('- MAIN SETTINGS for Extrusion -', self ) settings.LabelSeparator().getFromRepository(self) self.layerThickness = settings.FloatSpin().getFromValue( 0.1, 'Layer Height = Extrusion Thickness (mm):', self, 1.0, 0.4 ) self.perimeterWidthOverThickness = settings.FloatSpin().getFromValue( 0.2, 'Extrusion Width (mm):', self, 1.0, 0.6 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Layers to print -', self ) self.layersFrom = settings.IntSpin().getFromValue( 0, 'Print from Layer No::', self, 3333, 0 ) self.layersTo = settings.IntSpin().getSingleIncrementFromValue( 0, 'Print up to Layer No:', self, 912345678, 912345678 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Do not touch those below -', self ) settings.LabelSeparator().getFromRepository(self) self.meshTypeLabel = settings.LabelDisplay().getFromName('Mesh Type: ', self ) importLatentStringVar = settings.LatentStringVar() self.correctMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Correct Mesh', self, True ) self.unprovenMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Unproven Mesh', self, False ) self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser') self.addLayerTemplateToSVG = settings.BooleanSetting().getFromValue('Add Layer Template to SVG', self, True) self.extraDecimalPlaces = settings.FloatSpin().getFromValue(1.0, 'Extra Decimal Places (float):', self, 4.0, 3.0) self.importCoarseness = settings.FloatSpin().getFromValue( 0.5, 'Import Coarseness (ratio):', self, 2.0, 1.0 ) settings.LabelSeparator().getFromRepository(self) self.executeTitle = 'Carve' def execute(self): "Carve button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypes(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class CarveSkein: "A class to carve a carving." def getCarvedSVG(self, carving, fileName, repository): "Parse gnu triangulated surface text and store the carved gcode." layerThickness = repository.layerThickness.value perimeterWidth = repository.perimeterWidthOverThickness.value carving.setCarveLayerThickness(layerThickness) importRadius = 0.5 * repository.importCoarseness.value * abs(perimeterWidth) carving.setCarveImportRadius(max(importRadius, 0.01 * layerThickness)) carving.setCarveIsCorrectMesh(repository.correctMesh.value) loopLayers = carving.getCarveBoundaryLayers() if len(loopLayers) < 1: print('Warning, there are no slices for the model, this could be because the model is too small for the Layer Thickness.') return '' layerThickness = carving.getCarveLayerThickness() decimalPlacesCarried = euclidean.getDecimalPlacesCarried(repository.extraDecimalPlaces.value, layerThickness) perimeterWidth = repository.perimeterWidthOverThickness.value #todo why twice? svgWriter = svg_writer.SVGWriter( repository.addLayerTemplateToSVG.value, carving.getCarveCornerMaximum(), carving.getCarveCornerMinimum(), decimalPlacesCarried, carving.getCarveLayerThickness(), perimeterWidth) truncatedRotatedBoundaryLayers = svg_writer.getTruncatedRotatedBoundaryLayers(loopLayers, repository) return svgWriter.getReplacedSVGTemplate(fileName, truncatedRotatedBoundaryLayers, 'carve', carving.getFabmetheusXML()) def main(): "Display the carve dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/chamber.py000066400000000000000000000252551167321211700304500ustar00rootroot00000000000000""" This page is in the table of contents. Some filaments contract too much and warp the extruded object. To prevent this you have to print the object in a temperature regulated chamber and/or on a temperature regulated bed. The chamber tool allows you to control the bed and chamber temperature and the holding pressure. The chamber gcodes are also described at: http://reprap.org/wiki/Mendel_User_Manual:_RepRapGCodes The chamber manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Chamber ==Operation== The default 'Activate Chamber' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Bed Temperature=== Default is 60C. Defines the print_bed temperature in Celcius by adding an M140 command. ===Chamber Temperature=== Default is 30C. Defines the chamber temperature in Celcius by adding an M141 command. ===Holding Force=== Default is zero. Defines the holding pressure of a mechanism, like a vacuum table or electromagnet, to hold the bed surface or object, by adding an M142 command. The holding pressure is in bars. For hardware which only has on/off holding, when the holding pressure is zero, turn off holding, when the holding pressure is greater than zero, turn on holding. ==Heated Beds== ===Bothacker=== A resistor heated aluminum plate by Bothacker: http://bothacker.com with an article at: http://bothacker.com/2009/12/18/heated-build-platform/ ===Domingo=== A heated copper build plate by Domingo: http://casainho-emcrepstrap.blogspot.com/ with articles at: http://casainho-emcrepstrap.blogspot.com/2010/01/first-time-with-pla-testing-it-also-on.html http://casainho-emcrepstrap.blogspot.com/2010/01/call-for-helpideas-to-develop-heated.html http://casainho-emcrepstrap.blogspot.com/2010/01/new-heated-build-platform.html http://casainho-emcrepstrap.blogspot.com/2010/01/no-acrylic-and-instead-kapton-tape-on.html http://casainho-emcrepstrap.blogspot.com/2010/01/problems-with-heated-build-platform-and.html http://casainho-emcrepstrap.blogspot.com/2010/01/perfect-build-platform.html http://casainho-emcrepstrap.blogspot.com/2009/12/almost-no-warp.html http://casainho-emcrepstrap.blogspot.com/2009/12/heated-base-plate.html ===Jmil=== A heated build stage by jmil, over at: http://www.hive76.org with articles at: http://www.hive76.org/handling-hot-build-surfaces http://www.hive76.org/heated-build-stage-success ===Kulitorum=== Kulitorum has made a heated bed. It is a 5mm Alu sheet with a pattern laid out in kapton tape. The wire is a 0.6mm2 Konstantin wire and it's held in place by small pieces of kapton tape. The description and picture is at: http://gallery.kulitorum.com/main.php?g2_itemId=283 ===Metalab=== A heated base by the Metalab folks: http://reprap.soup.io with information at: http://reprap.soup.io/?search=heated%20base ===Nophead=== A resistor heated aluminum bed by Nophead: http://hydraraptor.blogspot.com with articles at: http://hydraraptor.blogspot.com/2010/01/will-it-stick.html http://hydraraptor.blogspot.com/2010/01/hot-metal-and-serendipity.html http://hydraraptor.blogspot.com/2010/01/new-year-new-plastic.html http://hydraraptor.blogspot.com/2010/01/hot-bed.html ===Prusajr=== A resistive wire heated plexiglass plate by prusajr: http://prusadjs.cz/ with articles at: http://prusadjs.cz/2010/01/heated-reprap-print-bed-mk2/ http://prusadjs.cz/2009/11/look-ma-no-warping-heated-reprap-print-bed/ ===Pumpernickel2=== A resistor heated aluminum plate by Pumpernickel2: http://dev.forums.reprap.org/profile.php?14,844 with a picture at: http://dev.forums.reprap.org/file.php?14,file=1228,filename=heatedplate.jpg ===Zaggo=== A resistor heated aluminum plate by Zaggo at Pleasant Software: http://pleasantsoftware.com/developer/3d/ with articles at: http://pleasantsoftware.com/developer/3d/2009/12/05/raftless/ http://pleasantsoftware.com/developer/3d/2009/11/15/living-in-times-of-warp-free-printing/ http://pleasantsoftware.com/developer/3d/2009/11/12/canned-heat/ ==Examples== The following examples chamber the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and chamber.py. > python chamber.py This brings up the chamber dialog. > python chamber.py Screw Holder Bottom.stl The chamber tool is parsing the file: Screw Holder Bottom.stl .. The chamber tool has created the file: Screw Holder Bottom_chamber.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, text='', repository=None): "Chamber the file or text." return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): "Chamber a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'chamber'): return gcodeText if repository is None: repository = settings.getReadRepository(ChamberRepository()) if not repository.activateChamber.value: return gcodeText return ChamberSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return ChamberRepository() def writeOutput(fileName, shouldAnalyze=True): "Chamber a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'chamber', shouldAnalyze) class ChamberRepository: "A class to handle the chamber settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.chamber.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Chamber', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Chamber') self.activateChamber = settings.BooleanSetting().getFromValue('Activate Chamber..if you want below functions to work', self, False ) settings.LabelSeparator().getFromRepository(self) self.bedTemperature = settings.FloatSpin().getFromValue( 20.0, 'Heated PrintBed Temperature Forced (Celcius):', self, 130.0, 60.0 ) self.nozzleTemperature = settings.FloatSpin().getFromValue( 20.0, 'Initial Extruder Nozzle Temperature Forced (Celcius):', self, 270.0, 175.0 ) settings.LabelSeparator().getFromRepository(self) self.bedTemperatureForced = settings.FloatSpin().getFromValue( 20.0, 'PrintBed Temp. Forced (Set 0 to disable):', self, 130.0, 0.0 ) self.turnBedHeaterOffAtShutDown = settings.BooleanSetting().getFromValue('Turn print Bed Heater Off at Shut Down', self, True ) self.turnExtruderHeaterOffAtShutDown = settings.BooleanSetting().getFromValue('Turn Extruder Heater Off at Shut Down ', self, True ) self.turnATXOffAtShutDown = settings.BooleanSetting().getFromValue('Turn ATX PSU Off at Shut Down ', self, False ) self.chamberTemperature = settings.FloatSpin().getFromValue( 20.0, 'Chamber Temperature (Celcius):', self, 90.0, 30.0 ) # self.holdingForce = settings.FloatSpin().getFromValue( 0.0, 'Holding Force (bar):', self, 100.0, 0.0 ) self.executeTitle = 'Chamber' def execute(self): "Chamber button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class ChamberSkein: "A class to chamber a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.lineIndex = 0 self.lines = None def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the chamber gcode." self.repository = repository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() for line in self.lines[self.lineIndex :]: self.parseLine(line) return self.distanceFeedRate.output.getvalue() def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('chamber') return self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the chamber skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == '()': self.distanceFeedRate.addLine(line) self.distanceFeedRate.addParameter('M190', self.repository.bedTemperatureForced.value ) # Set bed temperature forced. self.distanceFeedRate.addParameter('M140', self.repository.bedTemperature.value ) # Set bed temperature. self.distanceFeedRate.addParameter('M109', self.repository.nozzleTemperature.value ) # Set bed temperature. elif firstWord == '()': self.distanceFeedRate.addLine(line) if self.repository.turnExtruderHeaterOffAtShutDown.value: self.distanceFeedRate.addLine('M104 S0') # Turn extruder heater off. if self.repository.turnBedHeaterOffAtShutDown.value: self.distanceFeedRate.addLine('M140 S0') # Turn bed heater off. if self.repository.turnATXOffAtShutDown.value: self.distanceFeedRate.addLine('M81') # Turn ATX PSU off. self.distanceFeedRate.addParameter('M141', self.repository.chamberTemperature.value ) # Set chamber temperature. # self.distanceFeedRate.addParameter('M142', self.repository.holdingForce.value ) # Set holding pressure. return self.distanceFeedRate.addLine(line) def main(): "Display the chamber dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/chop.py000066400000000000000000000244411167321211700277740ustar00rootroot00000000000000""" This page is in the table of contents. Chop is a script to chop a shape into svg slice layers. ==Settings== ===Add Layer Template to SVG=== Default is on. When selected, the layer template will be added to the svg output, which adds javascript control boxes. So 'Add Layer Template to SVG' should be selected when the svg will be viewed in a browser. When off, no controls will be added, the svg output will only include the fabrication paths. So 'Add Layer Template to SVG' should be deselected when the svg will be used by other software, like Inkscape. ===Add Extra Top Layer if Necessary=== Default is on. When selected, chop will add an extra layer at the very top of the object if the top of the object is more than half the layer thickness above the first slice. This is so the cutting tool doesn't cut too deeply through the top of the object on its first pass. ===Extra Decimal Places=== Default is two. Defines the number of extra decimal places export will output compared to the number of decimal places in the layer thickness. The higher the 'Extra Decimal Places', the more significant figures the output numbers will have. ===Import Coarseness=== Default is one. When a triangle mesh has holes in it, the triangle mesh slicer switches over to a slow algorithm that spans gaps in the mesh. The higher the 'Import Coarseness' setting, the wider the gaps in the mesh it will span. An import coarseness of one means it will span gaps of the perimeter width. ===Layer Thickness=== Default is 0.4 mm. Defines the thickness of the layer, this is the most important chop setting. ===Layers=== Chop slices from top to bottom. To get only the bottom layer, set the "Layers From" to minus one. The 'Layers From' until 'Layers To' range is a python slice. ====Layers From==== Default is zero. Defines the index of the top layer that will be chopped. If the 'Layers From' is the default zero, the carving will start from the top layer. If the 'Layers From' index is negative, then the carving will start from the 'Layers From' index above the bottom layer. ====Layers To==== Default is a huge number, which will be limited to the highest index number. Defines the index of the bottom layer that will be chopped. If the 'Layers To' index is a huge number like the default, the carving will go to the bottom of the model. If the 'Layers To' index is negative, then the carving will go to the 'Layers To' index above the bottom layer. ===Mesh Type=== Default is 'Correct Mesh'. ====Correct Mesh==== When selected, the mesh will be accurately chopped, and if a hole is found, chop will switch over to the algorithm that spans gaps. ====Unproven Mesh==== When selected, chop will use the gap spanning algorithm from the start. The problem with the gap spanning algothm is that it will span gaps, even if there is not actually a gap in the model. ===Perimeter Width=== Default is 2 mm. Defines the width of the perimeter. ===SVG Viewer=== Default is webbrowser. If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened. ==Examples== The following examples chop the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and chop.py. > python chop.py This brings up the chop dialog. > python chop.py Screw Holder Bottom.stl The chop tool is parsing the file: Screw Holder Bottom.stl .. The chop tool has created the file: .. Screw Holder Bottom_chop.svg """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from fabmetheus_utilities import svg_writer from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import os import sys import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, gcodeText = '', repository=None): "Get chopped text." if fileName.endswith('.svg'): gcodeText = archive.getTextIfEmpty(fileName, gcodeText) if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'chop'): return gcodeText carving = svg_writer.getCarving(fileName) if carving is None: return '' if repository is None: repository = ChopRepository() settings.getReadRepository(repository) return ChopSkein().getCarvedSVG( carving, fileName, repository ) def getNewRepository(): 'Get new repository.' return ChopRepository() def writeOutput(fileName, shouldAnalyze=True): "Chop a GNU Triangulated Surface file. If no fileName is specified, chop the first GNU Triangulated Surface file in this folder." startTime = time.time() print('File ' + archive.getSummarizedFileName(fileName) + ' is being chopped.') repository = ChopRepository() settings.getReadRepository(repository) chopGcode = getCraftedText( fileName, '', repository ) if chopGcode == '': return suffixFileName = fileName[ : fileName.rfind('.') ] + '_chop.svg' suffixDirectoryName = os.path.dirname(suffixFileName) suffixReplacedBaseName = os.path.basename(suffixFileName).replace(' ', '_') suffixFileName = os.path.join( suffixDirectoryName, suffixReplacedBaseName ) archive.writeFileText( suffixFileName, chopGcode ) print('The chopped file is saved as ' + archive.getSummarizedFileName(suffixFileName) ) print('It took %s to chop the file.' % euclidean.getDurationString( time.time() - startTime ) ) if shouldAnalyze: settings.openSVGPage( suffixFileName, repository.svgViewer.value ) class ChopRepository: "A class to handle the chop settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.chop.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getTranslatorFileTypeTuples(), 'Open File to be Chopped', self, '') self.addExtraTopLayerIfNecessary = settings.BooleanSetting().getFromValue('Add Extra Top Layer if Necessary', self, True ) self.addLayerTemplateToSVG = settings.BooleanSetting().getFromValue('Add Layer Template to SVG', self, True) self.extraDecimalPlaces = settings.FloatSpin().getFromValue(0.0, 'Extra Decimal Places (float):', self, 3.0, 2.0) self.importCoarseness = settings.FloatSpin().getFromValue( 0.5, 'Import Coarseness (ratio):', self, 2.0, 1.0 ) self.layerThickness = settings.FloatSpin().getFromValue( 0.1, 'Layer Thickness (mm):', self, 1.0, 0.4 ) self.layersFrom = settings.IntSpin().getFromValue( 0, 'Layers From (index):', self, 20, 0 ) self.layersTo = settings.IntSpin().getSingleIncrementFromValue( 0, 'Layers To (index):', self, 912345678, 912345678 ) self.meshTypeLabel = settings.LabelDisplay().getFromName('Mesh Type: ', self, ) importLatentStringVar = settings.LatentStringVar() self.correctMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Correct Mesh', self, True ) self.unprovenMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Unproven Mesh', self, False ) self.perimeterWidth = settings.FloatSpin().getFromValue( 0.4, 'Perimeter Width (mm):', self, 4.0, 2.0 ) self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser') settings.LabelSeparator().getFromRepository(self) self.executeTitle = 'Chop' def execute(self): "Chop button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypes(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class ChopSkein: "A class to chop a carving." def addExtraTopLayerIfNecessary( self, carving, layerThickness, loopLayers ): "Add extra top layer if necessary." topRotatedBoundaryLayer = loopLayers[-1] cuttingSafeHeight = topRotatedBoundaryLayer.z + 0.5001 * layerThickness if cuttingSafeHeight > carving.getCarveCornerMaximum().z: return extraTopRotatedBoundaryLayer = topRotatedBoundaryLayer.getCopyAtZ( topRotatedBoundaryLayer.z + layerThickness ) loopLayers.append( extraTopRotatedBoundaryLayer ) def getCarvedSVG( self, carving, fileName, repository ): "Parse gnu triangulated surface text and store the chopped gcode." layerThickness = repository.layerThickness.value perimeterWidth = repository.perimeterWidth.value carving.setCarveLayerThickness( layerThickness ) importRadius = 0.5 * repository.importCoarseness.value * abs( perimeterWidth ) carving.setCarveImportRadius( max( importRadius, 0.01 * layerThickness ) ) carving.setCarveIsCorrectMesh( repository.correctMesh.value ) loopLayers = carving.getCarveBoundaryLayers() if len( loopLayers ) < 1: print('Warning, there are no slices for the model, this could be because the model is too small for the Layer Thickness.') return '' if repository.addExtraTopLayerIfNecessary.value: self.addExtraTopLayerIfNecessary( carving, layerThickness, loopLayers ) loopLayers.reverse() layerThickness = carving.getCarveLayerThickness() decimalPlacesCarried = euclidean.getDecimalPlacesCarried(repository.extraDecimalPlaces.value, layerThickness) svgWriter = svg_writer.SVGWriter( repository.addLayerTemplateToSVG.value, carving.getCarveCornerMaximum(), carving.getCarveCornerMinimum(), decimalPlacesCarried, carving.getCarveLayerThickness(), perimeterWidth) truncatedRotatedBoundaryLayers = svg_writer.getTruncatedRotatedBoundaryLayers(loopLayers, repository) return svgWriter.getReplacedSVGTemplate( fileName, truncatedRotatedBoundaryLayers, 'chop', carving.getFabmetheusXML()) def main(): "Display the chop dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/cleave.py000066400000000000000000000223561167321211700303050ustar00rootroot00000000000000""" This page is in the table of contents. Cleave is a script to cleave a shape into svg slice layers. ==Settings== ===Add Layer Template to SVG=== Default is on. When selected, the layer template will be added to the svg output, which adds javascript control boxes. So 'Add Layer Template to SVG' should be selected when the svg will be viewed in a browser. When off, no controls will be added, the svg output will only include the fabrication paths. So 'Add Layer Template to SVG' should be deselected when the svg will be used by other software, like Inkscape. ===Extra Decimal Places=== Default is two. Defines the number of extra decimal places export will output compared to the number of decimal places in the layer thickness. The higher the 'Extra Decimal Places', the more significant figures the output numbers will have. ===Import Coarseness=== Default is one. When a triangle mesh has holes in it, the triangle mesh slicer switches over to a slow algorithm that spans gaps in the mesh. The higher the 'Import Coarseness' setting, the wider the gaps in the mesh it will span. An import coarseness of one means it will span gaps of the perimeter width. ===Layer Thickness=== Default is 0.4 mm. Defines the thickness of the layer, this is the most important cleave setting. ===Layers=== Cleave slices from bottom to top. To get a single layer, set the "Layers From" to zero and the "Layers To" to one. The layer from until layer to range is a python slice. ====Layers From==== Default is zero. Defines the index of the bottom layer that will be cleaved. If the layer from is the default zero, the carving will start from the lowest layer. If the 'Layers From' index is negative, then the carving will start from the 'Layers From' index below the top layer. ====Layers To==== Default is a huge number, which will be limited to the highest index layer. Defines the index of the top layer that will be cleaved. If the 'Layers To' index is a huge number like the default, the carving will go to the top of the model. If the 'Layers To' index is negative, then the carving will go to the 'Layers To' index below the top layer. ===Mesh Type=== Default is 'Correct Mesh'. ====Correct Mesh==== When selected, the mesh will be accurately cleaved, and if a hole is found, cleave will switch over to the algorithm that spans gaps. ====Unproven Mesh==== When selected, cleave will use the gap spanning algorithm from the start. The problem with the gap spanning algothm is that it will span gaps, even if there is not actually a gap in the model. ===Perimeter Width=== Default is two millimeters. Defines the width of the perimeter. ===SVG Viewer=== Default is webbrowser. If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened. ==Examples== The following examples cleave the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and cleave.py. > python cleave.py This brings up the cleave dialog. > python cleave.py Screw Holder Bottom.stl The cleave tool is parsing the file: Screw Holder Bottom.stl .. The cleave tool has created the file: .. Screw Holder Bottom_cleave.svg """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from fabmetheus_utilities import svg_writer from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import os import sys import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, gcodeText = '', repository=None): "Get cleaved text." if fileName.endswith('.svg'): gcodeText = archive.getTextIfEmpty(fileName, gcodeText) if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'cleave'): return gcodeText carving = svg_writer.getCarving(fileName) if carving is None: return '' if repository is None: repository = CleaveRepository() settings.getReadRepository(repository) return CleaveSkein().getCarvedSVG( carving, fileName, repository ) def getNewRepository(): 'Get new repository.' return CleaveRepository() def writeOutput(fileName, shouldAnalyze=True): "Cleave a GNU Triangulated Surface file." startTime = time.time() print('File ' + archive.getSummarizedFileName(fileName) + ' is being cleaved.') repository = CleaveRepository() settings.getReadRepository(repository) cleaveGcode = getCraftedText( fileName, '', repository ) if cleaveGcode == '': return suffixFileName = fileName[ : fileName.rfind('.') ] + '_cleave.svg' suffixDirectoryName = os.path.dirname(suffixFileName) suffixReplacedBaseName = os.path.basename(suffixFileName).replace(' ', '_') suffixFileName = os.path.join( suffixDirectoryName, suffixReplacedBaseName ) archive.writeFileText( suffixFileName, cleaveGcode ) print('The cleaved file is saved as ' + archive.getSummarizedFileName(suffixFileName) ) print('It took %s to cleave the file.' % euclidean.getDurationString( time.time() - startTime ) ) if shouldAnalyze: settings.openSVGPage( suffixFileName, repository.svgViewer.value ) class CleaveRepository: "A class to handle the cleave settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.cleave.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getTranslatorFileTypeTuples(), 'Open File to be Cleaved', self, '') self.addLayerTemplateToSVG = settings.BooleanSetting().getFromValue('Add Layer Template to SVG', self, True) self.extraDecimalPlaces = settings.FloatSpin().getFromValue(0.0, 'Extra Decimal Places (float):', self, 3.0, 2.0) self.importCoarseness = settings.FloatSpin().getFromValue( 0.5, 'Import Coarseness (ratio):', self, 2.0, 1.0 ) self.layerThickness = settings.FloatSpin().getFromValue( 0.1, 'Layer Thickness (mm):', self, 1.0, 0.4 ) self.layersFrom = settings.IntSpin().getFromValue( 0, 'Layers From (index):', self, 20, 0 ) self.layersTo = settings.IntSpin().getSingleIncrementFromValue( 0, 'Layers To (index):', self, 912345678, 912345678 ) self.meshTypeLabel = settings.LabelDisplay().getFromName('Mesh Type: ', self, ) importLatentStringVar = settings.LatentStringVar() self.correctMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Correct Mesh', self, True ) self.unprovenMesh = settings.Radio().getFromRadio( importLatentStringVar, 'Unproven Mesh', self, False ) self.perimeterWidth = settings.FloatSpin().getFromValue( 0.4, 'Perimeter Width (mm):', self, 4.0, 2.0 ) self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser') settings.LabelSeparator().getFromRepository(self) self.executeTitle = 'Cleave' def execute(self): "Cleave button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypes(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class CleaveSkein: "A class to cleave a carving." def getCarvedSVG( self, carving, fileName, repository ): "Parse gnu triangulated surface text and store the cleaved gcode." layerThickness = repository.layerThickness.value perimeterWidth = repository.perimeterWidth.value carving.setCarveLayerThickness( layerThickness ) importRadius = 0.5 * repository.importCoarseness.value * abs( perimeterWidth ) carving.setCarveImportRadius( max( importRadius, 0.01 * layerThickness ) ) carving.setCarveIsCorrectMesh( repository.correctMesh.value ) loopLayers = carving.getCarveBoundaryLayers() if len( loopLayers ) < 1: print('Warning, there are no slices for the model, this could be because the model is too small for the Layer Thickness.') return '' layerThickness = carving.getCarveLayerThickness() decimalPlacesCarried = euclidean.getDecimalPlacesCarried(repository.extraDecimalPlaces.value, layerThickness) svgWriter = svg_writer.SVGWriter( repository.addLayerTemplateToSVG.value, carving.getCarveCornerMaximum(), carving.getCarveCornerMinimum(), decimalPlacesCarried, carving.getCarveLayerThickness(), perimeterWidth) truncatedRotatedBoundaryLayers = svg_writer.getTruncatedRotatedBoundaryLayers(loopLayers, repository) return svgWriter.getReplacedSVGTemplate( fileName, truncatedRotatedBoundaryLayers, 'cleave', carving.getFabmetheusXML()) def main(): "Display the cleave dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/clip.py000066400000000000000000000341331167321211700277710ustar00rootroot00000000000000""" This page is in the table of contents. The clip plugin clips the loop ends to prevent bumps from forming, and connects loops. The clip manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Clip ==Operation== The default 'Activate Clip' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Clip Over Perimeter Width=== Default is 0.2. Defines the ratio of the amount each end of the loop is clipped over the perimeter width. The total gap will therefore be twice the clip. If the ratio is too high loops will have a gap, if the ratio is too low there will be a bulge at the loop ends. This setting will affect the output of clip, and the output of the skin. In skin the half width perimeters will be clipped by according to this setting. ===Maximum Connection Distance Over Perimeter Width=== Default is ten. Defines the ratio of the maximum connection distance between loops over the perimeter width. Clip will attempt to connect loops that end close to each other, combining them into a spiral, so that the extruder does not stop and restart. This setting sets the maximum gap size to connect. This feature can reduce the amount of extra material or gaps formed at the loop end. Setting this to zero disables this feature, preventing the loops from being connected. ==Examples== The following examples clip the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and clip.py. > python clip.py This brings up the clip dialog. > python clip.py Screw Holder Bottom.stl The clip tool is parsing the file: Screw Holder Bottom.stl .. The clip tool has created the file: .. Screw Holder Bottom_clip.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, clipRepository = None ): "Clip a gcode linear move file or text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), clipRepository ) def getCraftedTextFromText( gcodeText, clipRepository = None ): "Clip a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'clip'): return gcodeText if clipRepository is None: clipRepository = settings.getReadRepository( ClipRepository() ) if not clipRepository.activateClip.value: return gcodeText return ClipSkein().getCraftedGcode( clipRepository, gcodeText ) def getNewRepository(): 'Get new repository.' return ClipRepository() def writeOutput(fileName, shouldAnalyze=True): "Clip a gcode linear move file. Chain clip the gcode if it is not already clipped." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'clip', shouldAnalyze) class ClipRepository: "A class to handle the clip settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.clip.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Clip', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Clip') self.activateClip = settings.BooleanSetting().getFromValue('Activate Clip..to clip the extrusion that overlaps when printing perimeters', self, True ) settings.LabelSeparator().getFromRepository(self) self.clipOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.5, 'Clip Over Perimeter Width adjuster (increase for bigger gap):', self, 1.5, 1.0 ) self.maximumConnectionDistanceOverPerimeterWidth = settings.FloatSpin().getFromValue( 1.0, 'Threshold for connecting inner loops (ratio):', self, 10.0, 2.5 ) self.executeTitle = 'Clip' def execute(self): "Clip button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class ClipSkein: "A class to clip a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.feedRateMinute = None self.isLoop = False self.isPerimeter = False self.layerCount = settings.LayerCount() self.loopPath = None self.lineIndex = 0 self.oldConnectionPoint = None self.oldLocation = None self.oldWiddershins = None self.travelFeedRateMinute = None def addGcodeFromThreadZ( self, thread, z ): "Add a gcode thread to the output." if len(thread) > 0: self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.travelFeedRateMinute, thread[0], z ) else: print( "zero length vertex positions array which was skipped over, this should never happen" ) if len(thread) < 2: print( "thread of only one point in clip, this should never happen" ) print(thread) return self.distanceFeedRate.addLine('M101') for point in thread[1 :]: self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.feedRateMinute, point, z ) def addSegmentToPixelTables(self, location, oldLocation): "Add the segment to the layer and mask table." euclidean.addValueSegmentToPixelTable(oldLocation, location, self.layerPixelTable, None, self.layerPixelWidth) def addTailoredLoopPath(self, line): "Add a clipped loop path." if self.clipLength > 0.0: removeTable = {} euclidean.addLoopToPixelTable(self.loopPath.path, removeTable, self.layerPixelWidth) euclidean.removePixelTableFromPixelTable( removeTable, self.layerPixelTable ) self.loopPath.path = euclidean.getClippedSimplifiedLoopPath(self.clipLength, self.loopPath.path, self.perimeterWidth) euclidean.addLoopToPixelTable( self.loopPath.path, self.layerPixelTable, self.layerPixelWidth ) if self.oldWiddershins is None: self.addGcodeFromThreadZ( self.loopPath.path, self.loopPath.z ) else: if self.oldWiddershins != euclidean.isWiddershins( self.loopPath.path ): self.loopPath.path.reverse() for point in self.loopPath.path: self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.feedRateMinute, point, self.loopPath.z ) if self.getNextThreadIsACloseLoop(self.loopPath.path): self.oldConnectionPoint = self.loopPath.path[-1] self.oldWiddershins = euclidean.isWiddershins(self.loopPath.path) else: self.oldConnectionPoint = None self.oldWiddershins = None self.distanceFeedRate.addLine(line) self.loopPath = None def getConnectionIsCloseWithoutOverlap( self, location, path ): "Determine if the connection is close enough and does not overlap another thread." if len(path) < 1: return False locationComplex = location.dropAxis() segment = locationComplex - path[-1] segmentLength = abs(segment) if segmentLength <= 0.0: return True if segmentLength > self.maximumConnectionDistance: return False segmentTable = {} euclidean.addSegmentToPixelTable( path[-1], locationComplex, segmentTable, 2.0, 2.0, self.layerPixelWidth ) if euclidean.isPixelTableIntersecting( self.layerPixelTable, segmentTable, {} ): return False euclidean.addValueSegmentToPixelTable( path[-1], locationComplex, self.layerPixelTable, None, self.layerPixelWidth ) return True def getCraftedGcode( self, clipRepository, gcodeText ): "Parse gcode text and store the clip gcode." self.lines = archive.getTextLines(gcodeText) self.parseInitialization( clipRepository ) for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getNextThreadIsACloseLoop(self, path): "Determine if the next thread is a loop." if self.oldLocation is None or self.maximumConnectionDistance <= 0.0: return False isLoop = False isPerimeter = False location = self.oldLocation for afterIndex in xrange(self.lineIndex + 1, len(self.lines)): line = self.lines[afterIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) elif firstWord == '(': isLoop = True elif firstWord == '(': isPerimeter = True elif firstWord == 'M101': if isLoop != self.isLoop or isPerimeter != self.isPerimeter: return False return self.getConnectionIsCloseWithoutOverlap(location, path) elif firstWord == '(': return False return False def isNextExtruderOn(self): "Determine if there is an extruder on command before a move command." for afterIndex in xrange(self.lineIndex + 1, len(self.lines)): line = self.lines[afterIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1' or firstWord == 'M103': return False elif firstWord == 'M101': return True return False def linearMove(self, splitLine): "Add to loop path if this is a loop or path." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) if self.isLoop or self.isPerimeter: if self.isNextExtruderOn(): self.loopPath = euclidean.PathZ(location.z) if self.loopPath is None: if self.extruderActive: self.oldWiddershins = None else: if self.oldConnectionPoint is not None: self.addSegmentToPixelTables(self.oldConnectionPoint, location.dropAxis()) self.oldConnectionPoint = None self.loopPath.path.append(location.dropAxis()) self.oldLocation = location def parseInitialization(self, clipRepository): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('clip') return elif firstWord == '(': self.distanceFeedRate.addTagBracketedLine('clipOverPerimeterWidth', clipRepository.clipOverPerimeterWidth.value) self.perimeterWidth = float(splitLine[1]) absolutePerimeterWidth = abs(self.perimeterWidth) self.clipLength = clipRepository.clipOverPerimeterWidth.value* self.perimeterWidth * (euclidean.globalQuarterPi/2) self.connectingStepLength = 0.5 * absolutePerimeterWidth self.layerPixelWidth = 0.24321 * absolutePerimeterWidth #todo check whether 1-0.25pi self.maximumConnectionDistance = clipRepository.maximumConnectionDistanceOverPerimeterWidth.value * absolutePerimeterWidth elif firstWord == '(': self.travelFeedRateMinute = 60.0 * float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the clip skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.linearMove(splitLine) elif firstWord == '(': self.setLayerPixelTable() elif firstWord == '(': self.isLoop = True elif firstWord == '()': self.isLoop = False elif firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False if self.loopPath is not None: self.addTailoredLoopPath(line) return elif firstWord == '(': self.isPerimeter = True elif firstWord == '()': self.isPerimeter = False if self.loopPath is None: self.distanceFeedRate.addLine(line) def setLayerPixelTable(self): "Set the layer pixel table." self.layerCount.printProgressIncrement('clip') boundaryLoop = None extruderActive = False self.lastInactiveLocation = None self.layerPixelTable = {} oldLocation = self.oldLocation for afterIndex in xrange(self.lineIndex + 1, len(self.lines)): line = self.lines[ afterIndex ] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(oldLocation, splitLine) if extruderActive and oldLocation is not None: self.addSegmentToPixelTables(location.dropAxis(), oldLocation.dropAxis()) if extruderActive: if self.lastInactiveLocation is not None: self.addSegmentToPixelTables(self.lastInactiveLocation.dropAxis(), location.dropAxis()) self.lastInactiveLocation = None else: self.lastInactiveLocation = location oldLocation = location elif firstWord == 'M101': extruderActive = True elif firstWord == 'M103': extruderActive = False elif firstWord == '()': euclidean.addLoopToPixelTable(boundaryLoop, self.layerPixelTable, self.layerPixelWidth) boundaryLoop = None elif firstWord == '(': if boundaryLoop is None: boundaryLoop = [] location = gcodec.getLocationFromSplitLine(None, splitLine) boundaryLoop.append(location.dropAxis()) elif firstWord == '()': return def main(): "Display the clip dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/coil.py000066400000000000000000000234751167321211700277770ustar00rootroot00000000000000""" This page is in the table of contents. Coil is a script to coil wire or filament around an object. ==Operation== The default 'Activate Coil' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Minimum Tool Distance=== Default is twenty millimeters. Defines the minimum distance between the wire dispenser and the object. The 'Minimum Tool Distance' should be set to the maximum radius of the wire dispenser, times at least 1.3 to get a reasonable safety margin. ==Examples== The following examples coil the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and coil.py. > python coil.py This brings up the coil dialog. > python coil.py Screw Holder Bottom.stl The coil tool is parsing the file: Screw Holder Bottom.stl .. The coil tool has created the file: Screw Holder Bottom_coil.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, gcodeText = '', repository=None): "Coil the file or gcodeText." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), repository ) def getCraftedTextFromText(gcodeText, repository=None): "Coil a gcode linear move gcodeText." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'coil'): return gcodeText if repository is None: repository = settings.getReadRepository( CoilRepository() ) if not repository.activateCoil.value: return gcodeText return CoilSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return CoilRepository() def writeOutput(fileName, shouldAnalyze=True): "Coil a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'coil', shouldAnalyze) class CoilRepository: "A class to handle the coil settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.coil.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Coil', self, '') self.activateCoil = settings.BooleanSetting().getFromValue('Activate Coil', self, True ) self.minimumToolDistance = settings.FloatSpin().getFromValue( 10.0, 'Minimum Tool Distance (millimeters):', self, 50.0, 20.0 ) self.executeTitle = 'Coil' def execute(self): "Coil button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class CoilSkein: "A class to coil a skein of extrusions." def __init__(self): self.boundaryLayers = [] self.distanceFeedRate = gcodec.DistanceFeedRate() self.lineIndex = 0 self.lines = None self.oldLocationComplex = complex() self.perimeterWidth = 0.6 self.shutdownLines = [] def addCoilLayer( self, boundaryLayers, radius, z ): "Add a coil layer." self.distanceFeedRate.addLine('( %s )' % z ) # Indicate that a new layer is starting. self.distanceFeedRate.addLine('()') thread = [] for boundaryLayerIndex in xrange(1, len(boundaryLayers) - 1): boundaryLayer = boundaryLayers[boundaryLayerIndex] boundaryLayerBegin = boundaryLayers[boundaryLayerIndex - 1] boundaryLayerEnd = boundaryLayers[boundaryLayerIndex + 1] beginLocation = Vector3(0.0, 0.0, 0.5 * (boundaryLayerBegin.z + boundaryLayer.z)) outsetLoop = intercircle.getLargestInsetLoopFromLoop(boundaryLayer.loops[0], - radius) self.addCoilToThread(beginLocation, 0.5 * (boundaryLayer.z + boundaryLayerEnd.z), outsetLoop, thread) self.addGcodeFromThread(thread) self.distanceFeedRate.addLine('()') self.distanceFeedRate.addLine('()') def addCoilLayers(self): "Add the coil layers." numberOfLayersFloat = round( self.perimeterWidth / self.layerThickness ) numberOfLayers = int( numberOfLayersFloat ) halfLayerThickness = 0.5 * self.layerThickness startOutset = self.repository.minimumToolDistance.value + halfLayerThickness startZ = self.boundaryLayers[0].z + halfLayerThickness zRange = self.boundaryLayers[-1].z - self.boundaryLayers[0].z zIncrement = 0.0 if zRange >= 0.0: zIncrement = zRange / numberOfLayersFloat for layerIndex in xrange( numberOfLayers ): settings.printProgressByNumber(layerIndex, numberOfLayers, 'coil') boundaryLayers = self.boundaryLayers if layerIndex % 2 == 1: boundaryLayers = self.boundaryReverseLayers radius = startOutset + layerIndex * self.layerThickness z = startZ + layerIndex * zIncrement self.addCoilLayer( boundaryLayers, radius, z ) def addCoilToThread(self, beginLocation, endZ, loop, thread): "Add a coil to the thread." if len(loop) < 1: return loop = euclidean.getLoopStartingClosest(self.halfPerimeterWidth, self.oldLocationComplex, loop) length = euclidean.getLoopLength(loop) if length <= 0.0: return oldPoint = loop[0] pathLength = 0.0 for point in loop[1 :]: pathLength += abs(point - oldPoint) along = pathLength / length z = (1.0 - along) * beginLocation.z + along * endZ location = Vector3(point.real, point.imag, z) thread.append(location) oldPoint = point self.oldLocationComplex = loop[-1] def addGcodeFromThread( self, thread ): "Add a thread to the output." if len(thread) > 0: firstLocation = thread[0] self.distanceFeedRate.addGcodeMovementZ( firstLocation.dropAxis(), firstLocation.z ) else: print( "zero length vertex positions array which was skipped over, this should never happen" ) if len(thread) < 2: print( "thread of only one point in addGcodeFromThread in coil, this should never happen" ) print(thread) return self.distanceFeedRate.addLine('M101') # Turn extruder on. for location in thread[1 :]: self.distanceFeedRate.addGcodeMovementZ( location.dropAxis(), location.z ) self.distanceFeedRate.addLine('M103') # Turn extruder off. def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the coil gcode." self.repository = repository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() self.parseBoundaries() self.parseUntilLayer() self.addCoilLayers() self.distanceFeedRate.addLines( self.shutdownLines ) return self.distanceFeedRate.output.getvalue() def parseBoundaries(self): "Parse the boundaries and add them to the boundary layers." boundaryLoop = None boundaryLayer = None for line in self.lines[self.lineIndex :]: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if len( self.shutdownLines ) > 0: self.shutdownLines.append(line) if firstWord == '()': boundaryLoop = None elif firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) if boundaryLoop is None: boundaryLoop = [] boundaryLayer.loops.append(boundaryLoop) boundaryLoop.append(location.dropAxis()) elif firstWord == '(': boundaryLayer = euclidean.LoopLayer(float(splitLine[1])) self.boundaryLayers.append(boundaryLayer) elif firstWord == '()': self.shutdownLines = [ line ] for boundaryLayer in self.boundaryLayers: if not euclidean.isWiddershins( boundaryLayer.loops[0] ): boundaryLayer.loops[0].reverse() self.boundaryReverseLayers = self.boundaryLayers[:] self.boundaryReverseLayers.reverse() def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('coil') return elif firstWord == '(': self.layerThickness = float(splitLine[1]) elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.halfPerimeterWidth = 0.5 * self.perimeterWidth self.distanceFeedRate.addLine(line) def parseUntilLayer(self): "Parse until the layer line and add it to the coil skein." for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '(': return self.distanceFeedRate.addLine(line) def main(): "Display the coil dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/comb.py000066400000000000000000000402001167321211700277520ustar00rootroot00000000000000""" This page is in the table of contents. Comb is a craft tool to comb the extrusion hair of a gcode file. The comb manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Comb Comb bends the extruder travel paths around holes in the slices, to avoid stringers. It moves the extruder to the inside of perimeters before turning the extruder on so any start up ooze will be inside the shape. ==Operation== The default 'Activate Comb' checkbox is off. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Running Jump Space=== Placeholder. ==Examples== The following examples comb the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and comb.py. > python comb.py This brings up the comb dialog. > python comb.py Screw Holder Bottom.stl The comb tool is parsing the file: Screw Holder Bottom.stl .. The comb tool has created the file: .. Screw Holder Bottom_comb.gcode """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, combRepository = None ): "Comb a gcode linear move text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), combRepository ) def getCraftedTextFromText( gcodeText, combRepository = None ): "Comb a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'comb'): return gcodeText if combRepository is None: combRepository = settings.getReadRepository( CombRepository() ) if not combRepository.activateComb.value: return gcodeText return CombSkein().getCraftedGcode( combRepository, gcodeText ) def getInsideness(path, loop): "Get portion of the path which is inside the loop." if len(path) < 2: return 0.0 pathLength = euclidean.getPathLength(path) if pathLength <= 0.0: return 0.0 incrementRatio = 0.017 increment = incrementRatio * pathLength oldPoint = path[0] numberOfPointsInside = float(euclidean.isPointInsideLoop(loop, oldPoint)) for point in path[1 :]: segment = point - oldPoint distance = abs(segment) numberOfPosts = int(math.ceil(distance / increment)) if numberOfPosts > 0: segmentIncrement = segment / float(numberOfPosts) for post in xrange(numberOfPosts): postPoint = oldPoint + float(post) * segmentIncrement numberOfPointsInside += float(euclidean.isPointInsideLoop(loop, postPoint)) oldPoint = point return incrementRatio * numberOfPointsInside def getNewRepository(): 'Get new repository.' return CombRepository() def getPathsByIntersectedLoop( begin, end, loop ): "Get both paths along the loop from the point closest to the begin to the point closest to the end." closestBeginDistanceIndex = euclidean.getClosestDistanceIndexToLine( begin, loop ) closestEndDistanceIndex = euclidean.getClosestDistanceIndexToLine( end, loop ) beginIndex = ( closestBeginDistanceIndex.index + 1 ) % len(loop) endIndex = ( closestEndDistanceIndex.index + 1 ) % len(loop) closestBegin = euclidean.getClosestPointOnSegment( loop[ closestBeginDistanceIndex.index ], loop[ beginIndex ], begin ) closestEnd = euclidean.getClosestPointOnSegment( loop[ closestEndDistanceIndex.index ], loop[ endIndex ], end ) clockwisePath = [ closestBegin ] widdershinsPath = [ closestBegin ] if closestBeginDistanceIndex.index != closestEndDistanceIndex.index: widdershinsPath += euclidean.getAroundLoop( beginIndex, endIndex, loop ) clockwisePath += euclidean.getAroundLoop( endIndex, beginIndex, loop )[: : -1] clockwisePath.append( closestEnd ) widdershinsPath.append( closestEnd ) return [ clockwisePath, widdershinsPath ] def writeOutput(fileName, shouldAnalyze=True): "Comb a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'comb', shouldAnalyze) class CombRepository: "A class to handle the comb settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.comb.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Comb', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Comb') self.activateComb = settings.BooleanSetting().getFromValue('Activate Comb', self, False ) self.executeTitle = 'Comb' def execute(self): "Comb button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class CombSkein: "A class to comb a skein of extrusions." def __init__(self): 'Initialize' self.betweenTable = {} self.boundaryLoop = None self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.layer = None self.layerCount = settings.LayerCount() self.layerTable = {} self.layerZ = None self.lineIndex = 0 self.lines = None self.nextLayerZ = None self.oldLocation = None self.oldZ = None self.operatingFeedRatePerMinute = None self.travelFeedRateMinute = None def addGcodePathZ( self, feedRateMinute, path, z ): "Add a gcode path, without modifying the extruder, to the output." for point in path: self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedRateMinute, point, z) def addIfTravel( self, splitLine ): "Add travel move around loops if the extruder is off." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if not self.extruderActive and self.oldLocation is not None: if len( self.getBoundaries() ) > 0: highestZ = max( location.z, self.oldLocation.z ) self.addGcodePathZ( self.travelFeedRateMinute, self.getPathsBetween( self.oldLocation.dropAxis(), location.dropAxis() ), highestZ ) self.oldLocation = location def addToLoop(self, location): "Add a location to loop." if self.layer is None: if not self.oldZ in self.layerTable: self.layerTable[ self.oldZ ] = [] self.layer = self.layerTable[ self.oldZ ] if self.boundaryLoop is None: self.boundaryLoop = [] #starting with an empty array because a closed loop does not have to restate its beginning self.layer.append( self.boundaryLoop ) if self.boundaryLoop is not None: self.boundaryLoop.append(location.dropAxis()) def getBetweens(self): "Set betweens for the layer." if self.layerZ in self.betweenTable: return self.betweenTable[ self.layerZ ] if self.layerZ not in self.layerTable: return [] self.betweenTable[ self.layerZ ] = [] for boundaryLoop in self.layerTable[ self.layerZ ]: self.betweenTable[ self.layerZ ] += intercircle.getInsetLoopsFromLoop(boundaryLoop, self.betweenInset) return self.betweenTable[ self.layerZ ] def getBoundaries(self): "Get boundaries for the layer." if self.layerZ in self.layerTable: return self.layerTable[ self.layerZ ] return [] def getCraftedGcode( self, combRepository, gcodeText ): "Parse gcode text and store the comb gcode." self.combRepository = combRepository self.lines = archive.getTextLines(gcodeText) self.parseInitialization( combRepository ) for lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[lineIndex] self.parseBoundariesLayers( combRepository, line ) for lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[lineIndex] self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getIsAsFarAndNotIntersecting( self, begin, end ): "Determine if the point on the line is at least as far from the loop as the center point." if begin == end: print('this should never happen but it does not really matter, begin == end in getIsAsFarAndNotIntersecting in comb.') print(begin) return True return not euclidean.isLineIntersectingLoops( self.getBetweens(), begin, end ) def getIsRunningJumpPathAdded( self, betweens, end, lastPoint, closestEndMinusLastSegment, pathAround, penultimatePoint, runningJumpSpace ): "Add a running jump path if possible, and return if it was added." jumpStartPoint = lastPoint - closestEndMinusLastSegment * runningJumpSpace if euclidean.isLineIntersectingLoops( betweens, penultimatePoint, jumpStartPoint ): return False pathAround[-1] = jumpStartPoint return True def getPathBetween(self, loop, points): "Add a path between the perimeter and the fill." paths = getPathsByIntersectedLoop(points[1], points[2], loop) shortestPath = paths[int(euclidean.getPathLength(paths[1]) < euclidean.getPathLength(paths[0]))] if len(shortestPath) < 2: return shortestPath if abs(points[1] - shortestPath[0]) > abs(points[1] - shortestPath[-1]): shortestPath.reverse() loopWiddershins = euclidean.isWiddershins(loop) pathBetween = [] for pointIndex in xrange(len(shortestPath)): center = shortestPath[pointIndex] centerPerpendicular = None beginIndex = pointIndex - 1 if beginIndex >= 0: begin = shortestPath[beginIndex] centerPerpendicular = intercircle.getWiddershinsByLength(center, begin, self.combInset) centerEnd = None endIndex = pointIndex + 1 if endIndex < len(shortestPath): end = shortestPath[endIndex] centerEnd = intercircle.getWiddershinsByLength(end, center, self.combInset) if centerPerpendicular is None: centerPerpendicular = centerEnd elif centerEnd is not None: centerPerpendicular = 0.5 * (centerPerpendicular + centerEnd) between = None if centerPerpendicular is None: between = center if between is None: centerSideWiddershins = center + centerPerpendicular if euclidean.isPointInsideLoop(loop, centerSideWiddershins) == loopWiddershins: between = centerSideWiddershins if between is None: centerSideClockwise = center - centerPerpendicular if euclidean.isPointInsideLoop(loop, centerSideClockwise) == loopWiddershins: between = centerSideClockwise if between is None: between = center pathBetween.append(between) return pathBetween def getPathsBetween(self, begin, end): "Insert paths between the perimeter and the fill." aroundBetweenPath = [] points = [begin] lineX = [] switchX = [] segment = euclidean.getNormalized(end - begin) segmentYMirror = complex(segment.real, - segment.imag) beginRotated = segmentYMirror * begin endRotated = segmentYMirror * end y = beginRotated.imag boundaries = self.getBoundaries() for boundaryIndex in xrange(len(boundaries)): boundary = boundaries[ boundaryIndex ] boundaryRotated = euclidean.getRotatedComplexes(segmentYMirror, boundary) euclidean.addXIntersectionIndexesFromLoopY(boundaryRotated, boundaryIndex, switchX, y) switchX.sort() maximumX = max(beginRotated.real, endRotated.real) minimumX = min(beginRotated.real, endRotated.real) for xIntersection in switchX: if xIntersection.x > minimumX and xIntersection.x < maximumX: point = segment * complex(xIntersection.x, y) points.append(point) lineX.append(xIntersection) points.append(end) lineXIndex = 0 # pathBetweenAdded = False while lineXIndex < len(lineX) - 1: lineXFirst = lineX[lineXIndex] lineXSecond = lineX[lineXIndex + 1] loopFirst = boundaries[lineXFirst.index] if lineXSecond.index == lineXFirst.index: pathBetween = self.getPathBetween(loopFirst, points[lineXIndex : lineXIndex + 4]) pathBetween = self.getSimplifiedAroundPath(points[lineXIndex], points[lineXIndex + 3], loopFirst, pathBetween) aroundBetweenPath += pathBetween lineXIndex += 2 else: lineXIndex += 1 # isLeavingPerimeter = False # if lineXSecond.index != lineXFirst.index: # isLeavingPerimeter = True # pathBetween = self.getPathBetween( points[ lineXIndex + 1 ], points[ lineXIndex + 2 ], isLeavingPerimeter, loopFirst ) # if isLeavingPerimeter: # pathBetweenAdded = True # else: # pathBetween = self.getSimplifiedAroundPath( points[ lineXIndex ], points[ lineXIndex + 3 ], loopFirst, pathBetween ) # pathBetweenAdded = True # aroundBetweenPath += pathBetween # lineXIndex += 2 return aroundBetweenPath def getSimplifiedAroundPath( self, begin, end, loop, pathAround ): "Get the simplified path between the perimeter and the fill." pathAround = self.getSimplifiedBeginPath(begin, loop, pathAround) return self.getSimplifiedEndPath(end, loop, pathAround) def getSimplifiedBeginPath( self, begin, loop, pathAround ): "Get the simplified begin path between the perimeter and the fill." if len(pathAround) < 2: return pathAround pathIndex = 0 while pathIndex < len(pathAround) - 1: if not self.getIsAsFarAndNotIntersecting(begin, pathAround[pathIndex + 1]): return pathAround[pathIndex :] pathIndex += 1 return pathAround[-1 :] def getSimplifiedEndPath(self, end, loop, pathAround): "Get the simplified end path between the perimeter and the fill." if len(pathAround) < 2: return pathAround pathIndex = len(pathAround) - 1 while pathIndex > 0: if not self.getIsAsFarAndNotIntersecting(end, pathAround[pathIndex - 1]): return pathAround[: pathIndex + 1] pathIndex -= 1 return pathAround[: 1] def parseBoundariesLayers( self, combRepository, line ): "Parse a gcode line." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'M103': self.boundaryLoop = None elif firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) self.addToLoop( location ) elif firstWord == '(': self.boundaryLoop = None self.layer = None self.oldZ = float(splitLine[1]) def parseInitialization( self, combRepository ): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('comb') return elif firstWord == '(': perimeterWidth = float(splitLine[1]) self.combInset = 0.7 * perimeterWidth self.betweenInset = 0.4 * perimeterWidth self.uTurnWidth = 0.5 * self.betweenInset elif firstWord == '(': self.travelFeedRateMinute = 60.0 * float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the comb skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if self.distanceFeedRate.getIsAlteration(line): return if firstWord == 'G1': self.addIfTravel(splitLine) self.layerZ = self.nextLayerZ elif firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False elif firstWord == '(': self.layerCount.printProgressIncrement('comb') self.nextLayerZ = float(splitLine[1]) if self.layerZ is None: self.layerZ = self.nextLayerZ self.distanceFeedRate.addLineCheckAlteration(line) def main(): "Display the comb dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py000066400000000000000000000467021167321211700300030ustar00rootroot00000000000000""" This page is in the table of contents. Cool is a craft tool to cool the shape. Cool works well with a stepper extruder, it does not work well with a DC motor extruder. If enabled, before each layer that takes less then "Minimum Layer Time" to print the tool head will orbit around the printed area for 'Minimum Layer Time' minus 'the time it takes to print the layer' before it starts printing the layer. This is great way to let layers with smaller area cool before you start printing on top of them (so you do not overheat the area). The cool manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Cool Allan Ecker aka The Masked Retriever's has written the "Skeinforge Quicktip: Cool" at: http://blog.thingiverse.com/2009/07/28/skeinforge-quicktip-cool/ ==Operation== The default 'Activate Cool' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Bridge Cool=== Default is one degree Celcius. If the layer is a bridge layer, then cool will lower the temperature by 'Bridge Cool' degrees Celcius. ===Cool Type=== Default is 'Slow Down'. ====Orbit==== When selected, cool will add orbits with the extruder off to give the layer time to cool, so that the next layer is not extruded on a molten base. The orbits will be around the largest island on that layer. Orbit should only be chosen if you can not upgrade to a stepper extruder. ====Slow Down==== When selected, cool will slow down the extruder so that it will take the minimum layer time to extrude the layer. DC motors do not operate properly at slow flow rates, so if you have a DC motor extruder, you should upgrade to a stepper extruder, but if you can't do that, you can try using the 'Orbit' option. ===Maximum Cool=== Default is 2 degrees Celcius. If it takes less time to extrude the layer than the minimum layer time, then cool will lower the temperature by the 'Maximum Cool' setting times the layer time over the minimum layer time. ===Minimum Layer Time=== Default is 60 seconds. Defines the minimum amount of time the extruder will spend on a layer, this is an important setting. ===Minimum Orbital Radius=== Default is 10 millimeters. When the orbit cool type is selected, if the area of the largest island is as large as the square of the "Minimum Orbital Radius" then the orbits will be just within the island. If the island is smaller, then the orbits will be in a square of the "Minimum Orbital Radius" around the center of the island. This is so that the hot extruder does not stay too close to small islands. ===Name of Alteration Files=== Cool looks for alteration files in the alterations folder in the .skeinforge folder in the home directory. Cool does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder. The cool start and end text idea is from: http://makerhahn.blogspot.com/2008/10/yay-minimug.html ====Name of Cool End File==== Default is cool_end.gcode. If there is a file with the name of the "Name of Cool End File" setting, it will be added to the end of the orbits. ====Name of Cool Start File==== Default is cool_start.gcode. If there is a file with the name of the "Name of Cool Start File" setting, it will be added to the start of the orbits. ===Orbital Outset=== Default is 2 millimeters. When the orbit cool type is selected, the orbits will be outset around the largest island by 'Orbital Outset' millimeters. If 'Orbital Outset' is negative, the orbits will be inset instead. ===Turn Fan On at Beginning=== Default is on. When selected, cool will turn the fan on at the beginning of the fabrication by adding the M106 command. ===Turn Fan Off at Ending=== Default is on. When selected, cool will turn the fan off at the ending of the fabrication by adding the M107 command. ==Examples== The following examples cool the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and cool.py. > python cool.py This brings up the cool dialog. > python cool.py Screw Holder Bottom.stl The cool tool is parsing the file: Screw Holder Bottom.stl .. The cool tool has created the file: .. Screw Holder Bottom_cool.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, text, repository=None): 'Cool a gcode linear move text.' return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): 'Cool a gcode linear move text.' if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'cool'): return gcodeText if repository is None: repository = settings.getReadRepository(CoolRepository()) if not repository.activateCool.value: return gcodeText return CoolSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return CoolRepository() def writeOutput(fileName, shouldAnalyze=True): 'Cool a gcode linear move file. Chain cool the gcode if it is not already cooled.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'cool', shouldAnalyze) class CoolRepository: 'A class to handle the cool settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.cool.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Cool', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute( 'http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Cool') self.activateCool = settings.BooleanSetting().getFromValue('Activate Cool.. but use with a fan!', self, False) settings.LabelDisplay().getFromName('- When To use Cool?-', self ) self.minimumLayerTime = settings.FloatSpin().getFromValue(0.0, 'Use Cool if layer takes shorter than(seconds):', self, 120.0, 10.0) self.minimumLayerFeedrate = settings.FloatSpin().getFromValue(5.0, 'Do not go slower than (mm/s):', self, 50.0, 15.0) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- What to do if Cool is necessary? -', self ) self.turnFanOnAtBeginning = settings.BooleanSetting().getFromValue('Turn Fan On at Beginning', self, True) self.turnFanOffAtEnding = settings.BooleanSetting().getFromValue('Turn Fan Off at Ending', self, True) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Name of Macro (gmc) Files to execute -', self ) self.nameOfCoolEndFile = settings.StringSetting().getFromValue('Execute when Cool ends:', self, 'cool_end.gmc') self.nameOfCoolStartFile = settings.StringSetting().getFromValue('Execute when Cool starts:', self, 'cool_start.gmc') settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- How to Cool? -', self ) self.coolType = settings.MenuButtonDisplay().getFromName('Cool by:', self) self.orbit = settings.MenuRadio().getFromMenuButtonDisplay(self.coolType, 'Orbiting around Object', self, False) self.slowDown = settings.MenuRadio().getFromMenuButtonDisplay(self.coolType, 'Slow Down during print', self, True) settings.LabelSeparator().getFromRepository(self) self.maximumCool = settings.FloatSpin().getFromValue(0.0, 'Maximum Cool (Celcius):', self, 10.0, 2.0) self.bridgeCool = settings.FloatSpin().getFromValue(0.0, 'Bridge Cool (Celcius):', self, 10.0, 1.0) self.minimumOrbitalRadius = settings.FloatSpin().getFromValue( 0.0, 'Minimum Orbital Radius (millimeters):', self, 20.0, 10.0) settings.LabelSeparator().getFromRepository(self) self.orbitalOutset = settings.FloatSpin().getFromValue(1.0, 'Orbital Outset (millimeters):', self, 5.0, 2.0) self.executeTitle = 'Cool' def execute(self): 'Cool button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class CoolSkein: 'A class to cool a skein of extrusions.' def __init__(self): self.boundaryLayer = None self.coolTemperature = None self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRateMinute = 960.0 self.highestZ = 1.0 self.isBridgeLayer = False self.isExtruderActive = False self.layerCount = settings.LayerCount() self.lineIndex = 0 self.lines = None self.multiplier = 1.0 self.oldFlowRate = None self.oldFlowRateString = None self.oldLocation = None self.oldTemperature = None def addCoolOrbits(self, remainingOrbitTime): 'Add the minimum radius cool orbits.' if len(self.boundaryLayer.loops) < 1: return insetBoundaryLoops = self.boundaryLayer.loops if abs(self.repository.orbitalOutset.value) > 0.1 * abs(self.perimeterWidth): insetBoundaryLoops = intercircle.getInsetLoopsFromLoops(self.boundaryLayer.loops, -self.repository.orbitalOutset.value) if len(insetBoundaryLoops) < 1: insetBoundaryLoops = self.boundaryLayer.loops largestLoop = euclidean.getLargestLoop(insetBoundaryLoops) loopArea = euclidean.getAreaLoopAbsolute(largestLoop) if loopArea < self.minimumArea: center = 0.5 * (euclidean.getMaximumByComplexPath(largestLoop) + euclidean.getMinimumByComplexPath(largestLoop)) centerXBounded = max(center.real, self.boundingRectangle.cornerMinimum.real) centerXBounded = min(centerXBounded, self.boundingRectangle.cornerMaximum.real) centerYBounded = max(center.imag, self.boundingRectangle.cornerMinimum.imag) centerYBounded = min(centerYBounded, self.boundingRectangle.cornerMaximum.imag) center = complex(centerXBounded, centerYBounded) maximumCorner = center + self.halfCorner minimumCorner = center - self.halfCorner largestLoop = euclidean.getSquareLoopWiddershins(minimumCorner, maximumCorner) pointComplex = euclidean.getXYComplexFromVector3(self.oldLocation) if pointComplex is not None: largestLoop = euclidean.getLoopStartingClosest(self.perimeterWidth, pointComplex, largestLoop) intercircle.addOrbitsIfLarge( self.distanceFeedRate, largestLoop, self.orbitalFeedRatePerSecond, remainingOrbitTime, self.highestZ) def addCoolTemperature(self, remainingOrbitTime): 'Parse a gcode line and add it to the cool skein.' layerCool = self.repository.maximumCool.value * remainingOrbitTime / self.repository.minimumLayerTime.value if self.isBridgeLayer: layerCool = max(self.repository.bridgeCool.value, layerCool) if self.oldTemperature is not None and layerCool != 0.0: self.coolTemperature = self.oldTemperature - layerCool self.addTemperature(self.coolTemperature) # def addFlowRate(self, flowRate): # 'Add a multipled line of flow rate if different.' # self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate)) def addGcodeFromFeedRateMovementZ(self, feedRateMinute, point, z): 'Add a movement to the output.' self.distanceFeedRate.addLine(self.distanceFeedRate.getLinearGcodeMovementWithFeedRate(feedRateMinute, point, z)) def addOrbitsIfNecessary(self, remainingOrbitTime): 'Parse a gcode line and add it to the cool skein.' if remainingOrbitTime > 0.0 and self.boundaryLayer is not None: self.addCoolOrbits(remainingOrbitTime) def addTemperature(self, temperature): 'Add a line of temperature.' self.distanceFeedRate.addLine('M104 S' + euclidean.getRoundedToThreePlaces(temperature)) def getCoolMove(self, line, location, splitLine): 'Get cool line according to time spent on layer.' self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) calcCoolFeedrate = self.multiplier * self.feedRateMinute if calcCoolFeedrate >= self.repository.minimumLayerFeedrate.value*60: coolFeedrate = calcCoolFeedrate else: coolFeedrate = self.repository.minimumLayerFeedrate.value*60 return self.distanceFeedRate.getLineWithFeedRate(coolFeedrate, line, splitLine) def getCraftedGcode(self, gcodeText, repository): 'Parse gcode text and store the cool gcode.' self.repository = repository self.coolEndLines = settings.getAlterationFileLines(repository.nameOfCoolEndFile.value) self.coolStartLines = settings.getAlterationFileLines(repository.nameOfCoolStartFile.value) self.halfCorner = complex(repository.minimumOrbitalRadius.value, repository.minimumOrbitalRadius.value) self.lines = archive.getTextLines(gcodeText) self.minimumArea = 4.0 * repository.minimumOrbitalRadius.value * repository.minimumOrbitalRadius.value self.parseInitialization() self.boundingRectangle = gcodec.BoundingRectangle().getFromGcodeLines( self.lines[self.lineIndex :], 0.5 * self.perimeterWidth) margin = 0.2 * self.perimeterWidth halfCornerMargin = self.halfCorner + complex(margin, margin) self.boundingRectangle.cornerMaximum -= halfCornerMargin self.boundingRectangle.cornerMinimum += halfCornerMargin for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) if repository.turnFanOffAtEnding.value: self.distanceFeedRate.addLine('M107') return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue()) def getLayerTime(self): 'Get the time the extruder spends on the layer.' feedRateMinute = self.feedRateMinute layerTime = 0.0 lastThreadLocation = self.oldLocation for lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(lastThreadLocation, splitLine) feedRateMinute = gcodec.getFeedRateMinute(feedRateMinute, splitLine) if lastThreadLocation is not None: feedRateSecond = feedRateMinute / 60.0 layerTime += location.distance(lastThreadLocation) / feedRateSecond lastThreadLocation = location elif firstWord == '(': self.isBridgeLayer = True elif firstWord == '()': return layerTime return layerTime def getLayerTimeActive(self): 'Get the time the extruder spends on the layer while active.' feedRateMinute = self.feedRateMinute isExtruderActive = self.isExtruderActive layerTime = 0.0 lastThreadLocation = self.oldLocation for lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(lastThreadLocation, splitLine) feedRateMinute = gcodec.getFeedRateMinute(feedRateMinute, splitLine) if lastThreadLocation is not None and isExtruderActive: feedRateSecond = feedRateMinute / 60.0 layerTime += location.distance(lastThreadLocation) / feedRateSecond lastThreadLocation = location elif firstWord == 'M101': isExtruderActive = True elif firstWord == 'M103': isExtruderActive = False elif firstWord == '(': self.isBridgeLayer = True elif firstWord == '()': return layerTime return layerTime def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) # if firstWord == 'M108': # self.oldFlowRate = float(splitLine[1][1 :]) if firstWord == '(': self.perimeterWidth = float(splitLine[1]) if self.repository.turnFanOnAtBeginning.value: self.distanceFeedRate.addLine('M106') elif firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('cool') return # elif firstWord == '(': # self.oldFlowRate = float(splitLine[1]) elif firstWord == '(': self.orbitalFeedRatePerSecond = float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): 'Parse a gcode line and add it to the cool skein.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.highestZ = max(location.z, self.highestZ) if self.isExtruderActive: line = self.getCoolMove(line, location, splitLine) self.oldLocation = location elif firstWord == 'M101': self.isExtruderActive = True elif firstWord == 'M103': self.isExtruderActive = False elif firstWord == 'M104': self.oldTemperature = gcodec.getDoubleAfterFirstLetter(splitLine[1]) # elif firstWord == 'M108': # self.oldFlowRate = float(splitLine[1][1 :]) # self.addFlowRate(self.multiplier * self.oldFlowRate) # return elif firstWord == '(': self.boundaryLoop.append(gcodec.getLocationFromSplitLine(None, splitLine).dropAxis()) elif firstWord == '(': self.layerCount.printProgressIncrement('cool') self.distanceFeedRate.addLine(line) self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.coolStartLines) layerTime = self.getLayerTime() remainingOrbitTime = max(self.repository.minimumLayerTime.value - layerTime, 0.0) self.addCoolTemperature(remainingOrbitTime) if self.repository.orbit.value: self.addOrbitsIfNecessary(remainingOrbitTime) else: self.setMultiplier(remainingOrbitTime) # self.addFlowRate(self.multiplier * self.oldFlowRate) z = float(splitLine[1]) self.boundaryLayer = euclidean.LoopLayer(z) self.highestZ = max(z, self.highestZ) self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.coolEndLines) return elif firstWord == '()': self.isBridgeLayer = False self.multiplier = 1.0 if self.coolTemperature is not None: self.addTemperature(self.oldTemperature) self.coolTemperature = None # self.addFlowRate(self.oldFlowRate) elif firstWord == '()': self.boundaryLoop = [] self.boundaryLayer.loops.append(self.boundaryLoop) self.distanceFeedRate.addLine(line) def setMultiplier(self, remainingOrbitTime): 'Set the feed and flow rate multiplier.' layerTimeActive = self.getLayerTimeActive() self.multiplier = min(1.0, layerTimeActive / (remainingOrbitTime + layerTimeActive)) def main(): 'Display the cool dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/dimension.py000066400000000000000000000550221167321211700310270ustar00rootroot00000000000000#! /usr/bin/env python """ This page is in the table of contents. Dimension adds Adrian's extruder distance E value so firmware does not have to calculate it on it's own and can set the extruder speed in relation to the distance that needs to be extruded. Some printers don't support this. Extruder distance is described at: http://blog.reprap.org/2009/05/4d-printing.html and in Erik de Bruijn's conversion script page at: http://objects.reprap.org/wiki/3D-to-5D-Gcode.php The dimension manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Dimension Nophead wrote an excellent article on how to set the filament parameters: http://hydraraptor.blogspot.com/2011/03/spot-on-flow-rate.html ==Operation== The default 'Activate Dimension' checkbox is off. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Extrusion Distance Format Choice=== Default is 'Absolute Extrusion Distance' because in Adrian's description the distance is absolute. In future, because the relative distances are smaller than the cumulative absolute distances, hopefully the firmware will be able to use relative distance. ====Absolute Extrusion Distance==== When selected, the extrusion distance output will be the total extrusion distance to that gcode line. ====Relative Extrusion Distance==== When selected, the extrusion distance output will be the extrusion distance from the last gcode line. ===Extruder Retraction Speed=== Default is 13.3 mm/s. Defines the extruder retraction feed rate. A high value will allow the retraction operation to complete before much material oozes out. If your extruder can handle it, this value should be much larger than your feed rate. As an example, I have a feed rate of 48 mm/s and a 'Extruder Retraction Speed' of 150 mm/s. ===Filament=== ====Filament Diameter==== Default is 2.8 millimeters. Defines the filament diameter. ====Filament Packing Density==== Default is 0.85. This is for ABS. Defines the effective filament packing density. The default value is so low for ABS because ABS is relatively soft and with a pinch wheel extruder the teeth of the pinch dig in farther, so it sees a smaller effective diameter. With a hard plastic like PLA the teeth of the pinch wheel don't dig in as far, so it sees a larger effective diameter, so feeds faster, so for PLA the value should be around 0.97. This is with Wade's hobbed bolt. The effect is less significant with larger pinch wheels. Overall, you'll have to find the optimal filament packing density by experiment. ===Maximum E Value before Reset=== Default: 91234.0 Defines the maximum E value before it is reset with the 'G92 E0' command line. The reason it is reset only after the maximum E value is reached is because at least one firmware takes time to reset. The problem with waiting until the E value is high before resetting is that more characters are sent. So if your firmware takes a lot of time to reset, set this parameter to a high value, if it doesn't set this parameter to a low value or even zero. ===Minimum Travel for Retraction=== Default: 1.0 millimeter Defines the minimum distance that the extruder head has to travel from the end of one thread to the beginning of another, in order to trigger the extruder retraction. Setting this to a high value means the extruder will retract only occasionally, setting it to a low value means the extruder will retract most of the time. ===Retract Within Island=== Default is off. When selected, retraction will work even when the next thread is within the same island. If it is not selected, retraction will only work when crossing a boundary. ===Retraction Distance=== Default is zero. Defines the amount the extruder retracts (sucks back) the extruded filament whenever an extruder stop is commanded. Using this seems to help prevent stringing. e.g. If set to 10 the extruder reverses the distance required to pull back 10mm of filament. In fact this does not actually happen but if you set this distance by trial and error you can get to a point where there is very little ooze from the extruder when it stops which is not normally the case. ===Restart Extra Distance=== Default is zero. Defines the restart extra distance when the thread restarts. The restart distance will be the retraction distance plus the restart extra distance. If this is greater than zero when the extruder starts this distance is added to the retract value giving extra filament. It can be a negative value in which case it is subtracted from the retraction distance. On some Repstrap machines a negative value can stop the build up of plastic that can occur at the start of perimeters. ==Examples== The following examples dimension the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and dimension.py. > python dimension.py This brings up the dimension dialog. > python dimension.py Screw Holder Bottom.stl The dimension tool is parsing the file: Screw Holder Bottom.stl .. The dimension tool has created the file: .. Screw Holder Bottom_dimension.gcode """ #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from datetime import date from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, gcodeText = '', repository=None): 'Dimension a gcode file or text.' return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), repository ) def getCraftedTextFromText(gcodeText, repository=None): 'Dimension a gcode text.' if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'dimension'): return gcodeText if repository is None: repository = settings.getReadRepository( DimensionRepository() ) if not repository.activateDimension.value: return gcodeText return DimensionSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return DimensionRepository() def writeOutput(fileName, shouldAnalyze=True): 'Dimension a gcode file.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'dimension', shouldAnalyze) class DimensionRepository: 'A class to handle the dimension settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.dimension.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Dimension', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Dimension') self.activateDimension = settings.BooleanSetting().getFromValue('Activate Volumetric Extrusion (Stepper driven Extruders)', self, True ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Filament Settings - YOU NEED TO HAVE YOUR EXTRUDER E-STEPS CALIBRATED FIRST -', self ) settings.LabelDisplay().getFromName('http://josefprusa.cz/skeinforge-40-volumetric-calibration', self ) settings.LabelDisplay().getFromName('- Filament -', self ) self.filamentDiameter = settings.FloatSpin().getFromValue(1.0, 'Filament Diameter (mm):', self, 6.0, 2.8) self.filamentPackingDensity = settings.FloatSpin().getFromValue(0.5, 'E-Steps corrector:', self, 1.5, 1.0) self.activateCalibration = settings.BooleanSetting().getFromValue('Are You Calibrating?', self, False ) self.MeasuredXSection = settings.FloatSpin().getFromValue(0.20, 'Measured Width of Extrusion:', self, 2.0, 0.6) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Filament Retraction Settings -', self ) self.extruderRetractionSpeed = settings.FloatSpin().getFromValue( 10, 'Extruder Retraction Speed (mm/s):', self, 50, 30 ) # self.extruderRetractionDwell = settings.FloatSpin().getFromValue( 0, 'Extruder Retraction Dwell (mS):', self, 500, 100 ) self.retractionDistance = settings.FloatSpin().getFromValue( 0.0, 'Retraction Distance (millimeters):', self, 3.0, 1.0 ) self.restartExtraDistance = settings.FloatSpin().getFromValue( 0.0, 'Restart Extra Distance (millimeters):', self, 1.0, 0.1 ) self.retractWithinIsland = settings.BooleanSetting().getFromValue('Retract Within Island', self, False) self.minimumTravelForRetraction = settings.FloatSpin().getFromValue(0.0, 'Minimum Travelmove after Retraction (millimeters):', self, 2.0, 1.0) settings.LabelSeparator().getFromRepository(self) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Firmware Related Stuff -', self ) # self.useFilamentDiameter = settings.BooleanSetting().getFromValue('Consider Filament Diameter?', self, True ) self.maximumEValueBeforeReset = settings.FloatSpin().getFromValue(0.0, 'Maximum E Value before Reset (float):', self, 999999.9, 91234.0) extrusionDistanceFormatLatentStringVar = settings.LatentStringVar() self.extrusionDistanceFormatChoiceLabel = settings.LabelDisplay().getFromName('Extrusion Distance Format Choice: ', self ) settings.Radio().getFromRadio( extrusionDistanceFormatLatentStringVar, 'Absolute Extrusion Distance', self, True ) self.relativeExtrusionDistance = settings.Radio().getFromRadio( extrusionDistanceFormatLatentStringVar, 'Relative Extrusion Distance', self, False ) self.executeTitle = 'Dimension' def execute(self): 'Dimension button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class DimensionSkein: 'A class to dimension a skein of extrusions.' def __init__(self): 'Initialize.' self.absoluteDistanceMode = True self.boundaryLayers = [] self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRateMinute = None self.isExtruderActive = False self.layerIndex = -1 self.lineIndex = 0 self.maximumZTravelFeedRatePerSecond = None self.oldLocation = None self.operatingFlowRate = None self.retractionRatio = 1.0 self.totalExtrusionDistance = 0.0 self.travelFeedRatePerSecond = None self.zDistanceRatio = 1.0 self.oldFlowRateString = None self.layerThickness = 0 self.perimeterWidth = 0 self.filamentXsection = 0 self.nozzleXsection = 0 self.flowRate = 0 self.extrusionReduction = 1 self.oldExtrusionDistance = 0 self.restartDistance = 0 def addLinearMoveExtrusionDistanceLine(self, extrusionDistance): 'Get the extrusion distance string from the extrusion distance.' # The lines that are inserted before extrusion starts if self.repository.extruderRetractionSpeed.value != 0.0: retractionString = self.getExtrusionDistanceStringFromExtrusionDistance(extrusionDistance) +' F'+ self.extruderRetractionSpeedMinuteString # self.distanceFeedRate.output.write('G1 F%s\n' % self.extruderRetractionSpeedMinuteString) self.distanceFeedRate.output.write('G1%s\n' % retractionString) # self.distanceFeedRate.output.write('G1 F%s\n' % self.distanceFeedRate.getRounded(self.feedRateMinute)) def getCraftedGcode(self, gcodeText, repository): 'Parse gcode text and store the dimension gcode.' self.repository = repository filamentRadius = 0.5 * repository.filamentDiameter.value self.minimumTravelForRetraction = self.repository.minimumTravelForRetraction.value self.doubleMinimumTravelForRetraction = self.minimumTravelForRetraction + self.minimumTravelForRetraction self.lines = archive.getTextLines(gcodeText) self.parseInitialization() self.filamentXsection = filamentRadius ** 2 * math.pi self.extrusionXsection=(((self.layerThickness+self.perimeterWidth)/4)*((self.layerThickness+self.perimeterWidth)/4)) * math.pi if not self.repository.retractWithinIsland.value: self.parseBoundaries() if repository.activateCalibration.value: self.calibrationFactor = (4 * (self.repository.MeasuredXSection.value - self.perimeterWidth))/((math.pi-4)*self.layerThickness+ 4* self.perimeterWidth )+1 self.newfilamentPackingDensity = repository.filamentPackingDensity.value * self.calibrationFactor print('***************E-Steps corrector Value (For Calibration)*********************:') print('****E-Steps corrector Value (For Calibration) STEPPER EXTRUDERS ONLY :*******', self.newfilamentPackingDensity ) print('***************E-Steps corrector Value (For Calibration)*********************') print('**********this created G-CODE is only for calculating The Value**************') print('****Enter the Value into SFACT, uncheck the calibration box, RE-Skein********') else : self.calibrationFactor = repository.filamentPackingDensity.value if self.calibrationFactor is None: print('Measured extrusion width cant be 0, either un-check calibration or set measured width to what you have measured!') if self.operatingFlowRate is None: print('There is no operatingFlowRate so dimension will do nothing.') return gcodeText # Calculate the extrusion volume self.extrusionReduction = self.filamentXsection * self.calibrationFactor #todo comment out later # Retraction for fixed self.restartDistance = self.repository.retractionDistance.value + self.repository.restartExtraDistance.value self.extruderRetractionSpeedMinuteString = self.distanceFeedRate.getRounded(60.0 * self.repository.extruderRetractionSpeed.value) if self.maximumZTravelFeedRatePerSecond is not None and self.travelFeedRatePerSecond is not None: self.zDistanceRatio = self.travelFeedRatePerSecond / self.maximumZTravelFeedRatePerSecond for lineIndex in xrange(self.lineIndex, len(self.lines)): self.parseLine( lineIndex ) return self.distanceFeedRate.output.getvalue() def getDimensionedArcMovement(self, line, splitLine): 'Get a dimensioned arc movement.' if self.oldLocation is None: return line relativeLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.oldLocation += relativeLocation distance = gcodec.getArcDistance(relativeLocation, splitLine) return line + self.getExtrusionDistanceString(distance, splitLine) def getDimensionedLinearMovement( self, line, splitLine ): 'Get a dimensioned linear movement.' distance = 0.0 if self.absoluteDistanceMode: location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.oldLocation is not None: distance = abs( location - self.oldLocation ) self.oldLocation = location else: if self.oldLocation is None: print('Warning: There was no absolute location when the G91 command was parsed, so the absolute location will be set to the origin.') self.oldLocation = Vector3() location = gcodec.getLocationFromSplitLine(None, splitLine) distance = abs( location ) self.oldLocation += location return line + self.getExtrusionDistanceString( distance, splitLine ) def getDistanceToNextThread(self, lineIndex): 'Get the travel distance to the next thread.' if self.oldLocation is None: return None isActive = False location = self.oldLocation for afterIndex in xrange(lineIndex + 1, len(self.lines)): line = self.lines[afterIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': if isActive: location = gcodec.getLocationFromSplitLine(location, splitLine) if not self.repository.retractWithinIsland.value: locationEnclosureIndex = self.getSmallestEnclosureIndex(location.dropAxis()) if locationEnclosureIndex != self.getSmallestEnclosureIndex(self.oldLocation.dropAxis()): return None locationMinusOld = location - self.oldLocation xyTravel = abs(locationMinusOld.dropAxis()) zTravelMultiplied = locationMinusOld.z * self.zDistanceRatio return math.hypot(xyTravel , zTravelMultiplied) elif firstWord == 'M101': isActive = True elif firstWord == 'M103': isActive = False return None def getExtrusionDistanceString( self, distance, splitLine ): 'Get the extrusion distance string.' self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) if not self.isExtruderActive: return '' if distance == 0.0: return '' if distance < 0.0: print('Warning, the distance is less than zero in getExtrusionDistanceString in dimension; so there will not be an E value') print(distance) print(splitLine) return '' scaledXSection = self.flowRate * self.extrusionXsection return self.getExtrusionDistanceStringFromExtrusionDistance((scaledXSection * distance) / self.extrusionReduction) def getExtrusionDistanceStringFromExtrusionDistance( self, extrusionDistance ): 'Get the extrusion distance string from the extrusion distance.' self.oldExtrusionDistance = self.distanceFeedRate.getRounded(extrusionDistance) if self.repository.relativeExtrusionDistance.value: return ' E' + self.distanceFeedRate.getRounded(extrusionDistance) self.totalExtrusionDistance += extrusionDistance return ' E' + self.distanceFeedRate.getRounded( self.totalExtrusionDistance ) def getRetractionRatio(self, lineIndex): 'Get the retraction ratio.' distanceToNextThread = self.getDistanceToNextThread(lineIndex) if distanceToNextThread is None: return 0.0 if distanceToNextThread >= self.doubleMinimumTravelForRetraction: return 1.0 if distanceToNextThread <= self.minimumTravelForRetraction: return 0.0 return #(distanceToNextThread - self.minimumTravelForRetraction) / self.minimumTravelForRetraction def getSmallestEnclosureIndex(self, point): 'Get the index of the smallest boundary loop which encloses the point.' boundaryLayer = self.boundaryLayers[self.layerIndex] for loopIndex, loop in enumerate(boundaryLayer.loops): if euclidean.isPointInsideLoop(loop, point): return loopIndex return None def parseBoundaries(self): 'Parse the boundaries and add them to the boundary layers.' boundaryLoop = None boundaryLayer = None for line in self.lines[self.lineIndex :]: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '()': boundaryLoop = None elif firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) if boundaryLoop is None: boundaryLoop = [] boundaryLayer.loops.append(boundaryLoop) boundaryLoop.append(location.dropAxis()) elif firstWord == '(': boundaryLayer = euclidean.LoopLayer(float(splitLine[1])) self.boundaryLayers.append(boundaryLayer) for boundaryLayer in self.boundaryLayers: triangle_mesh.sortLoopsInOrderOfArea(False, boundaryLayer.loops) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('dimension') return elif firstWord == '(': self.layerThickness = float(splitLine[1]) elif firstWord == '(': self.maximumZTravelFeedRatePerSecond = float(splitLine[1]) elif firstWord == '(': self.maximumZTravelFeedRatePerSecond = float(splitLine[1]) elif firstWord == '(': self.feedRateMinute = 60.0 * float(splitLine[1]) elif firstWord == '(': self.operatingFlowRate = float(splitLine[1]) self.flowRate = self.operatingFlowRate elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) elif firstWord == '(': self.travelFeedRatePerSecond = float(splitLine[1]) self.XtravelFeedRatePerSecond = self.travelFeedRatePerSecond elif firstWord == '(': self.firstLayertravelFeedRatePerSecond = float(splitLine[1]) elif firstWord == '(': self.nozzleDiameter = float(splitLine[1]) self.nozzleXsection = (self.nozzleDiameter/2)**2*math.pi self.distanceFeedRate.addLine(line) def parseLine( self, lineIndex ): 'Parse a gcode line and add it to the dimension skein.' line = self.lines[lineIndex].lstrip() splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == '()': if not self.repository.relativeExtrusionDistance.value: self.distanceFeedRate.addLine('M82') else: self.distanceFeedRate.addLine('M83') if firstWord == 'G2' or firstWord == 'G3': line = self.getDimensionedArcMovement( line, splitLine ) if firstWord == 'G1': line = self.getDimensionedLinearMovement( line, splitLine ) if firstWord == 'G90': self.absoluteDistanceMode = True elif firstWord == 'G91': self.absoluteDistanceMode = False elif firstWord == '(': self.layerIndex += 1 settings.printProgress(self.layerIndex, 'dimension') elif firstWord == 'M101': #counterretract self.addLinearMoveExtrusionDistanceLine(self.restartDistance * self.retractionRatio) if self.totalExtrusionDistance > self.repository.maximumEValueBeforeReset.value: if not self.repository.relativeExtrusionDistance.value: self.distanceFeedRate.addLine('G92 E0') self.totalExtrusionDistance = 0.0 self.isExtruderActive = True elif firstWord == 'M103': #retract self.addLinearMoveExtrusionDistanceLine(-self.repository.retractionDistance.value*self.retractionRatio) self.isExtruderActive = False elif firstWord == 'M108': self.flowRate = float( splitLine[1][1 :] ) self.distanceFeedRate.addLine(line) def main(): 'Display the dimension dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/drill.py000066400000000000000000000222061167321211700301460ustar00rootroot00000000000000""" This page is in the table of contents. Drill is a script to drill down small holes. ==Operation== The default 'Activate Drill' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Drilling Margin=== The drill script will move the tool from the top of the hole plus the 'Drilling Margin on Top', to the bottom of the hole minus the 'Drilling Margin on Bottom'. ===Drilling Margin on Top=== Default is three millimeters. ===Drilling Margin on Bottom=== Default is one millimeter. ==Examples== The following examples drill the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and drill.py. > python drill.py This brings up the drill dialog. > python drill.py Screw Holder Bottom.stl The drill tool is parsing the file: Screw Holder Bottom.stl .. The drill tool has created the file: .. Screw Holder Bottom_drill.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, repository=None): "Drill a gcode linear move file or text." return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): "Drill a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'drill'): return gcodeText if repository is None: repository = settings.getReadRepository( DrillRepository() ) if not repository.activateDrill.value: return gcodeText return DrillSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return DrillRepository() def getPolygonCenter( polygon ): "Get the centroid of a polygon." pointSum = complex() areaSum = 0.0 for pointIndex in xrange( len( polygon ) ): pointBegin = polygon[pointIndex] pointEnd = polygon[ (pointIndex + 1) % len( polygon ) ] area = pointBegin.real * pointEnd.imag - pointBegin.imag * pointEnd.real areaSum += area pointSum += complex( pointBegin.real + pointEnd.real, pointBegin.imag + pointEnd.imag ) * area return pointSum / 3.0 / areaSum def writeOutput(fileName, shouldAnalyze=True): "Drill a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'drill', shouldAnalyze) class ThreadLayer: "A layer of loops and paths." def __init__( self, z ): "Thread layer constructor." self.points = [] self.z = z def __repr__(self): "Get the string representation of this thread layer." return '%s, %s' % ( self.z, self.points ) class DrillRepository: "A class to handle the drill settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.drill.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Drill', self, '') self.activateDrill = settings.BooleanSetting().getFromValue('Activate Drill', self, True ) self.drillingMarginOnBottom = settings.FloatSpin().getFromValue( 0.0, 'Drilling Margin on Bottom (millimeters):', self, 5.0, 1.0 ) self.drillingMarginOnTop = settings.FloatSpin().getFromValue( 0.0, 'Drilling Margin on Top (millimeters):', self, 20.0, 3.0 ) self.executeTitle = 'Drill' def execute(self): "Drill button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class DrillSkein: "A class to drill a skein of extrusions." def __init__(self): self.boundary = None self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.halfLayerThickness = 0.4 self.isDrilled = False self.lineIndex = 0 self.lines = None self.maximumDistance = 0.06 self.oldLocation = None self.threadLayer = None self.threadLayers = [] def addDrillHoles(self): "Parse a gcode line." self.isDrilled = True if len( self.threadLayers ) < 1: return topThreadLayer = self.threadLayers[0] drillPoints = topThreadLayer.points for drillPoint in drillPoints: zTop = topThreadLayer.z + self.halfLayerThickness + self.repository.drillingMarginOnTop.value drillingCenterDepth = self.getDrillingCenterDepth( topThreadLayer.z, drillPoint ) zBottom = drillingCenterDepth - self.halfLayerThickness - self.repository.drillingMarginOnBottom.value self.addGcodeFromVerticalThread( drillPoint, zTop, zBottom ) def addGcodeFromVerticalThread( self, point, zBegin, zEnd ): "Add a thread to the output." self.distanceFeedRate.addGcodeMovementZ( point, zBegin ) self.distanceFeedRate.addLine('M101') # Turn extruder on. self.distanceFeedRate.addGcodeMovementZ( point, zEnd ) self.distanceFeedRate.addLine('M103') # Turn extruder off. def addThreadLayerIfNone(self): "Add a thread layer if it is none." if self.threadLayer is not None: return self.threadLayer = ThreadLayer( self.layerZ ) self.threadLayers.append( self.threadLayer ) def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the drill gcode." self.lines = archive.getTextLines(gcodeText) self.repository = repository self.parseInitialization() for line in self.lines[self.lineIndex :]: self.parseNestedRing(line) for line in self.lines[self.lineIndex :]: self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getDrillingCenterDepth( self, drillingCenterDepth, drillPoint ): "Get the drilling center depth." for threadLayer in self.threadLayers[1 :]: if self.isPointClose( drillPoint, threadLayer.points ): drillingCenterDepth = threadLayer.z else: return drillingCenterDepth return drillingCenterDepth def isPointClose( self, drillPoint, points ): "Determine if a point on the thread layer is close." for point in points: if abs( point - drillPoint ) < self.maximumDistance: return True return False def linearMove( self, splitLine ): "Add a linear move to the loop." self.addThreadLayerIfNone() location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.extruderActive: self.boundary = None self.oldLocation = location def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('drill') return elif firstWord == '(': self.halfLayerThickness = 0.5 * float(splitLine[1]) elif firstWord == '(': self.maximumDistance = 0.1 * float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] self.distanceFeedRate.addLine(line) if firstWord == '(': if not self.isDrilled: self.addDrillHoles() def parseNestedRing(self, line): "Parse a nested ring." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.linearMove(splitLine) if firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False elif firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) if self.boundary is None: self.boundary = [] self.boundary.append(location.dropAxis()) elif firstWord == '(': self.layerZ = float(splitLine[1]) self.threadLayer = None elif firstWord == '()': self.addThreadLayerIfNone() elif firstWord == '()': if self.boundary is not None: self.threadLayer.points.append( getPolygonCenter( self.boundary ) ) self.boundary = None def main(): "Display the drill dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/export.py000066400000000000000000000514361167321211700303700ustar00rootroot00000000000000""" This page is in the table of contents. Export is a craft tool to pick an export plugin, add information to the file name, and delete comments. The export manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Export ==Operation== The default 'Activate Export' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Add Descriptive Extension=== Default is off. When selected, key profile values will be added as an extension to the gcode file. For example: test.04hx06w_03fill_2cx2r_33EL.gcode would mean: * . (Carve section.) * 04h = 'Layer Thickness (mm):' 0.4 * x * 06w = 0.6 width i.e. 0.4 times 'Perimeter Width over Thickness (ratio):' 1.5 * _ (Fill section.) * 03fill = 'Infill Solidity (ratio):' 0.3 * _ (Multiply section; if there is one column and one row then this section is not shown.) * 2c = 'Number of Columns (integer):' 2 * x * 2r = 'Number of Rows (integer):' 2. * _ (Speed section.) * 33EL = 'Feed Rate (mm/s):' 33.0 and 'Flow Rate Setting (float):' 33.0. If either value has a positive value after the decimal place then this is also shown, but if it is zero it is hidden. Also, if the values differ (which they shouldn't with 5D volumetrics) then each should be displayed separately. For example, 35.2E30L = 'Feed Rate (mm/s):' 35.2 and 'Flow Rate Setting (float):' 30.0. ===Add Profile Extension=== Default is off. When selected, the current profile will be added to the file extension. For example: test.my_profile_name.gcode ===Add Timestamp Extension=== Default is off. When selected, the current date and time is added as an extension in format YYYYmmdd_HHMMSS (so it is sortable if one has many files). For example: test.my_profile_name.20110613_220113.gcode ===Also Send Output To=== Default is empty. Defines the output name for sending to a file or pipe. A common choice is stdout to print the output in the shell screen. Another common choice is stderr. With the empty default, nothing will be done. If the value is anything else, the output will be written to that file name. ===Analyze Gcode=== Default is on. When selected, the penultimate gcode will be sent to the analyze plugins to be analyzed and viewed. ===Comment Choice=== Default is 'Delete All Comments'. ====Do Not Delete Comments==== When selected, export will not delete comments. Crafting comments slow down the processing in many firmware types, which leads to pauses and therefore a lower quality print. ====Delete Crafting Comments==== When selected, export will delete the time consuming crafting comments, but leave the initialization comments. Since the crafting comments are deleted, there are no pauses during extrusion. The remaining initialization comments provide some useful information for the analyze tools. ====Delete All Comments==== When selected, export will delete all comments. The comments are not necessary to run a fabricator. Some printers do not support comments at all so the safest way is choose this option. ===Export Operations=== Export presents the user with a choice of the export plugins in the export_plugins folder. The chosen plugin will then modify the gcode or translate it into another format. There is also the "Do Not Change Output" choice, which will not change the output. An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. ===File Extension=== Default is gcode. Defines the file extension added to the name of the output file. The output file will be named as originalname_export.extension so if you are processing XYZ.stl the output will by default be XYZ_export.gcode ===Name of Replace File=== Default is replace.csv. When export is exporting the code, if there is a tab separated file with the name of the "Name of Replace File" setting, it will replace the string in the first column by its replacement in the second column. If there is nothing in the second column, the first column string will be deleted, if this leads to an empty line, the line will be deleted. If there are replacement columns after the second, they will be added as extra lines of text. There is an example file replace_example.csv to demonstrate the tab separated format, which can be edited in a text editor or a spreadsheet. Export looks for the alteration file in the alterations folder in the .skeinforge folder in the home directory. Export does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder. ===Save Penultimate Gcode=== Default is off. When selected, export will save the gcode file with the suffix '_penultimate.gcode' just before it is exported. This is useful because the code after it is exported could be in a form which the viewers can not display well. ==Examples== The following examples export the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and export.py. > python export.py This brings up the export dialog. > python export.py Screw Holder Bottom.stl The export tool is parsing the file: Screw Holder Bottom.stl .. The export tool has created the file: .. Screw Holder Bottom_export.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_analyze from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import cStringIO import os import sys import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __credits__ = 'Gary Hodgson ' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedTextFromText(gcodeText, repository=None): 'Export a gcode linear move text.' if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'export'): return gcodeText if repository is None: repository = settings.getReadRepository(ExportRepository()) if not repository.activateExport.value: return gcodeText return ExportSkein().getCraftedGcode(repository, gcodeText) def getDescriptionCarve(lines): 'Get the description for carve.' descriptionCarve = '' layerThicknessString = getSettingString(lines, 'carve', 'Layer Thickness') if layerThicknessString is not None: descriptionCarve += layerThicknessString.replace('.', '') + 'h' perimeterWidthString = getSettingString(lines, 'carve', 'Perimeter Width over Thickness') if perimeterWidthString is not None: descriptionCarve += 'x%sw' % str(float(perimeterWidthString) * float(layerThicknessString)).replace('.', '') return descriptionCarve def getDescriptionFill(lines): 'Get the description for fill.' activateFillString = getSettingString(lines, 'fill', 'Activate Fill') if activateFillString is None or activateFillString == 'False': return '' infillSolidityString = getSettingString(lines, 'fill', 'Infill Solidity') return '_' + infillSolidityString.replace('.', '') + 'fill' def getDescriptionMultiply(lines): 'Get the description for multiply.' activateMultiplyString = getSettingString(lines, 'multiply', 'Activate Multiply') if activateMultiplyString is None or activateMultiplyString == 'False': return '' columnsString = getSettingString(lines, 'multiply', 'Number of Columns') rowsString = getSettingString(lines, 'multiply', 'Number of Rows') if columnsString == '1' and rowsString == '1': return '' return '_%scx%sr' % (columnsString, rowsString) def getDescriptionSpeed(lines): 'Get the description for speed.' activateSpeedString = getSettingString(lines, 'speed', 'Activate Speed') if activateSpeedString is None or activateSpeedString == 'False': return '' feedRateString = getSettingString(lines, 'speed', 'Feed Rate') flowRateString = getSettingString(lines, 'speed', 'Flow Rate') if feedRateString == flowRateString: return '_%sEL' % feedRateString.replace('.0', '') return '_%sE%sL' % (feedRateString.replace('.0', ''), flowRateString.replace('.0', '')) def getDescriptiveExtension(gcodeText): 'Get the descriptive extension.' lines = archive.getTextLines(gcodeText) return '.' + getDescriptionCarve(lines) + getDescriptionFill(lines) + getDescriptionMultiply(lines) + getDescriptionSpeed(lines) def getDistanceGcode(exportText): 'Get gcode lines with distance variable added.' lines = archive.getTextLines(exportText) oldLocation = None for line in lines: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = None if len(splitLine) > 0: firstWord = splitLine[0] if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(oldLocation, splitLine) if oldLocation is not None: distance = location.distance(oldLocation) print( distance ) oldLocation = location return exportText def getFirstValue(gcodeText, word): 'Get the value from the first line which starts with the given word.' for line in archive.getTextLines(gcodeText): splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if gcodec.getFirstWord(splitLine) == word: return splitLine[1] return '' def getNewRepository(): 'Get new repository.' return ExportRepository() def getReplaceableExportGcode(nameOfReplaceFile, replaceableExportGcode): 'Get text with strings replaced according to replace.csv file.' replaceLines = settings.getAlterationLines(nameOfReplaceFile) if len(replaceLines) < 1: return replaceableExportGcode for replaceLine in replaceLines: splitLine = replaceLine.replace('\\n', '\t').split('\t') if len(splitLine) > 0: replaceableExportGcode = replaceableExportGcode.replace(splitLine[0], '\n'.join(splitLine[1 :])) output = cStringIO.StringIO() gcodec.addLinesToCString(output, archive.getTextLines(replaceableExportGcode)) return output.getvalue() def getSelectedPluginModule( plugins ): 'Get the selected plugin module.' for plugin in plugins: if plugin.value: return archive.getModuleWithDirectoryPath( plugin.directoryPath, plugin.name ) return None def getSettingString(lines, procedureName, settingNameStart): 'Get the setting value from the lines, return None if there is no setting starting with that name.' settingNameStart = settingNameStart.replace(' ', '_') for line in lines: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = None if len(splitLine) > 0: firstWord = splitLine[0] if firstWord == '(': if len(splitLine) > 4: if splitLine[1] == procedureName and splitLine[2].startswith(settingNameStart): return splitLine[3] elif firstWord == '()': return None return None def sendOutputTo(outputTo, text): 'Send output to a file or a standard output.' if outputTo.endswith('stderr'): sys.stderr.write(text) sys.stderr.write('\n') sys.stderr.flush() return if outputTo.endswith('stdout'): sys.stdout.write(text) sys.stdout.write('\n') sys.stdout.flush() return archive.writeFileText(outputTo, text) def writeOutput(fileName, shouldAnalyze=True): 'Export a gcode linear move file.' if fileName == '': return None repository = ExportRepository() settings.getReadRepository(repository) startTime = time.time() print('File ' + archive.getSummarizedFileName(fileName) + ' is being chain exported.') fileNameSuffix = fileName[: fileName.rfind('.')] if repository.addExportSuffix.value: fileNameSuffix += '_export' gcodeText = gcodec.getGcodeFileText(fileName, '') procedures = skeinforge_craft.getProcedures('export', gcodeText) gcodeText = skeinforge_craft.getChainTextFromProcedures(fileName, procedures[: -1], gcodeText) if gcodeText == '': return None if repository.addProfileExtension.value: fileNameSuffix += '.' + getFirstValue(gcodeText, '(') if repository.addDescriptiveExtension.value: fileNameSuffix += getDescriptiveExtension(gcodeText) if repository.addTimestampExtension.value: fileNameSuffix += '.' + getFirstValue(gcodeText, '(') fileNameSuffix += '.' + repository.fileExtension.value fileNamePenultimate = fileName[: fileName.rfind('.')] + '_penultimate.gcode' filePenultimateWritten = False if repository.savePenultimateGcode.value: archive.writeFileText(fileNamePenultimate, gcodeText) filePenultimateWritten = True print('The penultimate file is saved as ' + archive.getSummarizedFileName(fileNamePenultimate)) exportGcode = getCraftedTextFromText(gcodeText, repository) window = None if shouldAnalyze and repository.analyzeGcode.value: window = skeinforge_analyze.writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText) replaceableExportGcode = None selectedPluginModule = getSelectedPluginModule(repository.exportPlugins) if selectedPluginModule is None: replaceableExportGcode = exportGcode else: if selectedPluginModule.globalIsReplaceable: replaceableExportGcode = selectedPluginModule.getOutput(exportGcode) else: selectedPluginModule.writeOutput(fileNameSuffix, exportGcode) if replaceableExportGcode is not None: replaceableExportGcode = getReplaceableExportGcode(repository.nameOfReplaceFile.value, replaceableExportGcode) archive.writeFileText( fileNameSuffix, replaceableExportGcode ) print('The exported file is saved as ' + archive.getSummarizedFileName(fileNameSuffix)) if repository.alsoSendOutputTo.value != '': if replaceableExportGcode is None: replaceableExportGcode = selectedPluginModule.getOutput(exportGcode) sendOutputTo(repository.alsoSendOutputTo.value, replaceableExportGcode) print('It took %s to export the file.' % euclidean.getDurationString(time.time() - startTime)) return window class ExportRepository: 'A class to handle the export settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.export.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Export', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Export') self.activateExport = settings.BooleanSetting().getFromValue('Activate Export', self, True) self.addExportSuffix = settings.BooleanSetting().getFromValue('Add _export to filename (filename_export)', self, True) self.alsoSendOutputTo = settings.StringSetting().getFromValue('Also Send Output To:', self, '') self.analyzeGcode = settings.BooleanSetting().getFromValue('Analyze Gcode', self, True) self.commentChoice = settings.MenuButtonDisplay().getFromName('Handling of Comments in G-Code:', self) self.doNotDeleteComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Do Not Delete Comments', self, False) self.deleteCraftingComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Delete Crafting Comments', self, False) self.deleteAllComments = settings.MenuRadio().getFromMenuButtonDisplay(self.commentChoice, 'Delete All Comments', self, True) exportPluginsFolderPath = archive.getAbsoluteFrozenFolderPath(archive.getCraftPluginsDirectoryPath('export.py'), 'export_plugins') exportStaticDirectoryPath = os.path.join(exportPluginsFolderPath, 'static_plugins') exportPluginFileNames = archive.getPluginFileNamesFromDirectoryPath(exportPluginsFolderPath) exportStaticPluginFileNames = archive.getPluginFileNamesFromDirectoryPath(exportStaticDirectoryPath) settings.LabelDisplay().getFromName(' ', self) self.exportLabel = settings.LabelDisplay().getFromName('--Export Operations-- ', self) self.exportPlugins = [] exportLatentStringVar = settings.LatentStringVar() self.doNotChangeOutput = settings.RadioCapitalized().getFromRadio(exportLatentStringVar, 'Do Not Change Output', self, True) self.doNotChangeOutput.directoryPath = None allExportPluginFileNames = exportPluginFileNames + exportStaticPluginFileNames for exportPluginFileName in allExportPluginFileNames: exportPlugin = None if exportPluginFileName in exportPluginFileNames: path = os.path.join(exportPluginsFolderPath, exportPluginFileName) exportPlugin = settings.RadioCapitalizedButton().getFromPath(exportLatentStringVar, exportPluginFileName, path, self, False) exportPlugin.directoryPath = exportPluginsFolderPath else: exportPlugin = settings.RadioCapitalized().getFromRadio(exportLatentStringVar, exportPluginFileName, self, False) exportPlugin.directoryPath = exportStaticDirectoryPath self.exportPlugins.append(exportPlugin) self.fileExtension = settings.StringSetting().getFromValue('File Extension (gcode):', self, 'gcode') self.nameOfReplaceFile = settings.StringSetting().getFromValue('Name of Replace File:', self, 'replace.csv') self.savePenultimateGcode = settings.BooleanSetting().getFromValue('Save Penultimate Gcode', self, True) settings.LabelDisplay().getFromName(' ', self) settings.LabelDisplay().getFromName('--File Name Alterations--', self) settings.LabelDisplay().getFromName('"WARNING" IF ANY OF BELOW CHECKBOXES ARE CHECKED', self) settings.LabelDisplay().getFromName('SFACT WILL NOT WORK FROM WITHIN PRONTERFACE!!', self) self.addProfileExtension = settings.BooleanSetting().getFromValue('Add Profile Extension', self, False) self.addDescriptiveExtension = settings.BooleanSetting().getFromValue('Add Descriptive Extension', self, False) self.addTimestampExtension = settings.BooleanSetting().getFromValue('Add Timestamp Extension', self, False) self.executeTitle = 'Export' def execute(self): 'Export button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class ExportSkein: 'A class to export a skein of extrusions.' def __init__(self): self.crafting = False self.decimalPlacesExported = 2 self.output = cStringIO.StringIO() def addLine(self, line): 'Add a line of text and a newline to the output.' if line != '': self.output.write(line + '\n') def getCraftedGcode( self, repository, gcodeText ): 'Parse gcode text and store the export gcode.' self.repository = repository lines = archive.getTextLines(gcodeText) for line in lines: self.parseLine(line) return self.output.getvalue() def getLineWithTruncatedNumber(self, character, line, splitLine): 'Get a line with the number after the character truncated.' numberString = gcodec.getStringFromCharacterSplitLine(character, splitLine) if numberString is None: return line roundedNumberString = euclidean.getRoundedToPlacesString(self.decimalPlacesExported, float(numberString)) return gcodec.getLineWithValueString(character, line, splitLine, roundedNumberString) def parseLine(self, line): 'Parse a gcode line.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == '()': self.crafting = False elif firstWord == '(': self.decimalPlacesExported = int(splitLine[1]) - 1 if self.repository.deleteAllComments.value or (self.repository.deleteCraftingComments.value and self.crafting): if firstWord[0] == '(': return else: line = line.split(';')[0].split('(')[0].strip() if firstWord == '()': self.crafting = True if firstWord == '()': self.addLine(gcodec.getTagBracketedProcedure('export')) if firstWord != 'G1' and firstWord != 'G2' and firstWord != 'G3' : self.addLine(line) return line = self.getLineWithTruncatedNumber('X', line, splitLine) line = self.getLineWithTruncatedNumber('Y', line, splitLine) line = self.getLineWithTruncatedNumber('Z', line, splitLine) line = self.getLineWithTruncatedNumber('I', line, splitLine) line = self.getLineWithTruncatedNumber('J', line, splitLine) line = self.getLineWithTruncatedNumber('R', line, splitLine) self.addLine(line) def main(): 'Display the export dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/000077500000000000000000000000001167321211700315465ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/__init__.py000066400000000000000000000006571167321211700336670ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 4 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) binary_16_byte.py000066400000000000000000000223031167321211700346560ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins""" This page is in the table of contents. Binary 16 byte is an export plugin to convert gcode into 16 byte binary segments. An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getOutput function of this script takes a gcode text and returns that text converted into 16 byte segments. The writeOutput function of this script takes a gcode text and writes that in a binary format converted into 16 byte segments. This plugin is just a starter to make a real binary converter. ==Settings== ===Feed Rate Step Length=== Default is 0.1 millimeters/second. Defines the feed rate step length. ===File Extension=== Default is bin. Defines the file extension suffix. ===Offset=== ====X Offset==== Default is zero. Defines the X Offset. ====Y Offset==== Default is zero. Defines the Y Offset. ====Z Offset==== Default is zero. Defines the Z Offset. ===Step Length=== ====X Step Length==== Default is 0.1 millimeters. Defines the X axis step length. ====Y Step Length==== Default is 0.1 millimeters. Defines the Y axis step length. ====Z Step Length==== Default is 0.01 millimeters. Defines the Z axis step length. ==Record structure== BinArray(0) = AscW(Inst_Code_Letter) BinArray(1) = cInst_Code X Data sInt32_to_Hbytes(iXdim_1) BinArray(2) = lsb 'short lsb BinArray(3) = msb 'short msb Y Data sInt32_to_Hbytes(iYdim_2) BinArray(4) = lsb 'short lsb BinArray(5) = msb 'short msb Z Data sInt32_to_Hbytes(iZdim_3) BinArray(6) = lsb 'short lsb BinArray(7) = msb 'short msb I Data sInt32_to_Hbytes(iIdim_4) BinArray(8) = lsb 'short lsb BinArray(9) = msb 'short msb J Data sInt32_to_Hbytes(iJdim_5) BinArray(10) = lsb 'short lsb BinArray(11) = msb 'short msb BinArray(12) = FP_Char sInt32_to_Hbytes(iFP_Num) BinArray(13) = lsb 'short lsb BinArray(14) = bActiveFlags BinArray(15) = AscW("#")End of record filler Byte 14 is worth a few extra notes, this byte is used to define which of the axes are active, its used to get round the problem of say a line of code with no mention of z. This would be put into the file as z = 0 as the space for this data is reserved, if we did nothing, this would instruct the machine to go to z = 0. If we use the active flag to define the z axis as inactive the z = 0 is ignored and the value set to the last saved value of z, i.e it does not move. If the z data is actually set to z = 0 then the axis would be set to active and the move takes place. """ from __future__ import absolute_import import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile from struct import Struct import cStringIO import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' # This is true if the output is text and false if it is binary." globalIsReplaceable = False def getIntegerFlagFromCharacterSplitLine(character, splitLine): "Get the integer flag after the first occurence of the character in the split line." lineFromCharacter = gcodec.getStringFromCharacterSplitLine(character, splitLine) if lineFromCharacter is None: return 0 return 1 def getIntegerFromCharacterLengthLineOffset( character, offset, splitLine, stepLength ): "Get the integer after the first occurence of the character in the split line." lineFromCharacter = gcodec.getStringFromCharacterSplitLine(character, splitLine) if lineFromCharacter is None: return 0 floatValue = ( float( lineFromCharacter ) + offset ) / stepLength return int( round( floatValue ) ) def getNewRepository(): 'Get new repository.' return Binary16ByteRepository() def getOutput( gcodeText, binary16ByteRepository = None ): 'Get the exported version of a gcode file.' if gcodeText == '': return '' if binary16ByteRepository is None: binary16ByteRepository = Binary16ByteRepository() settings.getReadRepository( binary16ByteRepository ) return Binary16ByteSkein().getCraftedGcode( gcodeText, binary16ByteRepository ) def writeOutput( fileName, gcodeText = ''): "Write the exported version of a gcode file." binary16ByteRepository = Binary16ByteRepository() settings.getReadRepository( binary16ByteRepository ) gcodeText = gcodec.getGcodeFileText(fileName, gcodeText) skeinOutput = getOutput( gcodeText, binary16ByteRepository ) suffixFileName = fileName[ : fileName.rfind('.') ] + '.' + binary16ByteRepository.fileExtension.value archive.writeFileText( suffixFileName, skeinOutput ) print('The converted file is saved as ' + archive.getSummarizedFileName(suffixFileName) ) class Binary16ByteRepository: "A class to handle the export settings." def __init__(self): "Set the default settings, execute title & settings fileName." #Set the default settings. skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.binary_16_byte.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File to be Converted to Binary 16 Byte', self, '') self.feedRateStepLength = settings.FloatSpin().getFromValue( 0.0, 'Feed Rate Step Length (millimeters/second)', self, 1.0, 0.1 ) self.fileExtension = settings.StringSetting().getFromValue('File Extension:', self, 'bin') settings.LabelDisplay().getFromName('Offset:', self ) self.xOffset = settings.FloatSpin().getFromValue( - 100.0, 'X Offset (millimeters)', self, 100.0, 0.0 ) self.yOffset = settings.FloatSpin().getFromValue( -100.0, 'Y Offset (millimeters)', self, 100.0, 0.0 ) self.zOffset = settings.FloatSpin().getFromValue( - 10.0, 'Z Offset (millimeters)', self, 10.0, 0.0 ) settings.LabelDisplay().getFromName('Step Length:', self ) self.xStepLength = settings.FloatSpin().getFromValue( 0.0, 'X Step Length (millimeters)', self, 1.0, 0.1 ) self.yStepLength = settings.FloatSpin().getFromValue( 0.0, 'Y Step Length (millimeters)', self, 1.0, 0.1 ) self.zStepLength = settings.FloatSpin().getFromValue( 0.0, 'Z Step Length (millimeters)', self, 0.2, 0.01 ) self.executeTitle = 'Convert to Binary 16 Byte' def execute(self): "Convert to binary 16 byte button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, ['.gcode'], self.fileNameInput.wasCancelled ) for fileName in fileNames: writeOutput(fileName) class Binary16ByteSkein: "A class to convert gcode into 16 byte binary segments." def __init__(self): self.output = cStringIO.StringIO() def getCraftedGcode( self, gcodeText, binary16ByteRepository ): "Parse gcode text and store the gcode." self.binary16ByteRepository = binary16ByteRepository lines = archive.getTextLines(gcodeText) for line in lines: self.parseLine(line) return self.output.getvalue() def parseLine(self, line): "Parse a gcode line." binary16ByteRepository = self.binary16ByteRepository splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if len(firstWord) < 1: return firstLetter = firstWord[0] if firstLetter == '(': return feedRateInteger = getIntegerFromCharacterLengthLineOffset('F', 0.0, splitLine, binary16ByteRepository.feedRateStepLength.value ) iInteger = getIntegerFromCharacterLengthLineOffset('I', 0.0, splitLine, binary16ByteRepository.xStepLength.value ) jInteger = getIntegerFromCharacterLengthLineOffset('J', 0.0, splitLine, binary16ByteRepository.yStepLength.value ) xInteger = getIntegerFromCharacterLengthLineOffset('X', binary16ByteRepository.xOffset.value, splitLine, binary16ByteRepository.xStepLength.value ) yInteger = getIntegerFromCharacterLengthLineOffset('Y', binary16ByteRepository.yOffset.value, splitLine, binary16ByteRepository.yStepLength.value ) zInteger = getIntegerFromCharacterLengthLineOffset('Z', binary16ByteRepository.zOffset.value, splitLine, binary16ByteRepository.zStepLength.value ) sixteenByteStruct = Struct('cBhhhhhhBc') flagInteger = getIntegerFlagFromCharacterSplitLine('X', splitLine ) flagInteger += 2 * getIntegerFlagFromCharacterSplitLine('Y', splitLine ) flagInteger += 4 * getIntegerFlagFromCharacterSplitLine('Z', splitLine ) flagInteger += 8 * getIntegerFlagFromCharacterSplitLine('I', splitLine ) flagInteger += 16 * getIntegerFlagFromCharacterSplitLine('J', splitLine ) flagInteger += 32 * getIntegerFlagFromCharacterSplitLine('F', splitLine ) packedString = sixteenByteStruct.pack( firstLetter, int( firstWord[1 :] ), xInteger, yInteger, zInteger, iInteger, jInteger, feedRateInteger, flagInteger, '#') self.output.write( packedString ) def main(): "Display the export dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() gcode_step.py000066400000000000000000000224131167321211700341570ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins""" This page is in the table of contents. Gcode step is an export plugin to convert gcode from float position to number of steps. An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getOutput function of this script takes a gcode text and returns it with the positions converted into number of steps. The writeOutput function of this script takes a gcode text and writes that with the positions converted into number of steps. ==Settings== ===Add Feed Rate Even When Unchanging=== Default is on. When selected, the feed rate will be added even when it did not change from the previous line. ===Add Space Between Words=== Default is on. When selected, a space will be added between each gcode word. ===Add Z Even When Unchanging=== Default is on. When selected, the z word will be added even when it did not change. ===Feed Rate Step Length=== Default is 0.1 millimeters/second. Defines the feed rate step length. ===Offset=== ====X Offset==== Default is zero. Defines the X Offset. ====Y Offset==== Default is zero. Defines the Y Offset. ====Z Offset==== Default is zero. Defines the Z Offset. ===Step Length=== ====E Step Length==== Default is 0.1 millimeters. Defines the E extrusion distance step length. ===Radius Rate Step Length=== Default is 0.1 millimeters/second. Defines the radius step length. ====X Step Length==== Default is 0.1 millimeters. Defines the X axis step length. ====Y Step Length==== Default is 0.1 millimeters. Defines the Y axis step length. ====Z Step Length==== Default is 0.01 millimeters. Defines the Z axis step length. """ from __future__ import absolute_import import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile from struct import Struct import cStringIO import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' # This is true if the output is text and false if it is binary. globalIsReplaceable = True def getCharacterIntegerString(character, offset, splitLine, stepLength): 'Get a character and integer string.' floatValue = getFloatFromCharacterSplitLine(character, splitLine) if floatValue is None: return '' floatValue += offset integerValue = int(round(float(floatValue / stepLength))) return character + str(integerValue) def getFloatFromCharacterSplitLine(character, splitLine): 'Get the float after the first occurence of the character in the split line.' lineFromCharacter = gcodec.getStringFromCharacterSplitLine(character, splitLine) if lineFromCharacter is None: return None return float(lineFromCharacter) def getNewRepository(): 'Get new repository.' return GcodeStepRepository() def getOutput(gcodeText, repository=None): 'Get the exported version of a gcode file.' if gcodeText == '': return '' if repository is None: repository = GcodeStepRepository() settings.getReadRepository(repository) return GcodeStepSkein().getCraftedGcode(repository, gcodeText) def writeOutput( fileName, gcodeText = ''): 'Write the exported version of a gcode file.' gcodeText = gcodec.getGcodeFileText(fileName, gcodeText) repository = GcodeStepRepository() settings.getReadRepository(repository) output = getOutput(gcodeText, repository) suffixFileName = fileName[: fileName.rfind('.')] + '_gcode_step.gcode' archive.writeFileText(suffixFileName, output) print('The converted file is saved as ' + archive.getSummarizedFileName(suffixFileName)) class GcodeStepRepository: 'A class to handle the export settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_step.html', self) self.addFeedRateEvenWhenUnchanging = settings.BooleanSetting().getFromValue('Add Feed Rate Even When Unchanging', self, True) self.addSpaceBetweenWords = settings.BooleanSetting().getFromValue('Add Space Between Words', self, True) self.addZEvenWhenUnchanging = settings.BooleanSetting().getFromValue('Add Z Even When Unchanging', self, True) self.fileNameInput = settings.FileNameInput().getFromFileName([('Gcode text files', '*.gcode')], 'Open File to be Converted to Gcode Step', self, '') self.feedRateStepLength = settings.FloatSpin().getFromValue(0.0, 'Feed Rate Step Length (millimeters/second)', self, 1.0, 0.1) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Offset -', self ) self.xOffset = settings.FloatSpin().getFromValue(-100.0, 'X Offset (millimeters)', self, 100.0, 0.0) self.yOffset = settings.FloatSpin().getFromValue(-100.0, 'Y Offset (millimeters)', self, 100.0, 0.0) self.zOffset = settings.FloatSpin().getFromValue(-10.0, 'Z Offset (millimeters)', self, 10.0, 0.0) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Step Length -', self ) self.eStepLength = settings.FloatSpin().getFromValue(0.0, 'E Step Length (float)', self, 1.0, 0.1) self.radiusStepLength = settings.FloatSpin().getFromValue(0.0, 'Radius Step Length (millimeters)', self, 1.0, 0.1) self.xStepLength = settings.FloatSpin().getFromValue(0.0, 'X Step Length (millimeters)', self, 1.0, 0.1) self.yStepLength = settings.FloatSpin().getFromValue(0.0, 'Y Step Length (millimeters)', self, 1.0, 0.1) self.zStepLength = settings.FloatSpin().getFromValue(0.0, 'Z Step Length (millimeters)', self, 0.2, 0.01) self.executeTitle = 'Convert to Gcode Step' def execute(self): 'Convert to gcode step button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, ['.gcode'], self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class GcodeStepSkein: 'A class to convert gcode into 16 byte binary segments.' def __init__(self): self.oldFeedRateString = None self.oldZString = None self.output = cStringIO.StringIO() def addCharacterInteger(self, character, lineStringIO, offset, splitLine, stepLength): 'Add a character and integer to line string.' characterIntegerString = getCharacterIntegerString(character, offset, splitLine, stepLength) self.addStringToLine(lineStringIO, characterIntegerString) def addLine(self, line): 'Add a line of text and a newline to the output.' self.output.write(line + '\n') def addStringToLine(self, lineStringIO, wordString): 'Add a character and integer to line string.' if wordString == '': return if self.repository.addSpaceBetweenWords.value: lineStringIO.write(' ') lineStringIO.write(wordString) def getCraftedGcode(self, repository, gcodeText): 'Parse gcode text and store the gcode.' self.repository = repository lines = archive.getTextLines(gcodeText) for line in lines: self.parseLine(line) return self.output.getvalue() def parseLine(self, line): 'Parse a gcode line.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if len(firstWord) < 1: return firstLetter = firstWord[0] if firstLetter == '(': return if firstWord != 'G1' and firstWord != 'G2' and firstWord != 'G3': self.addLine(line) return lineStringIO = cStringIO.StringIO() lineStringIO.write(firstWord) self.addCharacterInteger('I', lineStringIO, 0.0, splitLine, self.repository.xStepLength.value) self.addCharacterInteger('J', lineStringIO, 0.0, splitLine, self.repository.yStepLength.value) self.addCharacterInteger('R', lineStringIO, 0.0, splitLine, self.repository.radiusStepLength.value) self.addCharacterInteger('X', lineStringIO, self.repository.xOffset.value, splitLine, self.repository.xStepLength.value) self.addCharacterInteger('Y', lineStringIO, self.repository.yOffset.value, splitLine, self.repository.yStepLength.value) zString = getCharacterIntegerString('Z', self.repository.zOffset.value, splitLine, self.repository.zStepLength.value) feedRateString = getCharacterIntegerString('F', 0.0, splitLine, self.repository.feedRateStepLength.value) if zString != '': if zString != self.oldZString or self.repository.addZEvenWhenUnchanging.value: self.addStringToLine(lineStringIO, zString) if feedRateString != '': if feedRateString != self.oldFeedRateString or self.repository.addFeedRateEvenWhenUnchanging.value: self.addStringToLine(lineStringIO, feedRateString) self.addCharacterInteger('E', lineStringIO, 0.0, splitLine, self.repository.eStepLength.value) self.addLine(lineStringIO.getvalue()) self.oldFeedRateString = feedRateString self.oldZString = zString def main(): 'Display the export dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() gcode_time_segment.py000066400000000000000000000217741167321211700356750ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins""" This page is in the table of contents. Gcode time segment is an export plugin to convert gcode from float position to number of steps. An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getOutput function of this script takes a gcode text and returns it with the positions converted into number of steps and time. The writeOutput function of this script takes a gcode text and writes that with the positions converted into number of steps and time. ==Settings== ===Add Space Between Words=== Default is on. When selected, a space will be added between each gcode word. ===Offset=== ====X Offset==== Default is zero. Defines the X Offset. ====Y Offset==== Default is zero. Defines the Y Offset. ====Z Offset==== Default is zero. Defines the Z Offset. ===Step=== ===Extrusion Step=== Default is 0.01 mm. Defines the radius step length. ===Time Step=== Default is 1 microsecond(mcs). Defines the time step duration. ====X Step==== Default is 0.1 mm. Defines the X axis step length. ====Y Step==== Default is 0.1 mm. Defines the Y axis step length. ====Z Step==== Default is 0.01 mm. Defines the Z axis step length. """ from __future__ import absolute_import import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile from struct import Struct import cStringIO import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' # This is true if the output is text and false if it is binary." globalIsReplaceable = True def getCharacterIntegerString( character, offset, splitLine, step ): "Get a character and integer string." floatValue = getFloatFromCharacterSplitLine(character, splitLine) if floatValue is None: return None floatValue += offset integerValue = int(round(float(floatValue / step))) return character + str( integerValue ) def getFloatFromCharacterSplitLine(character, splitLine): "Get the float after the first occurence of the character in the split line." lineFromCharacter = gcodec.getStringFromCharacterSplitLine(character, splitLine) if lineFromCharacter is None: return None return float(lineFromCharacter) def getNewRepository(): 'Get new repository.' return GcodeTimeSegmentRepository() def getOutput(gcodeText, repository=None): 'Get the exported version of a gcode file.' if gcodeText == '': return '' if repository is None: repository = GcodeTimeSegmentRepository() settings.getReadRepository(repository) return GcodeTimeSegmentSkein().getCraftedGcode(gcodeText, repository) def writeOutput( fileName, gcodeText = ''): "Write the exported version of a gcode file." gcodeText = gcodec.getGcodeFileText(fileName, gcodeText) repository = GcodeTimeSegmentRepository() settings.getReadRepository(repository) output = getOutput(gcodeText, repository) suffixFileName = fileName[ : fileName.rfind('.') ] + '_gcode_time_segment.gcode' archive.writeFileText( suffixFileName, output ) print('The converted file is saved as ' + archive.getSummarizedFileName(suffixFileName) ) class GcodeTimeSegmentRepository: "A class to handle the export settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_time.html', self) self.addSpaceBetweenWords = settings.BooleanSetting().getFromValue('Add Space Between Words', self, True ) self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File to be Converted to Gcode Time', self, '') self.initialTime = settings.FloatSpin().getFromValue(0.0, 'Initial Time (s)', self, 20.0, 10.0) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Offset -', self ) self.xOffset = settings.FloatSpin().getFromValue( - 100.0, 'X Offset (mm)', self, 100.0, 0.0 ) self.yOffset = settings.FloatSpin().getFromValue( -100.0, 'Y Offset (mm)', self, 100.0, 0.0 ) self.zOffset = settings.FloatSpin().getFromValue( - 10.0, 'Z Offset (mm)', self, 10.0, 0.0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Step -', self ) self.extrusionStep = settings.FloatSpin().getFromValue(0.0, 'Extrusion Step (mm)', self, 0.2, 0.01) self.timeStep = settings.FloatSpin().getFromValue(0.0, 'Time Step (mcs)', self, 2000.0, 1000.0) self.xStep = settings.FloatSpin().getFromValue(0.0, 'X Step (mm)', self, 1.0, 0.1) self.yStep = settings.FloatSpin().getFromValue(0.0, 'Y Step (mm)', self, 1.0, 0.1) self.zStep = settings.FloatSpin().getFromValue(0.0, 'Z Step (mm)', self, 0.2, 0.01) settings.LabelSeparator().getFromRepository(self) self.executeTitle = 'Convert to Gcode Time' def execute(self): "Convert to gcode step button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, ['.gcode'], self.fileNameInput.wasCancelled ) for fileName in fileNames: writeOutput(fileName) class GcodeTimeSegmentSkein: "A class to convert gcode into time segments." def __init__(self): 'Initialize.' self.feedRateMinute = None self.isExtruderActive = False self.oldFeedRateString = None self.oldLocation = None self.oldZString = None self.operatingFlowRate = None self.output = cStringIO.StringIO() def addCharacterInteger(self, character, lineStringIO, offset, splitLine, step): "Add a character and integer to line string." characterIntegerString = getCharacterIntegerString(character, offset, splitLine, step) self.addStringToLine(lineStringIO, characterIntegerString) def addLine(self, line): "Add a line of text and a newline to the output." self.output.write(line + '\n') def addStringToLine( self, lineStringIO, wordString ): "Add a character and integer to line string." if wordString is None: return if self.repository.addSpaceBetweenWords.value: lineStringIO.write(' ') lineStringIO.write( wordString ) def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the gcode." self.repository = repository lines = archive.getTextLines(gcodeText) for line in lines: self.parseLine(line) return self.output.getvalue() def parseLine(self, line): "Parse a gcode line." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if len(firstWord) < 1: return firstLetter = firstWord[0] if firstWord == '(': self.feedRateMinute = 60.0 * float(splitLine[1]) elif firstWord == '(': self.operatingFlowRate = float(splitLine[1]) self.flowRate = self.operatingFlowRate if firstLetter == '(': return if firstWord == 'M101': self.isExtruderActive = True elif firstWord == 'M103': self.isExtruderActive = False elif firstWord == 'M108': self.flowRate = float(splitLine[1][1 :]) if firstWord != 'G1' and firstWord != 'G2' and firstWord != 'G3': self.addLine(line) return self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) lineStringIO = cStringIO.StringIO() lineStringIO.write(firstWord) location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.addCharacterInteger('X', lineStringIO, self.repository.xOffset.value, splitLine, self.repository.xStep.value ) self.addCharacterInteger('Y', lineStringIO, self.repository.yOffset.value, splitLine, self.repository.yStep.value ) zString = getCharacterIntegerString('Z', self.repository.zOffset.value, splitLine, self.repository.zStep.value ) if zString is None: zString = self.oldZString self.addStringToLine(lineStringIO, zString) duration = self.repository.initialTime.value if self.oldLocation is not None: distance = abs(location - self.oldLocation) duration = 60.0 / self.feedRateMinute * distance extrusionDistance = 0.0 if self.isExtruderActive: extrusionDistance = self.flowRate * duration self.addStringToLine(lineStringIO, 'E%s' % int(round(extrusionDistance / self.repository.extrusionStep.value))) self.addStringToLine(lineStringIO, 'D%s' % int(round(duration * 1000000.0 / self.repository.timeStep.value))) self.addLine(lineStringIO.getvalue()) self.oldLocation = location self.oldZString = zString def main(): "Display the export dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() 000077500000000000000000000000001167321211700345175ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins__init__.py000066400000000000000000000006571167321211700366400ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 5 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) gcode_gen3.py000066400000000000000000000112751167321211700370740ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins""" This page is in the table of contents. Gcode_small is an export plugin to remove the comments and the redundant z and feed rate parameters from a gcode file. An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getOutput function of this script takes a gcode text and returns that text without comments and redundant z and feed rate parameters. The writeOutput function of this script takes a gcode text and writes that text without comments and redundant z and feed rate parameters to a file. Many of the functions in this script are copied from gcodec in skeinforge_utilities. They are copied rather than imported so developers making new plugins do not have to learn about gcodec, the code here is all they need to learn. """ from __future__ import absolute_import import cStringIO import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' # This is true if the output is text and false if it is binary." globalIsReplaceable = True def getOutput(gcodeText): """Get the exported version of a gcode file.""" return GcodeSmallSkein().getCraftedGcode(gcodeText) def getSplitLineBeforeBracketSemicolon(line): """Get the split line before a bracket or semicolon.""" bracketSemicolonIndex = min( line.find(';'), line.find('(') ) if bracketSemicolonIndex < 0: return line.split() return line[ : bracketSemicolonIndex ].split() def getStringFromCharacterSplitLine(character, splitLine): """Get the string after the first occurence of the character in the split line.""" indexOfCharacter = getIndexOfStartingWithSecond(character, splitLine) if indexOfCharacter < 0: return None return splitLine[indexOfCharacter][1 :] def getSummarizedFileName(fileName): """Get the fileName basename if the file is in the current working directory, otherwise return the original full name.""" if os.getcwd() == os.path.dirname(fileName): return os.path.basename(fileName) return fileName def getTextLines(text): """Get the all the lines of text of a text.""" return text.replace('\r', '\n').split('\n') def getIndexOfStartingWithSecond(letter, splitLine): """Get index of the first occurence of the given letter in the split line, starting with the second word. Return - 1 if letter is not found""" for wordIndex in xrange( 1, len(splitLine) ): word = splitLine[ wordIndex ] firstLetter = word[0] if firstLetter == letter: return wordIndex return - 1 class GcodeSmallSkein: """A class to remove redundant z and feed rate parameters from a skein of extrusions.""" def __init__(self): self.lastFeedRateString = None self.lastZString = None self.output = cStringIO.StringIO() def getCraftedGcode( self, gcodeText ): """Parse gcode text and store the gcode.""" lines = getTextLines(gcodeText) for line in lines: self.parseLine(line) return self.output.getvalue() def parseLine(self, line): """Parse a gcode line.""" splitLine = getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if len(firstWord) < 1: return if firstWord[0] == '(': return if firstWord != 'G1': self.output.write(line + '\n') return eString = getStringFromCharacterSplitLine('E', splitLine ) xString = getStringFromCharacterSplitLine('X', splitLine ) yString = getStringFromCharacterSplitLine('Y', splitLine ) zString = getStringFromCharacterSplitLine('Z', splitLine ) feedRateString = getStringFromCharacterSplitLine('F', splitLine ) if zString is not None and zString != self.lastZString: self.output.write('G1') self.output.write(' F50') self.output.write(' Z' + zString ) self.output.write(' F50') self.output.write('\n') self.output.write('G1') if feedRateString is not None : self.output.write(' F' + feedRateString ) self.output.write('\n') self.output.write('G1') if xString is not None: self.output.write(' X' + xString ) if yString is not None: self.output.write(' Y' + yString ) """if zString is not None and zString != self.lastZString: self.output.write(' Z' + zString )""" if feedRateString is not None and feedRateString != self.lastFeedRateString: self.output.write(' F' + feedRateString ) if eString is not None: self.output.write(' E' + eString ) self.lastFeedRateString = feedRateString self.lastZString = zString self.output.write('\n') gcode_small.py000066400000000000000000000104411167321211700373420ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins""" This page is in the table of contents. Gcode_small is an export plugin to remove the comments and the redundant z and feed rate parameters from a gcode file. An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name. The getOutput function of this script takes a gcode text and returns that text without comments and redundant z and feed rate parameters. The writeOutput function of this script takes a gcode text and writes that text without comments and redundant z and feed rate parameters to a file. Many of the functions in this script are copied from gcodec in skeinforge_utilities. They are copied rather than imported so developers making new plugins do not have to learn about gcodec, the code here is all they need to learn. """ from __future__ import absolute_import import cStringIO import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' # This is true if the output is text and false if it is binary." globalIsReplaceable = True def getIndexOfStartingWithSecond(letter, splitLine): "Get index of the first occurence of the given letter in the split line, starting with the second word. Return - 1 if letter is not found" for wordIndex in xrange( 1, len(splitLine) ): word = splitLine[ wordIndex ] firstLetter = word[0] if firstLetter == letter: return wordIndex return - 1 def getOutput(gcodeText): 'Get the exported version of a gcode file.' return GcodeSmallSkein().getCraftedGcode(gcodeText) def getSplitLineBeforeBracketSemicolon(line): "Get the split line before a bracket or semicolon." bracketSemicolonIndex = min( line.find(';'), line.find('(') ) if bracketSemicolonIndex < 0: return line.split() return line[ : bracketSemicolonIndex ].split() def getStringFromCharacterSplitLine(character, splitLine): "Get the string after the first occurence of the character in the split line." indexOfCharacter = getIndexOfStartingWithSecond(character, splitLine) if indexOfCharacter < 0: return None return splitLine[indexOfCharacter][1 :] def getSummarizedFileName(fileName): "Get the fileName basename if the file is in the current working directory, otherwise return the original full name." if os.getcwd() == os.path.dirname(fileName): return os.path.basename(fileName) return fileName def getTextLines(text): "Get the all the lines of text of a text." return text.replace('\r', '\n').split('\n') class GcodeSmallSkein: "A class to remove redundant z and feed rate parameters from a skein of extrusions." def __init__(self): self.lastFeedRateString = None self.lastZString = None self.output = cStringIO.StringIO() def getCraftedGcode( self, gcodeText ): "Parse gcode text and store the gcode." lines = getTextLines(gcodeText) for line in lines: self.parseLine(line) return self.output.getvalue() def parseLine(self, line): "Parse a gcode line." splitLine = getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if len(firstWord) < 1: return if firstWord[0] == '(': return if firstWord != 'G1': self.output.write(line + '\n') return eString = getStringFromCharacterSplitLine('E', splitLine ) xString = getStringFromCharacterSplitLine('X', splitLine ) yString = getStringFromCharacterSplitLine('Y', splitLine ) zString = getStringFromCharacterSplitLine('Z', splitLine ) feedRateString = getStringFromCharacterSplitLine('F', splitLine ) self.output.write('G1') if xString is not None: self.output.write(' X' + xString ) if yString is not None: self.output.write(' Y' + yString ) if zString is not None and zString != self.lastZString: self.output.write(' Z' + zString ) if feedRateString is not None and feedRateString != self.lastFeedRateString: self.output.write(' F' + feedRateString ) if eString is not None: self.output.write(' E' + eString ) self.lastFeedRateString = feedRateString self.lastZString = zString self.output.write('\n') sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/feed.py000066400000000000000000000162471167321211700277530ustar00rootroot00000000000000""" This page is in the table of contents. The feed script sets the maximum feed rate, operating feed rate & travel feed rate. ==Operation== The default 'Activate Feed' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Feed Rate=== Default is 16 millimeters/second. Defines the feed rate for the shape. ===Maximum Z Drill Feed Rate=== Default is 0.1 millimeters/second. If your firmware limits the z feed rate, you do not need to set this setting. Defines the maximum feed that the tool head will move in the z direction while the tool is on. ===Maximum Z Feed Rate=== Default is one millimeter per second. Defines the maximum speed that the tool head will move in the z direction. ===Travel Feed Rate=== Default is 16 millimeters/second. Defines the feed rate when the cutter is off. The travel feed rate could be set as high as the cutter can be moved, it does not have to be limited by the maximum cutter rate. ==Examples== The following examples feed the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and feed.py. > python feed.py This brings up the feed dialog. > python feed.py Screw Holder Bottom.stl The feed tool is parsing the file: Screw Holder Bottom.stl .. The feed tool has created the file: .. Screw Holder Bottom_feed.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, gcodeText='', repository=None): "Feed the file or text." return getCraftedTextFromText( archive.getTextIfEmpty( fileName, gcodeText ), repository ) def getCraftedTextFromText(gcodeText, repository=None): "Feed a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'feed'): return gcodeText if repository is None: repository = settings.getReadRepository(FeedRepository()) if not repository.activateFeed.value: return gcodeText return FeedSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return FeedRepository() def writeOutput(fileName, shouldAnalyze=True): "Feed a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'feed', shouldAnalyze) class FeedRepository: "A class to handle the feed settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.feed.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Feed', self, '') self.activateFeed = settings.BooleanSetting().getFromValue('Activate Feed', self, True) self.feedRatePerSecond = settings.FloatSpin().getFromValue(2.0, 'Feed Rate (mm/s):', self, 50.0, 16.0) self.maximumZDrillFeedRatePerSecond = settings.FloatSpin().getFromValue(0.02, 'Maximum Z Drill Feed Rate (mm/s):', self, 0.5, 0.1) self.maximumZFeedRatePerSecond = settings.FloatSpin().getFromValue(0.5, 'Maximum Z Feed Rate (mm/s):', self, 10.0, 1.0) self.travelFeedRatePerSecond = settings.FloatSpin().getFromValue(2.0, 'Travel Feed Rate (mm/s):', self, 50.0, 16.0) self.executeTitle = 'Feed' def execute(self): "Feed button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class FeedSkein: "A class to feed a skein of cuttings." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRatePerSecond = 16.0 self.isExtruderActive = False self.lineIndex = 0 self.lines = None self.oldFlowrateString = None self.oldLocation = None def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the feed gcode." self.repository = repository self.feedRatePerSecond = repository.feedRatePerSecond.value self.travelFeedRateMinute = 60.0 * self.repository.travelFeedRatePerSecond.value self.lines = archive.getTextLines(gcodeText) self.parseInitialization() for line in self.lines[self.lineIndex :]: self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getFeededLine(self, line, splitLine): "Get gcode line with feed rate." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.oldLocation = location feedRateMinute = 60.0 * self.feedRatePerSecond if not self.isExtruderActive: feedRateMinute = self.travelFeedRateMinute return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line, splitLine) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('feed') return elif firstWord == '(': self.absolutePerimeterWidth = abs(float(splitLine[1])) self.distanceFeedRate.addTagBracketedLine('maximumZDrillFeedRatePerSecond', self.repository.maximumZDrillFeedRatePerSecond.value) self.distanceFeedRate.addTagBracketedLine('maximumZFeedRatePerSecond', self.repository.maximumZFeedRatePerSecond.value ) self.distanceFeedRate.addTagBracketedLine('operatingFeedRatePerSecond', self.feedRatePerSecond) self.distanceFeedRate.addTagBracketedLine('travelFeedRatePerSecond', self.repository.travelFeedRatePerSecond.value) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the feed skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': line = self.getFeededLine(line, splitLine) elif firstWord == 'M101': self.isExtruderActive = True elif firstWord == 'M103': self.isExtruderActive = False self.distanceFeedRate.addLine(line) def main(): 'Display the feed dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/fill.py000066400000000000000000002214001167321211700277630ustar00rootroot00000000000000#! /usr/bin/env python """ This page is in the table of contents. Fill is a script to fill the perimeters of a gcode file. The fill manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fill Allan Ecker aka The Masked Retriever has written the "Skeinforge Quicktip: Fill" at: http://blog.thingiverse.com/2009/07/21/mysteries-of-skeinforge-fill/ ==Operation== The default 'Activate Fill' checkbox is off. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Diaphragm=== The diaphragm is a solid group of layers, at regular intervals. It can be used with a sparse infill to give the object watertight, horizontal compartments and/or a higher shear strength. ====Diaphragm Period==== Default is one hundred. Defines the number of layers between diaphrams. ====Diaphragm Thickness==== Default is zero, because the diaphragm feature is rarely used. Defines the number of layers the diaphram is composed of. ===Extra Shells=== The shells interior perimeter loops. Adding extra shells makes the object stronger & heavier. ====Extra Shells on Alternating Solid Layers==== Default is two. Defines the number of extra shells, on the alternating solid layers. ====Extra Shells on Base==== Default is one. Defines the number of extra shells on the bottom, base layer and every even solid layer after that. Setting this to a different value than the "Extra Shells on Alternating Solid Layers" means the infill pattern will alternate, creating a strong interleaved bond even if the perimeter loop shrinks. ====Extra Shells on Sparse Layer==== Default is one. Defines the number of extra shells on the sparse layers. The solid layers are those at the top & bottom, and wherever the object has a plateau or overhang, the sparse layers are the layers in between. ===Grid=== ====Grid Circle Separation over Perimeter Width==== Default is 0.2. Defines the ratio of the amount the grid circle is inset over the perimeter width, the default is zero. With a value of zero the circles will touch, with a value of one two threads could be fitted between the circles. ====Grid Extra Overlap==== Default is 0.1. Defines the amount of extra overlap added when extruding the grid to compensate for the fact that when the first thread going through a grid point is extruded, since there is nothing there yet for it to connect to it will shrink extra. ====Grid Junction Separation over Octogon Radius At End==== Default is zero. Defines the ratio of the amount the grid square is increased in each direction over the extrusion width at the end. With a value of one or so the grid pattern will have large squares to go with the octogons. ====Grid Junction Separation over Octogon Radius At Middle==== Default is zero. Defines the increase at the middle. If this value is different than the value at the end, the grid would have an accordion pattern, which would give it a higher shear strength. ====Grid Junction Separation Band Height==== Default is ten. Defines the height of the bands of the accordion pattern. ===Infill=== ====Infill Pattern==== Default is 'Line', since it is quicker to generate and does not add extra movements for the extruder. The grid pattern has extra diagonal lines, so when choosing a grid option, set the infill solidity to 0.2 or less so that there is not too much plastic and the grid generation time, which increases with the third power of solidity, will be reasonable. =====Grid Circular===== When selected, the infill will be a grid of separated circles. Because the circles are separated, the pattern is weak, it only provides support for the top layer threads and some strength in the z direction. The flip side is that this infill does not warp the object, the object will get warped only by the walls. Because this pattern turns the extruder on and off often, it is best to use a stepper motor extruder. =====Grid Hexagonal===== When selected, the infill will be a hexagonal grid. Because the grid is made with threads rather than with molding or milling, only a partial hexagon is possible, so the rectangular grid pattern is stronger. =====Grid Rectangular===== When selected, the infill will be a funky octogon square honeycomb like pattern which gives the object extra strength. =====Line===== When selected, the infill will be made up of lines. ====Infill Begin Rotation==== Default is forty five degrees, giving a diagonal infill. Defines the amount the infill direction of the base and every second layer thereafter is rotated. ====Infill Odd Layer Extra Rotation==== Default is ninety degrees, making the odd layer infill perpendicular to the base layer. Defines the extra amount the infill direction of the odd layers is rotated compared to the base layer. ====Infill Begin Rotation Repeat==== Default is one, giving alternating cross hatching. Defines the number of layers that the infill begin rotation will repeat. With a value higher than one, the infill will go in one direction more often, giving the object more strength in one direction and less in the other, this is useful for beams and cantilevers. ====Infill Perimeter Overlap==== Default is 0.15. Defines the amount the infill overlaps the perimeter over the average of the perimeter and infill width. The higher the value the more the infill will overlap the perimeter, and the thicker join between the infill and the perimeter. If the value is too high, the join will be so thick that the nozzle will run plow through the join below making a mess, also when it is above 0.45 fill may not be able to create infill correctly. If you want to stretch the infill a lot, set 'Path Stretch over Perimeter Width' in stretch to a high value. ====Infill Solidity==== Default is 0.2. Defines the solidity of the infill, this is the most important setting in fill. A value of one means the infill lines will be right beside each other, resulting in a solid, strong, heavy shape which takes a long time to extrude. A low value means the infill will be sparse, the interior will be mosty empty space, the object will be weak, light and quick to build. ====Infill Width over Thickness==== Default is 1.5. Defines the ratio of the infill width over the layer thickness. The higher the value the wider apart the infill will be and therefore the sparser the infill will be. ===Solid Surface Thickness=== Default is three. Defines the number of solid layers that are at the bottom, top, plateaus and overhang. With a value of zero, the entire object will be composed of a sparse infill, and water could flow right through it. With a value of one, water will leak slowly through the surface and with a value of three, the object could be watertight. The higher the solid surface thickness, the stronger and heavier the object will be. ===Start From Choice=== Default is 'Lower Left'. Defines where each layer starts from. ====Lower Left==== When selected the layer will start from the lower left corner. This is to extrude in round robin fashion so that the first extrusion will be deposited on the coolest part of the last layer. The reason for this is described at: http://hydraraptor.blogspot.com/2010/12/round-robin.html ====Nearest==== When selected the layer will start from the closest point to the end of the last layer. This leads to less stringing, but the first extrusion will be deposited on the hottest part of the last layer which leads to melting problems. So this option is deprecated, eventually this option will be removed and the layers will always start from the lower left. ===Surrounding Angle=== Default: 60 degrees Defines the angle that the surrounding layers around the infill are expanded. To decide whether or not the infill should be sparse or solid, fill looks at the 'Solid Surface Thickness' surrounding layers above and below the infill. If any of the expanded layers above or below the infill do not cover the infill, then the infill will be solid in that region. The layers are expanded by the height difference times the tangent of the surrounding angle, which is from the vertical. For example, if the model is a wedge with a wall angle less than the surrounding angle, the interior layers (those which are not on the bottom or top) will be sparse. If the wall angle is greater than the surrounding angle, the interior layers will be solid. The time required to examine the surrounding layers increases with the surrounding angle, so the surrounding angle is limited to eighty degrees, regardless of the input value. If you have an organic shape with gently sloping surfaces; if the surrounding angle is set too high, then too many layers will be sparse. If the surrounding angle is too low, then too many layers will be solid and the extruder may end up plowing through previous layers: http://hydraraptor.blogspot.com/2008/08/bearing-fruit.html ===Thread Sequence Choice=== The 'Thread Sequence Choice' is the sequence in which the threads will be extruded on the second and higher layers. There are three kinds of thread, the perimeter threads on the outside of the object, the loop threads aka inner shell threads, and the interior infill threads. The first layer thread sequence is 'Perimeter > Loops > Infill'. The default choice is 'Perimeter > Loops > Infill', which the default stretch parameters are based on. If you change from the default sequence choice setting of perimeter, then loops, then infill, the optimal stretch thread parameters would also be different. In general, if the infill is extruded first, the infill would have to be stretched more so that even after the filament shrinkage, it would still be long enough to connect to the loop or perimeter. The six sequence combinations follow below. ====Infill > Loops > Perimeter==== ====Infill > Perimeter > Loops==== ====Loops > Infill > Perimeter==== ====Loops > Perimeter > Infill==== ====Perimeter > Infill > Loops==== ====Perimeter > Loops > Infill==== ==Examples== The following examples fill the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and fill.py. > python fill.py This brings up the fill dialog. > python fill.py Screw Holder Bottom.stl The fill tool is parsing the file: Screw Holder Bottom.stl .. The fill tool has created the file: .. Screw Holder Bottom_fill.gcode """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/28/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addAroundGridPoint( arounds, gridPoint, gridPointInsetX, gridPointInsetY, gridPoints, gridSearchRadius, isBothOrNone, isDoubleJunction, isJunctionWide, paths, pixelTable, width ): 'Add the path around the grid point.' closestPathIndex = None aroundIntersectionPaths = [] for aroundIndex in xrange( len(arounds) ): loop = arounds[ aroundIndex ] for pointIndex in xrange(len(loop)): pointFirst = loop[pointIndex] pointSecond = loop[(pointIndex + 1) % len(loop)] yIntersection = euclidean.getYIntersectionIfExists( pointFirst, pointSecond, gridPoint.real ) addYIntersectionPathToList( aroundIndex, pointIndex, gridPoint.imag, yIntersection, aroundIntersectionPaths ) if len( aroundIntersectionPaths ) < 2: print('This should never happen, aroundIntersectionPaths is less than 2 in fill.') print( aroundIntersectionPaths ) print( gridPoint ) return yCloseToCenterArounds = getClosestOppositeIntersectionPaths( aroundIntersectionPaths ) if len( yCloseToCenterArounds ) < 2: # This used to be worth the warning below. # print('This should never happen, yCloseToCenterArounds is less than 2 in fill.') # print( gridPoint ) # print( len( yCloseToCenterArounds ) ) return segmentFirstY = min( yCloseToCenterArounds[0].y, yCloseToCenterArounds[1].y ) segmentSecondY = max( yCloseToCenterArounds[0].y, yCloseToCenterArounds[1].y ) yIntersectionPaths = [] gridPixel = euclidean.getStepKeyFromPoint( gridPoint / width ) segmentFirstPixel = euclidean.getStepKeyFromPoint( complex( gridPoint.real, segmentFirstY ) / width ) segmentSecondPixel = euclidean.getStepKeyFromPoint( complex( gridPoint.real, segmentSecondY ) / width ) pathIndexTable = {} addPathIndexFirstSegment( gridPixel, pathIndexTable, pixelTable, segmentFirstPixel ) addPathIndexSecondSegment( gridPixel, pathIndexTable, pixelTable, segmentSecondPixel ) for pathIndex in pathIndexTable.keys(): path = paths[ pathIndex ] for pointIndex in xrange( len(path) - 1 ): pointFirst = path[pointIndex] pointSecond = path[pointIndex + 1] yIntersection = getYIntersectionInsideYSegment( segmentFirstY, segmentSecondY, pointFirst, pointSecond, gridPoint.real ) addYIntersectionPathToList( pathIndex, pointIndex, gridPoint.imag, yIntersection, yIntersectionPaths ) if len( yIntersectionPaths ) < 1: return yCloseToCenterPaths = [] if isDoubleJunction: yCloseToCenterPaths = getClosestOppositeIntersectionPaths( yIntersectionPaths ) else: yIntersectionPaths.sort( compareDistanceFromCenter ) yCloseToCenterPaths = [ yIntersectionPaths[0] ] for yCloseToCenterPath in yCloseToCenterPaths: setIsOutside( yCloseToCenterPath, aroundIntersectionPaths ) if len( yCloseToCenterPaths ) < 2: yCloseToCenterPaths[0].gridPoint = gridPoint insertGridPointPair( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, paths, pixelTable, yCloseToCenterPaths[0], width ) return plusMinusSign = getPlusMinusSign( yCloseToCenterPaths[1].y - yCloseToCenterPaths[0].y ) yCloseToCenterPaths[0].gridPoint = complex( gridPoint.real, gridPoint.imag - plusMinusSign * gridPointInsetY ) yCloseToCenterPaths[1].gridPoint = complex( gridPoint.real, gridPoint.imag + plusMinusSign * gridPointInsetY ) yCloseToCenterPaths.sort( comparePointIndexDescending ) insertGridPointPairs( gridPoint, gridPointInsetX, gridPoints, yCloseToCenterPaths[0], yCloseToCenterPaths[1], isBothOrNone, isJunctionWide, paths, pixelTable, width ) def addInfillBoundary(infillBoundary, nestedRings): 'Add infill boundary to the nested ring that contains it.' infillPoint = infillBoundary[0] for nestedRing in nestedRings: if euclidean.isPointInsideLoop(nestedRing.boundary, infillPoint): nestedRing.infillBoundaries.append(infillBoundary) return def addLoop(infillWidth, infillPaths, loop, rotationPlaneAngle): 'Add simplified path to fill.' simplifiedLoop = euclidean.getSimplifiedLoop(loop, infillWidth) if len(simplifiedLoop) < 2: return simplifiedLoop.append(simplifiedLoop[0]) planeRotated = euclidean.getRotatedComplexes(rotationPlaneAngle, simplifiedLoop) infillPaths.append(planeRotated) def addPath(infillWidth, infillPaths, path, rotationPlaneAngle): 'Add simplified path to fill.' simplifiedPath = euclidean.getSimplifiedPath(path, infillWidth) if len(simplifiedPath) < 2: return planeRotated = euclidean.getRotatedComplexes(rotationPlaneAngle, simplifiedPath) infillPaths.append(planeRotated) def addPathIndexFirstSegment( gridPixel, pathIndexTable, pixelTable, segmentFirstPixel ): 'Add the path index of the closest segment found toward the second segment.' for yStep in xrange( gridPixel[1], segmentFirstPixel[1] - 1, - 1 ): if getKeyIsInPixelTableAddValue( ( gridPixel[0], yStep ), pathIndexTable, pixelTable ): return def addPathIndexSecondSegment( gridPixel, pathIndexTable, pixelTable, segmentSecondPixel ): 'Add the path index of the closest segment found toward the second segment.' for yStep in xrange( gridPixel[1], segmentSecondPixel[1] + 1 ): if getKeyIsInPixelTableAddValue( ( gridPixel[0], yStep ), pathIndexTable, pixelTable ): return def addPointOnPath( path, pathIndex, pixelTable, point, pointIndex, width ): 'Add a point to a path and the pixel table.' pointIndexMinusOne = pointIndex - 1 if pointIndex < len(path) and pointIndexMinusOne >= 0: segmentTable = {} begin = path[ pointIndexMinusOne ] end = path[pointIndex] euclidean.addValueSegmentToPixelTable( begin, end, segmentTable, pathIndex, width ) euclidean.removePixelTableFromPixelTable( segmentTable, pixelTable ) if pointIndexMinusOne >= 0: begin = path[ pointIndexMinusOne ] euclidean.addValueSegmentToPixelTable( begin, point, pixelTable, pathIndex, width ) if pointIndex < len(path): end = path[pointIndex] euclidean.addValueSegmentToPixelTable( point, end, pixelTable, pathIndex, width ) path.insert( pointIndex, point ) def addPointOnPathIfFree( path, pathIndex, pixelTable, point, pointIndex, width ): 'Add the closest point to a path, if the point added to a path is free.' if isAddedPointOnPathFree( path, pixelTable, point, pointIndex, width ): addPointOnPath( path, pathIndex, pixelTable, point, pointIndex, width ) def addSparseEndpoints(doubleInfillWidth, endpoints, horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey, infillSolidity, removedEndpoints, solidSurfaceThickness, surroundingXIntersections): 'Add sparse endpoints.' segments = horizontalSegmentsDictionary[horizontalSegmentsDictionaryKey] for segment in segments: addSparseEndpointsFromSegment(doubleInfillWidth, endpoints, horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey, infillSolidity, removedEndpoints, segment, solidSurfaceThickness, surroundingXIntersections) def addSparseEndpointsFromSegment(doubleInfillWidth, endpoints, horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey, infillSolidity, removedEndpoints, segment, solidSurfaceThickness, surroundingXIntersections): 'Add sparse endpoints from a segment.' if infillSolidity > 0.0: if int(round(round(float(horizontalSegmentsDictionaryKey) * infillSolidity) / infillSolidity)) == horizontalSegmentsDictionaryKey: endpoints += segment return if abs(segment[0].point - segment[1].point) < doubleInfillWidth: endpoints += segment return if not isSegmentAround(horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey - 1, segment): endpoints += segment return if not isSegmentAround(horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey + 1, segment): endpoints += segment return if solidSurfaceThickness == 0: removedEndpoints += segment return if isSegmentCompletelyInAnIntersection(segment, surroundingXIntersections): removedEndpoints += segment return endpoints += segment def addYIntersectionPathToList( pathIndex, pointIndex, y, yIntersection, yIntersectionPaths ): 'Add the y intersection path to the y intersection paths.' if yIntersection is None: return yIntersectionPath = YIntersectionPath( pathIndex, pointIndex, yIntersection ) yIntersectionPath.yMinusCenter = yIntersection - y yIntersectionPaths.append( yIntersectionPath ) def compareDistanceFromCenter(self, other): 'Get comparison in order to sort y intersections in ascending order of distance from the center.' distanceFromCenter = abs( self.yMinusCenter ) distanceFromCenterOther = abs( other.yMinusCenter ) if distanceFromCenter > distanceFromCenterOther: return 1 if distanceFromCenter < distanceFromCenterOther: return - 1 return 0 def comparePointIndexDescending(self, other): 'Get comparison in order to sort y intersections in descending order of point index.' if self.pointIndex > other.pointIndex: return - 1 if self.pointIndex < other.pointIndex: return 1 return 0 def createExtraFillLoops(nestedRing, radius, radiusAround, shouldExtraLoopsBeAdded): 'Create extra fill loops.' for innerNestedRing in nestedRing.innerNestedRings: createFillForSurroundings(innerNestedRing.innerNestedRings, radius, radiusAround, shouldExtraLoopsBeAdded) allFillLoops = intercircle.getInsetSeparateLoopsFromAroundLoops(nestedRing.getLoopsToBeFilled(), radius, max(1.4 * radius, radiusAround)) if len(allFillLoops) < 1: return if shouldExtraLoopsBeAdded: nestedRing.extraLoops += allFillLoops nestedRing.penultimateFillLoops = nestedRing.lastFillLoops nestedRing.lastFillLoops = allFillLoops def createFillForSurroundings(nestedRings, radius, radiusAround, shouldExtraLoopsBeAdded): 'Create extra fill loops for nested rings.' for nestedRing in nestedRings: createExtraFillLoops(nestedRing, radius, radiusAround, shouldExtraLoopsBeAdded) def getAdditionalLength( path, point, pointIndex ): 'Get the additional length added by inserting a point into a path.' if pointIndex == 0: return abs( point - path[0] ) if pointIndex == len(path): return abs( point - path[-1] ) return abs( point - path[pointIndex - 1] ) + abs( point - path[pointIndex] ) - abs( path[pointIndex] - path[pointIndex - 1] ) def getClosestOppositeIntersectionPaths( yIntersectionPaths ): 'Get the close to center paths, starting with the first and an additional opposite if it exists.' yIntersectionPaths.sort( compareDistanceFromCenter ) beforeFirst = yIntersectionPaths[0].yMinusCenter < 0.0 yCloseToCenterPaths = [ yIntersectionPaths[0] ] for yIntersectionPath in yIntersectionPaths[1 :]: beforeSecond = yIntersectionPath.yMinusCenter < 0.0 if beforeFirst != beforeSecond: yCloseToCenterPaths.append( yIntersectionPath ) return yCloseToCenterPaths return yCloseToCenterPaths def getCraftedText( fileName, gcodeText = '', repository=None): 'Fill the inset file or gcode text.' return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), repository ) def getCraftedTextFromText(gcodeText, repository=None): 'Fill the inset gcode text.' if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'fill'): return gcodeText if repository is None: repository = settings.getReadRepository( FillRepository() ) if not repository.activateFill.value: return gcodeText return FillSkein().getCraftedGcode( repository, gcodeText ) def getKeyIsInPixelTableAddValue( key, pathIndexTable, pixelTable ): 'Determine if the key is in the pixel table, and if it is and if the value is not None add it to the path index table.' if key in pixelTable: value = pixelTable[key] if value is not None: pathIndexTable[value] = None return True return False def getLowerLeftCorner(nestedRings): 'Get the lower left corner from the nestedRings.' lowerLeftCorner = Vector3() lowestRealPlusImaginary = 987654321.0 for nestedRing in nestedRings: for point in nestedRing.boundary: realPlusImaginary = point.real + point.imag if realPlusImaginary < lowestRealPlusImaginary: lowestRealPlusImaginary = realPlusImaginary lowerLeftCorner.setToXYZ(point.real, point.imag, nestedRing.z) return lowerLeftCorner def getNewRepository(): 'Get new repository.' return FillRepository() def getNonIntersectingGridPointLine( gridPointInsetX, isJunctionWide, paths, pixelTable, yIntersectionPath, width ): 'Get the points around the grid point that is junction wide that do not intersect.' pointIndexPlusOne = yIntersectionPath.getPointIndexPlusOne() path = yIntersectionPath.getPath(paths) begin = path[ yIntersectionPath.pointIndex ] end = path[ pointIndexPlusOne ] plusMinusSign = getPlusMinusSign( end.real - begin.real ) if isJunctionWide: gridPointXFirst = complex( yIntersectionPath.gridPoint.real - plusMinusSign * gridPointInsetX, yIntersectionPath.gridPoint.imag ) gridPointXSecond = complex( yIntersectionPath.gridPoint.real + plusMinusSign * gridPointInsetX, yIntersectionPath.gridPoint.imag ) if isAddedPointOnPathFree( path, pixelTable, gridPointXSecond, pointIndexPlusOne, width ): if isAddedPointOnPathFree( path, pixelTable, gridPointXFirst, pointIndexPlusOne, width ): return [ gridPointXSecond, gridPointXFirst ] if isAddedPointOnPathFree( path, pixelTable, yIntersectionPath.gridPoint, pointIndexPlusOne, width ): return [ gridPointXSecond, yIntersectionPath.gridPoint ] return [ gridPointXSecond ] if isAddedPointOnPathFree( path, pixelTable, yIntersectionPath.gridPoint, pointIndexPlusOne, width ): return [ yIntersectionPath.gridPoint ] return [] def getPlusMinusSign(number): 'Get one if the number is zero or positive else negative one.' if number >= 0.0: return 1.0 return - 1.0 def getWithLeastLength( path, point ): 'Insert a point into a path, at the index at which the path would be shortest.' if len(path) < 1: return 0 shortestPointIndex = None shortestAdditionalLength = 999999999987654321.0 for pointIndex in xrange( len(path) + 1 ): additionalLength = getAdditionalLength( path, point, pointIndex ) if additionalLength < shortestAdditionalLength: shortestAdditionalLength = additionalLength shortestPointIndex = pointIndex return shortestPointIndex def getYIntersectionInsideYSegment( segmentFirstY, segmentSecondY, beginComplex, endComplex, x ): 'Get the y intersection inside the y segment if it does, else none.' yIntersection = euclidean.getYIntersectionIfExists( beginComplex, endComplex, x ) if yIntersection is None: return None if yIntersection < min( segmentFirstY, segmentSecondY ): return None if yIntersection <= max( segmentFirstY, segmentSecondY ): return yIntersection return None def insertGridPointPair( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, paths, pixelTable, yIntersectionPath, width ): 'Insert a pair of points around the grid point is is junction wide, otherwise inset one point.' linePath = getNonIntersectingGridPointLine( gridPointInsetX, isJunctionWide, paths, pixelTable, yIntersectionPath, width ) insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, linePath, paths, pixelTable, yIntersectionPath, width ) def insertGridPointPairs( gridPoint, gridPointInsetX, gridPoints, intersectionPathFirst, intersectionPathSecond, isBothOrNone, isJunctionWide, paths, pixelTable, width ): 'Insert a pair of points around a pair of grid points.' gridPointLineFirst = getNonIntersectingGridPointLine( gridPointInsetX, isJunctionWide, paths, pixelTable, intersectionPathFirst, width ) if len( gridPointLineFirst ) < 1: if isBothOrNone: return intersectionPathSecond.gridPoint = gridPoint insertGridPointPair( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, paths, pixelTable, intersectionPathSecond, width ) return gridPointLineSecond = getNonIntersectingGridPointLine( gridPointInsetX, isJunctionWide, paths, pixelTable, intersectionPathSecond, width ) if len( gridPointLineSecond ) > 0: insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, gridPointLineFirst, paths, pixelTable, intersectionPathFirst, width ) insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, gridPointLineSecond, paths, pixelTable, intersectionPathSecond, width ) return if isBothOrNone: return originalGridPointFirst = intersectionPathFirst.gridPoint intersectionPathFirst.gridPoint = gridPoint gridPointLineFirstCenter = getNonIntersectingGridPointLine( gridPointInsetX, isJunctionWide, paths, pixelTable, intersectionPathFirst, width ) if len( gridPointLineFirstCenter ) > 0: insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, gridPointLineFirstCenter, paths, pixelTable, intersectionPathFirst, width ) return intersectionPathFirst.gridPoint = originalGridPointFirst insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, gridPointLineFirst, paths, pixelTable, intersectionPathFirst, width ) def insertGridPointPairWithLinePath( gridPoint, gridPointInsetX, gridPoints, isJunctionWide, linePath, paths, pixelTable, yIntersectionPath, width ): 'Insert a pair of points around the grid point is is junction wide, otherwise inset one point.' if len( linePath ) < 1: return if gridPoint in gridPoints: gridPoints.remove( gridPoint ) intersectionBeginPoint = None moreThanInset = 2.1 * gridPointInsetX path = yIntersectionPath.getPath(paths) begin = path[ yIntersectionPath.pointIndex ] end = path[ yIntersectionPath.getPointIndexPlusOne() ] if yIntersectionPath.isOutside: distanceX = end.real - begin.real if abs( distanceX ) > 2.1 * moreThanInset: intersectionBeginXDistance = yIntersectionPath.gridPoint.real - begin.real endIntersectionXDistance = end.real - yIntersectionPath.gridPoint.real intersectionPoint = begin * endIntersectionXDistance / distanceX + end * intersectionBeginXDistance / distanceX distanceYAbsoluteInset = max( abs( yIntersectionPath.gridPoint.imag - intersectionPoint.imag ), moreThanInset ) intersectionEndSegment = end - intersectionPoint intersectionEndSegmentLength = abs( intersectionEndSegment ) if intersectionEndSegmentLength > 1.1 * distanceYAbsoluteInset: intersectionEndPoint = intersectionPoint + intersectionEndSegment * distanceYAbsoluteInset / intersectionEndSegmentLength path.insert( yIntersectionPath.getPointIndexPlusOne(), intersectionEndPoint ) intersectionBeginSegment = begin - intersectionPoint intersectionBeginSegmentLength = abs( intersectionBeginSegment ) if intersectionBeginSegmentLength > 1.1 * distanceYAbsoluteInset: intersectionBeginPoint = intersectionPoint + intersectionBeginSegment * distanceYAbsoluteInset / intersectionBeginSegmentLength for point in linePath: addPointOnPath( path, yIntersectionPath.pathIndex, pixelTable, point, yIntersectionPath.getPointIndexPlusOne(), width ) if intersectionBeginPoint is not None: addPointOnPath( path, yIntersectionPath.pathIndex, pixelTable, intersectionBeginPoint, yIntersectionPath.getPointIndexPlusOne(), width ) def isAddedPointOnPathFree( path, pixelTable, point, pointIndex, width ): 'Determine if the point added to a path is intersecting the pixel table or the path.' if pointIndex > 0 and pointIndex < len(path): if isSharpCorner( ( path[pointIndex - 1] ), point, ( path[pointIndex] ) ): return False pointIndexMinusOne = pointIndex - 1 if pointIndexMinusOne >= 0: maskTable = {} begin = path[ pointIndexMinusOne ] if pointIndex < len(path): end = path[pointIndex] euclidean.addValueSegmentToPixelTable( begin, end, maskTable, None, width ) segmentTable = {} euclidean.addSegmentToPixelTable( point, begin, segmentTable, 0.0, 2.0, width ) if euclidean.isPixelTableIntersecting( pixelTable, segmentTable, maskTable ): return False if isAddedPointOnPathIntersectingPath( begin, path, point, pointIndexMinusOne ): return False if pointIndex < len(path): maskTable = {} begin = path[pointIndex] if pointIndexMinusOne >= 0: end = path[ pointIndexMinusOne ] euclidean.addValueSegmentToPixelTable( begin, end, maskTable, None, width ) segmentTable = {} euclidean.addSegmentToPixelTable( point, begin, segmentTable, 0.0, 2.0, width ) if euclidean.isPixelTableIntersecting( pixelTable, segmentTable, maskTable ): return False if isAddedPointOnPathIntersectingPath( begin, path, point, pointIndex ): return False return True def isAddedPointOnPathIntersectingPath( begin, path, point, pointIndex ): 'Determine if the point added to a path is intersecting the path by checking line intersection.' segment = point - begin segmentLength = abs(segment) if segmentLength <= 0.0: return False normalizedSegment = segment / segmentLength segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointRotated = segmentYMirror * point beginRotated = segmentYMirror * begin if euclidean.isXSegmentIntersectingPath( path[ max( 0, pointIndex - 20 ) : pointIndex ], pointRotated.real, beginRotated.real, segmentYMirror, pointRotated.imag ): return True return euclidean.isXSegmentIntersectingPath( path[ pointIndex + 1 : pointIndex + 21 ], pointRotated.real, beginRotated.real, segmentYMirror, pointRotated.imag ) def isIntersectingLoopsPaths( loops, paths, pointBegin, pointEnd ): 'Determine if the segment between the first and second point is intersecting the loop list.' normalizedSegment = pointEnd.dropAxis() - pointBegin.dropAxis() normalizedSegmentLength = abs( normalizedSegment ) if normalizedSegmentLength == 0.0: return False normalizedSegment /= normalizedSegmentLength segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = euclidean.getRoundZAxisByPlaneAngle( segmentYMirror, pointBegin ) pointEndRotated = euclidean.getRoundZAxisByPlaneAngle( segmentYMirror, pointEnd ) if euclidean.isLoopListIntersectingInsideXSegment( loops, pointBeginRotated.real, pointEndRotated.real, segmentYMirror, pointBeginRotated.imag ): return True return euclidean.isXSegmentIntersectingPaths( paths, pointBeginRotated.real, pointEndRotated.real, segmentYMirror, pointBeginRotated.imag ) def isPointAddedAroundClosest(layerInfillWidth, paths, pixelTable, removedEndpointPoint, width): 'Add the closest removed endpoint to the path, with minimal twisting.' closestDistanceSquared = 999999999987654321.0 closestPathIndex = None for pathIndex in xrange(len(paths)): path = paths[ pathIndex ] for pointIndex in xrange(len(path)): point = path[pointIndex] distanceSquared = abs(point - removedEndpointPoint) if distanceSquared < closestDistanceSquared: closestDistanceSquared = distanceSquared closestPathIndex = pathIndex if closestPathIndex is None: return if closestDistanceSquared < euclidean.globalQuarterPi * layerInfillWidth ** 2: return closestPath = paths[closestPathIndex] closestPointIndex = getWithLeastLength(closestPath, removedEndpointPoint) if isAddedPointOnPathFree(closestPath, pixelTable, removedEndpointPoint, closestPointIndex, width): addPointOnPath(closestPath, closestPathIndex, pixelTable, removedEndpointPoint, closestPointIndex, width) return True return isSidePointAdded(pixelTable, closestPath, closestPathIndex, closestPointIndex, layerInfillWidth, removedEndpointPoint, width) def isSegmentAround(aroundSegmentsDictionary, aroundSegmentsDictionaryKey, segment): 'Determine if there is another segment around.' if aroundSegmentsDictionaryKey not in aroundSegmentsDictionary: return False for aroundSegment in aroundSegmentsDictionary[aroundSegmentsDictionaryKey]: endpoint = aroundSegment[0] if isSegmentInX(segment, endpoint.point.real, endpoint.otherEndpoint.point.real): return True return False def isSegmentCompletelyInAnIntersection( segment, xIntersections ): 'Add sparse endpoints from a segment.' for xIntersectionIndex in xrange( 0, len( xIntersections ), 2 ): surroundingXFirst = xIntersections[ xIntersectionIndex ] surroundingXSecond = xIntersections[ xIntersectionIndex + 1 ] if euclidean.isSegmentCompletelyInX( segment, surroundingXFirst, surroundingXSecond ): return True return False def isSegmentInX( segment, xFirst, xSecond ): 'Determine if the segment overlaps within x.' segmentFirstX = segment[0].point.real segmentSecondX = segment[1].point.real if min( segmentFirstX, segmentSecondX ) > max( xFirst, xSecond ): return False return max( segmentFirstX, segmentSecondX ) > min( xFirst, xSecond ) def isSharpCorner( beginComplex, centerComplex, endComplex ): 'Determine if the three complex points form a sharp corner.' centerBeginComplex = beginComplex - centerComplex centerEndComplex = endComplex - centerComplex centerBeginLength = abs( centerBeginComplex ) centerEndLength = abs( centerEndComplex ) if centerBeginLength <= 0.0 or centerEndLength <= 0.0: return False centerBeginComplex /= centerBeginLength centerEndComplex /= centerEndLength return euclidean.getDotProduct( centerBeginComplex, centerEndComplex ) > 0.9 def isSidePointAdded( pixelTable, closestPath, closestPathIndex, closestPointIndex, layerInfillWidth, removedEndpointPoint, width ): 'Add side point along with the closest removed endpoint to the path, with minimal twisting.' if closestPointIndex <= 0 or closestPointIndex >= len( closestPath ): return False pointBegin = closestPath[ closestPointIndex - 1 ] pointEnd = closestPath[ closestPointIndex ] removedEndpointPoint = removedEndpointPoint closest = pointBegin farthest = pointEnd removedMinusClosest = removedEndpointPoint - pointBegin removedMinusClosestLength = abs( removedMinusClosest ) if removedMinusClosestLength <= 0.0: return False removedMinusOther = removedEndpointPoint - pointEnd removedMinusOtherLength = abs( removedMinusOther ) if removedMinusOtherLength <= 0.0: return False insertPointAfter = None insertPointBefore = None if removedMinusOtherLength < removedMinusClosestLength: closest = pointEnd farthest = pointBegin removedMinusClosest = removedMinusOther removedMinusClosestLength = removedMinusOtherLength insertPointBefore = removedEndpointPoint else: insertPointAfter = removedEndpointPoint removedMinusClosestNormalized = removedMinusClosest / removedMinusClosestLength perpendicular = removedMinusClosestNormalized * complex( 0.0, layerInfillWidth ) sidePoint = removedEndpointPoint + perpendicular #extra check in case the line to the side point somehow slips by the line to the perpendicular sidePointOther = removedEndpointPoint - perpendicular if abs( sidePoint - farthest ) > abs( sidePointOther - farthest ): perpendicular = - perpendicular sidePoint = sidePointOther maskTable = {} closestSegmentTable = {} toPerpendicularTable = {} euclidean.addValueSegmentToPixelTable( pointBegin, pointEnd, maskTable, None, width ) euclidean.addValueSegmentToPixelTable( closest, removedEndpointPoint, closestSegmentTable, None, width ) euclidean.addValueSegmentToPixelTable( sidePoint, farthest, toPerpendicularTable, None, width ) if euclidean.isPixelTableIntersecting( pixelTable, toPerpendicularTable, maskTable ) or euclidean.isPixelTableIntersecting( closestSegmentTable, toPerpendicularTable, maskTable ): sidePoint = removedEndpointPoint - perpendicular toPerpendicularTable = {} euclidean.addValueSegmentToPixelTable( sidePoint, farthest, toPerpendicularTable, None, width ) if euclidean.isPixelTableIntersecting( pixelTable, toPerpendicularTable, maskTable ) or euclidean.isPixelTableIntersecting( closestSegmentTable, toPerpendicularTable, maskTable ): return False if insertPointBefore is not None: addPointOnPathIfFree( closestPath, closestPathIndex, pixelTable, insertPointBefore, closestPointIndex, width ) addPointOnPathIfFree( closestPath, closestPathIndex, pixelTable, sidePoint, closestPointIndex, width ) if insertPointAfter is not None: addPointOnPathIfFree( closestPath, closestPathIndex, pixelTable, insertPointAfter, closestPointIndex, width ) return True def removeEndpoints(layerInfillWidth, paths, pixelTable, removedEndpoints, aroundWidth): 'Remove endpoints which are added to the path.' for removedEndpointIndex in xrange(len(removedEndpoints) -1, -1, -1): removedEndpoint = removedEndpoints[removedEndpointIndex] removedEndpointPoint = removedEndpoint.point if isPointAddedAroundClosest(layerInfillWidth, paths, pixelTable, removedEndpointPoint, aroundWidth): removedEndpoints.remove(removedEndpoint ) def setIsOutside( yCloseToCenterPath, yIntersectionPaths ): 'Determine if the yCloseToCenterPath is outside.' beforeClose = yCloseToCenterPath.yMinusCenter < 0.0 for yIntersectionPath in yIntersectionPaths: if yIntersectionPath != yCloseToCenterPath: beforePath = yIntersectionPath.yMinusCenter < 0.0 if beforeClose == beforePath: yCloseToCenterPath.isOutside = False return yCloseToCenterPath.isOutside = True def writeOutput(fileName, shouldAnalyze=True): 'Fill an inset gcode file.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'fill', shouldAnalyze) class FillRepository: 'A class to handle the fill settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.fill.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Fill', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fill') self.activateFill = settings.BooleanSetting().getFromValue('Activate Fill', self, True) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Main Fill Settings -', self ) self.infillSolidity = settings.FloatSpin().getFromValue( 0.05, 'Infill Solidity (ratio):', self, 1.00, 0.35 ) self.infillWidthOverThickness = settings.FloatSpin().getFromValue( 0.75, 'Extrusion Lines extra Spacing (Scaler):', self, 1.25, 1.0 ) self.infillPerimeterOverlap = settings.FloatSpin().getFromValue( 0.500, 'Infill Overlap over Perimeter (Scaler):', self, 1.500, 1.0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Shell Settings -', self ) settings.LabelDisplay().getFromName('- Additional Perimeter Shells -', self ) self.extraShellsAlternatingSolidLayer = settings.IntSpin().getFromValue( 0, 'Extra Shells on Alternating Solid Layer (shells):', self, 10, 3 ) self.extraShellsBase = settings.IntSpin().getFromValue( 0, 'Extra Shells on Base (shells):', self, 10, 2 ) self.extraShellsSparseLayer = settings.IntSpin().getFromValue( 0, 'Extra Shells on Sparse Layer (shells):', self, 10, 2 ) self.extraShellsBridgeLayer = settings.IntSpin().getFromValue( 0, 'Extra Shells on Bridge Layer (shells):', self, 10, 0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Top and Bottom Layers -', self ) self.solidSurfaceThickness = settings.IntSpin().getFromValue( 0, 'Fully filled Layers (each top and bottom):', self, 5, 2 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Extrusion Sequence -', self ) self.startFromChoice = settings.MenuButtonDisplay().getFromName('Start New Layer From :', self) self.startFromLowerLeft = settings.MenuRadio().getFromMenuButtonDisplay(self.startFromChoice, 'Lower Left', self, True) self.startFromNearest = settings.MenuRadio().getFromMenuButtonDisplay(self.startFromChoice, 'Nearest', self, False) settings.LabelSeparator().getFromRepository(self) self.threadSequenceChoice = settings.MenuButtonDisplay().getFromName('What order to print:', self) self.threadSequenceInfillLoops = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Infill > Loops > Perimeter', self, False) self.threadSequenceInfillPerimeter = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Infill > Perimeter > Loops', self, False) self.threadSequenceLoopsInfill = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Loops > Infill > Perimeter', self, False) self.threadSequenceLoopsPerimeter = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Loops > Perimeter > Infill', self, False) self.threadSequencePerimeterInfill = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Perimeter > Infill > Loops', self, False) self.threadSequencePerimeterLoops = settings.MenuRadio().getFromMenuButtonDisplay(self.threadSequenceChoice, 'Perimeter > Loops > Infill', self, True) self.surroundingAngle = settings.FloatSpin().getFromValue(30.0, 'Surrounding Angle (degrees):', self, 60.0, 45.0) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- How to make the infill -', self ) self.infillPatternLabel = settings.LabelDisplay().getFromName('Infill Pattern:', self ) infillLatentStringVar = settings.LatentStringVar() self.infillPatternLine = settings.Radio().getFromRadio( infillLatentStringVar, 'Line', self, True ) self.infillPatternGridCircular = settings.Radio().getFromRadio( infillLatentStringVar, 'Grid Circular', self, False ) self.infillPatternGridHexagonal = settings.Radio().getFromRadio( infillLatentStringVar, 'Grid Hexagonal', self, False ) self.infillPatternGridRectangular = settings.Radio().getFromRadio( infillLatentStringVar, 'Grid Rectangular', self, False ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Diaphragm (fully filled layers) -', self ) self.diaphragmPeriod = settings.IntSpin().getFromValue( 20, 'Diaphragm at every ...th Layer:', self, 200, 100 ) self.diaphragmThickness = settings.IntSpin().getFromValue( 0, 'Diaphragm Thickness (layers):', self, 5, 0 ) settings.LabelDisplay().getFromName('- if one of the Grids chosen as Infill Pattern -', self ) self.gridCircleSeparationOverPerimeterWidth = settings.FloatSpin().getFromValue(0.0, 'Grid Circle Separation over Perimeter Width (ratio):', self, 1.0, 0.2) self.gridExtraOverlap = settings.FloatSpin().getFromValue( 0.0, 'Grid Extra Overlap (ratio):', self, 0.5, 0.1 ) self.gridJunctionSeparationBandHeight = settings.IntSpin().getFromValue( 0, 'Grid Junction Separation Band Height (layers):', self, 20, 10 ) self.gridJunctionSeparationOverOctogonRadiusAtEnd = settings.FloatSpin().getFromValue( 0.0, 'Grid Junction Separation over Octogon Radius At End (ratio):', self, 0.7854, 0.0 ) self.gridJunctionSeparationOverOctogonRadiusAtMiddle = settings.FloatSpin().getFromValue( 0.0, 'Grid Junction Separation over Octogon Radius At Middle (ratio):', self, 0.7854, 0.0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelSeparator().getFromRepository(self) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Infill Angles -', self ) self.infillBeginRotation = settings.FloatSpin().getFromValue( 0.0, 'Infill Begin Rotation (degrees):', self, 90.0, 45.0 ) self.infillBeginRotationRepeat = settings.IntSpin().getFromValue( 0, 'Infill Begin Rotation Repeat (layers):', self, 3, 1 ) self.infillOddLayerExtraRotation = settings.FloatSpin().getFromValue( 30.0, 'Infill Odd Layer Extra Rotation (degrees):', self, 90.0, 90.0 ) self.executeTitle = 'Fill' def execute(self): 'Fill button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class FillSkein: 'A class to fill a skein of extrusions.' def __init__(self): 'Initialize.' # self.bridgeWidthMultiplier = 1.0 self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.fillInset = 0.18 self.isPerimeter = False self.lastExtraShells = - 1 self.lineIndex = 0 self.oldLocation = None self.oldOrderedLocation = None self.perimeterWidth = None self.rotatedLayer = None self.rotatedLayers = [] self.shutdownLineIndex = sys.maxint self.nestedRing = None self.thread = None self.scaledBridgeWidthMultiplier = 1 def addFill(self, layerIndex): 'Add fill to the carve layer.' # if layerIndex > 2: # return settings.printProgressByNumber(layerIndex, len(self.rotatedLayers), 'fill') arounds = [] endpoints = [] extraShells = self.repository.extraShellsSparseLayer.value extraShellsBridgeLayer = self.repository.extraShellsBridgeLayer.value infillPaths = [] layerInfillSolidity = self.infillSolidity layerRemainder = layerIndex % int(round(self.repository.diaphragmPeriod.value)) layerRotation = self.getLayerRotation(layerIndex) pixelTable = {} reverseRotation = complex(layerRotation.real, - layerRotation.imag) rotatedLayer = self.rotatedLayers[layerIndex] self.isDoubleJunction = True self.isJunctionWide = True # self.layerInfillWidth = self.infillWidth surroundingCarves = [] self.distanceFeedRate.addLine('( %s )' % rotatedLayer.z) if layerRemainder >= int(round(self.repository.diaphragmThickness.value)): for surroundingIndex in xrange(1, self.solidSurfaceThickness + 1): self.addRotatedCarve(layerIndex, -surroundingIndex, reverseRotation, surroundingCarves) self.addRotatedCarve(layerIndex, surroundingIndex, reverseRotation, surroundingCarves) if len(surroundingCarves) < self.doubleSolidSurfaceThickness: extraShells = self.repository.extraShellsAlternatingSolidLayer.value if self.lastExtraShells != self.repository.extraShellsBase.value: extraShells = self.repository.extraShellsBase.value if rotatedLayer.rotation is not None: extraShells = extraShellsBridgeLayer self.fillInset = self.infillWidth * self.repository.infillPerimeterOverlap.value * 0.9 #*euclidean.globalQuarterPi # self.scaledBridgeWidthMultiplier * self.repository.infillPerimeterOverlap.value # self.bridgeWidthMultiplier self.distanceFeedRate.addLine('( %s )' % rotatedLayer.rotation) self.distanceFeedRate.addLine('( %s )' % layerRotation) aroundInset = 0.24321 * self.infillWidth aroundWidth = 0.24321 * self.infillWidth doubleInfillWidth = 2.0 * self.infillWidth gridPointInsetX = 0.5 * self.fillInset self.lastExtraShells = extraShells if self.repository.infillPatternGridHexagonal.value: infillBeginRotationPolar = euclidean.getWiddershinsUnitPolar(self.infillBeginRotation) if abs(euclidean.getDotProduct(layerRotation, infillBeginRotationPolar)) < math.sqrt( 0.5): layerInfillSolidity *= 0.5 self.isDoubleJunction = False else: self.isJunctionWide = False nestedRings = euclidean.getOrderedNestedRings(rotatedLayer.nestedRings) # if not self.repository.addInfillPerimeter.value: # self.addThreadsBridgeLayer(layerIndex, nestedRings, rotatedLayer) # return radiusAround = 0.5 * min(self.infillWidth, self.perimeterWidth) createFillForSurroundings(nestedRings, self.perimeterMinusHalfInfillWidth, radiusAround, False) for extraShellIndex in xrange(extraShells): createFillForSurroundings(nestedRings, self.infillWidth, radiusAround, True) fillLoops = euclidean.getFillOfSurroundings(nestedRings, None) rotatedLoops = euclidean.getRotatedComplexLists(reverseRotation, fillLoops) infillDictionary = triangle_mesh.getInfillDictionary( aroundInset, arounds, aroundWidth, self.fillInset, self.infillWidth, pixelTable, rotatedLoops) if len(arounds) < 1: self.addThreadsBridgeLayer(layerIndex, nestedRings, rotatedLayer) return self.horizontalSegmentsDictionary = {} for infillDictionaryKey in infillDictionary.keys(): xIntersections = infillDictionary[infillDictionaryKey] xIntersections.sort() y = infillDictionaryKey * self.infillWidth self.horizontalSegmentsDictionary[infillDictionaryKey] = euclidean.getSegmentsFromXIntersections(xIntersections, y) self.surroundingXIntersectionsDictionary = {} gridCircular = False removedEndpoints = [] if len(surroundingCarves) >= self.doubleSolidSurfaceThickness: if self.repository.infillPatternGridCircular.value and self.repository.infillSolidity.value > 0.0: gridCircular = True layerInfillSolidity = 0.0 xSurroundingIntersectionsDictionaries = [infillDictionary] for surroundingCarve in surroundingCarves: xSurroundingIntersectionsDictionary = {} euclidean.addXIntersectionsFromLoopsForTable(surroundingCarve, xSurroundingIntersectionsDictionary, self.infillWidth) xSurroundingIntersectionsDictionaries.append(xSurroundingIntersectionsDictionary) self.surroundingXIntersectionsDictionary = euclidean.getIntersectionOfXIntersectionsTables(xSurroundingIntersectionsDictionaries) for horizontalSegmentsDictionaryKey in self.horizontalSegmentsDictionary.keys(): if horizontalSegmentsDictionaryKey in self.surroundingXIntersectionsDictionary: surroundingXIntersections = self.surroundingXIntersectionsDictionary[horizontalSegmentsDictionaryKey] else: surroundingXIntersections = [] addSparseEndpoints(doubleInfillWidth, endpoints, self.horizontalSegmentsDictionary, horizontalSegmentsDictionaryKey, layerInfillSolidity, removedEndpoints, self.solidSurfaceThickness, surroundingXIntersections) else: for segments in self.horizontalSegmentsDictionary.values(): for segment in segments: endpoints += segment paths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.infillWidth, pixelTable, aroundWidth) if gridCircular: startAngle = euclidean.globalGoldenAngle * float(layerIndex) for gridPoint in self.getGridPoints(fillLoops, reverseRotation): self.addGridCircle(gridPoint, infillPaths, layerRotation, pixelTable, rotatedLoops, layerRotation, aroundWidth) else: if self.isGridToBeExtruded(): self.addGrid( arounds, fillLoops, gridPointInsetX, layerIndex, paths, pixelTable, reverseRotation, surroundingCarves, aroundWidth) oldRemovedEndpointLength = len(removedEndpoints) + 1 while oldRemovedEndpointLength - len(removedEndpoints) > 0: oldRemovedEndpointLength = len(removedEndpoints) removeEndpoints(self.infillWidth, paths, pixelTable, removedEndpoints, aroundWidth) paths = euclidean.getConnectedPaths(paths, pixelTable, aroundWidth) for path in paths: addPath(self.infillWidth, infillPaths, path, layerRotation) euclidean.transferPathsToNestedRings(nestedRings, infillPaths) for fillLoop in fillLoops: addInfillBoundary(fillLoop, nestedRings) self.addThreadsBridgeLayer(layerIndex, nestedRings, rotatedLayer) def addGcodeFromThreadZ( self, thread, z ): 'Add a gcode thread to the output.' self.distanceFeedRate.addGcodeFromThreadZ( thread, z ) def addGrid(self, arounds, fillLoops, gridPointInsetX, layerIndex, paths, pixelTable, reverseRotation, surroundingCarves, width): 'Add the grid to the infill layer.' if len(surroundingCarves) < self.doubleSolidSurfaceThickness: return explodedPaths = [] pathGroups = [] for path in paths: pathIndexBegin = len( explodedPaths ) for pointIndex in xrange( len(path) - 1 ): pathSegment = [ path[pointIndex], path[pointIndex + 1] ] explodedPaths.append( pathSegment ) pathGroups.append( ( pathIndexBegin, len( explodedPaths ) ) ) for pathIndex in xrange( len( explodedPaths ) ): explodedPath = explodedPaths[ pathIndex ] euclidean.addPathToPixelTable( explodedPath, pixelTable, pathIndex, width ) gridPoints = self.getGridPoints(fillLoops, reverseRotation) gridPointInsetY = gridPointInsetX * ( 1.0 - self.repository.gridExtraOverlap.value ) if self.repository.infillPatternGridRectangular.value: gridBandHeight = self.repository.gridJunctionSeparationBandHeight.value gridLayerRemainder = ( layerIndex - self.solidSurfaceThickness ) % gridBandHeight halfBandHeight = 0.5 * float( gridBandHeight ) halfBandHeightFloor = math.floor( halfBandHeight ) fromMiddle = math.floor( abs( gridLayerRemainder - halfBandHeight ) ) fromEnd = halfBandHeightFloor - fromMiddle gridJunctionSeparation = self.gridJunctionEnd * fromMiddle + self.gridJunctionMiddle * fromEnd gridJunctionSeparation /= halfBandHeightFloor gridPointInsetX += gridJunctionSeparation gridPointInsetY += gridJunctionSeparation oldGridPointLength = len( gridPoints ) + 1 while oldGridPointLength - len( gridPoints ) > 0: oldGridPointLength = len( gridPoints ) self.addRemainingGridPoints( arounds, gridPointInsetX, gridPointInsetY, gridPoints, True, explodedPaths, pixelTable, width ) oldGridPointLength = len( gridPoints ) + 1 while oldGridPointLength - len( gridPoints ) > 0: oldGridPointLength = len( gridPoints ) self.addRemainingGridPoints( arounds, gridPointInsetX, gridPointInsetY, gridPoints, False, explodedPaths, pixelTable, width ) for pathGroupIndex in xrange( len( pathGroups ) ): pathGroup = pathGroups[ pathGroupIndex ] paths[ pathGroupIndex ] = [] for explodedPathIndex in xrange( pathGroup[0], pathGroup[1] ): explodedPath = explodedPaths[ explodedPathIndex ] if len( paths[ pathGroupIndex ] ) == 0: paths[ pathGroupIndex ] = explodedPath else: paths[ pathGroupIndex ] += explodedPath[1 :] def addGridCircle(self, center, infillPaths, layerRotation, pixelTable, rotatedLoops, startRotation, width): 'Add circle to the grid.' startAngle = -math.atan2(startRotation.imag, startRotation.real) loop = euclidean.getComplexPolygon(center, self.gridCircleRadius, 17, startAngle) loopPixelDictionary = {} euclidean.addLoopToPixelTable(loop, loopPixelDictionary, width) if not euclidean.isPixelTableIntersecting(pixelTable, loopPixelDictionary): if euclidean.getIsInFilledRegion(rotatedLoops, euclidean.getLeftPoint(loop)): addLoop(self.infillWidth, infillPaths, loop, layerRotation) return insideIndexPaths = [] insideIndexPath = None for pointIndex, point in enumerate(loop): nextPoint = loop[(pointIndex + 1) % len(loop)] segmentDictionary = {} euclidean.addValueSegmentToPixelTable(point, nextPoint, segmentDictionary, None, width) euclidean.addSquareTwoToPixelDictionary(segmentDictionary, point, None, width) euclidean.addSquareTwoToPixelDictionary(segmentDictionary, nextPoint, None, width) shouldAddLoop = not euclidean.isPixelTableIntersecting(pixelTable, segmentDictionary) if shouldAddLoop: shouldAddLoop = euclidean.getIsInFilledRegion(rotatedLoops, point) if shouldAddLoop: if insideIndexPath is None: insideIndexPath = [pointIndex] insideIndexPaths.append(insideIndexPath) else: insideIndexPath.append(pointIndex) else: insideIndexPath = None if len(insideIndexPaths) > 1: insideIndexPathFirst = insideIndexPaths[0] insideIndexPathLast = insideIndexPaths[-1] if insideIndexPathFirst[0] == 0 and insideIndexPathLast[-1] == len(loop) - 1: insideIndexPaths[0] = insideIndexPathLast + insideIndexPathFirst del insideIndexPaths[-1] for insideIndexPath in insideIndexPaths: path = [] for insideIndex in insideIndexPath: if len(path) == 0: path.append(loop[insideIndex]) path.append(loop[(insideIndex + 1) % len(loop)]) addPath(self.infillWidth, infillPaths, path, layerRotation) def addGridLinePoints( self, begin, end, gridPoints, gridRotationAngle, offset, y ): 'Add the segments of one line of a grid to the infill.' if self.gridRadius == 0.0: return gridXStep = int(math.floor((begin) / self.gridXStepSize)) - 3 gridXOffset = offset + self.gridXStepSize * float(gridXStep) while gridXOffset < end: if gridXOffset >= begin: gridPointComplex = complex(gridXOffset, y) * gridRotationAngle if self.repository.infillPatternGridCircular.value or self.isPointInsideLineSegments(gridPointComplex): gridPoints.append(gridPointComplex) gridXStep = self.getNextGripXStep(gridXStep) gridXOffset = offset + self.gridXStepSize * float(gridXStep) def addRemainingGridPoints( self, arounds, gridPointInsetX, gridPointInsetY, gridPoints, isBothOrNone, paths, pixelTable, width): 'Add the remaining grid points to the grid point list.' for gridPointIndex in xrange( len( gridPoints ) - 1, - 1, - 1 ): gridPoint = gridPoints[ gridPointIndex ] addAroundGridPoint( arounds, gridPoint, gridPointInsetX, gridPointInsetY, gridPoints, self.gridRadius, isBothOrNone, self.isDoubleJunction, self.isJunctionWide, paths, pixelTable, width ) def addRotatedCarve(self, currentLayer, layerDelta, reverseRotation, surroundingCarves): 'Add a rotated carve to the surrounding carves.rotatedCarveDictionary' layerIndex = currentLayer + layerDelta if layerIndex < 0 or layerIndex >= len(self.rotatedLayers): return layerDifference = abs(layerDelta) rotatedLayer = self.rotatedLayers[layerIndex] if layerDifference in rotatedLayer.rotatedCarveDictionary: surroundingCarves.append(rotatedLayer.rotatedCarveDictionary[layerDifference]) return nestedRings = rotatedLayer.nestedRings rotatedCarve = [] for nestedRing in nestedRings: planeRotatedLoop = euclidean.getRotatedComplexes(reverseRotation, nestedRing.boundary) rotatedCarve.append(planeRotatedLoop) outsetRadius = float(layerDifference) * self.layerThickness * self.surroundingSlope - self.perimeterWidth if outsetRadius > 0.0: rotatedCarve = intercircle.getInsetSeparateLoopsFromAroundLoops(rotatedCarve, -outsetRadius, self.layerThickness) surroundingCarves.append(rotatedCarve) rotatedLayer.rotatedCarveDictionary[layerDifference] = rotatedCarve def addThreadsBridgeLayer(self, layerIndex, nestedRings, rotatedLayer, testLoops=None): 'Add the threads, add the bridge end & the layer end tag.' if self.oldOrderedLocation is None or self.repository.startFromLowerLeft.value: self.oldOrderedLocation = getLowerLeftCorner(nestedRings) extrusionHalfWidth = 0.5 * self.infillWidth threadSequence = self.threadSequence if layerIndex < 1: threadSequence = ['perimeter', 'loops', 'infill'] euclidean.addToThreadsRemove(extrusionHalfWidth, nestedRings, self.oldOrderedLocation, self, threadSequence) if testLoops is not None: for testLoop in testLoops: self.addGcodeFromThreadZ(testLoop, self.oldOrderedLocation.z) self.distanceFeedRate.addLine('()') if rotatedLayer.rotation is not None: self.distanceFeedRate.addLine('()') self.distanceFeedRate.addLine('()') def addToThread(self, location): 'Add a location to thread.' if self.oldLocation is None: return if self.isPerimeter: self.nestedRing.addToLoop( location ) return if self.thread is None: self.thread = [ self.oldLocation.dropAxis() ] self.nestedRing.perimeterPaths.append(self.thread) self.thread.append(location.dropAxis()) def getCraftedGcode( self, repository, gcodeText ): 'Parse gcode text and store the bevel gcode.' self.repository = repository self.lines = archive.getTextLines(gcodeText) self.threadSequence = None if repository.threadSequenceInfillLoops.value: self.threadSequence = ['infill', 'loops', 'perimeter'] if repository.threadSequenceInfillPerimeter.value: self.threadSequence = ['infill', 'perimeter', 'loops'] if repository.threadSequenceLoopsInfill.value: self.threadSequence = ['loops', 'infill', 'perimeter'] if repository.threadSequenceLoopsPerimeter.value: self.threadSequence = ['loops', 'perimeter', 'infill'] if repository.threadSequencePerimeterInfill.value: self.threadSequence = ['perimeter', 'infill', 'loops'] if repository.threadSequencePerimeterLoops.value: self.threadSequence = ['perimeter', 'loops', 'infill'] if self.repository.infillPerimeterOverlap.value < 0.65: print('') print('!!! WARNING !!!') print('"Infill Perimeter Overlap" is less than 0.65, which may create problems with the infill, like threads going through empty space and/or the extruder switching on and off a lot.') print('If you want to stretch the infill a lot, set "Path Stretch over Perimeter Width" in stretch to a high value instead of setting "Infill Perimeter Overlap" to a high value.') print('') self.parseInitialization() if self.perimeterWidth is None: print('Warning, nothing will be done because self.perimeterWidth in getCraftedGcode in FillSkein was None.') return '' self.fillInset = self.infillWidth * self.repository.infillPerimeterOverlap.value # #todo check self.infillSolidity = repository.infillSolidity.value self.perimeterMinusHalfInfillWidth = self.perimeterWidth - 0.5 * self.infillWidth if self.isGridToBeExtruded(): self.setGridVariables(repository) self.infillBeginRotation = math.radians( repository.infillBeginRotation.value ) self.infillOddLayerExtraRotation = math.radians( repository.infillOddLayerExtraRotation.value ) self.solidSurfaceThickness = int( round( self.repository.solidSurfaceThickness.value ) ) self.doubleSolidSurfaceThickness = self.solidSurfaceThickness + self.solidSurfaceThickness for lineIndex in xrange(self.lineIndex, len(self.lines)): self.parseLine( lineIndex ) for layerIndex in xrange(len(self.rotatedLayers)): self.addFill(layerIndex) self.distanceFeedRate.addLines( self.lines[ self.shutdownLineIndex : ] ) return self.distanceFeedRate.output.getvalue() def getGridPoints(self, fillLoops, reverseRotation): 'Get the grid points.' if self.infillSolidity > euclidean.globalQuarterPi : return [] rotationBaseAngle = euclidean.getWiddershinsUnitPolar(self.infillBeginRotation) reverseRotationBaseAngle = complex(rotationBaseAngle.real, - rotationBaseAngle.imag) gridRotationAngle = reverseRotation * rotationBaseAngle slightlyGreaterThanFillInset = intercircle.globalIntercircleMultiplier * self.gridInset triangle_mesh.sortLoopsInOrderOfArea(True, fillLoops) rotatedLoops = euclidean.getRotatedComplexLists(reverseRotationBaseAngle, fillLoops) if self.repository.infillPatternGridCircular.value: return self.getGridPointsByLoops( gridRotationAngle, intercircle.getInsetSeparateLoopsFromLoops(rotatedLoops, -self.gridCircleRadius)) return self.getGridPointsByLoops(gridRotationAngle, intercircle.getInsetSeparateLoopsFromLoops(rotatedLoops, self.gridInset)) def getGridPointsByLoops(self, gridRotationAngle, loops): 'Get the grid points by loops.' gridIntersectionsDictionary = {} gridPoints = [] euclidean.addXIntersectionsFromLoopsForTable(loops, gridIntersectionsDictionary, self.gridRadius) for gridIntersectionsKey in gridIntersectionsDictionary: y = gridIntersectionsKey * self.gridRadius + self.gridRadius * 0.5 gridIntersections = gridIntersectionsDictionary[gridIntersectionsKey] gridIntersections.sort() gridIntersectionsLength = len(gridIntersections) if gridIntersectionsLength % 2 == 1: gridIntersectionsLength -= 1 for gridIntersectionIndex in xrange(0, gridIntersectionsLength, 2): begin = gridIntersections[gridIntersectionIndex] end = gridIntersections[gridIntersectionIndex + 1] offset = self.offsetMultiplier * (gridIntersectionsKey % 2) + self.offsetBaseX self.addGridLinePoints(begin, end, gridPoints, gridRotationAngle, offset, y) return gridPoints def getLayerRotation(self, layerIndex): 'Get the layer rotation.' rotation = self.rotatedLayers[layerIndex].rotation if rotation is not None: return rotation infillBeginRotationRepeat = self.repository.infillBeginRotationRepeat.value infillOddLayerRotationMultiplier = float( layerIndex % ( infillBeginRotationRepeat + 1 ) == infillBeginRotationRepeat ) layerAngle = self.infillBeginRotation + infillOddLayerRotationMultiplier * self.infillOddLayerExtraRotation return euclidean.getWiddershinsUnitPolar(layerAngle) def getNextGripXStep( self, gridXStep ): 'Get the next grid x step, increment by an extra one every three if hexagonal grid is chosen.' gridXStep += 1 if self.repository.infillPatternGridHexagonal.value: if gridXStep % 3 == 0: gridXStep += 1 return gridXStep def isGridToBeExtruded(self): 'Determine if the grid is to be extruded.' if self.repository.infillPatternLine.value: return False return self.repository.infillSolidity.value > 0.0 def isPointInsideLineSegments( self, gridPoint ): 'Is the point inside the line segments of the loops.' if self.solidSurfaceThickness <= 0: return True fillLine = int(round(gridPoint.imag / self.infillWidth)) if fillLine not in self.horizontalSegmentsDictionary: return False if fillLine not in self.surroundingXIntersectionsDictionary: return False lineSegments = self.horizontalSegmentsDictionary[fillLine] surroundingXIntersections = self.surroundingXIntersectionsDictionary[fillLine] for lineSegment in lineSegments: if isSegmentCompletelyInAnIntersection(lineSegment, surroundingXIntersections ): xFirst = lineSegment[0].point.real xSecond = lineSegment[1].point.real if gridPoint.real > min(xFirst, xSecond) and gridPoint.real < max(xFirst, xSecond): return True return False def linearMove( self, splitLine ): 'Add a linear move to the thread.' location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.extruderActive: self.addToThread( location ) self.oldLocation = location def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '(': self.bridgeWidthMultiplier = float(splitLine[1]) elif firstWord == '(': self.scaledBridgeWidthMultiplier = float(splitLine[1]) elif firstWord == '()': self.distanceFeedRate.addLine(line) return elif firstWord == '(': self.layerThickness = float(splitLine[1]) # self.infillWidth = self.repository.infillWidthOverThickness.value * self.layerThickness #todo elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.infillWidth = self.repository.infillWidthOverThickness.value * self.perimeterWidth * euclidean.globalQuarterPi self.surroundingSlope = math.tan(math.radians(min(self.repository.surroundingAngle.value, 80.0))) self.distanceFeedRate.addTagRoundedLine('infillPerimeterOverlap', self.repository.infillPerimeterOverlap.value) self.distanceFeedRate.addTagRoundedLine('infillWidth', self.infillWidth) threadSequenceString = ' '.join( self.threadSequence ) self.distanceFeedRate.addTagBracketedLine('threadSequenceString', threadSequenceString ) elif firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('fill') self.distanceFeedRate.addLine(line) def parseLine( self, lineIndex ): 'Parse a gcode line and add it to the fill skein.' line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.linearMove(splitLine) if firstWord == 'M101': self.extruderActive = True if firstWord == 'M103': self.extruderActive = False self.thread = None self.isPerimeter = False if firstWord == '()': self.nestedRing = euclidean.NestedBand() self.rotatedLayer.nestedRings.append( self.nestedRing ) if firstWord == '()': self.nestedRing = None if firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) self.nestedRing.addToBoundary( location ) if firstWord == '(': self.rotatedLayer.rotation = gcodec.getRotationBySplitLine(splitLine) if firstWord == '()': self.shutdownLineIndex = lineIndex if firstWord == '(': self.rotatedLayer = RotatedLayer(float(splitLine[1])) self.rotatedLayers.append( self.rotatedLayer ) self.thread = None if firstWord == '(': self.isPerimeter = True def setGridVariables( self, repository ): 'Set the grid variables.' self.gridInset = 1.2 * self.infillWidth self.gridRadius = self.infillWidth / self.infillSolidity self.gridXStepSize = 2.0 * self.gridRadius self.offsetMultiplier = self.gridRadius if self.repository.infillPatternGridHexagonal.value: self.gridXStepSize = 4.0 / 3.0 * self.gridRadius self.offsetMultiplier = 1.5 * self.gridXStepSize if self.repository.infillPatternGridCircular.value: self.gridRadius += self.gridRadius self.gridXStepSize = self.gridRadius / math.sqrt(.75) self.offsetMultiplier = 0.5 * self.gridXStepSize circleInsetOverPerimeterWidth = repository.gridCircleSeparationOverPerimeterWidth.value + 0.5 self.gridMinimumCircleRadius = self.perimeterWidth self.gridInset = self.gridMinimumCircleRadius self.gridCircleRadius = self.offsetMultiplier - circleInsetOverPerimeterWidth * self.perimeterWidth if self.gridCircleRadius < self.gridMinimumCircleRadius: print('') print('!!! WARNING !!!') print('Grid Circle Separation over Perimeter Width is too high, which makes the grid circles too small.') print('You should reduce Grid Circle Separation over Perimeter Width to a reasonable value, like the default of 0.5.') print('The grid circle radius will be set to the minimum grid circle radius.') print('') self.gridCircleRadius = self.gridMinimumCircleRadius self.offsetBaseX = 0.25 * self.gridXStepSize if self.repository.infillPatternGridRectangular.value: halfGridMinusWidth = 0.5 * ( self.gridRadius - self.infillWidth ) self.gridJunctionEnd = halfGridMinusWidth * repository.gridJunctionSeparationOverOctogonRadiusAtEnd.value self.gridJunctionMiddle = halfGridMinusWidth * repository.gridJunctionSeparationOverOctogonRadiusAtMiddle.value class RotatedLayer: 'A rotated layer.' def __init__( self, z ): 'Initialize.' self.rotatedCarveDictionary = {} self.rotation = None self.nestedRings = [] self.z = z def __repr__(self): 'Get the string representation of this RotatedLayer.' return '%s, %s, %s' % ( self.z, self.rotation, self.nestedRings ) class YIntersectionPath: 'A class to hold the y intersection position, the loop which it intersected and the point index of the loop which it intersected.' def __init__( self, pathIndex, pointIndex, y ): 'Initialize from the path, point index, and y.' self.pathIndex = pathIndex self.pointIndex = pointIndex self.y = y def __repr__(self): 'Get the string representation of this y intersection.' return '%s, %s, %s' % ( self.pathIndex, self.pointIndex, self.y ) def getPath( self, paths ): 'Get the path from the paths and path index.' return paths[ self.pathIndex ] def getPointIndexPlusOne(self): 'Get the point index plus one.' return self.pointIndex + 1 def main(): 'Display the fill dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/fillet.py000066400000000000000000000447171167321211700303320ustar00rootroot00000000000000""" This page is in the table of contents. Fillet rounds the corners slightly in a variety of ways. This is to reduce corner blobbing and sudden extruder acceleration. The fillet manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fillet ==Operation== The default 'Activate Fillet' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Fillet Procedure Choice=== Default is 'Bevel''. ====Arc Point==== When selected, the corners will be filleted with an arc using the gcode point form. ====Arc Radius==== When selected, the corners will be filleted with an arc using the gcode radius form. ====Arc Segment==== When selected, the corners will be filleted with an arc composed of several segments. ====Bevel==== When selected, the corners will be beveled. ===Corner Feed Rate Multiplier=== Default: 1.0 Defines the ratio of the feed rate in corners over the original feed rate. With a high value the extruder will move quickly in corners, accelerating quickly and leaving a thin extrusion. With a low value, the extruder will move slowly in corners, accelerating gently and leaving a thick extrusion. ===Fillet Radius over Perimeter Width=== Default is 0.35. Defines the width of the fillet. ===Reversal Slowdown over Perimeter Width=== Default is 0.5. Defines how far before a path reversal the extruder will slow down. Some tools, like nozzle wipe, double back the path of the extruder and this option will add a slowdown point in that path so there won't be a sudden jerk at the end of the path. If the value is less than 0.1 a slowdown will not be added. ===Use Intermediate Feed Rate in Corners=== Default is on. When selected, the feed rate entering the corner will be the average of the old feed rate and the new feed rate. ==Examples== The following examples fillet the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and fillet.py. > python fillet.py This brings up the fillet dialog. > python fillet.py Screw Holder Bottom.stl The fillet tool is parsing the file: Screw Holder Bottom.stl .. The fillet tool has created the file: .. Screw Holder Bottom_fillet.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, gcodeText, repository = None ): "Fillet a gcode linear move file or text." return getCraftedTextFromText( archive.getTextIfEmpty( fileName, gcodeText ), repository ) def getCraftedTextFromText( gcodeText, repository = None ): "Fillet a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'fillet'): return gcodeText if repository is None: repository = settings.getReadRepository( FilletRepository() ) if not repository.activateFillet.value: return gcodeText if repository.arcPoint.value: return ArcPointSkein().getCraftedGcode( repository, gcodeText ) elif repository.arcRadius.value: return ArcRadiusSkein().getCraftedGcode( repository, gcodeText ) elif repository.arcSegment.value: return ArcSegmentSkein().getCraftedGcode( repository, gcodeText ) elif repository.bevel.value: return BevelSkein().getCraftedGcode( repository, gcodeText ) return gcodeText def getNewRepository(): 'Get new repository.' return FilletRepository() def writeOutput(fileName, shouldAnalyze=True): "Fillet a gcode linear move file. Depending on the settings, either arcPoint, arcRadius, arcSegment, bevel or do nothing." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'fillet', shouldAnalyze) class BevelSkein: "A class to bevel a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.feedRateMinute = 960.0 self.filletRadius = 0.2 self.lineIndex = 0 self.lines = None self.oldFeedRateMinute = None self.oldLocation = None self.shouldAddLine = True def addLinearMovePoint( self, feedRateMinute, point ): "Add a gcode linear move, feedRate and newline to the output." self.distanceFeedRate.addLine( self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( feedRateMinute, point.dropAxis(), point.z ) ) def getCornerFeedRate(self): "Get the corner feed rate, which may be based on the intermediate feed rate." feedRateMinute = self.feedRateMinute if self.repository.useIntermediateFeedRateInCorners.value: if self.oldFeedRateMinute is not None: feedRateMinute = 0.5 * ( self.oldFeedRateMinute + self.feedRateMinute ) return feedRateMinute * self.cornerFeedRateMultiplier def getCraftedGcode( self, repository, gcodeText ): "Parse gcode text and store the bevel gcode." self.cornerFeedRateMultiplier = repository.cornerFeedRateMultiplier.value self.lines = archive.getTextLines(gcodeText) self.repository = repository self.parseInitialization( repository ) for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getExtruderOffReversalPoint( self, afterSegment, afterSegmentComplex, beforeSegment, beforeSegmentComplex, location ): "If the extruder is off and the path is reversing, add intermediate slow points." if self.repository.reversalSlowdownDistanceOverPerimeterWidth.value < 0.1: return None if self.extruderActive: return None reversalBufferSlowdownDistance = self.reversalSlowdownDistance * 2.0 afterSegmentComplexLength = abs( afterSegmentComplex ) if afterSegmentComplexLength < reversalBufferSlowdownDistance: return None beforeSegmentComplexLength = abs( beforeSegmentComplex ) if beforeSegmentComplexLength < reversalBufferSlowdownDistance: return None afterSegmentComplexNormalized = afterSegmentComplex / afterSegmentComplexLength beforeSegmentComplexNormalized = beforeSegmentComplex / beforeSegmentComplexLength if euclidean.getDotProduct( afterSegmentComplexNormalized, beforeSegmentComplexNormalized ) < 0.95: return None slowdownFeedRate = self.feedRateMinute * 0.5 self.shouldAddLine = False beforePoint = euclidean.getPointPlusSegmentWithLength( self.reversalSlowdownDistance * abs( beforeSegment ) / beforeSegmentComplexLength, location, beforeSegment ) self.addLinearMovePoint( self.feedRateMinute, beforePoint ) self.addLinearMovePoint( slowdownFeedRate, location ) afterPoint = euclidean.getPointPlusSegmentWithLength( self.reversalSlowdownDistance * abs( afterSegment ) / afterSegmentComplexLength, location, afterSegment ) self.addLinearMovePoint( slowdownFeedRate, afterPoint ) return afterPoint def getNextLocation(self): "Get the next linear move. Return none is none is found." for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ): line = self.lines[ afterIndex ] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if gcodec.getFirstWord(splitLine) == 'G1': nextLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) return nextLocation return None def linearMove( self, splitLine ): "Bevel a linear move." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) if self.oldLocation is not None: nextLocation = self.getNextLocation() if nextLocation is not None: location = self.splitPointGetAfter( location, nextLocation ) self.oldLocation = location self.oldFeedRateMinute = self.feedRateMinute def parseInitialization( self, repository ): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('fillet') return elif firstWord == '(': perimeterWidth = abs(float(splitLine[1])) self.curveSection = 0.7 * perimeterWidth self.filletRadius = perimeterWidth * repository.filletRadiusOverPerimeterWidth.value self.minimumRadius = 0.1 * perimeterWidth self.reversalSlowdownDistance = perimeterWidth * repository.reversalSlowdownDistanceOverPerimeterWidth.value self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the bevel gcode." self.shouldAddLine = True splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.linearMove(splitLine) elif firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False if self.shouldAddLine: self.distanceFeedRate.addLine(line) def splitPointGetAfter( self, location, nextLocation ): "Bevel a point and return the end of the bevel. should get complex for radius" if self.filletRadius < 2.0 * self.minimumRadius: return location afterSegment = nextLocation - location afterSegmentComplex = afterSegment.dropAxis() afterSegmentComplexLength = abs( afterSegmentComplex ) thirdAfterSegmentLength = 0.333 * afterSegmentComplexLength if thirdAfterSegmentLength < self.minimumRadius: return location beforeSegment = self.oldLocation - location beforeSegmentComplex = beforeSegment.dropAxis() beforeSegmentComplexLength = abs( beforeSegmentComplex ) thirdBeforeSegmentLength = 0.333 * beforeSegmentComplexLength if thirdBeforeSegmentLength < self.minimumRadius: return location extruderOffReversalPoint = self.getExtruderOffReversalPoint( afterSegment, afterSegmentComplex, beforeSegment, beforeSegmentComplex, location ) if extruderOffReversalPoint is not None: return extruderOffReversalPoint bevelRadius = min( thirdAfterSegmentLength, self.filletRadius ) bevelRadius = min( thirdBeforeSegmentLength, bevelRadius ) self.shouldAddLine = False beforePoint = euclidean.getPointPlusSegmentWithLength( bevelRadius * abs( beforeSegment ) / beforeSegmentComplexLength, location, beforeSegment ) self.addLinearMovePoint( self.feedRateMinute, beforePoint ) afterPoint = euclidean.getPointPlusSegmentWithLength( bevelRadius * abs( afterSegment ) / afterSegmentComplexLength, location, afterSegment ) self.addLinearMovePoint( self.getCornerFeedRate(), afterPoint ) return afterPoint class ArcSegmentSkein( BevelSkein ): "A class to arc segment a skein of extrusions." def addArc( self, afterCenterDifferenceAngle, afterPoint, beforeCenterSegment, beforePoint, center ): "Add arc segments to the filleted skein." absoluteDifferenceAngle = abs( afterCenterDifferenceAngle ) # steps = int( math.ceil( absoluteDifferenceAngle * 1.5 ) ) steps = int( math.ceil( min( absoluteDifferenceAngle * 1.5, absoluteDifferenceAngle * abs( beforeCenterSegment ) / self.curveSection ) ) ) stepPlaneAngle = euclidean.getWiddershinsUnitPolar( afterCenterDifferenceAngle / steps ) for step in xrange( 1, steps ): beforeCenterSegment = euclidean.getRoundZAxisByPlaneAngle( stepPlaneAngle, beforeCenterSegment ) arcPoint = center + beforeCenterSegment self.addLinearMovePoint( self.getCornerFeedRate(), arcPoint ) self.addLinearMovePoint( self.getCornerFeedRate(), afterPoint ) def splitPointGetAfter( self, location, nextLocation ): "Fillet a point into arc segments and return the end of the last segment." if self.filletRadius < 2.0 * self.minimumRadius: return location afterSegment = nextLocation - location afterSegmentComplex = afterSegment.dropAxis() thirdAfterSegmentLength = 0.333 * abs( afterSegmentComplex ) if thirdAfterSegmentLength < self.minimumRadius: return location beforeSegment = self.oldLocation - location beforeSegmentComplex = beforeSegment.dropAxis() thirdBeforeSegmentLength = 0.333 * abs( beforeSegmentComplex ) if thirdBeforeSegmentLength < self.minimumRadius: return location extruderOffReversalPoint = self.getExtruderOffReversalPoint( afterSegment, afterSegmentComplex, beforeSegment, beforeSegmentComplex, location ) if extruderOffReversalPoint is not None: return extruderOffReversalPoint bevelRadius = min( thirdAfterSegmentLength, self.filletRadius ) bevelRadius = min( thirdBeforeSegmentLength, bevelRadius ) self.shouldAddLine = False beforePoint = euclidean.getPointPlusSegmentWithLength( bevelRadius * abs( beforeSegment ) / abs( beforeSegmentComplex ), location, beforeSegment ) self.addLinearMovePoint( self.feedRateMinute, beforePoint ) afterPoint = euclidean.getPointPlusSegmentWithLength( bevelRadius * abs( afterSegment ) / abs( afterSegmentComplex ), location, afterSegment ) afterPointComplex = afterPoint.dropAxis() beforePointComplex = beforePoint.dropAxis() locationComplex = location.dropAxis() midpoint = 0.5 * ( afterPoint + beforePoint ) midpointComplex = midpoint.dropAxis() midpointMinusLocationComplex = midpointComplex - locationComplex midpointLocationLength = abs( midpointMinusLocationComplex ) if midpointLocationLength < 0.01 * self.filletRadius: self.addLinearMovePoint( self.getCornerFeedRate(), afterPoint ) return afterPoint midpointAfterPointLength = abs( midpointComplex - afterPointComplex ) midpointCenterLength = midpointAfterPointLength * midpointAfterPointLength / midpointLocationLength radius = math.sqrt( midpointCenterLength * midpointCenterLength + midpointAfterPointLength * midpointAfterPointLength ) centerComplex = midpointComplex + midpointMinusLocationComplex * midpointCenterLength / midpointLocationLength center = Vector3( centerComplex.real, centerComplex.imag, midpoint.z ) afterCenterComplex = afterPointComplex - centerComplex beforeCenter = beforePoint - center angleDifference = euclidean.getAngleDifferenceByComplex( afterCenterComplex, beforeCenter.dropAxis() ) self.addArc( angleDifference, afterPoint, beforeCenter, beforePoint, center ) return afterPoint class ArcPointSkein( ArcSegmentSkein ): "A class to arc point a skein of extrusions." def addArc( self, afterCenterDifferenceAngle, afterPoint, beforeCenterSegment, beforePoint, center ): "Add an arc point to the filleted skein." if afterCenterDifferenceAngle == 0.0: return afterPointMinusBefore = afterPoint - beforePoint centerMinusBefore = center - beforePoint firstWord = 'G3' if afterCenterDifferenceAngle < 0.0: firstWord = 'G2' centerMinusBeforeComplex = centerMinusBefore.dropAxis() if abs( centerMinusBeforeComplex ) <= 0.0: return radius = abs( centerMinusBefore ) arcDistanceZ = complex( abs( afterCenterDifferenceAngle ) * radius, afterPointMinusBefore.z ) distance = abs( arcDistanceZ ) if distance <= 0.0: return line = self.distanceFeedRate.getFirstWordMovement( firstWord, afterPointMinusBefore ) + self.getRelativeCenter( centerMinusBeforeComplex ) cornerFeedRate = self.getCornerFeedRate() if cornerFeedRate is not None: line += ' F' + self.distanceFeedRate.getRounded(cornerFeedRate) self.distanceFeedRate.addLine(line) def getRelativeCenter( self, centerMinusBeforeComplex ): "Get the relative center." return ' I%s J%s' % ( self.distanceFeedRate.getRounded( centerMinusBeforeComplex.real ), self.distanceFeedRate.getRounded( centerMinusBeforeComplex.imag ) ) class ArcRadiusSkein( ArcPointSkein ): "A class to arc radius a skein of extrusions." def getRelativeCenter( self, centerMinusBeforeComplex ): "Get the relative center." radius = abs( centerMinusBeforeComplex ) return ' R' + ( self.distanceFeedRate.getRounded(radius) ) class FilletRepository: "A class to handle the fillet settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.fillet.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File to be Filleted', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Fillet') self.activateFillet = settings.BooleanSetting().getFromValue('Activate Fillet', self, False ) self.filletProcedureChoiceLabel = settings.LabelDisplay().getFromName('Fillet Procedure Choice: ', self ) filletLatentStringVar = settings.LatentStringVar() self.arcPoint = settings.Radio().getFromRadio( filletLatentStringVar, 'Arc Point', self, False ) self.arcRadius = settings.Radio().getFromRadio( filletLatentStringVar, 'Arc Radius', self, False ) self.arcSegment = settings.Radio().getFromRadio( filletLatentStringVar, 'Arc Segment', self, False ) self.bevel = settings.Radio().getFromRadio( filletLatentStringVar, 'Bevel', self, True ) self.cornerFeedRateMultiplier = settings.FloatSpin().getFromValue(0.8, 'Corner Feed Rate Multiplier (ratio):', self, 1.2, 1.0) self.filletRadiusOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.25, 'Fillet Radius over Perimeter Width (ratio):', self, 0.65, 0.35 ) self.reversalSlowdownDistanceOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.3, 'Reversal Slowdown Distance over Perimeter Width (ratio):', self, 0.7, 0.5 ) self.useIntermediateFeedRateInCorners = settings.BooleanSetting().getFromValue('Use Intermediate Feed Rate in Corners', self, True ) self.executeTitle = 'Fillet' def execute(self): "Fillet button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) def main(): "Display the fillet dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/flow.py000066400000000000000000000124421167321211700300100ustar00rootroot00000000000000""" This page is in the table of contents. The flow script sets the flow rate by writing the M108 gcode. ==Operation== The default 'Activate Flow' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Flow Rate=== Default is 210. Defines the flow rate which will be written following the M108 command. The flow rate is usually a PWM setting, but could be anything, like the rpm of the tool or the duty cycle of the tool. ==Examples== The following examples flow the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and flow.py. > python flow.py This brings up the flow dialog. > python flow.py Screw Holder Bottom.stl The flow tool is parsing the file: Screw Holder Bottom.stl .. The flow tool has created the file: .. Screw Holder Bottom_flow.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text='', flowRepository = None ): "Flow the file or text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), flowRepository ) def getCraftedTextFromText( gcodeText, flowRepository = None ): "Flow a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'flow'): return gcodeText if flowRepository is None: flowRepository = settings.getReadRepository( FlowRepository() ) if not flowRepository.activateFlow.value: return gcodeText return FlowSkein().getCraftedGcode( gcodeText, flowRepository ) def getNewRepository(): 'Get new repository.' return FlowRepository() def writeOutput(fileName, shouldAnalyze=True): "Flow a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'flow', shouldAnalyze) class FlowRepository: "A class to handle the flow settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.flow.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Flow', self, '') self.activateFlow = settings.BooleanSetting().getFromValue('Activate Flow', self, True ) self.flowRate = settings.FloatSpin().getFromValue( 50.0, 'Flow Rate (arbitrary units):', self, 250.0, 210.0 ) self.executeTitle = 'Flow' def execute(self): "Flow button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class FlowSkein: "A class to flow a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.lineIndex = 0 self.lines = None self.oldFlowRate = None self.oldLocation = None def addFlowRateLine(self): "Add flow rate line." flowRate = self.flowRepository.flowRate.value if flowRate != self.oldFlowRate: self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate)) self.oldFlowRate = flowRate def getCraftedGcode( self, gcodeText, flowRepository ): "Parse gcode text and store the flow gcode." self.flowRepository = flowRepository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() for line in self.lines[self.lineIndex :]: self.parseLine(line) return self.distanceFeedRate.output.getvalue() def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('flow') return self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the flow skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1' or firstWord == '(': self.addFlowRateLine() self.distanceFeedRate.addLine(line) def main(): "Display the flow dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/home.py000066400000000000000000000175521167321211700300000ustar00rootroot00000000000000""" This page is in the table of contents. Plugin to home the tool at beginning of each layer. The home manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Home ==Operation== The default 'Activate Home' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Name of Home File=== Default: home.gcode At the beginning of a each layer, home will add the commands of a gcode script with the name of the "Name of Home File" setting, if one exists. Home does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. Home looks for those files in the alterations folder in the .skeinforge folder in the home directory. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder. ==Examples== The following examples home the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and home.py. > python home.py This brings up the home dialog. > python home.py Screw Holder Bottom.stl The home tool is parsing the file: Screw Holder Bottom.stl .. The home tool has created the file: .. Screw Holder Bottom_home.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, repository = None ): "Home a gcode linear move file or text." return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText( gcodeText, repository = None ): "Home a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'home'): return gcodeText if repository is None: repository = settings.getReadRepository( HomeRepository() ) if not repository.activateHome.value: return gcodeText return HomeSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return HomeRepository() def writeOutput(fileName, shouldAnalyze=True): "Home a gcode linear move file. Chain home the gcode if it is not already homed." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'home', shouldAnalyze) class HomeRepository: "A class to handle the home settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.home.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Home', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Home') self.activateHome = settings.BooleanSetting().getFromValue('Activate Home', self, False ) self.nameOfHomeFile = settings.StringSetting().getFromValue('Name of Home File:', self, 'home.gcode') self.executeTitle = 'Home' def execute(self): "Home button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class HomeSkein: "A class to home a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.highestZ = None self.homeLines = [] self.layerCount = settings.LayerCount() self.lineIndex = 0 self.lines = None self.oldLocation = None self.shouldHome = False self.travelFeedRateMinute = 957.0 def addFloat( self, begin, end ): "Add dive to the original height." beginEndDistance = begin.distance(end) alongWay = self.absolutePerimeterWidth / beginEndDistance closeToEnd = euclidean.getIntermediateLocation( alongWay, end, begin ) closeToEnd.z = self.highestZ self.distanceFeedRate.addLine( self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( self.travelFeedRateMinute, closeToEnd.dropAxis(), closeToEnd.z ) ) def addHomeTravel( self, splitLine ): "Add the home travel gcode." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.highestZ = max( self.highestZ, location.z ) if not self.shouldHome: return self.shouldHome = False if self.oldLocation is None: return if self.extruderActive: self.distanceFeedRate.addLine('M103') self.addHopUp( self.oldLocation ) self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.homeLines) self.addHopUp( self.oldLocation ) self.addFloat( self.oldLocation, location ) if self.extruderActive: self.distanceFeedRate.addLine('M101') def addHopUp(self, location): "Add hop to highest point." locationUp = Vector3( location.x, location.y, self.highestZ ) self.distanceFeedRate.addLine( self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( self.travelFeedRateMinute, locationUp.dropAxis(), locationUp.z ) ) def getCraftedGcode( self, gcodeText, repository ): "Parse gcode text and store the home gcode." self.repository = repository self.homeLines = settings.getAlterationFileLines(repository.nameOfHomeFile.value) if len(self.homeLines) < 1: return gcodeText self.lines = archive.getTextLines(gcodeText) self.parseInitialization( repository ) for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return self.distanceFeedRate.output.getvalue() def parseInitialization( self, repository ): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('home') return elif firstWord == '(': self.absolutePerimeterWidth = abs(float(splitLine[1])) elif firstWord == '(': self.travelFeedRateMinute = 60.0 * float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the bevel gcode." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.addHomeTravel(splitLine) self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) elif firstWord == '(': self.layerCount.printProgressIncrement('home') if len(self.homeLines) > 0: self.shouldHome = True elif firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False self.distanceFeedRate.addLine(line) def main(): "Display the home dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/hop.py000066400000000000000000000213741167321211700276330ustar00rootroot00000000000000""" This page is in the table of contents. Hop is a script to raise the extruder when it is not extruding. Note: Note: In some cases where you have thin overhang this plugin can help solve the problem object being knocked off by the head The hop manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Hop ==Operation== The default 'Activate Hop' checkbox is off. It is off because Vik and Nophead found better results without hopping. Numerous users reported better output without this plugin hence it is off by default. When activated the extruder will hop when traveling. When it is off, nothing will be done. ==Settings== ===Hop Over Layer Thickness=== Default is one. Defines the ratio of the hop height over the layer thickness, this is the most important hop setting. ===Minimum Hop Angle=== Default is 20 degrees. Defines the minimum angle that the path of the extruder will be raised. An angle of ninety means that the extruder will go straight up as soon as it is not extruding and a low angle means the extruder path will gradually rise to the hop height. ==Examples== The following examples hop the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and hop.py. > python hop.py This brings up the hop dialog. > python hop.py Screw Holder Bottom.stl The hop tool is parsing the file: Screw Holder Bottom.stl .. The hop tool has created the file: .. Screw Holder Bottom_hop.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, hopRepository = None ): "Hop a gcode linear move text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), hopRepository ) def getCraftedTextFromText( gcodeText, hopRepository = None ): "Hop a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'hop'): return gcodeText if hopRepository is None: hopRepository = settings.getReadRepository( HopRepository() ) if not hopRepository.activateHop.value: return gcodeText return HopSkein().getCraftedGcode( gcodeText, hopRepository ) def getNewRepository(): 'Get new repository.' return HopRepository() def writeOutput(fileName, shouldAnalyze=True): "Hop a gcode linear move file. Chain hop the gcode if it is not already hopped." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'hop', shouldAnalyze) class HopRepository: "A class to handle the hop settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.hop.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Hop', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Hop') self.activateHop = settings.BooleanSetting().getFromValue('Activate Hop', self, False ) self.hopOverLayerThickness = settings.FloatSpin().getFromValue( 0.5, 'Hop Over Layer Thickness (ratio):', self, 1.5, 1.0 ) self.minimumHopAngle = settings.FloatSpin().getFromValue( 20.0, 'Minimum Hop Angle (degrees):', self, 60.0, 30.0 ) self.executeTitle = 'Hop' def execute(self): "Hop button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class HopSkein: "A class to hop a skein of extrusions." def __init__(self): 'Initialize' self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.feedRateMinute = 961.0 self.hopHeight = 0.4 self.hopDistance = self.hopHeight self.justDeactivated = False self.layerCount = settings.LayerCount() self.lineIndex = 0 self.lines = None self.oldLocation = None def getCraftedGcode( self, gcodeText, hopRepository ): "Parse gcode text and store the hop gcode." self.lines = archive.getTextLines(gcodeText) self.minimumSlope = math.tan( math.radians( hopRepository.minimumHopAngle.value ) ) self.parseInitialization( hopRepository ) for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getHopLine(self, line): "Get hopped gcode line." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) if self.extruderActive: return line location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) highestZ = location.z if self.oldLocation is not None: highestZ = max( highestZ, self.oldLocation.z ) highestZHop = highestZ + self.hopHeight locationComplex = location.dropAxis() if self.justDeactivated: oldLocationComplex = self.oldLocation.dropAxis() distance = abs( locationComplex - oldLocationComplex ) if distance < self.minimumDistance: if self.isNextTravel() or distance == 0.0: return self.distanceFeedRate.getLineWithZ( line, splitLine, highestZHop ) alongRatio = min( 0.41666666, self.hopDistance / distance ) oneMinusAlong = 1.0 - alongRatio closeLocation = oldLocationComplex * oneMinusAlong + locationComplex * alongRatio self.distanceFeedRate.addLine( self.distanceFeedRate.getLineWithZ( line, splitLine, highestZHop ) ) if self.isNextTravel(): return self.distanceFeedRate.getLineWithZ( line, splitLine, highestZHop ) farLocation = oldLocationComplex * alongRatio + locationComplex * oneMinusAlong self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.feedRateMinute, farLocation, highestZHop ) return line if self.isNextTravel(): return self.distanceFeedRate.getLineWithZ( line, splitLine, highestZHop ) return line def isNextTravel(self): "Determine if there is another linear travel before the thread ends." for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ): line = self.lines[ afterIndex ] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': return True if firstWord == 'M101': return False return False def parseInitialization( self, hopRepository ): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '(': layerThickness = float(splitLine[1]) self.hopHeight = hopRepository.hopOverLayerThickness.value * layerThickness self.hopDistance = self.hopHeight / self.minimumSlope self.minimumDistance = 0.5 * layerThickness elif firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('hop') return self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the bevel gcode." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if self.distanceFeedRate.getIsAlteration(line): return if firstWord == 'G1': line = self.getHopLine(line) self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.justDeactivated = False elif firstWord == '(': self.layerCount.printProgressIncrement('hop') elif firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False self.justDeactivated = True self.distanceFeedRate.addLineCheckAlteration(line) def main(): "Display the hop dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/inset.py000066400000000000000000000533051167321211700301660ustar00rootroot00000000000000#! /usr/bin/env python """ This page is in the table of contents. Inset will inset the outside outlines by half the perimeter width, and outset the inside outlines by the same amount. The inset manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Inset ==Settings== ===Add Custom Code for Temperature Reading=== Default is on. When selected, the M105 custom code for temperature reading will be added at the beginning of the file. ===Infill in Direction of Bridge=== Default is on. When selected, the infill will be in the direction of any bridge across a gap, so that the fill will be able to span a bridge easier. ===Loop Order Choice=== Default loop order choice is 'Ascending Area'. When overlap is to be removed, for each loop, the overlap is checked against the list of loops already extruded. If the latest loop overlaps an already extruded loop, the overlap is removed from the latest loop. The loops are ordered according to their areas. ====Ascending Area==== When selected, the loops will be ordered in ascending area. With thin walled parts, if overlap is being removed the outside of the container will not be extruded. Holes will be the correct size. ====Descending Area==== When selected, the loops will be ordered in descending area. With thin walled parts, if overlap is being removed the inside of the container will not be extruded. Holes will be missing the interior wall so they will be slightly wider than model size. ===Overlap Removal Width over Perimeter Width=== Default is 0.6. Defines the ratio of the overlap removal width over the perimeter width. Any part of the extrusion that comes within the overlap removal width of another is removed. This is to prevent the extruder from depositing two extrusions right beside each other. If the 'Overlap Removal Width over Perimeter Width' is less than 0.2, the overlap will not be removed. ===Turn Extruder Heater Off at Shut Down=== Default is on. When selected, the M104 S0 gcode line will be added to the end of the file to turn the extruder heater off by setting the extruder heater temperature to 0. ==Examples== The following examples inset the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and inset.py. > python inset.py This brings up the inset dialog. > python inset.py Screw Holder Bottom.stl The inset tool is parsing the file: Screw Holder Bottom.stl .. The inset tool has created the file: .. Screw Holder Bottom_inset.gcode """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import cmath import math import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addAlreadyFilledArounds( alreadyFilledArounds, loop, radius ): "Add already filled loops around loop to alreadyFilledArounds." radius = abs(radius) alreadyFilledLoop = [] slightlyGreaterThanRadius = intercircle.globalIntercircleMultiplier * radius muchGreaterThanRadius = 2.5 * radius centers = intercircle.getCentersFromLoop( loop, slightlyGreaterThanRadius ) for center in centers: alreadyFilledInset = intercircle.getSimplifiedInsetFromClockwiseLoop( center, radius ) if intercircle.isLargeSameDirection( alreadyFilledInset, center, radius ): alreadyFilledLoop.append( alreadyFilledInset ) if len( alreadyFilledLoop ) > 0: alreadyFilledArounds.append( alreadyFilledLoop ) def addSegmentOutline( isThick, outlines, pointBegin, pointEnd, width ): "Add a diamond or hexagonal outline for a line segment." width = abs( width ) exclusionWidth = 0.6 * width slope = 0.2 if isThick: slope = 3.0 exclusionWidth = 0.8 * width segment = pointEnd - pointBegin segmentLength = abs(segment) if segmentLength == 0.0: return normalizedSegment = segment / segmentLength outline = [] segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd along = 0.05 alongLength = along * segmentLength if alongLength > 0.1 * exclusionWidth: along *= 0.1 * exclusionWidth / alongLength alongEnd = 1.0 - along remainingToHalf = 0.5 - along alongToWidth = exclusionWidth / slope / segmentLength pointBeginIntermediate = euclidean.getIntermediateLocation( along, pointBeginRotated, pointEndRotated ) pointEndIntermediate = euclidean.getIntermediateLocation( alongEnd, pointBeginRotated, pointEndRotated ) outline.append( pointBeginIntermediate ) verticalWidth = complex( 0.0, exclusionWidth ) if alongToWidth > 0.9 * remainingToHalf: verticalWidth = complex( 0.0, slope * remainingToHalf * segmentLength ) middle = ( pointBeginIntermediate + pointEndIntermediate ) * 0.5 middleDown = middle - verticalWidth middleUp = middle + verticalWidth outline.append( middleUp ) outline.append( pointEndIntermediate ) outline.append( middleDown ) else: alongOutsideBegin = along + alongToWidth alongOutsideEnd = alongEnd - alongToWidth outsideBeginCenter = euclidean.getIntermediateLocation( alongOutsideBegin, pointBeginRotated, pointEndRotated ) outsideBeginCenterDown = outsideBeginCenter - verticalWidth outsideBeginCenterUp = outsideBeginCenter + verticalWidth outsideEndCenter = euclidean.getIntermediateLocation( alongOutsideEnd, pointBeginRotated, pointEndRotated ) outsideEndCenterDown = outsideEndCenter - verticalWidth outsideEndCenterUp = outsideEndCenter + verticalWidth outline.append( outsideBeginCenterUp ) outline.append( outsideEndCenterUp ) outline.append( pointEndIntermediate ) outline.append( outsideEndCenterDown ) outline.append( outsideBeginCenterDown ) outlines.append( euclidean.getRotatedComplexes( normalizedSegment, outline ) ) def getBridgeDirection(belowLoops, layerLoops, radius): 'Get span direction for the majority of the overhanging extrusion perimeter, if any.' if len(belowLoops) < 1: return None belowOutsetLoops = intercircle.getInsetLoopsFromLoops(belowLoops, -radius) bridgeRotation = complex() for loop in layerLoops: for pointIndex, point in enumerate(loop): previousIndex = (pointIndex + len(loop) - 1) % len(loop) bridgeRotation += getOverhangDirection(belowOutsetLoops, loop[previousIndex], point) if abs(bridgeRotation) < 0.75 * radius: return None else: return cmath.sqrt(bridgeRotation / abs(bridgeRotation)) def getCraftedText( fileName, text='', repository=None): "Inset the preface file or text." return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): "Inset the preface gcode text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'inset'): return gcodeText if repository is None: repository = settings.getReadRepository( InsetRepository() ) return InsetSkein().getCraftedGcode(gcodeText, repository) def getDoubledRoundZ( overhangingSegment, segmentRoundZ ): 'Get doubled plane angle around z of the overhanging segment.' endpoint = overhangingSegment[0] roundZ = endpoint.point - endpoint.otherEndpoint.point roundZ *= segmentRoundZ if abs( roundZ ) == 0.0: return complex() if roundZ.real < 0.0: roundZ *= - 1.0 roundZLength = abs( roundZ ) return roundZ * roundZ / roundZLength def getInteriorSegments(loops, segments): 'Get segments inside the loops.' interiorSegments = [] for segment in segments: center = 0.5 * (segment[0].point + segment[1].point) if euclidean.getIsInFilledRegion(loops, center): interiorSegments.append(segment) return interiorSegments def getIsIntersectingWithinList(loop, loopList): "Determine if the loop is intersecting or is within the loop list." leftPoint = euclidean.getLeftPoint(loop) for otherLoop in loopList: if euclidean.getNumberOfIntersectionsToLeft(otherLoop, leftPoint) % 2 == 1: return True return euclidean.isLoopIntersectingLoops(loop, loopList) def getNewRepository(): 'Get new repository.' return InsetRepository() def getOverhangDirection( belowOutsetLoops, segmentBegin, segmentEnd ): 'Add to span direction from the endpoint segments which overhang the layer below.' segment = segmentEnd - segmentBegin normalizedSegment = euclidean.getNormalized( complex( segment.real, segment.imag ) ) segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) segmentBegin = segmentYMirror * segmentBegin segmentEnd = segmentYMirror * segmentEnd solidXIntersectionList = [] y = segmentBegin.imag solidXIntersectionList.append( euclidean.XIntersectionIndex( - 1.0, segmentBegin.real ) ) solidXIntersectionList.append( euclidean.XIntersectionIndex( - 1.0, segmentEnd.real ) ) for belowLoopIndex in xrange( len( belowOutsetLoops ) ): belowLoop = belowOutsetLoops[ belowLoopIndex ] rotatedOutset = euclidean.getRotatedComplexes( segmentYMirror, belowLoop ) euclidean.addXIntersectionIndexesFromLoopY( rotatedOutset, belowLoopIndex, solidXIntersectionList, y ) overhangingSegments = euclidean.getSegmentsFromXIntersectionIndexes( solidXIntersectionList, y ) overhangDirection = complex() for overhangingSegment in overhangingSegments: overhangDirection += getDoubledRoundZ( overhangingSegment, normalizedSegment ) return overhangDirection def getSegmentsFromLoopListsPoints( loopLists, pointBegin, pointEnd ): "Get endpoint segments from the beginning and end of a line segment." normalizedSegment = pointEnd - pointBegin normalizedSegmentLength = abs( normalizedSegment ) if normalizedSegmentLength == 0.0: return [] normalizedSegment /= normalizedSegmentLength segmentYMirror = complex(normalizedSegment.real, -normalizedSegment.imag) pointBeginRotated = segmentYMirror * pointBegin pointEndRotated = segmentYMirror * pointEnd rotatedLoopLists = [] for loopList in loopLists: rotatedLoopLists.append(euclidean.getRotatedComplexLists(segmentYMirror, loopList)) xIntersectionIndexList = [] xIntersectionIndexList.append( euclidean.XIntersectionIndex( - 1, pointBeginRotated.real ) ) xIntersectionIndexList.append( euclidean.XIntersectionIndex( - 1, pointEndRotated.real ) ) euclidean.addXIntersectionIndexesFromLoopListsY( rotatedLoopLists, xIntersectionIndexList, pointBeginRotated.imag ) segments = euclidean.getSegmentsFromXIntersectionIndexes( xIntersectionIndexList, pointBeginRotated.imag ) for segment in segments: for endpoint in segment: endpoint.point *= normalizedSegment return segments def isCloseToLast( paths, point, radius ): "Determine if the point is close to the last point of the last path." if len(paths) < 1: return False lastPath = paths[-1] return abs( lastPath[-1] - point ) < radius def isIntersectingItself( loop, width ): "Determine if the loop is intersecting itself." outlines = [] for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] if euclidean.isLineIntersectingLoops( outlines, pointBegin, pointEnd ): return True addSegmentOutline( False, outlines, pointBegin, pointEnd, width ) return False def isIntersectingWithinLists( loop, loopLists ): "Determine if the loop is intersecting or is within the loop lists." for loopList in loopLists: if getIsIntersectingWithinList( loop, loopList ): return True return False def writeOutput(fileName, shouldAnalyze=True): "Inset the carving of a gcode file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'inset', shouldAnalyze) class InsetRepository: "A class to handle the inset settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.inset.html', self ) self.baseNameSynonym = 'carve.csv' self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Inset', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Inset') # self.addCustomCodeForTemperatureReading = settings.BooleanSetting().getFromValue('Add Custom Code for Temperature Reading', self, True ) self.infillInDirectionOfBridge = settings.BooleanSetting().getFromValue('Infill in Direction of Bridge', self, True) self.bridgeWidthMultiplier = settings.FloatSpin().getFromValue( 0.7, 'Bridge Width Multiplier (ratio):', self, 2.0, 1.0 ) self.nozzleDiameter = settings.FloatSpin().getFromValue( 0.1, 'Nozzle Diameter(mm):', self, 1.0, 0.50 ) self.loopOrderChoice = settings.MenuButtonDisplay().getFromName('In case of Conflict Solve:', self ) self.loopOrderAscendingArea = settings.MenuRadio().getFromMenuButtonDisplay( self.loopOrderChoice, 'Prefer Loops', self, True ) self.loopOrderDescendingArea = settings.MenuRadio().getFromMenuButtonDisplay( self.loopOrderChoice, 'Prefer Perimeter', self, False ) self.overlapRemovalWidthOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.5, 'Overlap Removal(Scaler):', self, 1.5, 1.0 ) # self.turnExtruderHeaterOffAtShutDown = settings.BooleanSetting().getFromValue('Turn Extruder Heater Off at Shut Down', self, True ) self.executeTitle = 'Inset' def execute(self): "Inset button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class InsetSkein: "A class to inset a skein of extrusions." def __init__(self): 'Initialize.' self.belowLoops = [] self.boundary = None self.distanceFeedRate = gcodec.DistanceFeedRate() self.layerCount = settings.LayerCount() self.lineIndex = 0 self.loopLayer = None self.scaledBridgeWidthMultiplier = 0.5 def addGcodeFromPerimeterPaths(self, isIntersectingSelf, loop, loopLayer, loopLists, radius): "Add the perimeter paths to the output." segments = [] outlines = [] thickOutlines = [] allLoopLists = loopLists[:] + [thickOutlines] aroundLists = loopLists for pointIndex in xrange(len(loop)): pointBegin = loop[pointIndex] pointEnd = loop[(pointIndex + 1) % len(loop)] if isIntersectingSelf: if euclidean.isLineIntersectingLoops(outlines, pointBegin, pointEnd): segments += getSegmentsFromLoopListsPoints(allLoopLists, pointBegin, pointEnd) else: segments += getSegmentsFromLoopListsPoints(loopLists, pointBegin, pointEnd) addSegmentOutline(False, outlines, pointBegin, pointEnd, self.overlapRemovalWidth) addSegmentOutline(True, thickOutlines, pointBegin, pointEnd, self.overlapRemovalWidth) else: segments += getSegmentsFromLoopListsPoints(loopLists, pointBegin, pointEnd) perimeterPaths = [] path = [] muchSmallerThanRadius = 0.1 * radius segments = getInteriorSegments(loopLayer.loops, segments) for segment in segments: pointBegin = segment[0].point if not isCloseToLast(perimeterPaths, pointBegin, muchSmallerThanRadius): path = [pointBegin] perimeterPaths.append(path) path.append(segment[1].point) if len(perimeterPaths) > 1: firstPath = perimeterPaths[0] lastPath = perimeterPaths[-1] if abs(lastPath[-1] - firstPath[0]) < 0.1 * muchSmallerThanRadius: connectedBeginning = lastPath[: -1] + firstPath perimeterPaths[0] = connectedBeginning perimeterPaths.remove(lastPath) muchGreaterThanRadius = 6.0 * radius for perimeterPath in perimeterPaths: if euclidean.getPathLength(perimeterPath) > muchGreaterThanRadius: self.distanceFeedRate.addGcodeFromThreadZ(perimeterPath, loopLayer.z) def addGcodeFromRemainingLoop(self, loop, loopLayer, loopLists, radius): "Add the remainder of the loop which does not overlap the alreadyFilledArounds loops." centerOutset = intercircle.getLargestCenterOutsetLoopFromLoopRegardless(loop, radius) euclidean.addNestedRingBeginning(self.distanceFeedRate, centerOutset.outset, loopLayer.z) self.addGcodePerimeterBlockFromRemainingLoop(centerOutset.center, loopLayer, loopLists, radius) self.distanceFeedRate.addLine('()') self.distanceFeedRate.addLine('()') def addGcodePerimeterBlockFromRemainingLoop(self, loop, loopLayer, loopLists, radius): "Add the perimter block remainder of the loop which does not overlap the alreadyFilledArounds loops." if self.repository.overlapRemovalWidthOverPerimeterWidth.value < 0.2:#ACT self.distanceFeedRate.addPerimeterBlock(loop, loopLayer.z) return isIntersectingSelf = isIntersectingItself(loop, self.overlapRemovalWidth) if isIntersectingWithinLists(loop, loopLists) or isIntersectingSelf: self.addGcodeFromPerimeterPaths(isIntersectingSelf, loop, loopLayer, loopLists, radius) else: self.distanceFeedRate.addPerimeterBlock(loop, loopLayer.z) addAlreadyFilledArounds(loopLists, loop, self.overlapRemovalWidth) # def addInitializationToOutput(self): # "Add initialization gcode to the output." # if self.repository.addCustomCodeForTemperatureReading.value: # self.distanceFeedRate.addLine('M105') # Custom code for temperature reading. def addInset(self, loopLayer): "Add inset to the layer." alreadyFilledArounds = [] extrudateLoops = intercircle.getInsetLoopsFromLoops(loopLayer.loops, self.halfPerimeterWidth) if self.repository.infillInDirectionOfBridge.value: self.halfBridgeWidth = self.repository.bridgeWidthMultiplier.value * self.halfPerimeterWidth #* (self.nozzleXsection / self.extrusionXsection) bridgeRotation = getBridgeDirection(self.belowLoops, extrudateLoops, self.halfBridgeWidth ) if bridgeRotation is not None: self.distanceFeedRate.addTagBracketedLine('bridgeRotation', bridgeRotation) # print 'bridge' , self.layerCount self.belowLoops = loopLayer.loops triangle_mesh.sortLoopsInOrderOfArea(not self.repository.loopOrderAscendingArea.value, extrudateLoops) for extrudateLoop in extrudateLoops: self.addGcodeFromRemainingLoop(extrudateLoop, loopLayer, alreadyFilledArounds, self.halfPerimeterWidth) def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the bevel gcode." self.repository = repository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() for line in self.lines[self.lineIndex :]: self.parseLine(line) return self.distanceFeedRate.output.getvalue() def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '(': # self.addInitializationToOutput() self.distanceFeedRate.addTagBracketedLine('bridgeWidthMultiplier', self.distanceFeedRate.getRounded( self.repository.bridgeWidthMultiplier.value )) self.distanceFeedRate.addTagBracketedLine('scaledBridgeWidthMultiplier', self.distanceFeedRate.getRounded( self.scaledBridgeWidthMultiplier )) elif firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('inset') return elif firstWord == '(': self.layerThickness = float(splitLine[1]) elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.halfPerimeterWidth = 0.5 * self.perimeterWidth self.overlapRemovalWidth = self.perimeterWidth * self.repository.overlapRemovalWidthOverPerimeterWidth.value self.distanceFeedRate.addTagBracketedLine('nozzleDiameter', self.repository.nozzleDiameter.value ) self.nozzleXsection = (self.repository.nozzleDiameter.value/2) ** 2 * math.pi self.extrusionXsection = ((self.perimeterWidth + self.layerThickness)/4) ** 2 * math.pi self.distanceFeedRate.addTagBracketedLine('nozzleXsection', self.nozzleXsection) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the inset skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) self.boundary.append(location.dropAxis()) elif firstWord == '(': self.loopLayer.rotation = gcodec.getRotationBySplitLine(splitLine) # elif firstWord == '()': # self.distanceFeedRate.addLine(line) # if self.repository.turnExtruderHeaterOffAtShutDown.value: # self.distanceFeedRate.addLine('M104 S0') # Turn extruder heater off. # return elif firstWord == '(': self.layerCount.printProgressIncrement('inset') self.loopLayer = euclidean.LoopLayer(float(splitLine[1])) self.distanceFeedRate.addLine(line) elif firstWord == '()': self.addInset(self.loopLayer) self.loopLayer = None elif firstWord == '()': self.boundary = [] self.loopLayer.loops.append(self.boundary) if self.loopLayer is None: self.distanceFeedRate.addLine(line) def main(): "Display the inset dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/jitter.py000066400000000000000000000247201167321211700303440ustar00rootroot00000000000000""" This page is in the table of contents. This craft tool jitters the loop end position to a different place on each layer to prevent a ridge from being created on the side of the object. The jitter manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Jitter ==Operation== The default 'Activate Jitter' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Jitter Over Perimeter Width=== Default: 2 Defines the amount the loop ends will be jittered over the perimeter width. A high value means the loops will start all over the place and a low value means loops will start at roughly the same place on each layer. For example if you turn jitter off and print a cube every outside shell on the cube will start from exactly the same point so you will have a visible "mark/line/seam" on the side of the cube. Using the jitter tool you move that start point around hence you avoid that visible seam. ==Examples== The following examples jitter the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and jitter.py. > python jitter.py This brings up the jitter dialog. > python jitter.py Screw Holder Bottom.stl The jitter tool is parsing the file: Screw Holder Bottom.stl .. The jitter tool has created the file: .. Screw Holder Bottom_jitter.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, jitterRepository = None ): 'Jitter a gcode linear move text.' return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), jitterRepository ) def getCraftedTextFromText( gcodeText, jitterRepository = None ): 'Jitter a gcode linear move text.' if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'jitter'): return gcodeText if jitterRepository is None: jitterRepository = settings.getReadRepository( JitterRepository() ) if not jitterRepository.activateJitter.value: return gcodeText return JitterSkein().getCraftedGcode( jitterRepository, gcodeText ) def getJitteredLoop( jitterDistance, jitterLoop ): 'Get a jittered loop path.' loopLength = euclidean.getLoopLength( jitterLoop ) lastLength = 0.0 pointIndex = 0 totalLength = 0.0 jitterPosition = ( jitterDistance + 256.0 * loopLength ) % loopLength while totalLength < jitterPosition and pointIndex < len( jitterLoop ): firstPoint = jitterLoop[pointIndex] secondPoint = jitterLoop[ (pointIndex + 1) % len( jitterLoop ) ] pointIndex += 1 lastLength = totalLength totalLength += abs(firstPoint - secondPoint) remainingLength = jitterPosition - lastLength pointIndex = pointIndex % len( jitterLoop ) ultimateJitteredPoint = jitterLoop[pointIndex] penultimateJitteredPointIndex = ( pointIndex + len( jitterLoop ) - 1 ) % len( jitterLoop ) penultimateJitteredPoint = jitterLoop[ penultimateJitteredPointIndex ] segment = ultimateJitteredPoint - penultimateJitteredPoint segmentLength = abs(segment) originalOffsetLoop = euclidean.getAroundLoop( pointIndex, pointIndex, jitterLoop ) if segmentLength <= 0.0: return originalOffsetLoop newUltimatePoint = penultimateJitteredPoint + segment * remainingLength / segmentLength return [newUltimatePoint] + originalOffsetLoop def getNewRepository(): 'Get new repository.' return JitterRepository() def isLoopNumberEqual( betweenX, betweenXIndex, loopNumber ): 'Determine if the loop number is equal.' if betweenXIndex >= len( betweenX ): return False return betweenX[ betweenXIndex ].index == loopNumber def writeOutput(fileName, shouldAnalyze=True): 'Jitter a gcode linear move file.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'jitter', shouldAnalyze) class JitterRepository: 'A class to handle the jitter settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.jitter.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Jitter', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Jitter') self.activateJitter = settings.BooleanSetting().getFromValue('Activate Jitter to have your perimeter and loop endpoints scattered', self, False) self.jitterOverPerimeterWidth = settings.FloatSpin().getFromValue(0.0, 'Jitter Over Perimeter Width (ratio):', self, 10.0, 2.0) self.executeTitle = 'Jitter' def execute(self): 'Jitter button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class JitterSkein: 'A class to jitter a skein of extrusions.' def __init__(self): 'Initialize.' self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRateMinute = None self.isLoopPerimeter = False self.layerCount = settings.LayerCount() self.layerGolden = 0.0 self.lineIndex = 0 self.lines = None self.loopPath = None self.oldLocation = None self.operatingFeedRatePerMinute = None self.travelFeedRateMinute = None def addGcodeFromThreadZ( self, thread, z ): 'Add a gcode thread to the output.' if len(thread) > 0: self.addGcodeMovementZ( self.travelFeedRateMinute, thread[0], z ) else: print('zero length vertex positions array which was skipped over, this should never happen.') if len(thread) < 2: return self.distanceFeedRate.addLine('M101') self.addGcodePathZ( self.feedRateMinute, thread[1 :], z ) def addGcodeMovementZ(self, feedRateMinute, point, z): 'Add a movement to the output.' if feedRateMinute is None: feedRateMinute = self.operatingFeedRatePerMinute self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedRateMinute, point, z) def addGcodePathZ( self, feedRateMinute, path, z ): 'Add a gcode path, without modifying the extruder, to the output.' for point in path: self.addGcodeMovementZ(feedRateMinute, point, z) def addTailoredLoopPath(self): 'Add a clipped and jittered loop path.' loop = getJitteredLoop(self.layerJitter, self.loopPath.path[: -1]) loop = euclidean.getAwayPoints(loop, 0.2 * self.perimeterWidth) self.addGcodeFromThreadZ(loop + [loop[0]], self.loopPath.z) self.loopPath = None def getCraftedGcode(self, jitterRepository, gcodeText): 'Parse gcode text and store the jitter gcode.' if jitterRepository.jitterOverPerimeterWidth.value == 0.0: print('Warning, Jitter Over Perimeter Width is zero so thing will be done.') return gcodeText self.lines = archive.getTextLines(gcodeText) self.parseInitialization(jitterRepository) for self.lineIndex in xrange(self.lineIndex, len(self.lines)): self.parseLine(self.lines[self.lineIndex]) return self.distanceFeedRate.output.getvalue() def parseInitialization( self, jitterRepository ): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('jitter') return elif firstWord == '(': self.operatingFeedRatePerMinute = 60.0 * float(splitLine[1]) elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.jitter = jitterRepository.jitterOverPerimeterWidth.value * self.perimeterWidth elif firstWord == '(': self.travelFeedRateMinute = 60.0 * float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): 'Parse a gcode line, jitter it and add it to the jitter skein.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.setFeedRateLocationLoopPath(line, splitLine) if self.loopPath is not None: self.loopPath.path.append(self.oldLocation.dropAxis()) return elif firstWord == 'M101': if self.loopPath is not None: return elif firstWord == 'M103': self.isLoopPerimeter = False if self.loopPath is not None: self.addTailoredLoopPath() elif firstWord == '(': self.layerCount.printProgressIncrement('jitter') self.layerGolden = math.fmod(self.layerGolden + 0.61803398874989479, 1.0) self.layerJitter = self.jitter * self.layerGolden - 0.5 elif firstWord == '(' or firstWord == '(': self.isLoopPerimeter = True self.distanceFeedRate.addLine(line) def setFeedRateLocationLoopPath(self, line, splitLine): 'Set the feedRateMinute, oldLocation and loopPath.' self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if not self.isLoopPerimeter or self.loopPath is not None: return for afterIndex in xrange(self.lineIndex + 1, len(self.lines)): line = self.lines[afterIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1' or firstWord == 'M103': return elif firstWord == 'M101': self.loopPath = euclidean.PathZ(self.oldLocation.z) return def main(): 'Display the jitter dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/lash.py000066400000000000000000000147371167321211700300010ustar00rootroot00000000000000""" This page is in the table of contents. Lash is a script to partially compensate for the backlash of the tool head. The lash manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Lash The lash tool is ported from Erik de Bruijn's 3D-to-5D-Gcode php GPL'd script at: http://objects.reprap.org/wiki/3D-to-5D-Gcode.php The default values are from the settings in Erik's 3D-to-5D-Gcode, I believe the settings are used on his Darwin reprap. ==Operation== The default 'Activate Lash' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===X Backlash=== Default is 0.2 millimeters. Defines the distance the tool head will be lashed in the X direction. ===Y Backlash=== Default is 0.2 millimeters. Defines the distance the tool head will be lashed in the Y direction. ==Examples== The following examples lash the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and lash.py. > python lash.py This brings up the lash dialog. > python lash.py Screw Holder Bottom.stl The lash tool is parsing the file: Screw Holder Bottom.stl .. The lash tool has created the file: .. Screw Holder Bottom_lash.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, lashRepository = None ): "Get a lashed gcode linear move text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), lashRepository ) def getCraftedTextFromText( gcodeText, lashRepository = None ): "Get a lashed gcode linear move text from text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'lash'): return gcodeText if lashRepository is None: lashRepository = settings.getReadRepository( LashRepository() ) if not lashRepository.activateLash.value: return gcodeText return LashSkein().getCraftedGcode( gcodeText, lashRepository ) def getNewRepository(): 'Get new repository.' return LashRepository() def writeOutput(fileName, shouldAnalyze=True): "Lash a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'lash', shouldAnalyze) class LashRepository: "A class to handle the lash settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.lash.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Lash', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Lash') self.activateLash = settings.BooleanSetting().getFromValue('Activate Lash if you have backlash in your axes', self, False ) self.xBacklash = settings.FloatSpin().getFromValue( 0.1, 'X Backlash (mm):', self, 0.5, 0.2 ) self.yBacklash = settings.FloatSpin().getFromValue( 0.1, 'Y Backlash (mm):', self, 0.5, 0.3 ) self.executeTitle = 'Lash' def execute(self): "Lash button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class LashSkein: "A class to lash a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRateMinute = 958.0 self.lineIndex = 0 self.lines = None self.oldLocation = None def getCraftedGcode( self, gcodeText, lashRepository ): "Parse gcode text and store the lash gcode." self.lines = archive.getTextLines(gcodeText) self.lashRepository = lashRepository self.xBacklash = lashRepository.xBacklash.value self.yBacklash = lashRepository.yBacklash.value self.parseInitialization() for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLash(line) return self.distanceFeedRate.output.getvalue() def getLashedLine( self, line, location, splitLine ): "Get lashed gcode line." if self.oldLocation is None: return line if location.x > self.oldLocation.x: line = self.distanceFeedRate.getLineWithX( line, splitLine, location.x + self.xBacklash ) else: line = self.distanceFeedRate.getLineWithX( line, splitLine, location.x - self.xBacklash ) if location.y > self.oldLocation.y: line = self.distanceFeedRate.getLineWithY( line, splitLine, location.y + self.yBacklash ) else: line = self.distanceFeedRate.getLineWithY( line, splitLine, location.y - self.yBacklash ) return line def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('lash') return self.distanceFeedRate.addLine(line) def parseLash(self, line): "Parse a gcode line and add it to the lash skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) line = self.getLashedLine( line, location, splitLine ) self.oldLocation = location self.distanceFeedRate.addLine(line) def main(): "Display the lash dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/lift.py000066400000000000000000000204511167321211700277760ustar00rootroot00000000000000""" This page is in the table of contents. Lift will change the altitude of the cutting tool when it is on so that it will cut through the slab at the correct altitude. It will also lift the gcode when the tool is off so that the cutting tool will clear the top of the slab. ==Operation== The default 'Activate Lift' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Cutting Lift over Layer Step=== Default is minus 0.5, because the end mill is the more common tool. Defines the ratio of the amount the cutting tool will be lifted over the layer step. If whittle is off the layer step will be the layer thickness, if it is on, it will be the layer step from the whittle gcode. If the cutting tool is like an end mill, where the cutting happens until the end of the tool, then the 'Cutting Lift over Layer Step' should be minus 0.5, so that the end mill cuts to the bottom of the slab. If the cutting tool is like a laser, where the cutting happens around the focal point. the 'Cutting Lift over Layer Step' should be zero, so that the cutting action will be focused in the middle of the slab. ===Clearance above Top=== Default is 5 millimeters. Defines the distance above the top of the slab the cutting tool will be lifted when will tool is off so that the cutting tool will clear the top of the slab. ==Examples== The following examples lift the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and lift.py. > python lift.py This brings up the lift dialog. > python lift.py Screw Holder Bottom.stl The lift tool is parsing the file: Screw Holder Bottom.stl .. The lift tool has created the file: .. Screw Holder Bottom_lift.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text='', liftRepository = None ): "Lift the preface file or text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), liftRepository ) def getCraftedTextFromText( gcodeText, liftRepository = None ): "Lift the preface gcode text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'lift'): return gcodeText if liftRepository is None: liftRepository = settings.getReadRepository( LiftRepository() ) if not liftRepository.activateLift.value: return gcodeText return LiftSkein().getCraftedGcode( liftRepository, gcodeText ) def getNewRepository(): 'Get new repository.' return LiftRepository() def writeOutput(fileName, shouldAnalyze=True): "Lift the carving of a gcode file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'lift', shouldAnalyze) class LiftRepository: "A class to handle the lift settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.lift.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File to be Lifted', self, '') self.activateLift = settings.BooleanSetting().getFromValue('Activate Lift', self, True ) self.cuttingLiftOverLayerStep = settings.FloatSpin().getFromValue( - 1.0, 'Cutting Lift over Layer Step (ratio):', self, 1.0, - 0.5 ) self.clearanceAboveTop = settings.FloatSpin().getFromValue( 0.0, 'Clearance above Top (mm):', self, 10.0, 5.0 ) self.executeTitle = 'Lift' def execute(self): "Lift button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class LiftSkein: "A class to lift a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.layerStep = None self.layerThickness = 0.3333333333 self.lineIndex = 0 self.maximumZ = - 912345678.0 self.oldLocation = None self.previousActiveMovementLine = None self.previousInactiveMovementLine = None def addPreviousInactiveMovementLineIfNecessary(self): "Add the previous inactive movement line if necessary." if self.previousInactiveMovementLine is not None: self.distanceFeedRate.addLine( self.previousInactiveMovementLine ) self.previousInactiveMovementLine = None def getCraftedGcode( self, liftRepository, gcodeText ): "Parse gcode text and store the lift gcode." self.liftRepository = liftRepository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() self.oldLocation = None if self.layerStep is None: self.layerStep = self.layerThickness self.cuttingLift = self.layerStep * liftRepository.cuttingLiftOverLayerStep.value self.setMaximumZ() self.travelZ = self.maximumZ + 0.5 * self.layerStep + liftRepository.clearanceAboveTop.value for line in self.lines[self.lineIndex :]: self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getLinearMove( self, line, location, splitLine ): "Get the linear move." if self.extruderActive: z = location.z + self.cuttingLift return self.distanceFeedRate.getLineWithZ( line, splitLine, z ) if self.previousActiveMovementLine is not None: previousActiveMovementLineSplit = self.previousActiveMovementLine.split() self.distanceFeedRate.addLine( self.distanceFeedRate.getLineWithZ( self.previousActiveMovementLine, previousActiveMovementLineSplit, self.travelZ ) ) self.previousActiveMovementLine = None self.distanceFeedRate.addLine( self.distanceFeedRate.getLineWithZ( line, splitLine, self.travelZ ) ) self.previousInactiveMovementLine = line return '' def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex].lstrip() splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('lift') return elif firstWord == '(': self.layerThickness = float(splitLine[1]) elif firstWord == '(': self.layerStep = float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the lift skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) line = self.getLinearMove( line, location, splitLine ) self.previousActiveMovementLine = line self.oldLocation = location elif firstWord == 'M101': self.addPreviousInactiveMovementLineIfNecessary() self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False self.distanceFeedRate.addLine(line) def setMaximumZ(self): "Set maximum z." localOldLocation = None for line in self.lines[self.lineIndex :]: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine( localOldLocation, splitLine ) self.maximumZ = max( self.maximumZ, location.z ) localOldLocation = location def main(): "Display the lift dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/limit.py000066400000000000000000000200561167321211700301570ustar00rootroot00000000000000#! /usr/bin/env python """ This page is in the table of contents. This plugin limits the feed rate of the tool head, so that the stepper motors are not driven too fast and skip steps. The limit manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Limit The maximum z feed rate is defined in speed. ==Operation== The default 'Activate Limit' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Maximum Initial Feed Rate=== Default is one millimeter per second. Defines the maximum speed of the inital tool head move. ==Examples== The following examples limit the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and limit.py. > python limit.py This brings up the limit dialog. > python limit.py Screw Holder Bottom.stl The limit tool is parsing the file: Screw Holder Bottom.stl .. The limit tool has created the file: .. Screw Holder Bottom_limit.gcode """ #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from datetime import date from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/28/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, gcodeText='', repository=None): 'Limit a gcode file or text.' return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), repository ) def getCraftedTextFromText(gcodeText, repository=None): 'Limit a gcode text.' if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'limit'): return gcodeText if repository is None: repository = settings.getReadRepository(LimitRepository()) if not repository.activateLimit.value: return gcodeText return LimitSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return LimitRepository() def writeOutput(fileName, shouldAnalyze=True): 'Limit a gcode file.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'limit', shouldAnalyze) class LimitRepository: 'A class to handle the limit settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.limit.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Limit', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Limit') self.activateLimit = settings.BooleanSetting().getFromValue('Activate Limit', self, False) self.maximumInitialFeedRate = settings.FloatSpin().getFromValue(0.5, 'Maximum Initial Feed Rate (mm/s):', self, 10.0, 1.0) self.executeTitle = 'Limit' def execute(self): 'Limit button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class LimitSkein: 'A class to limit a skein of extrusions.' def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRateMinute = None self.lineIndex = 0 self.maximumZDrillFeedRatePerSecond = 987654321.0 self.oldLocation = None def getCraftedGcode(self, gcodeText, repository): 'Parse gcode text and store the limit gcode.' self.repository = repository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() self.maximumZDrillFeedRatePerSecond = min(self.maximumZDrillFeedRatePerSecond, self.maximumZTravelFeedRatePerSecond) self.maximumZFeedRatePerSecond = self.maximumZTravelFeedRatePerSecond for lineIndex in xrange(self.lineIndex, len(self.lines)): self.parseLine( lineIndex ) return self.distanceFeedRate.output.getvalue() def getLimitedInitialMovement(self, line, splitLine): 'Get a limited linear movement.' if self.oldLocation is None: line = self.distanceFeedRate.getLineWithFeedRate(60.0 * self.repository.maximumInitialFeedRate.value, line, splitLine) return line def getZLimitedLine(self, deltaZ, distance, line, splitLine): 'Get a replaced z limited gcode movement line.' zFeedRateSecond = self.feedRateMinute * deltaZ / distance / 60.0 if zFeedRateSecond <= self.maximumZFeedRatePerSecond: return line limitedFeedRateMinute = self.feedRateMinute * self.maximumZFeedRatePerSecond / zFeedRateSecond return self.distanceFeedRate.getLineWithFeedRate(limitedFeedRateMinute, line, splitLine) def getZLimitedLineArc(self, line, splitLine): 'Get a replaced z limited gcode arc movement line.' self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) if self.feedRateMinute is None or self.oldLocation is None: return line relativeLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.oldLocation += relativeLocation deltaZ = abs(relativeLocation.z) distance = gcodec.getArcDistance(relativeLocation, splitLine) return self.getZLimitedLine(deltaZ, distance, line, splitLine) def getZLimitedLineLinear(self, line, location, splitLine): 'Get a replaced z limited gcode linear movement line.' self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) if location == self.oldLocation: return '' if self.feedRateMinute is None or self.oldLocation is None: return line deltaZ = abs(location.z - self.oldLocation.z) distance = abs(location - self.oldLocation) return self.getZLimitedLine(deltaZ, distance, line, splitLine) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('limit') return elif firstWord == '(': self.maximumZDrillFeedRatePerSecond = float(splitLine[1]) elif firstWord == '(': self.maximumZTravelFeedRatePerSecond = float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine( self, lineIndex ): 'Parse a gcode line and add it to the limit skein.' line = self.lines[lineIndex].lstrip() splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) line = self.getLimitedInitialMovement(line, splitLine) line = self.getZLimitedLineLinear(line, location, splitLine) self.oldLocation = location elif firstWord == 'G2' or firstWord == 'G3': line = self.getZLimitedLineArc(line, splitLine) elif firstWord == 'M101': self.maximumZFeedRatePerSecond = self.maximumZDrillFeedRatePerSecond elif firstWord == 'M103': self.maximumZFeedRatePerSecond = self.maximumZTravelFeedRatePerSecond self.distanceFeedRate.addLine(line) def main(): 'Display the limit dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/mill.py000066400000000000000000000404661167321211700300050ustar00rootroot00000000000000""" This page is in the table of contents. Mill is a script to mill the outlines. ==Operation== The default 'Activate Mill' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Add Loops=== ====Add Inner Loops==== Default is on. When selected, the inner milling loops will be added. ====Add Outer Loops==== Default is on. When selected, the outer milling loops will be added. ===Cross Hatch=== Default is on. When selected, there will be alternating horizontal and vertical milling paths, if it is off there will only be horizontal milling paths. ===Loop Outset=== ====Loop Inner Outset over Perimeter Width==== Default is 0.5. Defines the ratio of the amount the inner milling loop will be outset over the perimeter width. ====Loop Outer Outset over Perimeter Width==== Default is one. Defines the ratio of the amount the outer milling loop will be outset over the perimeter width. The 'Loop Outer Outset over Perimeter Width' ratio should be greater than the 'Loop Inner Outset over Perimeter Width' ratio. ===Mill Width over Perimeter Width=== Default is one. Defines the ratio of the mill line width over the perimeter width. If the ratio is one, all the material will be milled. The greater the 'Mill Width over Perimeter Width' the farther apart the mill lines will be and so less of the material will be directly milled, the remaining material might still be removed in chips if the ratio is not much greater than one. ==Examples== The following examples mill the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and mill.py. > python mill.py This brings up the mill dialog. > python mill.py Screw Holder Bottom.stl The mill tool is parsing the file: Screw Holder Bottom.stl .. The mill tool has created the file: Screw Holder Bottom_mill.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, gcodeText = '', repository=None): 'Mill the file or gcodeText.' return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), repository ) def getCraftedTextFromText(gcodeText, repository=None): 'Mill a gcode linear move gcodeText.' if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'mill'): return gcodeText if repository is None: repository = settings.getReadRepository( MillRepository() ) if not repository.activateMill.value: return gcodeText return MillSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return MillRepository() def getPointsFromSegmentTable(segmentTable): 'Get the points from the segment table.' points = [] segmentTableKeys = segmentTable.keys() segmentTableKeys.sort() for segmentTableKey in segmentTableKeys: for segment in segmentTable[segmentTableKey]: for endpoint in segment: points.append(endpoint.point) return points def isPointOfTableInLoop( loop, pointTable ): 'Determine if a point in the point table is in the loop.' for point in loop: if point in pointTable: return True return False def writeOutput(fileName, shouldAnalyze=True): 'Mill a gcode linear move file.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'mill', shouldAnalyze) class Average: 'A class to hold values and get the average.' def __init__(self): self.reset() def addValue( self, value ): 'Add a value to the total and the number of values.' self.numberOfValues += 1 self.total += value def getAverage(self): 'Get the average.' if self.numberOfValues == 0: print('should never happen, self.numberOfValues in Average is zero') return 0.0 return self.total / float( self.numberOfValues ) def reset(self): 'Set the number of values and the total to the default.' self.numberOfValues = 0 self.total = 0.0 class MillRepository: 'A class to handle the mill settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.mill.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Mill', self, '') self.activateMill = settings.BooleanSetting().getFromValue('Activate Mill', self, True ) settings.LabelDisplay().getFromName('- Add Loops -', self ) self.addInnerLoops = settings.BooleanSetting().getFromValue('Add Inner Loops', self, True ) self.addOuterLoops = settings.BooleanSetting().getFromValue('Add Outer Loops', self, True ) self.crossHatch = settings.BooleanSetting().getFromValue('Cross Hatch', self, True ) settings.LabelDisplay().getFromName('- Loop Outset -', self ) self.loopInnerOutsetOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.3, 'Loop Inner Outset over Perimeter Width (ratio):', self, 0.7, 0.5 ) self.loopOuterOutsetOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.8, 'Loop Outer Outset over Perimeter Width (ratio):', self, 1.4, 1.0 ) self.millWidthOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.8, 'Mill Width over Perimeter Width (ratio):', self, 1.8, 1.0 ) self.executeTitle = 'Mill' def execute(self): 'Mill button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class MillSkein: 'A class to mill a skein of extrusions.' def __init__(self): self.aroundPixelTable = {} self.average = Average() self.boundaryLayers = [] self.distanceFeedRate = gcodec.DistanceFeedRate() self.isExtruderActive = False self.layerIndex = 0 self.lineIndex = 0 self.lines = None self.oldLocation = None self.perimeterWidth = 0.6 def addGcodeFromLoops(self, loops, z): 'Add gcode from loops.' if self.oldLocation is None: self.oldLocation = Vector3() self.oldLocation.z = z for loop in loops: self.distanceFeedRate.addGcodeFromThreadZ(loop, z) euclidean.addToThreadsFromLoop(self.halfPerimeterWidth, 'loop', loop, self.oldLocation, self) def addGcodeFromThreadZ( self, thread, z ): 'Add a thread to the output.' self.distanceFeedRate.addGcodeFromThreadZ( thread, z ) def addMillThreads(self): 'Add the mill threads to the skein.' boundaryLayer = self.boundaryLayers[self.layerIndex] endpoints = euclidean.getEndpointsFromSegmentTable( boundaryLayer.segmentTable ) if len(endpoints) < 1: return paths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.millWidth, self.aroundPixelTable, self.aroundWidth) averageZ = self.average.getAverage() if self.repository.addInnerLoops.value: self.addGcodeFromLoops( boundaryLayer.innerLoops, averageZ ) if self.repository.addOuterLoops.value: self.addGcodeFromLoops( boundaryLayer.outerLoops, averageZ ) for path in paths: simplifiedPath = euclidean.getSimplifiedPath( path, self.millWidth ) self.distanceFeedRate.addGcodeFromThreadZ( simplifiedPath, averageZ ) def addSegmentTableLoops( self, boundaryLayerIndex ): 'Add the segment tables and loops to the boundary.' boundaryLayer = self.boundaryLayers[boundaryLayerIndex] euclidean.subtractXIntersectionsTable(boundaryLayer.outerHorizontalTable, boundaryLayer.innerHorizontalTable) euclidean.subtractXIntersectionsTable(boundaryLayer.outerVerticalTable, boundaryLayer.innerVerticalTable) boundaryLayer.horizontalSegmentTable = self.getHorizontalSegmentTableForXIntersectionsTable( boundaryLayer.outerHorizontalTable) boundaryLayer.verticalSegmentTable = self.getVerticalSegmentTableForXIntersectionsTable( boundaryLayer.outerVerticalTable) betweenPoints = getPointsFromSegmentTable(boundaryLayer.horizontalSegmentTable) betweenPoints += getPointsFromSegmentTable(boundaryLayer.verticalSegmentTable) innerPoints = euclidean.getPointsByHorizontalDictionary(self.millWidth, boundaryLayer.innerHorizontalTable) innerPoints += euclidean.getPointsByVerticalDictionary(self.millWidth, boundaryLayer.innerVerticalTable) innerPointTable = {} for innerPoint in innerPoints: innerPointTable[innerPoint] = None boundaryLayer.innerLoops = [] boundaryLayer.outerLoops = [] millRadius = 0.75 * self.millWidth loops = triangle_mesh.getDescendingAreaOrientedLoops(betweenPoints, betweenPoints, millRadius) for loop in loops: if isPointOfTableInLoop(loop, innerPointTable): boundaryLayer.innerLoops.append(loop) else: boundaryLayer.outerLoops.append(loop) if self.repository.crossHatch.value and boundaryLayerIndex % 2 == 1: boundaryLayer.segmentTable = boundaryLayer.verticalSegmentTable else: boundaryLayer.segmentTable = boundaryLayer.horizontalSegmentTable def getCraftedGcode(self, gcodeText, repository): 'Parse gcode text and store the mill gcode.' self.repository = repository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() self.parseBoundaries() for line in self.lines[self.lineIndex :]: self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getHorizontalSegmentTableForXIntersectionsTable( self, xIntersectionsTable ): 'Get the horizontal segment table from the xIntersectionsTable.' horizontalSegmentTable = {} xIntersectionsTableKeys = xIntersectionsTable.keys() xIntersectionsTableKeys.sort() for xIntersectionsTableKey in xIntersectionsTableKeys: xIntersections = xIntersectionsTable[ xIntersectionsTableKey ] segments = euclidean.getSegmentsFromXIntersections( xIntersections, xIntersectionsTableKey * self.millWidth ) horizontalSegmentTable[ xIntersectionsTableKey ] = segments return horizontalSegmentTable def getHorizontalXIntersectionsTable(self, loops): 'Get the horizontal x intersections table from the loops.' horizontalXIntersectionsTable = {} euclidean.addXIntersectionsFromLoopsForTable(loops, horizontalXIntersectionsTable, self.millWidth) return horizontalXIntersectionsTable def getVerticalSegmentTableForXIntersectionsTable( self, xIntersectionsTable ): 'Get the vertical segment table from the xIntersectionsTable which has the x and y swapped.' verticalSegmentTable = {} xIntersectionsTableKeys = xIntersectionsTable.keys() xIntersectionsTableKeys.sort() for xIntersectionsTableKey in xIntersectionsTableKeys: xIntersections = xIntersectionsTable[ xIntersectionsTableKey ] segments = euclidean.getSegmentsFromXIntersections( xIntersections, xIntersectionsTableKey * self.millWidth ) for segment in segments: for endpoint in segment: endpoint.point = complex( endpoint.point.imag, endpoint.point.real ) verticalSegmentTable[ xIntersectionsTableKey ] = segments return verticalSegmentTable def parseBoundaries(self): 'Parse the boundaries and add them to the boundary layers.' boundaryLoop = None boundaryLayer = None for line in self.lines[self.lineIndex :]: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '()': boundaryLoop = None elif firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) if boundaryLoop is None: boundaryLoop = [] boundaryLayer.loops.append(boundaryLoop) boundaryLoop.append(location.dropAxis()) elif firstWord == '(': boundaryLayer = euclidean.LoopLayer(float(splitLine[1])) self.boundaryLayers.append(boundaryLayer) if len(self.boundaryLayers) < 2: return for boundaryLayer in self.boundaryLayers: boundaryLayer.innerOutsetLoops = intercircle.getInsetSeparateLoopsFromLoops(boundaryLayer.loops, -self.loopInnerOutset) boundaryLayer.outerOutsetLoops = intercircle.getInsetSeparateLoopsFromLoops(boundaryLayer.loops, -self.loopOuterOutset) boundaryLayer.innerHorizontalTable = self.getHorizontalXIntersectionsTable( boundaryLayer.innerOutsetLoops ) boundaryLayer.outerHorizontalTable = self.getHorizontalXIntersectionsTable( boundaryLayer.outerOutsetLoops ) boundaryLayer.innerVerticalTable = self.getHorizontalXIntersectionsTable( euclidean.getDiagonalFlippedLoops( boundaryLayer.innerOutsetLoops ) ) boundaryLayer.outerVerticalTable = self.getHorizontalXIntersectionsTable( euclidean.getDiagonalFlippedLoops( boundaryLayer.outerOutsetLoops ) ) for boundaryLayerIndex in xrange( len(self.boundaryLayers) - 2, - 1, - 1 ): boundaryLayer = self.boundaryLayers[ boundaryLayerIndex ] boundaryLayerBelow = self.boundaryLayers[ boundaryLayerIndex + 1 ] euclidean.joinXIntersectionsTables( boundaryLayerBelow.outerHorizontalTable, boundaryLayer.outerHorizontalTable ) euclidean.joinXIntersectionsTables( boundaryLayerBelow.outerVerticalTable, boundaryLayer.outerVerticalTable ) for boundaryLayerIndex in xrange( 1, len(self.boundaryLayers) ): boundaryLayer = self.boundaryLayers[ boundaryLayerIndex ] boundaryLayerAbove = self.boundaryLayers[ boundaryLayerIndex - 1 ] euclidean.joinXIntersectionsTables( boundaryLayerAbove.innerHorizontalTable, boundaryLayer.innerHorizontalTable ) euclidean.joinXIntersectionsTables( boundaryLayerAbove.innerVerticalTable, boundaryLayer.innerVerticalTable ) for boundaryLayerIndex in xrange( len(self.boundaryLayers) ): self.addSegmentTableLoops(boundaryLayerIndex) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('mill') return elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.aroundWidth = 0.1 * self.perimeterWidth self.halfPerimeterWidth = 0.5 * self.perimeterWidth self.millWidth = self.perimeterWidth * self.repository.millWidthOverPerimeterWidth.value self.loopInnerOutset = self.halfPerimeterWidth + self.perimeterWidth * self.repository.loopInnerOutsetOverPerimeterWidth.value self.loopOuterOutset = self.halfPerimeterWidth + self.perimeterWidth * self.repository.loopOuterOutsetOverPerimeterWidth.value self.distanceFeedRate.addLine(line) def parseLine(self, line): 'Parse a gcode line and add it to the mill skein.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.isExtruderActive: self.average.addValue(location.z) if self.oldLocation is not None: euclidean.addValueSegmentToPixelTable( self.oldLocation.dropAxis(), location.dropAxis(), self.aroundPixelTable, None, self.aroundWidth ) self.oldLocation = location elif firstWord == 'M101': self.isExtruderActive = True elif firstWord == 'M103': self.isExtruderActive = False elif firstWord == '(': settings.printProgress(self.layerIndex, 'mill') self.aroundPixelTable = {} self.average.reset() elif firstWord == '()': if len(self.boundaryLayers) > self.layerIndex: self.addMillThreads() self.layerIndex += 1 self.distanceFeedRate.addLine(line) def main(): 'Display the mill dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/multiply.py000066400000000000000000000300641167321211700307200ustar00rootroot00000000000000""" This page is in the table of contents. The multiply plugin will take a single object and create an array of objects. It is used when you want to print single object multiple times in a single pass. You can also position any object using this plugin by setting the center X and center Y to the desired coordinates (0,0 for the center of the print_bed) and setting the number of rows and columns to 1 (effectively setting a 1x1 matrix - printing only a single object). The multiply manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Multiply Besides using the multiply tool, another way of printing many copies of the model is to duplicate the model in Art of Illusion, however many times you want, with the appropriate offsets. Then you can either use the Join Objects script in the scripts submenu to create a combined shape or you can export the whole scene as an xml file, which skeinforge can then slice. ==Operation== The default 'Activate Multiply' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Center=== Default is the origin. The center of the shape will be moved to the "Center X" and "Center Y" coordinates. ====Center X==== ====Center Y==== ===Number of Cells=== ====Number of Columns==== Default is one. Defines the number of columns in the array table. ====Number of Rows==== Default is one. Defines the number of rows in the table. ===Reverse Sequence every Odd Layer=== Default is off. When selected the build sequence will be reversed on every odd layer so that the tool will travel less. The problem is that the builds would be made with different amount of time to cool, so some would be too hot and some too cold, which is why the default is off. ===Separation over Perimeter Width=== Default is fifteen. Defines the ratio of separation between the shape copies over the perimeter width. ==Examples== The following examples multiply the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and multiply.py. > python multiply.py This brings up the multiply dialog. > python multiply.py Screw Holder Bottom.stl The multiply tool is parsing the file: Screw Holder Bottom.stl .. The multiply tool has created the file: .. Screw Holder Bottom_multiply.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, text='', repository=None): 'Multiply the fill file or text.' return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): 'Multiply the fill text.' if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'multiply'): return gcodeText if repository is None: repository = settings.getReadRepository(MultiplyRepository()) if not repository.activateMultiply.value: return gcodeText return MultiplySkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return MultiplyRepository() def writeOutput(fileName, shouldAnalyze=True): 'Multiply a gcode linear move file.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'multiply', shouldAnalyze) class MultiplyRepository: 'A class to handle the multiply settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.multiply.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Multiply', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Multiply') self.activateMultiply = settings.BooleanSetting().getFromValue('Activate Multiply: ', self, True ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Center - (Set half your total x and y travel distance \nfor centering your prints!', self ) self.centerX = settings.FloatSpin().getFromValue(-240.0, 'Center X (mm):', self, 240.0, 100.0) self.centerY = settings.FloatSpin().getFromValue(-240.0, 'Center Y (mm):', self, 240.0, 100.0) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Number of Cells -', self) self.numberOfColumns = settings.IntSpin().getFromValue(1, 'Number of Columns (integer):', self, 10, 1) self.numberOfRows = settings.IntSpin().getFromValue(1, 'Number of Rows (integer):', self, 10, 1) settings.LabelSeparator().getFromRepository(self) self.reverseSequenceEveryOddLayer = settings.BooleanSetting().getFromValue('Reverse Sequence every Odd Layer', self, False) self.separationOverPerimeterWidth = settings.FloatSpin().getFromValue( 5.0, 'Separation over Perimeter Width (ratio):', self, 25.0, 15.0) self.executeTitle = 'Multiply' def execute(self): 'Multiply button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class MultiplySkein: 'A class to multiply a skein of extrusions.' def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.isExtrusionActive = False self.layerIndex = 0 self.layerLines = [] self.lineIndex = 0 self.lines = None self.oldLocation = None self.rowIndex = 0 self.shouldAccumulate = True def addElement(self, offset): 'Add moved element to the output.' for line in self.layerLines: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '(': movedLocation = self.getMovedLocationSetOldLocation(offset, splitLine) line = self.distanceFeedRate.getBoundaryLine(movedLocation) elif firstWord == 'G1': movedLocation = self.getMovedLocationSetOldLocation(offset, splitLine) line = self.distanceFeedRate.getLinearGcodeMovement(movedLocation.dropAxis(), movedLocation.z) elif firstWord == '(': movedLocation = self.getMovedLocationSetOldLocation(offset, splitLine) line = self.distanceFeedRate.getInfillBoundaryLine(movedLocation) self.distanceFeedRate.addLine(line) def addLayer(self): 'Add multiplied layer to the output.' self.addRemoveThroughLayer() offset = self.centerOffset - self.arrayCenter - self.shapeCenter for rowIndex in xrange(self.repository.numberOfRows.value): yRowOffset = float(rowIndex) * self.extentPlusSeparation.imag if self.layerIndex % 2 == 1 and self.repository.reverseSequenceEveryOddLayer.value: yRowOffset = self.arrayExtent.imag - yRowOffset for columnIndex in xrange(self.repository.numberOfColumns.value): xColumnOffset = float(columnIndex) * self.extentPlusSeparation.real if self.rowIndex % 2 == 1: xColumnOffset = self.arrayExtent.real - xColumnOffset elementOffset = complex(offset.real + xColumnOffset, offset.imag + yRowOffset) self.addElement(elementOffset) self.rowIndex += 1 settings.printProgress(self.layerIndex, 'multiply') if len(self.layerLines) > 1: self.layerIndex += 1 self.layerLines = [] def addRemoveThroughLayer(self): 'Parse gcode initialization and store the parameters.' for layerLineIndex in xrange(len(self.layerLines)): line = self.layerLines[layerLineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.addLine(line) if firstWord == '(': self.layerLines = self.layerLines[layerLineIndex + 1 :] return def getCraftedGcode(self, gcodeText, repository): 'Parse gcode text and store the multiply gcode.' self.centerOffset = complex(repository.centerX.value, repository.centerY.value) self.repository = repository self.numberOfColumns = repository.numberOfColumns.value self.numberOfRows = repository.numberOfRows.value self.lines = archive.getTextLines(gcodeText) self.parseInitialization() self.setCorners() for line in self.lines[self.lineIndex :]: self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getMovedLocationSetOldLocation(self, offset, splitLine): 'Get the moved location and set the old location.' location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.oldLocation = location return Vector3(location.x + offset.real, location.y + offset.imag, location.z) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('multiply') self.distanceFeedRate.addLine(line) self.lineIndex += 1 return elif firstWord == '(': self.absolutePerimeterWidth = abs(float(splitLine[1])) self.distanceFeedRate.addLine(line) def parseLine(self, line): 'Parse a gcode line and add it to the multiply skein.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == '()': self.addLayer() self.distanceFeedRate.addLine(line) return elif firstWord == '()': self.shouldAccumulate = False if self.shouldAccumulate: self.layerLines.append(line) return self.distanceFeedRate.addLine(line) def setCorners(self): 'Set maximum and minimum corners and z.' cornerMaximumComplex = complex(-987654321.0, -987654321.0) cornerMinimumComplex = -cornerMaximumComplex for line in self.lines[self.lineIndex :]: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.isExtrusionActive: locationComplex = location.dropAxis() cornerMaximumComplex = euclidean.getMaximum(locationComplex, cornerMaximumComplex) cornerMinimumComplex = euclidean.getMinimum(locationComplex, cornerMinimumComplex) self.oldLocation = location elif firstWord == 'M101': self.isExtrusionActive = True elif firstWord == 'M103': self.isExtrusionActive = False self.extent = cornerMaximumComplex - cornerMinimumComplex self.shapeCenter = 0.5 * (cornerMaximumComplex + cornerMinimumComplex) self.separation = self.repository.separationOverPerimeterWidth.value * self.absolutePerimeterWidth self.extentPlusSeparation = self.extent + complex(self.separation, self.separation) columnsMinusOne = self.numberOfColumns - 1 rowsMinusOne = self.numberOfRows - 1 self.arrayExtent = complex(self.extentPlusSeparation.real * columnsMinusOne, self.extentPlusSeparation.imag * rowsMinusOne) self.arrayCenter = 0.5 * self.arrayExtent def main(): 'Display the multiply dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/oozebane.py000066400000000000000000000655571167321211700306620ustar00rootroot00000000000000""" This page is in the table of contents. Oozebane is a script to turn off the extruder before the end of a thread and turn it on before the beginning. The oozebane manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Oozebane After oozebane turns the extruder on, it slows the feed rate down where the thread starts. Then it speeds it up in steps so in theory the thread will remain at roughly the same thickness from the beginning. ==Operation== The default 'Activate Oozebane' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===After Startup Distance=== Default is 1.2. When oozebane reaches the point where the extruder would of turned on, it slows down so that the thread will be thick at that point. Afterwards it speeds the extruder back up to operating speed. The speed up distance is the "After Startup Distance". ===Early Shutdown Distance=== Default is 1.2. Defines the distance before the end of the thread that the extruder will be turned off. It is the most important oozebane setting. A higher distance means the extruder will turn off sooner and the end of the line will be thinner. ===Early Startup Maximum Distance=== Default is 1.2. Defines the maximum distance before the thread starts that the extruder will be turned on ===Early Startup Distance Constant=== Default is twenty. The longer the extruder has been off, the earlier the extruder will turn back on, the ratio is one minus one over e to the power of the distance the extruder has been off over the "Early Startup Distance Constant". ===First Early Startup Distance=== Default is twenty five. Defines the distance before the first thread starts that the extruder will be turned off. This value should be high because, according to Marius, the extruder takes a second or two to extrude when starting for the first time. ===Minimum Distance for Early Shutdown=== Default is zero. Defines the minimum distance that the extruder has to be off after the thread end for the early shutdown feature to activate. ===Minimum Distance for Early Startup=== Default is zero. Defines the minimum distance that the extruder has to be off before the thread begins for the early start up feature to activate. ===Slowdown Startup Steps=== Default is three. When oozebane turns the extruder off, it slows the feed rate down in steps so in theory the thread will remain at roughly the same thickness until the end. The "Slowdown Startup Steps" setting is the number of steps, the more steps the smaller the size of the step that the feed rate will be decreased and the larger the size of the resulting gcode file. ==Examples== The following examples oozebane the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and oozebane.py. > python oozebane.py This brings up the oozebane dialog. > python oozebane.py Screw Holder Bottom.stl The oozebane tool is parsing the file: Screw Holder Bottom.stl .. The oozebane tool has created the file: .. Screw Holder Bottom_oozebane.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, oozebaneRepository = None ): "Oozebane a gcode linear move file or text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), oozebaneRepository ) def getCraftedTextFromText( gcodeText, oozebaneRepository = None ): "Oozebane a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'oozebane'): return gcodeText if oozebaneRepository is None: oozebaneRepository = settings.getReadRepository( OozebaneRepository() ) if not oozebaneRepository.activateOozebane.value: return gcodeText return OozebaneSkein().getCraftedGcode( gcodeText, oozebaneRepository ) def getNewRepository(): 'Get new repository.' return OozebaneRepository() def writeOutput(fileName, shouldAnalyze=True): "Oozebane a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'oozebane', shouldAnalyze) class OozebaneRepository: "A class to handle the oozebane settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.oozebane.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Oozebane', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Oozebane') self.activateOozebane = settings.BooleanSetting().getFromValue('Activate Oozebane', self, False ) self.afterStartupDistance = settings.FloatSpin().getFromValue( 0.7, 'After Startup Distance (millimeters):', self, 1.7, 1.2 ) self.earlyShutdownDistance = settings.FloatSpin().getFromValue( 0.7, 'Early Shutdown Distance (millimeters):', self, 1.7, 1.2 ) self.earlyStartupDistanceConstant = settings.FloatSpin().getFromValue( 10.0, 'Early Startup Distance Constant (millimeters):', self, 30.0, 20.0 ) self.earlyStartupMaximumDistance = settings.FloatSpin().getFromValue( 0.7, 'Early Startup Maximum Distance (millimeters):', self, 1.7, 1.2 ) self.firstEarlyStartupDistance = settings.FloatSpin().getFromValue( 5.0, 'First Early Startup Distance (millimeters):', self, 45.0, 25.0 ) self.minimumDistanceForEarlyStartup = settings.FloatSpin().getFromValue( 0.0, 'Minimum Distance for Early Startup (millimeters):', self, 10.0, 0.0 ) self.minimumDistanceForEarlyShutdown = settings.FloatSpin().getFromValue( 0.0, 'Minimum Distance for Early Shutdown (millimeters):', self, 10.0, 0.0 ) self.slowdownStartupSteps = settings.IntSpin().getFromValue( 2, 'Slowdown Startup Steps (positive integer):', self, 5, 3 ) self.executeTitle = 'Oozebane' def execute(self): "Oozebane button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class OozebaneSkein: "A class to oozebane a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.distanceFromThreadEndToThreadBeginning = None self.earlyStartupDistance = None self.extruderInactiveLongEnough = True self.feedRateMinute = 961.0 self.isExtruderActive = False self.isFirstExtrusion = True self.isShutdownEarly = False self.isStartupEarly = False self.lineIndex = 0 self.lines = None self.oldLocation = None self.operatingFeedRateMinute = 959.0 self.shutdownStepIndex = 999999999 self.startupStepIndex = 999999999 def addAfterStartupLine( self, splitLine ): "Add the after startup lines." distanceAfterThreadBeginning = self.getDistanceAfterThreadBeginning() location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) segment = self.oldLocation - location segmentLength = segment.magnitude() distanceBack = distanceAfterThreadBeginning - self.afterStartupDistances[ self.startupStepIndex ] if segmentLength > 0.0: locationBack = location + segment * distanceBack / segmentLength feedRate = self.operatingFeedRateMinute * self.afterStartupFlowRates[ self.startupStepIndex ] if not self.isCloseToEither( locationBack, location, self.oldLocation ): self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( feedRate, locationBack ) ) self.startupStepIndex += 1 def addLineSetShutdowns(self, line): "Add a line and set the shutdown variables." self.distanceFeedRate.addLine(line) self.isShutdownEarly = True def getActiveFeedRateRatio(self): "Get the feed rate of the first active move over the operating feed rate." isSearchExtruderActive = self.isExtruderActive for afterIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[ afterIndex ] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': if isSearchExtruderActive: return gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) / self.operatingFeedRateMinute elif firstWord == 'M101': isSearchExtruderActive = True print('active feed rate ratio was not found in oozebane.') return 1.0 def getAddAfterStartupLines(self, line): "Get and / or add after the startup lines." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) while self.isDistanceAfterThreadBeginningGreater(): self.addAfterStartupLine(splitLine) if self.startupStepIndex >= len( self.afterStartupDistances ): self.startupStepIndex = len( self.afterStartupDistances ) + 999999999999 return self.getLinearMoveWithFeedRateSplitLine( self.operatingFeedRateMinute, splitLine ) feedRate = self.operatingFeedRateMinute * self.getStartupFlowRateMultiplier( self.getDistanceAfterThreadBeginning() / self.afterStartupDistance, len( self.afterStartupDistances ) ) return self.getLinearMoveWithFeedRateSplitLine( feedRate, splitLine ) def getAddBeforeStartupLines(self, line): "Get and / or add before the startup lines." distanceThreadBeginning = self.getDistanceToThreadBeginning() if distanceThreadBeginning is None: return line splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) self.extruderInactiveLongEnough = False self.isStartupEarly = True location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) segment = self.oldLocation - location segmentLength = segment.magnitude() distanceBack = self.earlyStartupDistance - distanceThreadBeginning if segmentLength <= 0.0: print('This should never happen, segmentLength is zero in getAddBeforeStartupLines in oozebane.') print(line) self.extruderInactiveLongEnough = True self.isStartupEarly = False return line locationBack = location + segment * distanceBack / segmentLength self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) , locationBack ) ) self.distanceFeedRate.addLine('M101') if self.isCloseToEither( locationBack, location, self.oldLocation ): return '' return self.getLinearMoveWithFeedRate( self.operatingFeedRateMinute, location ) def getAddShutSlowDownLine(self, line): "Add the shutdown and slowdown lines." if self.shutdownStepIndex >= len( self.earlyShutdownDistances ): self.shutdownStepIndex = len( self.earlyShutdownDistances ) + 99999999 return False splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) distanceThreadEnd = self.getDistanceToExtruderOffCommand( self.earlyShutdownDistances[ self.shutdownStepIndex ] ) location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if distanceThreadEnd is None: distanceThreadEnd = self.getDistanceToExtruderOffCommand( self.earlyShutdownDistances[0] ) if distanceThreadEnd is not None: shutdownFlowRateMultiplier = self.getShutdownFlowRateMultiplier( 1.0 - distanceThreadEnd / self.earlyShutdownDistance, len( self.earlyShutdownDistances ) ) line = self.getLinearMoveWithFeedRate( self.feedRateMinute * shutdownFlowRateMultiplier, location ) self.distanceFeedRate.addLine(line) return False segment = self.oldLocation - location segmentLength = segment.magnitude() distanceBack = self.earlyShutdownDistances[ self.shutdownStepIndex ] - distanceThreadEnd locationBack = location if segmentLength > 0.0: locationBack = location + segment * distanceBack / segmentLength if self.shutdownStepIndex == 0: if not self.isCloseToEither( locationBack, location, self.oldLocation ): line = self.getLinearMoveWithFeedRate( self.feedRateMinute, locationBack ) self.distanceFeedRate.addLine(line) self.addLineSetShutdowns('M103') return True if self.isClose( locationBack, self.oldLocation ): return True feedRate = self.feedRateMinute * self.earlyShutdownFlowRates[ self.shutdownStepIndex ] line = self.getLinearMoveWithFeedRate( feedRate, locationBack ) if self.isClose( locationBack, location ): line = self.getLinearMoveWithFeedRate( feedRate, location ) self.distanceFeedRate.addLine(line) return True def getAddShutSlowDownLines(self, line): "Get and / or add the shutdown and slowdown lines." while self.getAddShutSlowDownLine(line): self.shutdownStepIndex += 1 return '' def getCraftedGcode( self, gcodeText, oozebaneRepository ): "Parse gcode text and store the oozebane gcode." self.lines = archive.getTextLines(gcodeText) self.oozebaneRepository = oozebaneRepository self.parseInitialization( oozebaneRepository ) for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getDistanceAfterThreadBeginning(self): "Get the distance after the beginning of the thread." line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) totalDistance = 0.0 extruderOnReached = False for beforeIndex in xrange( self.lineIndex - 1, 3, - 1 ): line = self.lines[ beforeIndex ] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine ) totalDistance += location.distance( lastThreadLocation ) lastThreadLocation = location if extruderOnReached: return totalDistance elif firstWord == 'M101': extruderOnReached = True return None def getDistanceToExtruderOffCommand( self, remainingDistance ): "Get the distance to the word." line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) totalDistance = 0.0 for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ): line = self.lines[ afterIndex ] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine ) totalDistance += location.distance( lastThreadLocation ) lastThreadLocation = location if totalDistance >= remainingDistance: return None elif firstWord == 'M103': return totalDistance return None def getDistanceToThreadBeginning(self): "Get the distance to the beginning of the thread." if self.earlyStartupDistance is None: return None line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) totalDistance = 0.0 for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ): line = self.lines[ afterIndex ] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine ) totalDistance += location.distance( lastThreadLocation ) lastThreadLocation = location if totalDistance >= self.earlyStartupDistance: return None elif firstWord == 'M101': return totalDistance return None def getDistanceToThreadBeginningAfterThreadEnd( self, remainingDistance ): "Get the distance to the thread beginning after the end of this thread." extruderOnReached = False line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) threadEndReached = False totalDistance = 0.0 for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ): line = self.lines[ afterIndex ] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine ) if threadEndReached: totalDistance += location.distance( lastThreadLocation ) if totalDistance >= remainingDistance: return None if extruderOnReached: return totalDistance lastThreadLocation = location elif firstWord == 'M101': extruderOnReached = True elif firstWord == 'M103': threadEndReached = True return None def getDistanceToThreadEnd(self): "Get the distance to the end of the thread." if self.shutdownStepIndex >= len( self.earlyShutdownDistances ): return None return self.getDistanceToExtruderOffCommand( self.earlyShutdownDistances[ self.shutdownStepIndex ] ) def getLinearMoveWithFeedRate( self, feedRate, location ): "Get a linear move line with the feed rate." return self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( feedRate, location.dropAxis(), location.z ) def getLinearMoveWithFeedRateSplitLine( self, feedRate, splitLine ): "Get a linear move line with the feed rate and split line." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) return self.getLinearMoveWithFeedRate( feedRate, location ) def getOozebaneLine(self, line): "Get oozebaned gcode line." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) if self.oldLocation is None: return line if self.startupStepIndex < len( self.afterStartupDistances ): return self.getAddAfterStartupLines(line) if self.extruderInactiveLongEnough: return self.getAddBeforeStartupLines(line) if self.shutdownStepIndex < len( self.earlyShutdownDistances ): return self.getAddShutSlowDownLines(line) if self.isStartupEarly: return self.getLinearMoveWithFeedRateSplitLine( self.operatingFeedRateMinute, splitLine ) return line def getShutdownFlowRateMultiplier( self, along, numberOfDistances ): "Get the shut down flow rate multipler." if numberOfDistances <= 0: return 1.0 return 1.0 - 0.5 / float( numberOfDistances ) - along * float( numberOfDistances - 1 ) / float( numberOfDistances ) def getStartupFlowRateMultiplier( self, along, numberOfDistances ): "Get the startup flow rate multipler." if numberOfDistances <= 0: return 1.0 return min( 1.0, 0.5 / float( numberOfDistances ) + along ) def isClose( self, location, otherLocation ): "Determine if the location is close to the other location." return location.distanceSquared( otherLocation ) < self.closeSquared def isCloseToEither( self, location, otherLocationFirst, otherLocationSecond ): "Determine if the location is close to the other locations." if self.isClose( location, otherLocationFirst ): return True return self.isClose( location, otherLocationSecond ) def isDistanceAfterThreadBeginningGreater(self): "Determine if the distance after the thread beginning is greater than the step index after startup distance." if self.startupStepIndex >= len( self.afterStartupDistances ): return False return self.getDistanceAfterThreadBeginning() > self.afterStartupDistances[ self.startupStepIndex ] def parseInitialization( self, oozebaneRepository ): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('oozebane') return elif firstWord == '(': self.operatingFeedRateMinute = 60.0 * float(splitLine[1]) self.feedRateMinute = self.operatingFeedRateMinute elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.setExtrusionWidth( oozebaneRepository ) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the bevel gcode." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.setEarlyStartupDistance(splitLine) line = self.getOozebaneLine(line) self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) elif firstWord == 'M101': self.isExtruderActive = True self.extruderInactiveLongEnough = False if self.getDistanceToExtruderOffCommand( self.earlyShutdownDistance ) is None: self.setEarlyShutdown() if self.getDistanceToExtruderOffCommand( 1.03 * ( self.earlyShutdownDistance + self.afterStartupDistance ) ) is None: afterStartupRatio = 1.0 if self.minimumDistanceForEarlyStartup > 0.0: if self.distanceFromThreadEndToThreadBeginning is not None: afterStartupRatio = self.distanceFromThreadEndToThreadBeginning / self.minimumDistanceForEarlyStartup self.setAfterStartupFlowRates( afterStartupRatio ) self.startupStepIndex = 9999999999 if len( self.afterStartupDistances ) > 0: self.startupStepIndex = 0 if self.isStartupEarly: self.isStartupEarly = False return elif firstWord == 'M103': self.isExtruderActive = False self.shutdownStepIndex = 999999999 if self.getDistanceToThreadBeginning() is None: self.extruderInactiveLongEnough = True self.distanceFromThreadEndToThreadBeginning = None self.earlyStartupDistance = None if self.isShutdownEarly: self.isShutdownEarly = False return self.distanceFeedRate.addLine(line) def setAfterStartupFlowRates( self, afterStartupRatio ): "Set the after startup flow rates." afterStartupRatio = min( 1.0, afterStartupRatio ) afterStartupRatio = max( 0.0, afterStartupRatio ) self.afterStartupDistance = afterStartupRatio * self.getActiveFeedRateRatio() * self.oozebaneRepository.afterStartupDistance.value self.afterStartupDistances = [] self.afterStartupFlowRate = 1.0 self.afterStartupFlowRates = [] afterStartupSteps = int( math.floor( afterStartupRatio * float( self.oozebaneRepository.slowdownStartupSteps.value ) ) ) if afterStartupSteps < 1: return if afterStartupSteps < 2: afterStartupSteps = 2 for stepIndex in xrange( afterStartupSteps ): afterWay = ( stepIndex + 1 ) / float( afterStartupSteps ) afterMiddleWay = self.getStartupFlowRateMultiplier( stepIndex / float( afterStartupSteps ), afterStartupSteps ) self.afterStartupDistances.append( afterWay * self.afterStartupDistance ) if stepIndex == 0: self.afterStartupFlowRate = afterMiddleWay else: self.afterStartupFlowRates.append( afterMiddleWay ) if afterStartupSteps > 0: self.afterStartupFlowRates.append(1.0) def setEarlyShutdown(self): "Set the early shutdown variables." distanceToThreadBeginning = self.getDistanceToThreadBeginningAfterThreadEnd( self.minimumDistanceForEarlyShutdown ) earlyShutdownRatio = 1.0 if distanceToThreadBeginning is not None: if self.minimumDistanceForEarlyShutdown > 0.0: earlyShutdownRatio = distanceToThreadBeginning / self.minimumDistanceForEarlyShutdown self.setEarlyShutdownFlowRates( earlyShutdownRatio ) if len( self.earlyShutdownDistances ) > 0: self.shutdownStepIndex = 0 def setEarlyShutdownFlowRates( self, earlyShutdownRatio ): "Set the extrusion width." earlyShutdownRatio = min( 1.0, earlyShutdownRatio ) earlyShutdownRatio = max( 0.0, earlyShutdownRatio ) self.earlyShutdownDistance = earlyShutdownRatio * self.getActiveFeedRateRatio() * self.oozebaneRepository.earlyShutdownDistance.value self.earlyShutdownDistances = [] self.earlyShutdownFlowRates = [] earlyShutdownSteps = int( math.floor( earlyShutdownRatio * float( self.oozebaneRepository.slowdownStartupSteps.value ) ) ) if earlyShutdownSteps < 2: earlyShutdownSteps = 0 earlyShutdownStepsMinusOne = float( earlyShutdownSteps ) - 1.0 for stepIndex in xrange( earlyShutdownSteps ): downMiddleWay = self.getShutdownFlowRateMultiplier( stepIndex / earlyShutdownStepsMinusOne, earlyShutdownSteps ) downWay = 1.0 - stepIndex / earlyShutdownStepsMinusOne self.earlyShutdownFlowRates.append( downMiddleWay ) self.earlyShutdownDistances.append( downWay * self.earlyShutdownDistance ) def setEarlyStartupDistance( self, splitLine ): "Set the early startup distance." if self.earlyStartupDistance is not None: return self.distanceFromThreadEndToThreadBeginning = 0.0 lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.oldLocation is not None: self.distanceFromThreadEndToThreadBeginning = lastThreadLocation.distance( self.oldLocation ) for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ): line = self.lines[ afterIndex ] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine ) self.distanceFromThreadEndToThreadBeginning += location.distance( lastThreadLocation ) lastThreadLocation = location elif firstWord == 'M101': distanceConstantRatio = self.distanceFromThreadEndToThreadBeginning / self.earlyStartupDistanceConstant earlyStartupOperatingDistance = self.earlyStartupMaximumDistance * ( 1.0 - math.exp( - distanceConstantRatio ) ) if self.isFirstExtrusion: earlyStartupOperatingDistance = self.oozebaneRepository.firstEarlyStartupDistance.value self.isFirstExtrusion = False self.earlyStartupDistance = earlyStartupOperatingDistance * self.getActiveFeedRateRatio() return def setExtrusionWidth( self, oozebaneRepository ): "Set the extrusion width." self.closeSquared = 0.01 * self.perimeterWidth * self.perimeterWidth self.earlyStartupMaximumDistance = oozebaneRepository.earlyStartupMaximumDistance.value self.earlyStartupDistanceConstant = oozebaneRepository.earlyStartupDistanceConstant.value self.minimumDistanceForEarlyStartup = oozebaneRepository.minimumDistanceForEarlyStartup.value self.minimumDistanceForEarlyShutdown = oozebaneRepository.minimumDistanceForEarlyShutdown.value self.setEarlyShutdownFlowRates(1.0) self.setAfterStartupFlowRates(1.0) def main(): "Display the oozebane dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/outset.py000066400000000000000000000147421167321211700303710ustar00rootroot00000000000000""" This page is in the table of contents. Outset outsets the perimeters of the slices of a gcode file. The outside perimeters will be outset by half the perimeter width, and the inside perimeters will be inset by half the perimeter width. Outset is needed for subtractive machining, like cutting or milling. ==Operation== The default 'Activate Outset' checkbox is on. When it is on, the gcode will be outset, when it is off, the gcode will not be changed. ==Examples== The following examples outset the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and outset.py. > python outset.py This brings up the outset dialog. > python outset.py Screw Holder Bottom.stl The outset tool is parsing the file: Screw Holder Bottom.stl .. The outset tool has created the file: .. Screw Holder Bottom_outset.gcode """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text='', repository=None): 'Outset the preface file or text.' return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): 'Outset the preface gcode text.' if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'outset'): return gcodeText if repository is None: repository = settings.getReadRepository( OutsetRepository() ) if not repository.activateOutset.value: return gcodeText return OutsetSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return OutsetRepository() def writeOutput(fileName, shouldAnalyze=True): 'Outset the carving of a gcode file.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'outset', shouldAnalyze) class OutsetRepository: 'A class to handle the outset settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.outset.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Outset', self, '') self.activateOutset = settings.BooleanSetting().getFromValue('Activate Outset', self, True ) self.executeTitle = 'Outset' def execute(self): 'Outset button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class OutsetSkein: 'A class to outset a skein of extrusions.' def __init__(self): self.boundary = None self.distanceFeedRate = gcodec.DistanceFeedRate() self.layerCount = settings.LayerCount() self.lineIndex = 0 self.loopLayer = None def addGcodeFromRemainingLoop( self, loop, radius, z ): 'Add the remainder of the loop.' boundary = intercircle.getLargestInsetLoopFromLoopRegardless( loop, radius ) euclidean.addNestedRingBeginning( self.distanceFeedRate, boundary, z ) self.distanceFeedRate.addPerimeterBlock(loop, z) self.distanceFeedRate.addLine('()') self.distanceFeedRate.addLine('()') def addOutset(self, loopLayer): 'Add outset to the layer.' extrudateLoops = intercircle.getInsetLoopsFromLoops(loopLayer.loops, -self.absoluteHalfPerimeterWidth) triangle_mesh.sortLoopsInOrderOfArea(False, extrudateLoops) for extrudateLoop in extrudateLoops: self.addGcodeFromRemainingLoop(extrudateLoop, self.absoluteHalfPerimeterWidth, loopLayer.z) def getCraftedGcode(self, gcodeText, repository): 'Parse gcode text and store the bevel gcode.' self.repository = repository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() for lineIndex in xrange(self.lineIndex, len(self.lines)): self.parseLine( lineIndex ) return self.distanceFeedRate.output.getvalue() def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex].lstrip() splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('outset') return elif firstWord == '(': self.absoluteHalfPerimeterWidth = 0.5 * abs(float(splitLine[1])) self.distanceFeedRate.addLine(line) def parseLine( self, lineIndex ): 'Parse a gcode line and add it to the outset skein.' line = self.lines[lineIndex].lstrip() splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) self.boundary.append(location.dropAxis()) elif firstWord == '(': self.layerCount.printProgressIncrement('outset') self.loopLayer = euclidean.LoopLayer(float(splitLine[1])) self.distanceFeedRate.addLine(line) elif firstWord == '()': self.addOutset( self.loopLayer ) self.loopLayer = None elif firstWord == '()': self.boundary = [] self.loopLayer.loops.append( self.boundary ) if self.loopLayer is None: self.distanceFeedRate.addLine(line) def main(): 'Display the outset dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/preface.py000066400000000000000000000252011167321211700304430ustar00rootroot00000000000000#! /usr/bin/env python """ This page is in the table of contents. Preface converts the svg slices into gcode extrusion layers, optionally with home, positioning, turn off, and unit commands. The preface manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Preface ==Settings== ===Meta=== Default is empty. The 'Meta' field is to add meta tags or a note to all your files. Whatever is in that field will be added in a meta tagged line to the output. ===Set Positioning to Absolute=== Default is on. When selected, preface will add the G90 command to set positioning to absolute. ===Set Units to Millimeters=== Default is on. When selected, preface will add the G21 command to set the units to millimeters. ===Start at Home=== Default is off. When selected, the G28 go to home gcode will be added at the beginning of the file. ===Turn Extruder Off=== ====Turn Extruder Off at Shut Down==== Default is on. When selected, the M103 turn extruder off gcode will be added at the end of the file. ====Turn Extruder Off at Start Up==== Default is on. When selected, the M103 turn extruder off gcode will be added at the beginning of the file. ==Examples== The following examples preface the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and preface.py. > python preface.py This brings up the preface dialog. > python preface.py Screw Holder Bottom.stl The preface tool is parsing the file: Screw Holder Bottom.stl .. The preface tool has created the file: .. Screw Holder Bottom_preface.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from datetime import date, datetime from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.svg_reader import SVGReader from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from fabmetheus_utilities import svg_writer from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile from time import strftime import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text='', repository = None ): "Preface and convert an svg file or text." return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText( text, repository = None ): "Preface and convert an svg text." if gcodec.isProcedureDoneOrFileIsEmpty( text, 'preface'): return text if repository is None: repository = settings.getReadRepository(PrefaceRepository()) return PrefaceSkein().getCraftedGcode(repository, text) def getNewRepository(): 'Get new repository.' return PrefaceRepository() def writeOutput(fileName, shouldAnalyze=True): "Preface the carving of a gcode file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'preface', shouldAnalyze) class PrefaceRepository: "A class to handle the preface settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.preface.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Preface', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Preface') self.meta = settings.StringSetting().getFromValue('Meta:', self, '') settings.LabelSeparator().getFromRepository(self) self.setPositioningToAbsolute = settings.BooleanSetting().getFromValue('Set Positioning to Absolute', self, True ) self.setUnitsToMillimeters = settings.BooleanSetting().getFromValue('Set Units to Millimeters', self, True ) self.startAtHome = settings.BooleanSetting().getFromValue('Home before Print', self, False ) self.resetExtruder = settings.BooleanSetting().getFromValue('Reset Extruder before Print', self, True ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Turn Extruder Off -', self ) self.turnExtruderOffAtShutDown = settings.BooleanSetting().getFromValue('Turn Extruder Off at Shut Down', self, True ) # self.turnExtruderOffAtStartUp = settings.BooleanSetting().getFromValue('Turn Extruder Off at Start Up', self, True ) self.executeTitle = 'Preface' def execute(self): "Preface button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class PrefaceSkein: "A class to preface a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.lineIndex = 0 self.oldLocation = None self.svgReader = SVGReader() def addInitializationToOutput(self): "Add initialization gcode to the output." self.distanceFeedRate.addTagBracketedLine('format', 'skeinforge gcode') absoluteFilePathUntilDot = archive.getUntilDot(archive.getCraftPluginsDirectoryPath('preface.py')) dateTodayString = date.today().isoformat().replace('-', '.')[2 :] if absoluteFilePathUntilDot == '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/preface': #is this script on Enrique's computer? archive.writeFileText(archive.getVersionFileName(), dateTodayString) versionText = archive.getFileText(archive.getVersionFileName()) self.distanceFeedRate.addTagBracketedLine('version', versionText) dateTimeTuple = datetime.now().timetuple() created = dateTodayString + '|%s:%s' % (dateTimeTuple[3], dateTimeTuple[4]) self.distanceFeedRate.addTagBracketedLine('created', created) self.distanceFeedRate.addLine('()') if self.repository.setPositioningToAbsolute.value: self.distanceFeedRate.addLine('G90 ;set positioning to absolute') # Set positioning to absolute. if self.repository.setUnitsToMillimeters.value: self.distanceFeedRate.addLine('G21 ;set units to millimeters') # Set units to millimeters. if self.repository.startAtHome.value: self.distanceFeedRate.addLine('G28 ;start at home') # Start at home. if self.repository.resetExtruder.value: self.distanceFeedRate.addLine('G92 E0 ;reset extruder distance') # Start at home. # if self.repository.turnExtruderOffAtStartUp.value: # self.distanceFeedRate.addLine('M103') # Turn extruder off. craftTypeName = skeinforge_profile.getCraftTypeName() self.distanceFeedRate.addTagBracketedLine('craftTypeName', craftTypeName) self.distanceFeedRate.addTagBracketedLine('decimalPlacesCarried', self.distanceFeedRate.decimalPlacesCarried) layerThickness = float(self.svgReader.sliceDictionary['layerThickness']) self.distanceFeedRate.addTagRoundedLine('layerThickness', layerThickness) if self.repository.meta.value: self.distanceFeedRate.addTagBracketedLine('meta', self.repository.meta.value) perimeterWidth = float(self.svgReader.sliceDictionary['perimeterWidth']) self.distanceFeedRate.addTagRoundedLine('perimeterWidth', perimeterWidth) self.distanceFeedRate.addTagBracketedLine('profileName', skeinforge_profile.getProfileName(craftTypeName)) self.distanceFeedRate.addLine('()') pluginFileNames = skeinforge_craft.getPluginFileNames() for pluginFileName in pluginFileNames: self.addToolSettingLines(pluginFileName) self.distanceFeedRate.addLine('()') self.distanceFeedRate.addTagBracketedLine('timeStampPreface', strftime('%Y%m%d_%H%M%S')) procedureNames = self.svgReader.sliceDictionary['procedureName'].replace(',', ' ').split() for procedureName in procedureNames: self.distanceFeedRate.addTagBracketedProcedure(procedureName) self.distanceFeedRate.addTagBracketedProcedure('preface') self.distanceFeedRate.addLine('()') # Initialization is finished, extrusion is starting. self.distanceFeedRate.addLine('()') # Initialization is finished, crafting is starting. def addPreface( self, loopLayer ): "Add preface to the carve layer." self.distanceFeedRate.addLine('( %s )' % loopLayer.z ) # Indicate that a new layer is starting. for loop in loopLayer.loops: self.distanceFeedRate.addGcodeFromLoop(loop, loopLayer.z) self.distanceFeedRate.addLine('()') def addShutdownToOutput(self): "Add shutdown gcode to the output." self.distanceFeedRate.addLine('()') # GCode formatted comment if self.repository.turnExtruderOffAtShutDown.value: self.distanceFeedRate.addLine('M103') # Turn extruder motor off. def addToolSettingLines(self, pluginName): "Add tool setting lines." preferences = skeinforge_craft.getCraftPreferences(pluginName) if skeinforge_craft.getCraftValue('Activate %s' % pluginName.capitalize(), preferences) != True: return for preference in preferences: valueWithoutReturn = str(preference.value).replace('\n', ' ').replace('\r', ' ') if preference.name != 'WindowPosition' and not preference.name.startswith('Open File'): line = '%s %s %s' % (pluginName, preference.name.replace(' ', '_'), valueWithoutReturn) self.distanceFeedRate.addTagBracketedLine('setting', line) def getCraftedGcode( self, repository, gcodeText ): "Parse gcode text and store the bevel gcode." self.repository = repository self.svgReader.parseSVG('', gcodeText) if self.svgReader.sliceDictionary is None: print('Warning, nothing will be done because the sliceDictionary could not be found getCraftedGcode in preface.') return '' self.distanceFeedRate.decimalPlacesCarried = int(self.svgReader.sliceDictionary['decimalPlacesCarried']) self.addInitializationToOutput() for loopLayerIndex, loopLayer in enumerate(self.svgReader.loopLayers): settings.printProgressByNumber(loopLayerIndex, len(self.svgReader.loopLayers), 'preface') self.addPreface( loopLayer ) self.addShutdownToOutput() return self.distanceFeedRate.output.getvalue() def main(): "Display the preface dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/raft.py000066400000000000000000001615401167321211700300010ustar00rootroot00000000000000""" This page is in the table of contents. Raft is a plugin to create a raft, elevate the nozzle and set the temperature. A raft is a flat base structure on top of which your object is being build and has a few different purposes. It fills irregularities like scratches and pits in your printbed and gives you a nice base parallel to the printheads movement. It also glues your object to the bed so to prevent warping in bigger object. The rafts base layer performs these tricks while the sparser interface layer(s) help you removing the object from the raft after printing. It is based on the Nophead's reusable raft, which has a base layer running one way, and a couple of perpendicular layers above. Each set of layers can be set to a different temperature. There is the option of having the extruder orbit the raft for a while, so the heater barrel has time to reach a different temperature, without ooze accumulating around the nozzle. The raft manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Raft The important values for the raft settings are the temperatures of the raft, the first layer and the next layers. These will be different for each material. The default settings for ABS, HDPE, PCL & PLA are extrapolated from Nophead's experiments. You don't necessarily need a raft and especially small object will print fine on a flat bed without one, sometimes its even better when you need a water tight base to print directly on the bed. If you want to only set the temperature or only create support material or only elevate the nozzle without creating a raft, set the Base Layers and Interface Layers to zero. Image:Raft.jpg|Raft Example of a raft on the left with the interface layers partially removed exposing the base layer. Notice that the first line of the base is rarely printed well because of the startup time of the extruder. On the right you see an object with its raft still attached. The Raft panel has some extra settings, it probably made sense to have them there but they have not that much to do with the actual Raft. First are the Support material settings. Since close to all RepRap style printers have no second extruder for support material Skeinforge offers the option to print support structures with the same material set at a different speed and temperature. The idea is that the support sticks less to the actual object when it is extruded around the minimum possible working temperature. This results in a temperature change EVERY layer so build time will increase seriously. Allan Ecker aka The Masked Retriever's has written two quicktips for raft which follow below. "Skeinforge Quicktip: The Raft, Part 1" at: http://blog.thingiverse.com/2009/07/14/skeinforge-quicktip-the-raft-part-1/ "Skeinforge Quicktip: The Raft, Part II" at: http://blog.thingiverse.com/2009/08/04/skeinforge-quicktip-the-raft-part-ii/ Nophead has written about rafts on his blog: http://hydraraptor.blogspot.com/2009/07/thoughts-on-rafts.html More pictures of rafting in action are available from the Metalab blog at: http://reprap.soup.io/?search=rafting ==Operation== Default: On When it is on, the functions described below will work, when it is off, nothing will be done, so no temperatures will be set, nozzle will not be lifted.. ==Settings== ===Add Raft, Elevate Nozzle, Orbit=== Default: On When selected, the script will also create a raft, elevate the nozzle, orbit and set the altitude of the bottom of the raft. It also turns on support generation. ===Base=== Base layer is the part of the raft that touches the bed. ====Base Feed Rate Multiplier==== Default is one. Defines the base feed rate multiplier. The greater the 'Base Feed Rate Multiplier', the thinner the base, the lower the 'Base Feed Rate Multiplier', the thicker the base. ====Base Flow Rate Multiplier==== Default is one. Defines the base flow rate multiplier. The greater the 'Base Flow Rate Multiplier', the thicker the base, the lower the 'Base Flow Rate Multiplier', the thinner the base. ====Base Infill Density==== Default is 0.5. Defines the infill density ratio of the base of the raft. ====Base Layer Height over Layer Thickness==== Default is two. Defines the ratio of the height & width of the base layer compared to the height and width of the object infill. The feed rate will be slower for raft layers which have thicker extrusions than the object infill. ====Base Layers==== Default is one. Defines the number of base layers. ====Base Nozzle Lift over Base Layer Thickness==== Default is 0.4. Defines the amount the nozzle is above the center of the base extrusion divided by the base layer thickness. ===Initial Circling=== Default is off. When selected, the extruder will initially circle around until it reaches operating temperature. ===Infill Overhang over Extrusion Width=== Default is 0.05. Defines the ratio of the infill overhang over the the extrusion width of the raft. ===Interface=== ====Interface Feed Rate Multiplier==== Default is one. Defines the interface feed rate multiplier. The greater the 'Interface Feed Rate Multiplier', the thinner the interface, the lower the 'Interface Feed Rate Multiplier', the thicker the interface. ====Interface Flow Rate Multiplier==== Default is one. Defines the interface flow rate multiplier. The greater the 'Interface Flow Rate Multiplier', the thicker the interface, the lower the 'Interface Flow Rate Multiplier', the thinner the interface. ====Interface Infill Density==== Default is 0.5. Defines the infill density ratio of the interface of the raft. ====Interface Layer Thickness over Extrusion Height==== Default is one. Defines the ratio of the height & width of the interface layer compared to the height and width of the object infill. The feed rate will be slower for raft layers which have thicker extrusions than the object infill. ====Interface Layers==== Default is two. Defines the number of interface layers to print. ====Interface Nozzle Lift over Interface Layer Thickness==== Default is 0.45. Defines the amount the nozzle is above the center of the interface extrusion divided by the interface layer thickness. ===Name of Alteration Files=== If support material is generated, raft looks for alteration files in the alterations folder in the .skeinforge folder in the home directory. Raft does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder. ====Name of Support End File==== Default is support_end.gcode. If support material is generated and if there is a file with the name of the "Name of Support End File" setting, it will be added to the end of the support gcode. ====Name of Support Start File==== If support material is generated and if there is a file with the name of the "Name of Support Start File" setting, it will be added to the start of the support gcode. ===Operating Nozzle Lift over Layer Thickness=== Default is 0.5. Defines the amount the nozzle is above the center of the operating extrusion divided by the layer thickness. ===Raft Size=== The raft fills a rectangle whose base size is the rectangle around the bottom layer of the object expanded on each side by the 'Raft Margin' plus the 'Raft Additional Margin over Length (%)' percentage times the length of the side. ====Raft Additional Margin over Length==== Default is 1 percent. ====Raft Margin==== Default is three millimeters. ===Support=== Good articles on support material are at: http://davedurant.wordpress.com/2010/07/31/skeinforge-support-part-1/ http://davedurant.wordpress.com/2010/07/31/skeinforge-support-part-2/ ====Support Cross Hatch==== Default is off. When selected, the support material will cross hatched. Cross hatching the support makes it stronger and harder to remove, which is why the default is off. ====Support Flow Rate over Operating Flow Rate==== Default: 0.9. Defines the ratio of the flow rate when the support is extruded over the operating flow rate. With a number less than one, the support flow rate will be smaller so the support will be thinner and easier to remove. ====Support Gap over Perimeter Extrusion Width==== Default: 0.5. Defines the gap between the support material and the object over the perimeter extrusion width. ====Support Material Choice==== Default is 'None' because the raft takes time to generate. =====Empty Layers Only===== When selected, support material will be only on the empty layers. This is useful when making identical objects in a stack. =====Everywhere===== When selected, support material will be added wherever there are overhangs, even inside the object. Because support material inside objects is hard or impossible to remove, this option should only be chosen if the object has a cavity that needs support and there is some way to extract the support material. =====Exterior Only===== When selected, support material will be added only the exterior of the object. This is the best option for most objects which require support material. =====None===== When selected, raft will not add support material. ====Support Minimum Angle==== Default is sixty degrees. Defines the minimum angle that a surface overhangs before support material is added. If angle is lower then this value the support will be generated. This angle is defined from the vertical, so zero is a vertical wall, ten is a wall with a bit of overhang, thirty is the typical safe angle for filament extrusion, sixty is a really high angle for extrusion and ninety is an unsupported horizontal ceiling. ==Examples== The following examples raft the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and raft.py. > python raft.py This brings up the raft dialog. > python raft.py Screw Holder Bottom.stl The raft tool is parsing the file: Screw Holder Bottom.stl .. The raft tool has created the file: Screw Holder Bottom_raft.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' #maybe later wide support #raft outline temperature http://hydraraptor.blogspot.com/2008/09/screw-top-pot.html def getCraftedText( fileName, text='', repository=None): 'Raft the file or text.' return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): 'Raft a gcode linear move text.' if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'raft'): return gcodeText if repository is None: repository = settings.getReadRepository( RaftRepository() ) if not repository.activateRaft.value: return gcodeText return RaftSkein().getCraftedGcode(gcodeText, repository) def getCrossHatchPointLine( crossHatchPointLineTable, y ): 'Get the cross hatch point line.' if not crossHatchPointLineTable.has_key(y): crossHatchPointLineTable[ y ] = {} return crossHatchPointLineTable[ y ] def getEndpointsFromYIntersections( x, yIntersections ): 'Get endpoints from the y intersections.' endpoints = [] for yIntersectionIndex in xrange( 0, len( yIntersections ), 2 ): firstY = yIntersections[ yIntersectionIndex ] secondY = yIntersections[ yIntersectionIndex + 1 ] if firstY != secondY: firstComplex = complex( x, firstY ) secondComplex = complex( x, secondY ) endpointFirst = euclidean.Endpoint() endpointSecond = euclidean.Endpoint().getFromOtherPoint( endpointFirst, secondComplex ) endpointFirst.getFromOtherPoint( endpointSecond, firstComplex ) endpoints.append( endpointFirst ) endpoints.append( endpointSecond ) return endpoints def getExtendedLineSegment(extensionDistance, lineSegment, loopXIntersections): 'Get extended line segment.' pointBegin = lineSegment[0].point pointEnd = lineSegment[1].point segment = pointEnd - pointBegin segmentLength = abs(segment) if segmentLength <= 0.0: print('This should never happen in getExtendedLineSegment in raft, the segment should have a length greater than zero.') print(lineSegment) return None segmentExtend = segment * extensionDistance / segmentLength lineSegment[0].point -= segmentExtend lineSegment[1].point += segmentExtend for loopXIntersection in loopXIntersections: setExtendedPoint(lineSegment[0], pointBegin, loopXIntersection) setExtendedPoint(lineSegment[1], pointEnd, loopXIntersection) return lineSegment def getLoopsBySegmentsDictionary(segmentsDictionary, width): 'Get loops from a horizontal segments dictionary.' points = [] for endpoint in getVerticalEndpoints(segmentsDictionary, width, 0.1 * width, width): points.append(endpoint.point) for endpoint in euclidean.getEndpointsFromSegmentTable(segmentsDictionary): points.append(endpoint.point) return triangle_mesh.getDescendingAreaOrientedLoops(points, points, width + width) def getNewRepository(): 'Get new repository.' return RaftRepository() def getVerticalEndpoints(horizontalSegmentsTable, horizontalStep, verticalOverhang, verticalStep): 'Get vertical endpoints.' interfaceSegmentsTableKeys = horizontalSegmentsTable.keys() interfaceSegmentsTableKeys.sort() verticalTableTable = {} for interfaceSegmentsTableKey in interfaceSegmentsTableKeys: interfaceSegments = horizontalSegmentsTable[interfaceSegmentsTableKey] for interfaceSegment in interfaceSegments: begin = int(round(interfaceSegment[0].point.real / verticalStep)) end = int(round(interfaceSegment[1].point.real / verticalStep)) for stepIndex in xrange(begin, end + 1): if stepIndex not in verticalTableTable: verticalTableTable[stepIndex] = {} verticalTableTable[stepIndex][interfaceSegmentsTableKey] = None verticalTableTableKeys = verticalTableTable.keys() verticalTableTableKeys.sort() verticalEndpoints = [] for verticalTableTableKey in verticalTableTableKeys: verticalTable = verticalTableTable[verticalTableTableKey] verticalTableKeys = verticalTable.keys() verticalTableKeys.sort() xIntersections = [] for verticalTableKey in verticalTableKeys: y = verticalTableKey * horizontalStep if verticalTableKey - 1 not in verticalTableKeys: xIntersections.append(y - verticalOverhang) if verticalTableKey + 1 not in verticalTableKeys: xIntersections.append(y + verticalOverhang) for segment in euclidean.getSegmentsFromXIntersections(xIntersections, verticalTableTableKey * verticalStep): for endpoint in segment: endpoint.point = complex(endpoint.point.imag, endpoint.point.real) verticalEndpoints.append(endpoint) return verticalEndpoints def setExtendedPoint( lineSegmentEnd, pointOriginal, x ): 'Set the point in the extended line segment.' if x > min( lineSegmentEnd.point.real, pointOriginal.real ) and x < max( lineSegmentEnd.point.real, pointOriginal.real ): lineSegmentEnd.point = complex( x, pointOriginal.imag ) def writeOutput(fileName, shouldAnalyze=True): 'Raft a gcode linear move file.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'raft', shouldAnalyze) class RaftRepository: 'A class to handle the raft settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.raft.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Raft', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute( 'http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Raft') self.activateRaft = settings.BooleanSetting().getFromValue('Activate Raft', self, True) self.addRaftElevateNozzleOrbitSetAltitude = settings.BooleanSetting().getFromValue( 'Add Raft, Elevate Nozzle, Orbit:', self, True) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Support -', self) self.supportMaterialChoice = settings.MenuButtonDisplay().getFromName('Where to add support: ', self) self.supportChoiceNone = settings.MenuRadio().getFromMenuButtonDisplay(self.supportMaterialChoice, 'None', self, True) self.supportChoiceEmptyLayersOnly = settings.MenuRadio().getFromMenuButtonDisplay(self.supportMaterialChoice, 'Empty Layers Only', self, False) self.supportChoiceEverywhere = settings.MenuRadio().getFromMenuButtonDisplay(self.supportMaterialChoice, 'Everywhere', self, False) self.supportChoiceExteriorOnly = settings.MenuRadio().getFromMenuButtonDisplay(self.supportMaterialChoice, 'Exterior Only', self, False) self.supportMinimumAngle = settings.FloatSpin().getFromValue(40.0, 'Add support if flatter than (degrees):', self, 80.0, 50.0) self.supportCrossHatch = settings.BooleanSetting().getFromValue('Cross Hatch instead of Lines', self, False) self.interfaceInfillDensity = settings.FloatSpin().getFromValue(0.1, 'Interface/Support Lines Density (ratio):', self, 0.5, 0.25) self.interfaceLayerThicknessOverLayerThickness = settings.FloatSpin().getFromValue( 0.8, 'Interface/Support Layer Thickness over Layer Thickness:', self, 1.5, 1.0) self.supportFeedRate = settings.FloatSpin().getFromValue(10.0, 'Support Feed Rate mm/sec:', self, 50.0,30.0)#todo ACT self.supportFlowRateOverOperatingFlowRate = settings.FloatSpin().getFromValue( 0.5, 'Support Flow Rate (scaler):', self, 2.0, 1.0) self.supportGapOverPerimeterExtrusionWidth = settings.FloatSpin().getFromValue( 0.5, 'Support Gap over Perimeter Extrusion Width (ratio):', self, 1.5, 1.0) self.raftAdditionalMarginOverLengthPercent = settings.FloatSpin().getFromValue( 0.0, 'Raft/Support extension in (%):', self, 10.0, 5.0) self.raftMargin = settings.FloatSpin().getFromValue(0.0, 'Raft/Support extension in(mm):', self, 5.0, 2.0) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Name of Support Macro files (gcode) -', self) self.nameOfSupportEndFile = settings.StringSetting().getFromValue('Name of Support End File:', self, 'support_end.gmc') self.nameOfSupportStartFile = settings.StringSetting().getFromValue('Name of Support Start File:', self, 'support_start.gmc') settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Print Adhesion to Printbed Objects first layer -', self) self.operatingNozzleLiftOverLayerThickness = settings.FloatSpin().getFromValue( -0.1, 'Extra Nozzle clearance over Object(ratio):', self, 0.3, 0.0) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Interface -', self) self.interfaceLayers = settings.IntSpin().getFromValue( 0, 'Interface Layers (integer):', self, 3, 0) self.interfaceFeedRateMultiplier = settings.FloatSpin().getFromValue(0.7, 'Interface Feed Rate Multiplier (ratio):', self, 1.1, 1.0) self.interfaceFlowRateMultiplier = settings.FloatSpin().getFromValue(0.7, 'Interface Flow Rate Multiplier (ratio):', self, 1.1, 1.0) self.interfaceNozzleLiftOverInterfaceLayerThickness = settings.FloatSpin().getFromValue(0.25, 'Interface Nozzle Lift over Interface Layer Thickness (ratio):', self, 0.85, 0.45) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Base -', self) self.baseLayers = settings.IntSpin().getFromValue(0, 'Base Layers (integer):', self, 3, 0) self.baseFeedRateMultiplier = settings.FloatSpin().getFromValue(0.1, 'Base Feed Rate Multiplier (ratio):', self, 2.0, 1.0) self.baseFlowRateMultiplier = settings.FloatSpin().getFromValue(0.1, 'Base Flow Rate Multiplier (ratio):', self, 2.0, 1.0) self.baseInfillDensity = settings.FloatSpin().getFromValue(0.2, 'Base Infill Density (ratio):', self, 1.0, 0.5) self.baseLayerThicknessOverLayerThickness = settings.FloatSpin().getFromValue( 1.0, 'Base Layer Thickness over Layer Thickness:', self, 3.0, 2.0) self.baseNozzleLiftOverBaseLayerThickness = settings.FloatSpin().getFromValue( 0.2, 'Base Nozzle Lift over Base Layer Thickness (ratio):', self, 0.8, 0.4) settings.LabelSeparator().getFromRepository(self) self.initialCircling = settings.BooleanSetting().getFromValue('Initial Circling:', self, False) self.infillOverhangOverExtrusionWidth = settings.FloatSpin().getFromValue( 0.0, 'Infill Overhang over Extrusion Width (ratio):', self, 5.0, 3.00) settings.LabelSeparator().getFromRepository(self) self.executeTitle = 'Raft' def execute(self): 'Raft button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class RaftSkein: 'A class to raft a skein of extrusions.' def __init__(self): self.addLineLayerStart = True self.baseTemperature = None self.beginLoop = None self.boundaryLayers = [] self.coolingRate = None self.distanceFeedRate = gcodec.DistanceFeedRate() self.extrusionStart = True self.extrusionTop = 0.0 self.feedRateMinute = 961.0 self.heatingRate = None self.insetTable = {} self.interfaceTemperature = None self.isNestedRing = True self.isPerimeterPath = False self.isStartupEarly = False self.layerIndex = - 1 self.layerStarted = False self.layerThickness = 0.4 self.lineIndex = 0 self.lines = None self.objectFirstLayerInfillTemperature = None self.objectFirstLayerPerimeterTemperature = None self.objectNextLayersTemperature = None self.oldFlowRate = None self.oldLocation = None self.oldTemperatureOutputString = None self.operatingFeedRateMinute = None self.operatingLayerEndLine = '( )' self.operatingJump = None self.orbitalFeedRatePerSecond = 2.01 self.perimeterWidth = 0.6 self.supportFeedRate = 10 self.supportFlowRate = None self.supportLayers = [] self.supportLayersTemperature = None self.supportedLayersTemperature = None self.travelFeedRateMinute = None def addBaseLayer(self): 'Add a base layer.' baseLayerThickness = self.layerThickness * self.baseLayerThicknessOverLayerThickness zCenter = self.extrusionTop + 0.5 * baseLayerThickness z = zCenter + baseLayerThickness * self.repository.baseNozzleLiftOverBaseLayerThickness.value if len(self.baseEndpoints) < 1: print('This should never happen, the base layer has a size of zero.') return self.addLayerFromEndpoints( self.baseEndpoints, self.repository.baseFeedRateMultiplier.value, self.repository.baseFlowRateMultiplier.value, baseLayerThickness, self.baseLayerThicknessOverLayerThickness, self.baseStep, z) def addBaseSegments(self, baseExtrusionWidth): 'Add the base segments.' baseOverhang = self.repository.infillOverhangOverExtrusionWidth.value * baseExtrusionWidth self.baseEndpoints = getVerticalEndpoints(self.interfaceSegmentsTable, self.interfaceStep, baseOverhang, self.baseStep) def addEmptyLayerSupport( self, boundaryLayerIndex ): 'Add support material to a layer if it is empty.' supportLayer = SupportLayer([]) self.supportLayers.append(supportLayer) if len( self.boundaryLayers[ boundaryLayerIndex ].loops ) > 0: return aboveXIntersectionsTable = {} euclidean.addXIntersectionsFromLoopsForTable( self.getInsetLoopsAbove(boundaryLayerIndex), aboveXIntersectionsTable, self.interfaceStep ) belowXIntersectionsTable = {} euclidean.addXIntersectionsFromLoopsForTable( self.getInsetLoopsBelow(boundaryLayerIndex), belowXIntersectionsTable, self.interfaceStep ) supportLayer.xIntersectionsTable = euclidean.getIntersectionOfXIntersectionsTables( [ aboveXIntersectionsTable, belowXIntersectionsTable ] ) def addFlowRate(self, flowRate): 'Add a flow rate value if different.' if flowRate is not None: self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate)) def addInterfaceLayer(self): 'Add an interface layer.' interfaceLayerThickness = self.layerThickness * self.interfaceLayerThicknessOverLayerThickness zCenter = self.extrusionTop + 0.5 * interfaceLayerThickness z = zCenter + interfaceLayerThickness * self.repository.interfaceNozzleLiftOverInterfaceLayerThickness.value if len(self.interfaceEndpoints) < 1: print('This should never happen, the interface layer has a size of zero.') return self.addLayerFromEndpoints( self.interfaceEndpoints, self.repository.interfaceFeedRateMultiplier.value, self.repository.interfaceFlowRateMultiplier.value, interfaceLayerThickness, self.interfaceLayerThicknessOverLayerThickness, self.interfaceStep, z) def addInterfaceTables(self, interfaceExtrusionWidth): 'Add interface tables.' overhang = self.repository.infillOverhangOverExtrusionWidth.value * interfaceExtrusionWidth self.interfaceEndpoints = [] self.interfaceIntersectionsTableKeys = self.interfaceIntersectionsTable.keys() self.interfaceSegmentsTable = {} for yKey in self.interfaceIntersectionsTableKeys: self.interfaceIntersectionsTable[yKey].sort() y = yKey * self.interfaceStep lineSegments = euclidean.getSegmentsFromXIntersections(self.interfaceIntersectionsTable[yKey], y) xIntersectionIndexList = [] for lineSegmentIndex in xrange(len(lineSegments)): lineSegment = lineSegments[lineSegmentIndex] endpointBegin = lineSegment[0] endpointEnd = lineSegment[1] endpointBegin.point = complex(self.baseStep * math.floor(endpointBegin.point.real / self.baseStep) - overhang, y) endpointEnd.point = complex(self.baseStep * math.ceil(endpointEnd.point.real / self.baseStep) + overhang, y) if endpointEnd.point.real > endpointBegin.point.real: euclidean.addXIntersectionIndexesFromSegment(lineSegmentIndex, lineSegment, xIntersectionIndexList) xIntersections = euclidean.getJoinOfXIntersectionIndexes(xIntersectionIndexList) joinedSegments = euclidean.getSegmentsFromXIntersections(xIntersections, y) if len(joinedSegments) > 0: self.interfaceSegmentsTable[yKey] = joinedSegments for joinedSegment in joinedSegments: self.interfaceEndpoints += joinedSegment def addLayerFromEndpoints( self, endpoints, feedRateMultiplier, flowRateMultiplier, layerLayerThickness, layerThicknessRatio, step, z): 'Add a layer from endpoints and raise the extrusion top.' layerThicknessRatioSquared = layerThicknessRatio * layerThicknessRatio feedRateMinute = self.feedRateMinute * feedRateMultiplier / layerThicknessRatioSquared if len(endpoints) < 1: return aroundPixelTable = {} aroundWidth = 0.24321 * step paths = euclidean.getPathsFromEndpoints(endpoints, 1.5 * step, aroundPixelTable, aroundWidth) self.addLayerLine(z) if self.oldFlowRate is not None: self.addFlowRate(flowRateMultiplier * self.oldFlowRate) for path in paths: simplifiedPath = euclidean.getSimplifiedPath(path, step) self.distanceFeedRate.addGcodeFromFeedRateThreadZ(feedRateMinute, simplifiedPath, self.travelFeedRateMinute, z) self.extrusionTop += layerLayerThickness self.addFlowRate(self.oldFlowRate) def addLayerLine(self, z): 'Add the layer gcode line and close the last layer gcode block.' if self.layerStarted: self.distanceFeedRate.addLine('()') self.distanceFeedRate.addLine('( %s )' % self.distanceFeedRate.getRounded(z)) # Indicate that a new layer is starting. if self.beginLoop is not None: zBegin = self.extrusionTop + self.layerThickness intercircle.addOrbitsIfLarge(self.distanceFeedRate, self.beginLoop, self.orbitalFeedRatePerSecond, self.temperatureChangeTimeBeforeRaft, zBegin) self.beginLoop = None self.layerStarted = True def addOperatingOrbits(self, boundaryLoops, pointComplex, temperatureChangeTime, z): 'Add the orbits before the operating layers.' if len(boundaryLoops) < 1: return insetBoundaryLoops = intercircle.getInsetLoopsFromLoops(boundaryLoops, self.perimeterWidth) if len(insetBoundaryLoops) < 1: insetBoundaryLoops = boundaryLoops largestLoop = euclidean.getLargestLoop(insetBoundaryLoops) if pointComplex is not None: largestLoop = euclidean.getLoopStartingClosest(self.perimeterWidth, pointComplex, largestLoop) intercircle.addOrbitsIfLarge(self.distanceFeedRate, largestLoop, self.orbitalFeedRatePerSecond, temperatureChangeTime, z) def addRaft(self): 'Add the raft.' if len(self.boundaryLayers) < 0: print('this should never happen, there are no boundary layers in addRaft') return self.baseLayerThicknessOverLayerThickness = self.repository.baseLayerThicknessOverLayerThickness.value baseExtrusionWidth = self.perimeterWidth * self.baseLayerThicknessOverLayerThickness self.baseStep = baseExtrusionWidth / self.repository.baseInfillDensity.value self.interfaceLayerThicknessOverLayerThickness = self.repository.interfaceLayerThicknessOverLayerThickness.value interfaceExtrusionWidth = self.perimeterWidth * self.interfaceLayerThicknessOverLayerThickness self.interfaceStep = interfaceExtrusionWidth / self.repository.interfaceInfillDensity.value self.setCornersZ() self.cornerMinimumComplex = self.cornerMinimum.dropAxis() originalExtent = self.cornerMaximumComplex - self.cornerMinimumComplex self.raftOutsetRadius = self.repository.raftMargin.value + self.repository.raftAdditionalMarginOverLengthPercent.value * 0.01 * max(originalExtent.real, originalExtent.imag) self.setBoundaryLayers() outsetSeparateLoops = intercircle.getInsetSeparateLoopsFromLoops(self.boundaryLayers[0].loops, -self.raftOutsetRadius, 0.8) self.interfaceIntersectionsTable = {} euclidean.addXIntersectionsFromLoopsForTable(outsetSeparateLoops, self.interfaceIntersectionsTable, self.interfaceStep) if len(self.supportLayers) > 0: supportIntersectionsTable = self.supportLayers[0].xIntersectionsTable euclidean.joinXIntersectionsTables(supportIntersectionsTable, self.interfaceIntersectionsTable) self.addInterfaceTables(interfaceExtrusionWidth) self.addRaftPerimeters() self.baseIntersectionsTable = {} complexRadius = complex(self.raftOutsetRadius, self.raftOutsetRadius) self.complexHigh = complexRadius + self.cornerMaximumComplex self.complexLow = self.cornerMinimumComplex - complexRadius self.beginLoop = euclidean.getSquareLoopWiddershins(self.cornerMinimumComplex, self.cornerMaximumComplex) if not intercircle.orbitsAreLarge(self.beginLoop, self.temperatureChangeTimeBeforeRaft): self.beginLoop = None if self.repository.baseLayers.value > 0: self.addTemperatureLineIfDifferent(self.baseTemperature) self.addBaseSegments(baseExtrusionWidth) for baseLayerIndex in xrange(self.repository.baseLayers.value): self.addBaseLayer() if self.repository.interfaceLayers.value > 0: self.addTemperatureLineIfDifferent(self.interfaceTemperature) self.interfaceIntersectionsTableKeys.sort() for interfaceLayerIndex in xrange(self.repository.interfaceLayers.value): self.addInterfaceLayer() self.operatingJump = self.extrusionTop + self.layerThickness * (self.repository.operatingNozzleLiftOverLayerThickness.value + 0.5) for boundaryLayer in self.boundaryLayers: if self.operatingJump is not None: boundaryLayer.z += self.operatingJump if self.repository.baseLayers.value > 0 or self.repository.interfaceLayers.value > 0: boundaryZ = self.boundaryLayers[0].z if self.layerStarted: self.distanceFeedRate.addLine('()') self.layerStarted = False self.distanceFeedRate.addLine('( )') self.addLayerLine(boundaryZ) temperatureChangeTimeBeforeFirstLayer = self.getTemperatureChangeTime(self.objectFirstLayerPerimeterTemperature) self.addTemperatureLineIfDifferent(self.objectFirstLayerPerimeterTemperature) largestOutsetLoop = intercircle.getLargestInsetLoopFromLoop(euclidean.getLargestLoop(outsetSeparateLoops), -self.raftOutsetRadius) intercircle.addOrbitsIfLarge(self.distanceFeedRate, largestOutsetLoop, self.orbitalFeedRatePerSecond, temperatureChangeTimeBeforeFirstLayer, boundaryZ) self.addLineLayerStart = False def addRaftedLine( self, splitLine ): 'Add elevated gcode line with operating feed rate.' self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) z = self.oldLocation.z if self.operatingJump is not None: z += self.operatingJump temperature = self.objectNextLayersTemperature if self.layerIndex == 0: if self.isPerimeterPath: temperature = self.objectFirstLayerPerimeterTemperature else: temperature = self.objectFirstLayerInfillTemperature self.addTemperatureLineIfDifferent(temperature) self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, self.oldLocation.dropAxis(), z) return ### location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) feedRateMinuteMultiplied = self.feedRateMinute self.oldLocation = location z = location.z if self.operatingJump is not None: z += self.operatingJump flowRate = self.oldFlowRate temperature = self.objectNextLayersTemperature if self.layerIndex == 0: if self.isPerimeterPath: feedRateMinuteMultiplied = self.repository.objectFirstLayerFeedRatePerimeterMultiplier.value * 60 if flowRate is not None: flowRate = self.repository.objectFirstLayerFlowRatePerimeterMultiplier.value temperature = self.objectFirstLayerPerimeterTemperature else: feedRateMinuteMultiplied = self.firstLayertravelFeedRateMinute if flowRate is not None: flowRate *= self.objectFirstLayerFlowRateInfillMultiplier temperature = self.objectFirstLayerInfillTemperature self.addFlowRate(flowRate) self.addTemperatureLineIfDifferent(temperature) self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedRateMinuteMultiplied, location.dropAxis(), z) self.addFlowRate(self.oldFlowRate) def addRaftPerimeters(self): 'Add raft perimeters if there is a raft.' interfaceOutset = self.halfPerimeterWidth * self.interfaceLayerThicknessOverLayerThickness for supportLayer in self.supportLayers: supportSegmentTable = supportLayer.supportSegmentTable if len(supportSegmentTable) > 0: outset = interfaceOutset self.addRaftPerimetersByLoops(getLoopsBySegmentsDictionary(supportSegmentTable, self.interfaceStep), outset) if self.repository.baseLayers.value < 1 and self.repository.interfaceLayers.value < 1: return overhangMultiplier = 1.0 + self.repository.infillOverhangOverExtrusionWidth.value + self.repository.infillOverhangOverExtrusionWidth.value outset = self.halfPerimeterWidth if self.repository.interfaceLayers.value > 0: outset = max(interfaceOutset * overhangMultiplier, outset) if self.repository.baseLayers.value > 0: outset = max(self.halfPerimeterWidth * self.baseLayerThicknessOverLayerThickness * overhangMultiplier, outset) self.addRaftPerimetersByLoops(getLoopsBySegmentsDictionary(self.interfaceSegmentsTable, self.interfaceStep), outset) def addRaftPerimetersByLoops(self, loops, outset): 'Add raft perimeters to the gcode for loops.' loops = intercircle.getInsetSeparateLoopsFromLoops(loops, -outset) for loop in loops: self.distanceFeedRate.addLine('()') for point in loop: roundedX = self.distanceFeedRate.getRounded(point.real) roundedY = self.distanceFeedRate.getRounded(point.imag) self.distanceFeedRate.addTagBracketedLine('raftPoint', 'X%s Y%s' % (roundedX, roundedY)) self.distanceFeedRate.addLine('()') def addSegmentTablesToSupportLayers(self): 'Add segment tables to the support layers.' for supportLayer in self.supportLayers: supportLayer.supportSegmentTable = {} xIntersectionsTable = supportLayer.xIntersectionsTable for xIntersectionsTableKey in xIntersectionsTable: y = xIntersectionsTableKey * self.interfaceStep supportLayer.supportSegmentTable[ xIntersectionsTableKey ] = euclidean.getSegmentsFromXIntersections( xIntersectionsTable[ xIntersectionsTableKey ], y ) def addSupportLayerTemperature(self, endpoints, z): 'Add support layer and temperature before the object layer.' self.distanceFeedRate.addLine('()') self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.supportStartLines) self.addTemperatureOrbits(endpoints, self.supportedLayersTemperature, z) aroundPixelTable = {} aroundWidth = 0.24321 * self.interfaceStep boundaryLoops = self.boundaryLayers[self.layerIndex].loops halfSupportOutset = 0.5 * self.supportOutset aroundBoundaryLoops = intercircle.getAroundsFromLoops(boundaryLoops, halfSupportOutset) for aroundBoundaryLoop in aroundBoundaryLoops: euclidean.addLoopToPixelTable(aroundBoundaryLoop, aroundPixelTable, aroundWidth) paths = euclidean.getPathsFromEndpoints(endpoints, 1.5 * self.interfaceStep, aroundPixelTable, aroundWidth) feedRateMinuteMultiplied = self.repository.supportFeedRate.value * 60 supportFlowRateMultiplied = self.repository.supportFlowRateOverOperatingFlowRate.value*(self.nozzleXsection / self.extrusionXsection) if self.layerIndex == 0: feedRateMinuteMultiplied = self.objectFirstLayerFeedRateInfillMultiplier * 60 if supportFlowRateMultiplied is not None: supportFlowRateMultiplied = supportFlowRateMultiplied *1.25 self.travelFeedRateMinute = self.firstLayertravelFeedRateMinute self.addFlowRate(supportFlowRateMultiplied) for path in paths: self.distanceFeedRate.addGcodeFromFeedRateThreadZ(feedRateMinuteMultiplied, path, self.travelFeedRateMinute, z) self.addFlowRate(self.oldFlowRate) self.addTemperatureOrbits(endpoints, self.supportLayersTemperature, z) self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.supportEndLines) self.distanceFeedRate.addLine('()') def addSupportSegmentTable( self, layerIndex ): 'Add support segments from the boundary layers.' aboveLayer = self.boundaryLayers[ layerIndex + 1 ] aboveLoops = aboveLayer.loops supportLayer = self.supportLayers[layerIndex] if len( aboveLoops ) < 1: return boundaryLayer = self.boundaryLayers[layerIndex] rise = aboveLayer.z - boundaryLayer.z outsetSupportLoops = intercircle.getInsetSeparateLoopsFromLoops(boundaryLayer.loops, -self.minimumSupportRatio * rise) numberOfSubSteps = 4 subStepSize = self.interfaceStep / float( numberOfSubSteps ) aboveIntersectionsTable = {} euclidean.addXIntersectionsFromLoopsForTable( aboveLoops, aboveIntersectionsTable, subStepSize ) outsetIntersectionsTable = {} euclidean.addXIntersectionsFromLoopsForTable( outsetSupportLoops, outsetIntersectionsTable, subStepSize ) euclidean.subtractXIntersectionsTable( aboveIntersectionsTable, outsetIntersectionsTable ) for aboveIntersectionsTableKey in aboveIntersectionsTable.keys(): supportIntersectionsTableKey = int( round( float( aboveIntersectionsTableKey ) / numberOfSubSteps ) ) xIntersectionIndexList = [] if supportIntersectionsTableKey in supportLayer.xIntersectionsTable: euclidean.addXIntersectionIndexesFromXIntersections( 0, xIntersectionIndexList, supportLayer.xIntersectionsTable[ supportIntersectionsTableKey ] ) euclidean.addXIntersectionIndexesFromXIntersections( 1, xIntersectionIndexList, aboveIntersectionsTable[ aboveIntersectionsTableKey ] ) supportLayer.xIntersectionsTable[ supportIntersectionsTableKey ] = euclidean.getJoinOfXIntersectionIndexes( xIntersectionIndexList ) def addTemperatureLineIfDifferent(self, temperature): 'Add a line of temperature if different.' if temperature is None: return temperatureOutputString = euclidean.getRoundedToThreePlaces(temperature) if temperatureOutputString == self.oldTemperatureOutputString: return if temperatureOutputString is not None: self.distanceFeedRate.addLine('M104 S' + temperatureOutputString) # Set temperature. self.oldTemperatureOutputString = temperatureOutputString def addTemperatureOrbits( self, endpoints, temperature, z ): 'Add the temperature and orbits around the support layer.' if self.layerIndex < 0: return boundaryLoops = self.boundaryLayers[self.layerIndex].loops temperatureTimeChange = self.getTemperatureChangeTime( temperature ) self.addTemperatureLineIfDifferent( temperature ) if len( boundaryLoops ) < 1: layerCornerHigh = complex(-987654321.0, -987654321.0) layerCornerLow = complex(987654321.0, 987654321.0) for endpoint in endpoints: layerCornerHigh = euclidean.getMaximum( layerCornerHigh, endpoint.point ) layerCornerLow = euclidean.getMinimum( layerCornerLow, endpoint.point ) squareLoop = euclidean.getSquareLoopWiddershins( layerCornerLow, layerCornerHigh ) intercircle.addOrbitsIfLarge( self.distanceFeedRate, squareLoop, self.orbitalFeedRatePerSecond, temperatureTimeChange, z ) return perimeterInset = 0.4 * self.perimeterWidth insetBoundaryLoops = intercircle.getInsetLoopsFromLoops(boundaryLoops, perimeterInset) if len( insetBoundaryLoops ) < 1: insetBoundaryLoops = boundaryLoops largestLoop = euclidean.getLargestLoop( insetBoundaryLoops ) intercircle.addOrbitsIfLarge( self.distanceFeedRate, largestLoop, self.orbitalFeedRatePerSecond, temperatureTimeChange, z ) def addToFillXIntersectionIndexTables( self, supportLayer ): 'Add fill segments from the boundary layers.' supportLoops = supportLayer.supportLoops supportLayer.fillXIntersectionsTable = {} if len(supportLoops) < 1: return euclidean.addXIntersectionsFromLoopsForTable( supportLoops, supportLayer.fillXIntersectionsTable, self.interfaceStep ) def extendXIntersections( self, loops, radius, xIntersectionsTable ): 'Extend the support segments.' xIntersectionsTableKeys = xIntersectionsTable.keys() for xIntersectionsTableKey in xIntersectionsTableKeys: lineSegments = euclidean.getSegmentsFromXIntersections( xIntersectionsTable[ xIntersectionsTableKey ], xIntersectionsTableKey ) xIntersectionIndexList = [] loopXIntersections = [] euclidean.addXIntersectionsFromLoops( loops, loopXIntersections, xIntersectionsTableKey ) for lineSegmentIndex in xrange( len( lineSegments ) ): lineSegment = lineSegments[ lineSegmentIndex ] extendedLineSegment = getExtendedLineSegment( radius, lineSegment, loopXIntersections ) if extendedLineSegment is not None: euclidean.addXIntersectionIndexesFromSegment( lineSegmentIndex, extendedLineSegment, xIntersectionIndexList ) xIntersections = euclidean.getJoinOfXIntersectionIndexes( xIntersectionIndexList ) if len( xIntersections ) > 0: xIntersectionsTable[ xIntersectionsTableKey ] = xIntersections else: del xIntersectionsTable[ xIntersectionsTableKey ] def getCraftedGcode(self, gcodeText, repository): 'Parse gcode text and store the raft gcode.' self.repository = repository self.minimumSupportRatio = math.tan( math.radians( repository.supportMinimumAngle.value ) ) self.supportEndLines = settings.getAlterationFileLines(repository.nameOfSupportEndFile.value) self.supportStartLines = settings.getAlterationFileLines(repository.nameOfSupportStartFile.value) self.lines = archive.getTextLines(gcodeText) self.parseInitialization() self.temperatureChangeTimeBeforeRaft = 0.0 if self.repository.initialCircling.value: maxBaseInterfaceTemperature = max(self.baseTemperature, self.interfaceTemperature) firstMaxTemperature = max(maxBaseInterfaceTemperature, self.objectFirstLayerPerimeterTemperature) self.temperatureChangeTimeBeforeRaft = self.getTemperatureChangeTime(firstMaxTemperature) if repository.addRaftElevateNozzleOrbitSetAltitude.value: self.addRaft() self.addTemperatureLineIfDifferent( self.objectFirstLayerPerimeterTemperature ) for line in self.lines[self.lineIndex :]: self.parseLine(line) return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue()) def getElevatedBoundaryLine( self, splitLine ): 'Get elevated boundary gcode line.' location = gcodec.getLocationFromSplitLine(None, splitLine) if self.operatingJump is not None: location.z += self.operatingJump return self.distanceFeedRate.getBoundaryLine( location ) def getInsetLoops( self, boundaryLayerIndex ): 'Inset the support loops if they are not already inset.' if boundaryLayerIndex not in self.insetTable: self.insetTable[ boundaryLayerIndex ] = intercircle.getInsetSeparateLoopsFromLoops(self.boundaryLayers[ boundaryLayerIndex ].loops, self.quarterPerimeterWidth) return self.insetTable[ boundaryLayerIndex ] def getInsetLoopsAbove( self, boundaryLayerIndex ): 'Get the inset loops above the boundary layer index.' for aboveLayerIndex in xrange( boundaryLayerIndex + 1, len(self.boundaryLayers) ): if len( self.boundaryLayers[ aboveLayerIndex ].loops ) > 0: return self.getInsetLoops( aboveLayerIndex ) return [] def getInsetLoopsBelow( self, boundaryLayerIndex ): 'Get the inset loops below the boundary layer index.' for belowLayerIndex in xrange( boundaryLayerIndex - 1, - 1, - 1 ): if len( self.boundaryLayers[ belowLayerIndex ].loops ) > 0: return self.getInsetLoops( belowLayerIndex ) return [] def getStepsUntilEnd( self, begin, end, stepSize ): 'Get steps from the beginning until the end.' step = begin steps = [] while step < end: steps.append( step ) step += stepSize return steps def getSupportEndpoints(self): 'Get the support layer segments.' if len(self.supportLayers) <= self.layerIndex: return [] supportSegmentTable = self.supportLayers[self.layerIndex].supportSegmentTable if self.layerIndex % 2 == 1 and self.repository.supportCrossHatch.value: return getVerticalEndpoints(supportSegmentTable, self.interfaceStep, 0.1 * self.perimeterWidth, self.interfaceStep) return euclidean.getEndpointsFromSegmentTable(supportSegmentTable) def getTemperatureChangeTime( self, temperature ): 'Get the temperature change time.' if temperature is None: return 0.0 oldTemperature = 25.0 # typical chamber temperature if self.oldTemperatureOutputString is not None: oldTemperature = float( self.oldTemperatureOutputString ) if temperature == oldTemperature: return 0.0 if temperature > oldTemperature: return ( temperature - oldTemperature ) / self.heatingRate return ( oldTemperature - temperature ) / abs( self.coolingRate ) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '(': self.baseTemperature = float(splitLine[1]) elif firstWord == '(': self.coolingRate = float(splitLine[1]) elif firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('raft') elif firstWord == '(': self.heatingRate = float(splitLine[1]) elif firstWord == '(': self.interfaceTemperature = float(splitLine[1]) elif firstWord == '(': return elif firstWord == '(': self.layerThickness = float(splitLine[1]) elif firstWord == '(': self.objectFirstLayerFeedRateInfillMultiplier = float(splitLine[1]) elif firstWord == '(': self.objectFirstLayerFlowRateInfillMultiplier = float(splitLine[1]) elif firstWord == '(': self.objectFirstLayerInfillTemperature = float(splitLine[1]) elif firstWord == '(': self.objectFirstLayerPerimeterTemperature = float(splitLine[1]) elif firstWord == '(': self.objectNextLayersTemperature = float(splitLine[1]) elif firstWord == '(': self.orbitalFeedRatePerSecond = float(splitLine[1]) elif firstWord == '(': self.operatingFeedRateMinute = 60.0 * float(splitLine[1]) self.feedRateMinute = self.operatingFeedRateMinute elif firstWord == '(': self.oldFlowRate = float(splitLine[1]) self.supportFlowRate = self.repository.supportFlowRateOverOperatingFlowRate.value elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.halfPerimeterWidth = 0.5 * self.perimeterWidth self.quarterPerimeterWidth = 0.25 * self.perimeterWidth self.supportOutset = self.perimeterWidth + self.perimeterWidth * self.repository.supportGapOverPerimeterExtrusionWidth.value self.extrusionXsection = ((self.perimeterWidth + self.layerThickness)/4) ** 2 * math.pi self.supportFlowRate = self.repository.supportFlowRateOverOperatingFlowRate.value * (self.nozzleXsection / self.extrusionXsection) elif firstWord == '(': self.supportLayersTemperature = float(splitLine[1]) elif firstWord == '(': self.supportedLayersTemperature = float(splitLine[1]) elif firstWord == '(': self.travelFeedRateMinute = 60.0 * float(splitLine[1]) elif firstWord == '(': self.firstLayertravelFeedRateMinute = 60.0 * float(splitLine[1]) elif firstWord == '(': self.nozzleDiameter = float(splitLine[1]) elif firstWord == '(': self.nozzleXsection = float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): 'Parse a gcode line and add it to the raft skein.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': if self.extrusionStart: self.addRaftedLine(splitLine) return elif firstWord == 'M101': self.isExtruderActive = True if self.isStartupEarly: self.isStartupEarly = False return elif firstWord == 'M103': self.isExtruderActive = False elif firstWord == 'M108': self.oldFlowRate = float(splitLine[1][1 :]) elif firstWord == '(': line = self.getElevatedBoundaryLine(splitLine) elif firstWord == '()': self.extrusionStart = False self.distanceFeedRate.addLine( self.operatingLayerEndLine ) elif firstWord == '(': self.layerIndex += 1 settings.printProgress(self.layerIndex, 'raft') boundaryLayer = None layerZ = self.extrusionTop + float(splitLine[1]) if len(self.boundaryLayers) > 0: boundaryLayer = self.boundaryLayers[self.layerIndex] layerZ = boundaryLayer.z if self.operatingJump is not None: line = '( %s )' % self.distanceFeedRate.getRounded( layerZ ) if self.layerStarted and self.addLineLayerStart: self.distanceFeedRate.addLine('()') self.layerStarted = False if self.layerIndex > len(self.supportLayers) + 1: self.distanceFeedRate.addLine( self.operatingLayerEndLine ) self.operatingLayerEndLine = '' if self.addLineLayerStart: self.distanceFeedRate.addLine(line) self.addLineLayerStart = True line = '' endpoints = self.getSupportEndpoints() if self.layerIndex == 1: if len(endpoints) < 1: temperatureChangeTimeBeforeNextLayers = self.getTemperatureChangeTime( self.objectNextLayersTemperature ) self.addTemperatureLineIfDifferent( self.objectNextLayersTemperature ) if self.repository.addRaftElevateNozzleOrbitSetAltitude.value and len( boundaryLayer.loops ) > 0: self.addOperatingOrbits( boundaryLayer.loops, euclidean.getXYComplexFromVector3( self.oldLocation ), temperatureChangeTimeBeforeNextLayers, layerZ ) if len(endpoints) > 0: self.addSupportLayerTemperature( endpoints, layerZ ) elif firstWord == '(' or firstWord == '()': self.isPerimeterPath = True elif firstWord == '()' or firstWord == '()': self.isPerimeterPath = False self.distanceFeedRate.addLine(line) def setBoundaryLayers(self): 'Set the boundary layers.' if self.repository.supportChoiceNone.value: return if len(self.boundaryLayers) < 2: return if self.repository.supportChoiceEmptyLayersOnly.value: supportLayer = SupportLayer([]) self.supportLayers.append(supportLayer) for boundaryLayerIndex in xrange(1, len(self.boundaryLayers) -1): self.addEmptyLayerSupport(boundaryLayerIndex) self.truncateSupportSegmentTables() self.addSegmentTablesToSupportLayers() return for boundaryLayer in self.boundaryLayers: # thresholdRadius of 0.8 is needed to avoid the ripple inset bug http://hydraraptor.blogspot.com/2010/12/crackers.html supportLoops = intercircle.getInsetSeparateLoopsFromLoops(boundaryLayer.loops, -self.supportOutset, 0.8) supportLayer = SupportLayer(supportLoops) self.supportLayers.append(supportLayer) for supportLayerIndex in xrange(len(self.supportLayers) - 1): self.addSupportSegmentTable(supportLayerIndex) self.truncateSupportSegmentTables() for supportLayerIndex in xrange(len(self.supportLayers) - 1): boundaryLoops = self.boundaryLayers[supportLayerIndex].loops self.extendXIntersections( boundaryLoops, self.supportOutset, self.supportLayers[supportLayerIndex].xIntersectionsTable) for supportLayer in self.supportLayers: self.addToFillXIntersectionIndexTables(supportLayer) if self.repository.supportChoiceExteriorOnly.value: for supportLayerIndex in xrange(1, len(self.supportLayers)): self.subtractJoinedFill(supportLayerIndex) for supportLayer in self.supportLayers: euclidean.subtractXIntersectionsTable(supportLayer.xIntersectionsTable, supportLayer.fillXIntersectionsTable) for supportLayerIndex in xrange(len(self.supportLayers) - 2, -1, -1): xIntersectionsTable = self.supportLayers[supportLayerIndex].xIntersectionsTable aboveXIntersectionsTable = self.supportLayers[supportLayerIndex + 1].xIntersectionsTable euclidean.joinXIntersectionsTables(aboveXIntersectionsTable, xIntersectionsTable) for supportLayerIndex in xrange(len(self.supportLayers)): supportLayer = self.supportLayers[supportLayerIndex] self.extendXIntersections(supportLayer.supportLoops, self.raftOutsetRadius, supportLayer.xIntersectionsTable) for supportLayer in self.supportLayers: euclidean.subtractXIntersectionsTable(supportLayer.xIntersectionsTable, supportLayer.fillXIntersectionsTable) self.addSegmentTablesToSupportLayers() def setCornersZ(self): 'Set maximum and minimum corners and z.' boundaryLoop = None boundaryLayer = None layerIndex = - 1 self.cornerMaximumComplex = complex(-912345678.0, -912345678.0) self.cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0) self.firstLayerLoops = [] for line in self.lines[self.lineIndex :]: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '()': boundaryLoop = None elif firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) if boundaryLoop is None: boundaryLoop = [] boundaryLayer.loops.append(boundaryLoop) boundaryLoop.append(location.dropAxis()) self.cornerMaximumComplex = euclidean.getMaximum(self.cornerMaximumComplex, location.dropAxis()) self.cornerMinimum.minimize(location) elif firstWord == '(': z = float(splitLine[1]) boundaryLayer = euclidean.LoopLayer(z) self.boundaryLayers.append(boundaryLayer) elif firstWord == '(': layerIndex += 1 if self.repository.supportChoiceNone.value: if layerIndex > 1: return def subtractJoinedFill( self, supportLayerIndex ): 'Join the fill then subtract it from the support layer table.' supportLayer = self.supportLayers[supportLayerIndex] fillXIntersectionsTable = supportLayer.fillXIntersectionsTable belowFillXIntersectionsTable = self.supportLayers[ supportLayerIndex - 1 ].fillXIntersectionsTable euclidean.joinXIntersectionsTables( belowFillXIntersectionsTable, supportLayer.fillXIntersectionsTable ) euclidean.subtractXIntersectionsTable( supportLayer.xIntersectionsTable, supportLayer.fillXIntersectionsTable ) def truncateSupportSegmentTables(self): 'Truncate the support segments after the last support segment which contains elements.' for supportLayerIndex in xrange( len(self.supportLayers) - 1, - 1, - 1 ): if len( self.supportLayers[supportLayerIndex].xIntersectionsTable ) > 0: self.supportLayers = self.supportLayers[ : supportLayerIndex + 1 ] return self.supportLayers = [] class SupportLayer: 'Support loops with segment tables.' def __init__( self, supportLoops ): self.supportLoops = supportLoops self.supportSegmentTable = {} self.xIntersectionsTable = {} def __repr__(self): 'Get the string representation of this loop layer.' return '%s' % ( self.supportLoops ) def main(): 'Display the raft dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/scale.py000066400000000000000000000160071167321211700301310ustar00rootroot00000000000000#! /usr/bin/env python """ This page is in the table of contents. Scale scales the carving to compensate for shrinkage after the extrusion has cooled. The scale manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Scale It is best to only change the XY Plane Scale, because that does not affect other variables. If you choose to change the Z Axis Scale, that increases the layer thickness so you must increase the feed rate in speed by the same amount and maybe some other variables which depend on layer thickness. ==Operation== The default 'Activate Scale' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===XY Plane Scale=== Default is 1.01. Defines the amount the xy plane of the carving will be scaled. The xy coordinates will be scaled, but the perimeterWidth is not changed, so this can be changed without affecting other variables. ===Z Axis Scale=== Default is one. Defines the amount the z axis of the carving will be scaled. The default is one because changing this changes many variables related to the layer thickness. For example, the feedRate should be multiplied by the Z Axis Scale because the layers would be farther apart. ===SVG Viewer=== Default is webbrowser. If the 'SVG Viewer' is set to the default 'webbrowser', the scalable vector graphics file will be sent to the default browser to be opened. If the 'SVG Viewer' is set to a program name, the scalable vector graphics file will be sent to that program to be opened. ==Examples== The following examples scale the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and scale.py. > python scale.py This brings up the scale dialog. > python scale.py Screw Holder Bottom.stl The scale tool is parsing the file: Screw Holder Bottom.stl .. The scale tool has created the file: .. Screw Holder Bottom_scale.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from datetime import date from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.svg_reader import SVGReader from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from fabmetheus_utilities import svg_writer from fabmetheus_utilities import xml_simple_writer from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import cStringIO import os import sys import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, svgText='', repository=None): "Scale and convert an svg file or svgText." return getCraftedTextFromText(fileName, archive.getTextIfEmpty(fileName, svgText), repository) def getCraftedTextFromText(fileName, svgText, repository=None): "Scale and convert an svgText." if gcodec.isProcedureDoneOrFileIsEmpty(svgText, 'scale'): return svgText if repository is None: repository = settings.getReadRepository(ScaleRepository()) if repository.activateScale.value: return ScaleSkein().getCraftedGcode(fileName, repository, svgText) return svgText def getNewRepository(): 'Get new repository.' return ScaleRepository() def setLoopLayerScale(loopLayer, xyPlaneScale, zAxisScale): "Set the slice element scale." for loop in loopLayer.loops: for pointIndex in xrange(len(loop)): loop[pointIndex] *= xyPlaneScale loopLayer.z *= zAxisScale def writeOutput(fileName, shouldAnalyze=True): 'Scale the carving.' skeinforge_craft.writeSVGTextWithNounMessage(fileName, ScaleRepository(), shouldAnalyze) class ScaleRepository: "A class to handle the scale settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.scale.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Scale', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Scale') self.activateScale = settings.BooleanSetting().getFromValue('Activate Scale to finetune print size (try to find the fault somewhere else..):', self, False) self.xyPlaneScale = settings.FloatSpin().getFromValue(0.99, 'XY Plane Scale (ratio):', self, 1.03, 1.01) self.zAxisScale = settings.FloatSpin().getFromValue(0.99, 'Z Axis Scale (ratio):', self, 1.02, 1.0) self.svgViewer = settings.StringSetting().getFromValue('SVG Viewer:', self, 'webbrowser') self.executeTitle = 'Scale' def execute(self): "Scale button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class ScaleSkein: "A class to scale a skein of extrusions." def getCraftedGcode(self, fileName, repository, svgText): "Parse svgText and store the scale svgText." svgReader = SVGReader() svgReader.parseSVG('', svgText) if svgReader.sliceDictionary is None: print('Warning, nothing will be done because the sliceDictionary could not be found getCraftedGcode in preface.') return '' xyPlaneScale = repository.xyPlaneScale.value zAxisScale = repository.zAxisScale.value decimalPlacesCarried = int(svgReader.sliceDictionary['decimalPlacesCarried']) layerThickness = zAxisScale * float(svgReader.sliceDictionary['layerThickness']) perimeterWidth = float(svgReader.sliceDictionary['perimeterWidth']) loopLayers = svgReader.loopLayers for loopLayer in loopLayers: setLoopLayerScale(loopLayer, xyPlaneScale, zAxisScale) cornerMaximum = Vector3(-912345678.0, -912345678.0, -912345678.0) cornerMinimum = Vector3(912345678.0, 912345678.0, 912345678.0) svg_writer.setSVGCarvingCorners(cornerMaximum, cornerMinimum, layerThickness, loopLayers) svgWriter = svg_writer.SVGWriter( True, cornerMaximum, cornerMinimum, decimalPlacesCarried, layerThickness, perimeterWidth) commentElement = svg_writer.getCommentElement(svgReader.documentElement) procedureNameString = svgReader.sliceDictionary['procedureName'] + ',scale' return svgWriter.getReplacedSVGTemplate(fileName, loopLayers, procedureNameString, commentElement) def main(): "Display the scale dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/skin.py000066400000000000000000000420371167321211700300100ustar00rootroot00000000000000""" This page is in the table of contents. Skin is a plugin to smooth the surface skin of an object by replacing the perimeter surface with a surface printed at a fraction of the carve height. This gives the impression that the object was carved at a much thinner height giving a high-quality finish, but still prints in a relatively short time. The latest process has some similarities with a description at: http://adventuresin3-dprinting.blogspot.com/2011/05/skinning.html The skin manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skin ==Operation== The default 'Activate Skin' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Division=== ====Horizontal Infill Divisions==== Default: 2 Defines the number of times the skinned infill is divided horizontally. ====Horizontal Perimeter Divisions==== Default: 1 Defines the number of times the skinned perimeters are divided horizontally. ====Vertical Divisions==== Default: 2 Defines the number of times the skinned infill and perimeters are divided vertically. ===Hop When Extruding Infill=== Default is off. When selected, the extruder will hop before and after extruding the lower infill in order to avoid the regular thickness threads. ===Layers From=== Default: 1 Defines which layer of the print the skinning process starts from. It is not wise to set this to zero, skinning the bottom layer is likely to cause the bottom perimeter not to adhere well to the print surface. ==Tips== Due to the very small Z-axis moves skinning can generate as it prints the perimeter, it can cause the Z-axis speed to be limited by the Limit plug-in, if you have it enabled. This can cause some printers to pause excessively during each layer change. To overcome this, ensure that the Z-axis max speed in the Limit tool is set to an appropriate value for your printer, e.g. 10mm/s Since Skin prints a number of fractional-height perimeter layers for each layer, printing the perimeter last causes the print head to travel down from the current print height. Depending on the shape of your extruder nozzle, you may get higher quality prints if you print the perimeters first, so the print head always travels up. This is set via the Thread Sequence Choice setting in the Fill tool. ==Examples== The following examples skin the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and skin.py. > python skin.py This brings up the skin dialog. > python skin.py Screw Holder Bottom.stl The skin tool is parsing the file: Screw Holder Bottom.stl .. The skin tool has created the file: .. Screw Holder Bottom_skin.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique aht yahoo.com) & James Blackwell (jim_blag ahht hotmail.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, gcodeText, repository=None): 'Skin a gcode linear move text.' return getCraftedTextFromText(archive.getTextIfEmpty(fileName, gcodeText), repository) def getCraftedTextFromText(gcodeText, repository=None): 'Skin a gcode linear move text.' if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'skin'): return gcodeText if repository is None: repository = settings.getReadRepository(SkinRepository()) if not repository.activateSkin.value: return gcodeText return SkinSkein().getCraftedGcode(gcodeText, repository) def getIsMinimumSides(loops, sides=3): 'Determine if all the loops have at least the given number of sides.' for loop in loops: if len(loop) < sides: return False return True def getNewRepository(): 'Get new repository.' return SkinRepository() def writeOutput(fileName, shouldAnalyze=True): 'Skin a gcode linear move file. Chain skin the gcode if it is not already skinned.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'skin', shouldAnalyze) class SkinRepository: 'A class to handle the skin settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.skin.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Skin', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skin') self.activateSkin = settings.BooleanSetting().getFromValue('Activate Skin', self, False) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Division -', self) self.horizontalInfillDivisions = settings.IntSpin().getSingleIncrementFromValue(1, 'Horizontal Infill Divisions (integer):', self, 3, 2) self.horizontalPerimeterDivisions = settings.IntSpin().getSingleIncrementFromValue(1, 'Horizontal Perimeter Divisions (integer):', self, 3, 1) self.verticalDivisions = settings.IntSpin().getSingleIncrementFromValue(1, 'Vertical Divisions (integer):', self, 3, 2) settings.LabelSeparator().getFromRepository(self) self.hopWhenExtrudingInfill = settings.BooleanSetting().getFromValue('Hop When Extruding Infill', self, False) self.layersFrom = settings.IntSpin().getSingleIncrementFromValue(0, 'Layers From (index):', self, 912345678, 1) self.executeTitle = 'Skin' def execute(self): 'Skin button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class SkinSkein: 'A class to skin a skein of extrusions.' def __init__(self): 'Initialize.' self.clipOverPerimeterWidth = 0.0 self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRateMinute = 959.0 self.infill = None self.infillBoundaries = None self.infillBoundary = None self.layerIndex = -1 self.lineIndex = 0 self.lines = None self.maximumZFeedRateMinute = 60.0 self.oldFlowRate = None self.oldLocation = None self.perimeter = None self.travelFeedRateMinute = 957.0 def addFlowRateLine(self, flowRate): 'Add a flow rate line.' self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate)) def addPerimeterLoop(self, thread, z): 'Add the perimeter loop to the gcode.' self.distanceFeedRate.addGcodeFromFeedRateThreadZ(self.feedRateMinute, thread, self.travelFeedRateMinute, z) def addSkinnedInfill(self): 'Add skinned infill.' if self.infillBoundaries is None: return bottomZ = self.oldLocation.z + self.layerThickness / self.verticalDivisionsFloat - self.layerThickness offsetY = 0.5 * self.skinInfillWidth self.addFlowRateLine(self.oldFlowRate / self.verticalDivisionsFloat / self.horizontalInfillDivisionsFloat) for verticalDivisionIndex in xrange(self.verticalDivisions): z = bottomZ + self.layerThickness / self.verticalDivisionsFloat * float(verticalDivisionIndex) self.addSkinnedInfillBoundary(self.infillBoundaries, offsetY * (verticalDivisionIndex % 2 == 0), self.oldLocation.z, z) self.addFlowRateLine(self.oldFlowRate) self.infillBoundaries = None def addSkinnedInfillBoundary(self, infillBoundaries, offsetY, upperZ, z): 'Add skinned infill boundary.' aroundInset = 0.24321 * self.skinInfillInset arounds = [] aroundWidth = 0.24321 * self.skinInfillInset endpoints = [] pixelTable = {} rotatedLoops = [] for infillBoundary in infillBoundaries: infillBoundaryRotated = euclidean.getRotatedComplexes(self.reverseRotation, infillBoundary) if offsetY != 0.0: for infillPointRotatedIndex, infillPointRotated in enumerate(infillBoundaryRotated): infillBoundaryRotated[infillPointRotatedIndex] = complex(infillPointRotated.real, infillPointRotated.imag - offsetY) rotatedLoops.append(infillBoundaryRotated) infillDictionary = triangle_mesh.getInfillDictionary( aroundInset, arounds, aroundWidth, self.skinInfillInset, self.skinInfillWidth, pixelTable, rotatedLoops) for infillDictionaryKey in infillDictionary.keys(): xIntersections = infillDictionary[infillDictionaryKey] xIntersections.sort() for segment in euclidean.getSegmentsFromXIntersections(xIntersections, infillDictionaryKey * self.skinInfillWidth): for endpoint in segment: endpoint.point = complex(endpoint.point.real, endpoint.point.imag + offsetY) endpoints.append(endpoint) infillPaths = euclidean.getPathsFromEndpoints(endpoints, 5.0 * self.skinInfillWidth, pixelTable, aroundWidth) for infillPath in infillPaths: infillRotated = euclidean.getRotatedComplexes(self.rotation, infillPath) if upperZ > z and self.repository.hopWhenExtrudingInfill.value: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, infillRotated[0], upperZ) self.distanceFeedRate.addGcodeFromFeedRateThreadZ(self.feedRateMinute, infillRotated, self.travelFeedRateMinute, z) lastPointRotated = infillRotated[-1] self.oldLocation = Vector3(lastPointRotated.real, lastPointRotated.imag, upperZ) if upperZ > z and self.repository.hopWhenExtrudingInfill.value: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.maximumZFeedRateMinute, lastPointRotated, upperZ) def addSkinnedPerimeter(self): 'Add skinned perimeter.' if self.perimeter is None: return bottomZ = self.oldLocation.z + self.layerThickness / self.verticalDivisionsFloat - self.layerThickness perimeterThread = self.perimeter[: -1] perimeters = [] radiusAddition = self.perimeterWidth / self.horizontalPerimeterDivisionsFloat radius = 0.5 * radiusAddition - self.halfPerimeterWidth for division in xrange(self.repository.horizontalPerimeterDivisions.value): perimeters.append(self.getClippedSimplifiedLoopPathByLoop(intercircle.getLargestInsetLoopFromLoop(perimeterThread, radius))) radius += radiusAddition skinnedPerimeterFlowRate = self.oldFlowRate / self.verticalDivisionsFloat if getIsMinimumSides(perimeters): self.addFlowRateLine(skinnedPerimeterFlowRate / self.horizontalPerimeterDivisionsFloat) for verticalDivisionIndex in xrange(self.verticalDivisions): z = bottomZ + self.layerThickness / self.verticalDivisionsFloat * float(verticalDivisionIndex) for perimeter in perimeters: self.addPerimeterLoop(perimeter, z) else: self.addFlowRateLine(skinnedPerimeterFlowRate) for verticalDivisionIndex in xrange(self.verticalDivisions): z = bottomZ + self.layerThickness / self.verticalDivisionsFloat * float(verticalDivisionIndex) self.addPerimeterLoop(self.perimeter, z) self.addFlowRateLine(self.oldFlowRate) self.perimeter = None def getClippedSimplifiedLoopPathByLoop(self, loop): 'Get clipped and simplified loop path from a loop.' if len(loop) == 0: return [] loopPath = loop + [loop[0]] return euclidean.getClippedSimplifiedLoopPath(self.clipLength, loopPath, self.halfPerimeterWidth) def getCraftedGcode( self, gcodeText, repository ): 'Parse gcode text and store the skin gcode.' self.lines = archive.getTextLines(gcodeText) self.repository = repository self.layersFromBottom = repository.layersFrom.value self.horizontalInfillDivisionsFloat = float(repository.horizontalInfillDivisions.value) self.horizontalPerimeterDivisionsFloat = float(repository.horizontalPerimeterDivisions.value) self.verticalDivisions = max(repository.verticalDivisions.value, 1) self.verticalDivisionsFloat = float(self.verticalDivisions) self.parseInitialization() self.clipLength = 0.5 * self.clipOverPerimeterWidth * self.perimeterWidth self.skinInfillInset = 0.5 * (self.infillWidth + self.skinInfillWidth) * (1.0 - self.infillPerimeterOverlap) self.parseBoundaries() for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue()) def parseBoundaries(self): 'Parse the boundaries and add them to the boundary layers.' self.boundaryLayers = [] self.layerIndexTop = -1 boundaryLoop = None boundaryLayer = None for line in self.lines[self.lineIndex :]: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '()': boundaryLoop = None elif firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) if boundaryLoop is None: boundaryLoop = [] boundaryLayer.loops.append(boundaryLoop) boundaryLoop.append(location.dropAxis()) elif firstWord == '(': boundaryLayer = euclidean.LoopLayer(float(splitLine[1])) self.boundaryLayers.append(boundaryLayer) self.layerIndexTop += 1 for boundaryLayerIndex, boundaryLayer in enumerate(self.boundaryLayers): if len(boundaryLayer.loops) > 0: self.layersFromBottom += boundaryLayerIndex return def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '(': self.clipOverPerimeterWidth = float(splitLine[1]) elif firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('skin') return elif firstWord == '(': self.infillPerimeterOverlap = float(splitLine[1]) elif firstWord == '(': self.infillWidth = float(splitLine[1]) self.skinInfillWidth = self.infillWidth / self.horizontalInfillDivisionsFloat elif firstWord == '(': self.layerThickness = float(splitLine[1]) elif firstWord == '(': self.maximumZFeedRateMinute = 60.0 * float(splitLine[1]) elif firstWord == '(': self.oldFlowRate = float(splitLine[1]) elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.halfPerimeterWidth = 0.5 * self.perimeterWidth elif firstWord == '(': self.travelFeedRateMinute = 60.0 * float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): 'Parse a gcode line and add it to the skin skein.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.oldLocation = location if self.infillBoundaries is not None: return if self.perimeter is not None: self.perimeter.append(location.dropAxis()) return elif firstWord == '()': if self.layerIndex >= self.layersFromBottom and self.layerIndex == self.layerIndexTop: self.infillBoundaries = [] elif firstWord == '()': self.addSkinnedInfill() elif firstWord == '()': if self.infillBoundaries is not None: self.infillBoundary = [] self.infillBoundaries.append(self.infillBoundary) elif firstWord == '(': if self.infillBoundaries is not None: location = gcodec.getLocationFromSplitLine(None, splitLine) self.infillBoundary.append(location.dropAxis()) elif firstWord == '(': self.layerIndex += 1 settings.printProgress(self.layerIndex, 'skin') elif firstWord == 'M101' or firstWord == 'M103': if self.infillBoundaries is not None or self.perimeter is not None: return elif firstWord == 'M108': self.oldFlowRate = gcodec.getDoubleAfterFirstLetter(splitLine[1]) elif firstWord == '(': if self.layerIndex >= self.layersFromBottom: self.perimeter = [] elif firstWord == '(': self.rotation = gcodec.getRotationBySplitLine(splitLine) self.reverseRotation = complex(self.rotation.real, -self.rotation.imag) elif firstWord == '()': self.addSkinnedPerimeter() self.distanceFeedRate.addLine(line) def main(): 'Display the skin dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/skirt.py000066400000000000000000000351061167321211700301770ustar00rootroot00000000000000""" This page is in the table of contents. Skirt is a plugin to give the extruder some extra time to begin extruding properly before beginning the object, and to put a baffle around the model in order to keep the extrusion warm. The skirt manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skirt It is loosely based on Lenbook's outline plugin: http://www.thingiverse.com/thing:4918 it is also loosely based on the outline that Nophead sometimes uses: http://hydraraptor.blogspot.com/2010/01/hot-metal-and-serendipity.html and also loosely based on the baffles that Nophead made to keep corners warm: http://hydraraptor.blogspot.com/2010/09/some-corners-like-it-hot.html If you want only an outline, set 'Layers To' to one. This gives the extruder some extra time to begin extruding properly before beginning your object, and gives you an early verification of where your object will be extruded. If you also want an insulating skirt around the entire object, set 'Layers To' to a huge number, like 912345678. This will additionally make an insulating baffle around the object; to prevent moving air from cooling the object, which increases warping, especially in corners. ==Operation== The default 'Activate Skirt' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Convex=== Default is on. When selected, the skirt will be convex, going around the model with only convex angles. If convex is not selected, the skirt will hug the model, going into every nook and cranny. ===Gap over Perimeter Width=== Default is three. Defines the ratio of the gap between the object and the skirt over the perimeter width. If the ratio is too low, the skirt will connect to the object, if the ratio is too high, the skirt willl not provide much insulation for the object. ===Layers To=== Default is a one. Defines the number of layers of the skirt. If you want only an outline, set 'Layers To' to one. If you want an insulating skirt around the entire object, set 'Layers To' to a huge number, like 912345678. ==Examples== The following examples skirt the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and skirt.py. > python skirt.py This brings up the skirt dialog. > python skirt.py Screw Holder Bottom.stl The skirt tool is parsing the file: Screw Holder Bottom.stl .. The skirt tool has created the file: .. Screw Holder Bottom_skirt.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, text='', repository=None): 'Skirt the fill file or text.' return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): 'Skirt the fill text.' if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'skirt'): return gcodeText if repository is None: repository = settings.getReadRepository(SkirtRepository()) if not repository.activateSkirt.value: return gcodeText return SkirtSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return SkirtRepository() def getOuterLoops(loops): 'Get widdershins outer loops.' outerLoops = [] for loop in loops: if not euclidean.isPathInsideLoops(outerLoops, loop): outerLoops.append(loop) intercircle.directLoops(True, outerLoops) return outerLoops def writeOutput(fileName, shouldAnalyze=True): 'Skirt a gcode linear move file.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'skirt', shouldAnalyze) class LoopCrossDictionary: 'Loop with a horizontal and vertical dictionary.' def __init__(self): 'Initialize LoopCrossDictionary.' self.loop = [] def __repr__(self): 'Get the string representation of this LoopCrossDictionary.' return str(self.loop) class SkirtRepository: 'A class to handle the skirt settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.skirt.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Skirt', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Skirt') self.activateSkirt = settings.BooleanSetting().getFromValue('Activate Skirt', self, True) self.convex = settings.BooleanSetting().getFromValue('Convex:', self, True) self.gapOverPerimeterWidth = settings.FloatSpin().getFromValue( 1.0, 'Gap over Perimeter Width (ratio):', self, 10.0, 5.0) self.layersTo = settings.IntSpin().getSingleIncrementFromValue(0, 'Layers To (index):', self, 912345678, 1) self.boundaryCheck = settings.BooleanSetting().getFromValue('Check for Limits:', self, True) self.executeTitle = 'Skirt' def execute(self): 'Skirt button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class SkirtSkein: 'A class to skirt a skein of extrusions.' def __init__(self): 'Initialize variables.' self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRateMinute = 961.0 self.isExtruderActive = False self.isSupportLayer = False self.layerCount = settings.LayerCount() self.layerIndex = -1 self.lineIndex = 0 self.lines = None self.oldFlowRate = None self.oldLocation = None self.oldTemperatureInput = None self.skirtFlowRate = None self.skirtTemperature = None self.travelFeedRateMinute = 957.0 self.unifiedLoop = LoopCrossDictionary() def addFlowRate(self, flowRate): 'Add a line of temperature if different.' if flowRate is not None: self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate)) def addSkirt(self, z): 'At skirt at z to gcode output.' self.setSkirtFeedFlowTemperature() self.distanceFeedRate.addLine('()') oldTemperature = self.oldTemperatureInput self.addTemperatureLineIfDifferent(self.skirtTemperature) self.addFlowRate(self.skirtFlowRate) for outsetLoop in self.outsetLoops: closedLoop = outsetLoop + [outsetLoop[0]] self.distanceFeedRate.addGcodeFromFeedRateThreadZ(self.feedRateMinute, closedLoop, self.travelFeedRateMinute, z) self.addFlowRate(self.oldFlowRate) self.addTemperatureLineIfDifferent(oldTemperature) self.distanceFeedRate.addLine('()') def addTemperatureLineIfDifferent(self, temperature): 'Add a line of temperature if different.' if temperature is None or temperature == self.oldTemperatureInput: return self.distanceFeedRate.addLine('M104 S' + euclidean.getRoundedToThreePlaces(temperature)) self.oldTemperatureInput = temperature def createSegmentDictionaries(self, loopCrossDictionary): 'Create horizontal and vertical segment dictionaries.' loopCrossDictionary.horizontalDictionary = self.getHorizontalXIntersectionsTable(loopCrossDictionary.loop) flippedLoop = euclidean.getDiagonalFlippedLoop(loopCrossDictionary.loop) loopCrossDictionary.verticalDictionary = self.getHorizontalXIntersectionsTable(flippedLoop) def createSkirtLoops(self): 'Create the skirt loops.' points = euclidean.getPointsByHorizontalDictionary(self.perimeterWidth, self.unifiedLoop.horizontalDictionary) points += euclidean.getPointsByVerticalDictionary(self.perimeterWidth, self.unifiedLoop.verticalDictionary) loops = triangle_mesh.getDescendingAreaOrientedLoops(points, points, 2.5 * self.perimeterWidth) outerLoops = getOuterLoops(loops) outsetLoops = intercircle.getInsetSeparateLoopsFromLoops(outerLoops, -self.skirtOutset) self.outsetLoops = getOuterLoops(outsetLoops) if self.repository.convex.value: self.outsetLoops = [euclidean.getLoopConvex(euclidean.getConcatenatedList(self.outsetLoops))] def getCraftedGcode(self, gcodeText, repository): 'Parse gcode text and store the skirt gcode.' self.repository = repository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() self.parseBoundaries() self.createSkirtLoops() for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue()) def getHorizontalXIntersectionsTable(self, loop): 'Get the horizontal x intersections table from the loop.' horizontalXIntersectionsTable = {} euclidean.addXIntersectionsFromLoopForTable(loop, horizontalXIntersectionsTable, self.perimeterWidth) return horizontalXIntersectionsTable def parseBoundaries(self): 'Parse the boundaries and union them.' self.createSegmentDictionaries(self.unifiedLoop) if self.repository.layersTo.value < 1: return loopCrossDictionary = None layerIndex = -1 for line in self.lines[self.lineIndex :]: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == '()' or firstWord == '()': self.createSegmentDictionaries(loopCrossDictionary) self.unifyLayer(loopCrossDictionary) loopCrossDictionary = None elif firstWord == '(' or firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) if not loopCrossDictionary : loopCrossDictionary = LoopCrossDictionary() loopCrossDictionary.loop.append(location.dropAxis()) elif firstWord == '(': layerIndex += 1 if layerIndex > self.repository.layersTo.value: return settings.printProgress(layerIndex, 'skirt') def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('skirt') return elif firstWord == '(': self.oldTemperatureInput = float(splitLine[1]) self.skirtTemperature = self.oldTemperatureInput elif firstWord == '(':#todo make it firstlayer self.feedRateMinute = 60.0 * float(splitLine[1]) elif firstWord == '(': self.oldFlowRate = float(splitLine[1]) self.skirtFlowRate = self.oldFlowRate elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.skirtOutset = (self.repository.gapOverPerimeterWidth.value + 0.5) * self.perimeterWidth self.distanceFeedRate.addTagRoundedLine('skirtOutset', self.skirtOutset) elif firstWord == '(':#todo make it firstlayer self.travelFeedRateMinute = 60.0 * float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): 'Parse a gcode line and add it to the skirt skein.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == '()' or firstWord == '()' or firstWord == '(': return self.distanceFeedRate.addLine(line) if firstWord == 'G1': self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) elif firstWord == '(': self.layerIndex += 1 if self.layerIndex < self.repository.layersTo.value: self.addSkirt(float(splitLine[1])) elif firstWord == 'M101': self.isExtruderActive = True elif firstWord == 'M103': self.isExtruderActive = False elif firstWord == 'M104': self.oldTemperatureInput = gcodec.getDoubleAfterFirstLetter(splitLine[1]) self.skirtTemperature = self.oldTemperatureInput elif firstWord == 'M108': self.oldFlowRate = gcodec.getDoubleAfterFirstLetter(splitLine[1]) self.skirtFlowRate = self.oldFlowRate elif firstWord == '()': self.isSupportLayer = True elif firstWord == '()': self.isSupportLayer = False def setSkirtFeedFlowTemperature(self): 'Set the skirt feed rate, flow rate and temperature to that of the next extrusion.' isExtruderActive = self.isExtruderActive isSupportLayer = self.isSupportLayer for lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) if isExtruderActive: if not isSupportLayer: return elif firstWord == 'M101': isExtruderActive = True elif firstWord == 'M103': isExtruderActive = False elif firstWord == 'M104': self.skirtTemperature = gcodec.getDoubleAfterFirstLetter(splitLine[1]) elif firstWord == 'M108': self.skirtFlowRate = gcodec.getDoubleAfterFirstLetter(splitLine[1]) elif firstWord == '()': isSupportLayer = True elif firstWord == '()': isSupportLayer = False def unifyLayer(self, loopCrossDictionary): 'Union the loopCrossDictionary with the unifiedLoop.' euclidean.joinXIntersectionsTables(loopCrossDictionary.horizontalDictionary, self.unifiedLoop.horizontalDictionary) euclidean.joinXIntersectionsTables(loopCrossDictionary.verticalDictionary, self.unifiedLoop.verticalDictionary) def main(): 'Display the skirt dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/smooth.py000066400000000000000000000245361167321211700303610ustar00rootroot00000000000000""" This page is in the table of contents. This plugin smooths jagged extruder paths. It takes shortcuts through jagged paths and decreases the feed rate to compensate. Smooth is based on ideas in Nophead's frequency limit post: http://hydraraptor.blogspot.com/2010/12/frequency-limit.html The smooth manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Smooth ==Operation== The default 'Activate Smooth' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Layers From=== Default: 1 Defines which layer of the print the smoothing process starts from. If this is set this to zero, that might cause the smoothed parts of the bottom perimeter not to adhere well to the print surface. However, this is just a potential problem in theory, no bottom adhesion problem has been reported. ===Maximum Shortening over Width=== Default: 1.2 Defines the maximum shortening of the shortcut compared to the original path. Smooth goes over the path and if the shortcut between the midpoint of one line and the midpoint of the second line after is not too short compared to the original and the shortcut is not too long, it replaces the jagged original with the shortcut. If the maximum shortening is too much, smooth will shorten paths which should not of been shortened and will leave blobs and holes in the model. If the maximum shortening is too little, even jagged paths that could be shortened safely won't be smoothed. ==Examples== The following examples smooth the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and smooth.py. > python smooth.py This brings up the smooth dialog. > python smooth.py Screw Holder Bottom.stl The smooth tool is parsing the file: Screw Holder Bottom.stl .. The smooth tool has created the file: .. Screw Holder Bottom_smooth.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique aht yahoo.com) & James Blackwell (jim_blag ahht hotmail.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, gcodeText, repository=None): 'Smooth a gcode linear move text.' return getCraftedTextFromText(archive.getTextIfEmpty(fileName, gcodeText), repository) def getCraftedTextFromText(gcodeText, repository=None): 'Smooth a gcode linear move text.' if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'smooth'): return gcodeText if repository is None: repository = settings.getReadRepository(SmoothRepository()) if not repository.activateSmooth.value: return gcodeText return SmoothSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return SmoothRepository() def writeOutput(fileName, shouldAnalyze=True): 'Smooth a gcode linear move file. Chain smooth the gcode if it is not already smoothed.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'smooth', shouldAnalyze) class SmoothRepository: 'A class to handle the smooth settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.smooth.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Smooth', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Smooth') self.activateSmooth = settings.BooleanSetting().getFromValue('Activate Smooth', self, False) self.layersFrom = settings.IntSpin().getSingleIncrementFromValue(0, 'Layers From (index):', self, 912345678, 1) self.maximumShorteningOverWidth = settings.FloatSpin().getFromValue(0.2, 'Maximum Shortening over Width (float):', self, 2.0, 1.2) self.executeTitle = 'Smooth' def execute(self): 'Smooth button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class SmoothSkein: 'A class to smooth a skein of extrusions.' def __init__(self): 'Initialize.' self.boundaryLayerIndex = -1 self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRateMinute = 959.0 self.infill = None self.layerCount = settings.LayerCount() self.lineIndex = 0 self.lines = None self.oldLocation = None self.travelFeedRateMinute = 957.0 def addSmoothedInfill(self): 'Add smoothed infill.' if len(self.infill) < 4: self.distanceFeedRate.addGcodeFromFeedRateThreadZ(self.feedRateMinute, self.infill, self.travelFeedRateMinute, self.oldLocation.z) return self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.travelFeedRateMinute, self.infill[0], self.oldLocation.z) self.distanceFeedRate.addLine('M101') lengthMinusOne = len(self.infill) - 1 lengthMinusTwo = lengthMinusOne - 1 wasOriginalPoint = True pointIndex = 0 while pointIndex < lengthMinusOne: nextPoint = self.infill[pointIndex + 1] afterNextIndex = pointIndex + 2 if afterNextIndex < lengthMinusTwo: point = self.infill[pointIndex] midpoint = 0.5 * (point + nextPoint) afterNextPoint = self.infill[afterNextIndex] afterNextNextPoint = self.infill[afterNextIndex + 1] afterNextMidpoint = 0.5 * (afterNextPoint + afterNextNextPoint) shortcutDistance = abs(afterNextMidpoint - midpoint) originalDistance = abs(midpoint - point) + abs(afterNextPoint - nextPoint) + abs(afterNextMidpoint - afterNextPoint) segment = euclidean.getNormalized(nextPoint - point) afterNextSegment = euclidean.getNormalized(afterNextNextPoint - afterNextPoint) sameDirection = self.getIsParallelToRotation(segment) and self.getIsParallelToRotation(afterNextSegment) if originalDistance - shortcutDistance < self.maximumShortening and shortcutDistance < self.maximumDistance and sameDirection: if wasOriginalPoint: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, midpoint, self.oldLocation.z) feedrate = self.feedRateMinute if originalDistance != 0.0: feedrate *= shortcutDistance / originalDistance self.distanceFeedRate.addGcodeMovementZWithFeedRate(feedrate, afterNextMidpoint, self.oldLocation.z) wasOriginalPoint = False pointIndex += 1 else: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, nextPoint, self.oldLocation.z) wasOriginalPoint = True else: self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, nextPoint, self.oldLocation.z) wasOriginalPoint = True pointIndex += 1 self.distanceFeedRate.addLine('M103') def getCraftedGcode( self, gcodeText, repository ): 'Parse gcode text and store the smooth gcode.' self.lines = archive.getTextLines(gcodeText) self.repository = repository self.layersFromBottom = repository.layersFrom.value self.parseInitialization() for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getIsParallelToRotation(self, segment): 'Determine if the segment is parallel to the rotation.' return abs(euclidean.getDotProduct(segment, self.rotation)) > 0.99999 def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('smooth') return elif firstWord == '(': self.infillWidth = float(splitLine[1]) self.maximumShortening = self.repository.maximumShorteningOverWidth.value * self.infillWidth self.maximumDistance = 1.5 * self.maximumShortening elif firstWord == '(': self.travelFeedRateMinute = 60.0 * float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): 'Parse a gcode line and add it to the smooth skein.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == '()': if self.boundaryLayerIndex < 0: self.boundaryLayerIndex = 0 elif firstWord == 'G1': self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.oldLocation = location if self.infill is not None: self.infill.append(location.dropAxis()) return elif firstWord == '()': if self.boundaryLayerIndex >= self.layersFromBottom: self.infill = [] elif firstWord == '()': self.infill = None elif firstWord == '(': self.layerCount.printProgressIncrement('smooth') if self.boundaryLayerIndex >= 0: self.boundaryLayerIndex += 1 elif firstWord == 'M101': if self.infill is not None: if len(self.infill) > 1: self.infill = [self.infill[0]] return elif firstWord == 'M103': if self.infill is not None: self.addSmoothedInfill() self.infill = [] return elif firstWord == '(': self.rotation = gcodec.getRotationBySplitLine(splitLine) self.distanceFeedRate.addLine(line) def main(): 'Display the smooth dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/speed.py000066400000000000000000000474401167321211700301470ustar00rootroot00000000000000""" This page is in the table of contents. Speed is a plugin to set the feed rate and flow rate. The speed manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Speed ==Operation== The default 'Activate Speed' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Add Flow Rate=== Default is on. When selected, the flow rate will be added to the gcode. ===Bridge=== ====Bridge Feed Rate Multiplier==== Default is one. Defines the ratio of the feed rate (head speed) on the bridge layers over the feed rate of the typical non bridge layers. ====Bridge Flow Rate Multiplier==== Default is one. Defines the ratio of the flow rate (extruder speed) on the bridge layers over the flow rate of the typical non bridge layers. ===Duty Cyle=== ====Duty Cyle at Beginning==== Default is one, which will set the extruder motor to full current. Defines the duty cycle of the stepper motor pulse width modulation by adding an M113 command toward the beginning of the gcode text. If the hardware has the option of using a potentiometer to set the duty cycle, to select the potentiometer option set 'Duty Cyle at Beginning' to an empty string. To turn off the extruder, set the 'Duty Cyle at Beginning' to zero. ====Duty Cyle at Ending==== Default is zero, which will turn off the extruder motor. Defines the duty cycle of the stepper motor pulse width modulation by adding an M113 command toward the ending of the gcode text. If the hardware has the option of using a potentiometer to set the duty cycle, to select the potentiometer option set 'Duty Cyle at Beginning' to an empty string. To turn off the extruder, set the 'Duty Cyle at Ending' to zero. ===Feed Rate=== Default is sixteen millimeters per second. Defines the operating feed rate, the speed your printing head moves in XY plane, before any modifiers. ===Flow Rate Setting=== Default is 210. Defines the operating flow rate. RapMan uses this parameter to define the RPM of the extruder motor. The extruder motor RPM is flow rate / 10 so if your flow rate is 150.0 that will set the extruder stepper to run at 15 RPM, different printers might read this value differently. ===Maximum Z Feed Rate=== Default is one millimeter per second. Defines the speed of a vertical hop, like the infill hop in skin. Also, if the Limit plugin is activated, it will limit the maximum speed of the tool head in the z direction to this value. ===Object First Layer=== ====Object First Layer Feed Rate Infill Multiplier==== Default is 0.4. Defines the object first layer infill feed rate multiplier. The greater the 'Object First Layer Feed Rate Infill Multiplier, the thinner the infill, the lower the 'Object First Layer Feed Rate Infill Multiplier', the thicker the infill. ====Object First Layer Feed Rate Perimeter Multiplier==== Default is 0.4. Defines the object first layer perimeter feed rate multiplier. The greater the 'Object First Layer Feed Rate Perimeter Multiplier, the thinner the perimeter, the lower the 'Object First Layer Feed Rate Perimeter Multiplier', the thicker the perimeter. ====Object First Layer Flow Rate Infill Multiplier==== Default is 0.4. Defines the object first layer infill flow rate multiplier. The greater the 'Object First Layer Flow Rate Infill Multiplier', the thicker the infill, the lower the 'Object First Layer Flow Rate Infill Multiplier, the thinner the infill. ====Object First Layer Flow Rate Perimeter Multiplier==== Default is 0.4. Defines the object first layer perimeter flow rate multiplier. The greater the 'Object First Layer Flow Rate Perimeter Multiplier', the thicker the perimeter, the lower the 'Object First Layer Flow Rate Perimeter Multiplier, the thinner the perimeter. ===Orbital Feed Rate over Operating Feed Rate=== Default is 0.5. Defines the speed when the head is orbiting compared to the operating extruder speed. If you want the orbit to be very short, set the "Orbital Feed Rate over Operating Feed Rate" setting to a low value like 0.1. ===Perimeter=== To have higher build quality on the outside at the expense of slower build speed, a typical setting for the 'Perimeter Feed Rate over Operating Feed Rate' would be 0.5. To go along with that, if you are using a speed controlled extruder like a stepper extruder, the 'Perimeter Flow Rate over Operating Flow Rate' should also be 0.5. A stepper motor is the best way of driving the extruder; however, if you are stuck with a DC motor extruder using Pulse Width Modulation to control the speed, then you'll probably need a slightly higher ratio because there is a minimum voltage 'Flow Rate PWM Setting' required for the extruder motor to turn. The flow rate PWM ratio would be determined by trial and error, with the first trial being: Perimeter Flow Rate over Operating Flow Rate ~ Perimeter Feed Rate over Operating Feed Rate * (Flow Rate PWM Setting - Minimum Flow Rate PWM Setting) + Minimum Flow Rate PWM Setting ====Perimeter Feed Rate Multiplier==== Default: 1.0 Defines the ratio of the feed rate of the perimeter (outside shell) over the feed rate of the infill. If you for example set this to 0.8 you will have a "stronger" outside edge than inside extrusion as the outside edge will be printed slower hence better lamination will occur and more filament will be placed there. ====Perimeter Flow Rate Multiplier==== Default: 1.0 Defines the ratio of the flow rate of the perimeter (outside shell) over the flow rate of the infill. If you want the same thickness of the perimeter but better lamination you need to compensate for the slower feed rate by slowing down the flow rate, but all combinations are possible for different results. ===Travel Feed Rate=== Default is sixteen millimeters per second. Defines the feed rate when the extruder is off (not printing). The 'Travel Feed Rate' could be set as high as the extruder can be moved, it is not limited by the maximum extrusion rate. ==Examples== The following examples speed the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and speed.py. > python speed.py This brings up the speed dialog. > python speed.py Screw Holder Bottom.stl The speed tool is parsing the file: Screw Holder Bottom.stl .. The speed tool has created the file: .. Screw Holder Bottom_speed.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text='', repository=None): "Speed the file or text." return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): "Speed a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'speed'): return gcodeText if repository is None: repository = settings.getReadRepository( SpeedRepository() ) if not repository.activateSpeed.value: return gcodeText return SpeedSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return SpeedRepository() def writeOutput(fileName, shouldAnalyze=True): "Speed a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'speed', shouldAnalyze) class SpeedRepository: "A class to handle the speed settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.speed.html', self ) self.baseNameSynonym = 'raft.csv' self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Speed', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Speed') self.activateSpeed = settings.BooleanSetting().getFromValue('Activate Speed', self, True ) self.addFlowRate = settings.BooleanSetting().getFromValue('Add Flow Rate:', self, True ) self.addAccelerationRate = settings.BooleanSetting().getFromValue('Add Acceleration Rate:', self, False ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Main Feedrate Settings -', self ) self.feedRatePerSecond = settings.FloatSpin().getFromValue( 20, 'Main Feed Rate (mm/s):', self, 140, 60 ) self.flowRateSetting = settings.FloatSpin().getFromValue( 0.5, 'Main Flow Rate (scaler):', self, 1.5, 1.0 ) self.accelerationRate = settings.FloatSpin().getFromValue( 500, 'Main Acceleration Rate for Extruder (mm/s2):', self, 10000, 300 ) self.orbitalFeedRateOverOperatingFeedRate = settings.FloatSpin().getFromValue( 0.1, 'Feed Rate ratio for Orbiting move (ratio):', self, 0.9, 0.5 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Perimeter Printing -', self ) self.perimeterFeedRateMultiplier = settings.FloatSpin().getFromValue( 20, 'Perimeter Feed Rate (mm/s):', self, 80, 30 ) self.perimeterFlowRateMultiplier = settings.FloatSpin().getFromValue( 0.5, 'Perimeter Flow Rate (scaler):', self, 1.5, 1.0 ) self.perimeterAccelerationRate = settings.FloatSpin().getFromValue( 5, 'Perimeter Acceleration Rate for Extruder (mm/s2):', self, 10000, 50 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Object First Layer -', self) self.objectFirstLayerFeedRateInfillMultiplier = settings.FloatSpin().getFromValue(5, 'First Layer Main Feed Rate(mm/sec):', self, 100, 25) self.objectFirstLayerFeedRatePerimeterMultiplier = settings.FloatSpin().getFromValue(5, 'First Layer Perimeter Feed Rate (mm/sec):', self, 50 , 15) self.objectFirstLayerFlowRateInfillMultiplier = settings.FloatSpin().getFromValue(0.8, 'First Layer Main Flow Rate Infill Multiplier (ratio):', self, 2.0, 1.0) self.objectFirstLayerFlowRatePerimeterMultiplier = settings.FloatSpin().getFromValue(0.8, 'First Layer Perimeter Flow Rate Multiplier (ratio):', self, 2.0, 1.0) self.objectFirstLayerTravelSpeed = settings.FloatSpin().getFromValue(10, 'First Layer Travel Feedrate:', self, 100, 50) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Travel Moves -', self ) self.maximumZFeedRatePerSecond = settings.FloatSpin().getFromValue(0.5, 'Maximum Z Feed Rate (mm/s):', self, 10.0, 1.0) settings.LabelSeparator().getFromRepository(self) self.travelFeedRatePerSecond = settings.FloatSpin().getFromValue( 40, 'Travel Feed Rate (mm/s):', self, 300, 100 ) settings.LabelDisplay().getFromName('- Duty Cyle for DC extruders only -', self ) self.dutyCycleAtBeginning = settings.FloatSpin().getFromValue( 0.0, 'Duty Cyle at Beginning (portion):', self, 1.0, 1.0 ) self.dutyCycleAtEnding = settings.FloatSpin().getFromValue( 0.0, 'Duty Cyle at Ending (portion):', self, 1.0, 0.0 ) self.executeTitle = 'Speed' settings.LabelDisplay().getFromName('- Bridge Layers -', self ) self.bridgeFeedRateMultiplier = settings.FloatSpin().getFromValue( 0.5, 'Bridge Feed Rate (ratio to Perim.feed):', self, 1.5, 1.0 ) self.bridgeFlowRateMultiplier = settings.FloatSpin().getFromValue( 0.5, 'Bridge Flow Rate (scaler):', self, 1.3, 1.05 ) self.bridgeAccelerationRate = settings.FloatSpin().getFromValue( 10, 'Bridge Acceleration Rate for Extruder(mm/s2):', self, 10000, 50 ) def execute(self): "Speed button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class SpeedSkein: "A class to speed a skein of extrusions." def __init__(self): 'Initialize.' self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRatePerSecond = 16.0 self.isBridgeLayer = False self.isExtruderActive = False self.isPerimeterPath = False self.layerIndex = -1 self.lineIndex = 0 self.lines = None self.oldFlowRate = None self.oldAccelerationRate = None def addFlowRateLine(self): "Add flow rate line." if not self.repository.addFlowRate.value: return flowRate = self.repository.flowRateSetting.value self.nozzleXsection = (self.nozzleDiameter/2) ** 2 * math.pi extrusionXsection = ((self.absolutePerimeterWidth + self.layerThickness)/4) ** 2 * math.pi#todo transfer to inset if self.isBridgeLayer: flowRate = self.repository.bridgeFlowRateMultiplier.value * self.repository.perimeterFlowRateMultiplier.value # flowRate = self.repository.bridgeFlowRateMultiplier.value * self.repository.perimeterFlowRateMultiplier.value * (self.nozzleXsection / extrusionXsection) if self.isPerimeterPath: flowRate = self.repository.perimeterFlowRateMultiplier.value if self.layerIndex == 0: if self.isPerimeterPath: flowRate *= self.repository.objectFirstLayerFlowRatePerimeterMultiplier.value else: flowRate *= self.repository.objectFirstLayerFlowRateInfillMultiplier.value if flowRate != self.oldFlowRate: self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate)) self.oldFlowRate = flowRate def addAccelerationRateLine(self): "Add Accelerationrate line." if not self.repository.addAccelerationRate.value: return accelerationRate = self.repository.accelerationRate.value if self.isBridgeLayer: accelerationRate = self.repository.bridgeAccelerationRate.value * self.repository.perimeterAccelerationRate.value if self.isPerimeterPath: accelerationRate = self.repository.perimeterAccelerationRate.value if accelerationRate != self.oldAccelerationRate: self.distanceFeedRate.addLine('M201 E' + euclidean.getFourSignificantFigures(accelerationRate)) self.oldAccelerationRate = accelerationRate def addParameterString( self, firstWord, parameterWord ): "Add parameter string." if parameterWord == '': self.distanceFeedRate.addLine(firstWord) return self.distanceFeedRate.addParameter( firstWord, parameterWord ) def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the speed gcode." self.repository = repository self.feedRatePerSecond = repository.feedRatePerSecond.value self.travelFeedRateMinute = 60.0 * self.repository.travelFeedRatePerSecond.value self.lines = archive.getTextLines(gcodeText) self.parseInitialization() for line in self.lines[self.lineIndex :]: self.parseLine(line) self.addParameterString('M113', self.repository.dutyCycleAtEnding.value ) # Set duty cycle . return self.distanceFeedRate.output.getvalue() def getSpeededLine(self, line, splitLine): 'Get gcode line with feed rate.' if gcodec.getIndexOfStartingWithSecond('F', splitLine) > 0: return line tempfeedRateMinute = 60.0 * self.feedRatePerSecond travelFeedRateMinute = self.repository.travelFeedRatePerSecond.value * 60 if self.layerIndex <= 0: travelFeedRateMinute = self.repository.objectFirstLayerTravelSpeed.value * 60 if self.isPerimeterPath: tempfeedRateMinute = self.repository.objectFirstLayerFeedRatePerimeterMultiplier.value * 60 else: tempfeedRateMinute = self.repository.objectFirstLayerFeedRateInfillMultiplier.value * 60 elif self.layerIndex > 0: travelFeedRateMinute = self.repository.travelFeedRatePerSecond.value * 60 if self.isPerimeterPath: tempfeedRateMinute = self.repository.perimeterFeedRateMultiplier.value * 60 if self.isBridgeLayer: tempfeedRateMinute = self.repository.bridgeFeedRateMultiplier.value * self.repository.perimeterFeedRateMultiplier.value * 60 if self.isExtruderActive is True: feedRateMinute = tempfeedRateMinute if self.isExtruderActive is False: feedRateMinute = travelFeedRateMinute self.addFlowRateLine() self.addAccelerationRateLine() return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line , splitLine) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '(': self.layerThickness = float(splitLine[1]) elif firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('speed') return elif firstWord == '(': self.absolutePerimeterWidth = abs(float(splitLine[1])) self.distanceFeedRate.addTagBracketedLine('maximumZTravelFeedRatePerSecond', self.repository.maximumZFeedRatePerSecond.value ) self.distanceFeedRate.addTagBracketedLine('objectFirstLayerFeedRateInfillMultiplier', self.repository.objectFirstLayerFeedRateInfillMultiplier.value) self.distanceFeedRate.addTagBracketedLine('operatingFeedRatePerSecond', self.feedRatePerSecond ) self.distanceFeedRate.addTagBracketedLine('perimeterFeedRatePerSecond', self.repository.perimeterFeedRateMultiplier.value )#todo comment? if self.repository.addFlowRate.value: self.distanceFeedRate.addTagBracketedLine('objectFirstLayerFlowRateInfillMultiplier', self.repository.objectFirstLayerFlowRateInfillMultiplier.value) self.distanceFeedRate.addTagBracketedLine('operatingFlowRate', self.repository.flowRateSetting.value ) orbitalFeedRatePerSecond = self.feedRatePerSecond * self.repository.orbitalFeedRateOverOperatingFeedRate.value self.distanceFeedRate.addTagBracketedLine('orbitalFeedRatePerSecond', orbitalFeedRatePerSecond ) self.distanceFeedRate.addTagBracketedLine('travelFeedRatePerSecond', self.repository.travelFeedRatePerSecond.value ) self.distanceFeedRate.addTagBracketedLine('firstLayertravelFeedRatePerSecond', self.repository.objectFirstLayerTravelSpeed.value ) elif firstWord == '(': self.nozzleDiameter = float(splitLine[1]) elif firstWord == '(': self.nozzleXsection = float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the speed skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == '(': self.isBridgeLayer = True if firstWord == '()': self.distanceFeedRate.addLine(line) self.addParameterString('M113', self.repository.dutyCycleAtBeginning.value ) # Set duty cycle . return elif firstWord == 'G1': line = self.getSpeededLine(line, splitLine) elif firstWord == 'M101': self.isExtruderActive = True elif firstWord == 'M103': self.isExtruderActive = False elif firstWord == '(': self.layerIndex += 1 settings.printProgress(self.layerIndex, 'speed') self.isBridgeLayer = False self.addFlowRateLine() self.addAccelerationRateLine() elif firstWord == '(' or firstWord == '()': self.isPerimeterPath = True elif firstWord == '()' or firstWord == '()': self.isPerimeterPath = False self.distanceFeedRate.addLine(line) def main(): "Display the speed dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/splodge.py000066400000000000000000000351171167321211700305020ustar00rootroot00000000000000""" This page is in the table of contents. Splodge turns the extruder on just before the start of a thread. This is to give the extrusion a bit anchoring at the beginning. The splodge manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Splodge ==Operation== The default 'Activate Splodge' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Initial=== ====Initial Lift over Extra Thickness==== Default is one. Defines the amount the extruder will be lifted over the extra thickness of the initial splodge thread. The higher the ratio, the more the extruder will be lifted over the splodge, if the ratio is too low the extruder might plow through the splodge extrusion. ====Initial Splodge Feed Rate==== Default is one millimeter per second. Defines the feed rate at which the initial extra extrusion will be added. With the default feed rate, the splodge will be added slower so it will be thicker than the regular extrusion. ====Initial Splodge Quantity Length==== Default is thirty millimeters. Defines the quantity length of extra extrusion at the operating feed rate that will be added to the initial thread. If a splodge quantity length is smaller than 0.1 times the perimeter width, no splodge of that type will be added. ===Operating=== ====Operating Lift over Extra Thickness==== Default is one. Defines the amount the extruder will be lifted over the extra thickness of the operating splodge thread. ====Operating Splodge Feed Rate==== Default is one millimeter per second. Defines the feed rate at which the next extra extrusions will be added. ====Operating Splodge Quantity Length==== Default is thirty millimeters. Defines the quantity length of extra extrusion at the operating feed rate that will be added for the next threads. ==Examples== The following examples splodge the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and splodge.py. > python splodge.py This brings up the splodge dialog. > python splodge.py Screw Holder Bottom.stl The splodge tool is parsing the file: Screw Holder Bottom.stl .. The splodge tool has created the file: .. Screw Holder Bottom_splodge.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, splodgeRepository = None ): "Splodge a gcode linear move file or text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), splodgeRepository ) def getCraftedTextFromText( gcodeText, splodgeRepository = None ): "Splodge a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'splodge'): return gcodeText if splodgeRepository is None: splodgeRepository = settings.getReadRepository( SplodgeRepository() ) if not splodgeRepository.activateSplodge.value: return gcodeText return SplodgeSkein().getCraftedGcode( gcodeText, splodgeRepository ) def getNewRepository(): 'Get new repository.' return SplodgeRepository() def writeOutput(fileName, shouldAnalyze=True): "Splodge a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'splodge', shouldAnalyze) class SplodgeRepository: "A class to handle the splodge settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.splodge.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Splodge', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Splodge') self.activateSplodge = settings.BooleanSetting().getFromValue('Activate Splodge', self, False ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Initial -', self ) self.initialLiftOverExtraThickness = settings.FloatSpin().getFromValue( 0.5, 'Initial Lift over Extra Thickness (ratio):', self, 1.5, 1.0 ) self.initialSplodgeFeedRate = settings.FloatSpin().getFromValue( 0.4, 'Initial Splodge Feed Rate (mm/s):', self, 2.4, 1.0 ) self.initialSplodgeQuantityLength = settings.FloatSpin().getFromValue( 10.0, 'Initial Splodge Quantity Length (millimeters):', self, 90.0, 30.0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Operating -', self ) self.operatingLiftOverExtraThickness = settings.FloatSpin().getFromValue( 0.5, 'Operating Lift over Extra Thickness (ratio):', self, 1.5, 1.0 ) self.operatingSplodgeFeedRate = settings.FloatSpin().getFromValue( 0.4, 'Operating Splodge Feed Rate (mm/s):', self, 2.4, 1.0 ) self.operatingSplodgeQuantityLength = settings.FloatSpin().getFromValue( 0.4, 'Operating Splodge Quantity Length (millimeters):', self, 2.4, 1.0 ) settings.LabelSeparator().getFromRepository(self) self.executeTitle = 'Splodge' def execute(self): "Splodge button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class SplodgeSkein: "A class to splodge a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRateMinute = 961.0 self.isExtruderActive = False self.hasInitialSplodgeBeenAdded = False self.isLastExtruderCommandActivate = False self.lastLineOutput = None self.lineIndex = 0 self.lines = None self.oldLocation = None self.operatingFeedRatePerSecond = 15.0 def addLineUnlessIdentical(self, line): "Add a line, unless it is identical to the last line." if line == self.lastLineOutput: return self.lastLineOutput = line self.distanceFeedRate.addLine(line) def addLineUnlessIdenticalReactivate(self, line): "Add a line, unless it is identical to the last line or another M101." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'M101': if not self.isLastExtruderCommandActivate: self.addLineUnlessIdentical(line) self.isLastExtruderCommandActivate = True return if firstWord == 'M103': self.isLastExtruderCommandActivate = False self.addLineUnlessIdentical(line) def getCraftedGcode( self, gcodeText, splodgeRepository ): "Parse gcode text and store the splodge gcode." self.lines = archive.getTextLines(gcodeText) self.setRotations() self.splodgeRepository = splodgeRepository self.parseInitialization( splodgeRepository ) self.boundingRectangle = gcodec.BoundingRectangle().getFromGcodeLines( self.lines[self.lineIndex :], 0.5 * self.perimeterWidth ) self.initialSplodgeFeedRateMinute = 60.0 * splodgeRepository.initialSplodgeFeedRate.value self.initialStartupDistance = splodgeRepository.initialSplodgeQuantityLength.value * splodgeRepository.initialSplodgeFeedRate.value / self.operatingFeedRatePerSecond self.operatingSplodgeFeedRateMinute = 60.0 * splodgeRepository.operatingSplodgeFeedRate.value self.operatingStartupDistance = splodgeRepository.operatingSplodgeQuantityLength.value * splodgeRepository.operatingSplodgeFeedRate.value / self.operatingFeedRatePerSecond for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getInitialSplodgeLine( self, line, location ): "Add the initial splodge line." if not self.isJustBeforeExtrusion(): return line self.hasInitialSplodgeBeenAdded = True if self.splodgeRepository.initialSplodgeQuantityLength.value < self.minimumQuantityLength: return line return self.getSplodgeLineGivenDistance( self.initialSplodgeFeedRateMinute, line, self.splodgeRepository.initialLiftOverExtraThickness.value, location, self.initialStartupDistance ) def getNextActiveLocationComplex(self): "Get the next active line." isActive = False for lineIndex in xrange( self.lineIndex + 1, len(self.lines) ): line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'M101': isActive = True if firstWord == 'G1' and isActive: return gcodec.getLocationFromSplitLine(self.oldLocation, splitLine).dropAxis() return None def getOperatingSplodgeLine( self, line, location ): "Get the operating splodge line." if not self.isJustBeforeExtrusion(): return line if self.splodgeRepository.operatingSplodgeQuantityLength.value < self.minimumQuantityLength: return line return self.getSplodgeLineGivenDistance( self.operatingSplodgeFeedRateMinute, line, self.splodgeRepository.operatingLiftOverExtraThickness.value, location, self.operatingStartupDistance ) def getSplodgeLine(self, line, location, splitLine): "Get splodged gcode line." self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) if self.hasInitialSplodgeBeenAdded: return self.getOperatingSplodgeLine(line, location) return self.getInitialSplodgeLine(line, location) def getSplodgeLineGivenDistance( self, feedRateMinute, line, liftOverExtraThickness, location, startupDistance ): "Add the splodge line." locationComplex = location.dropAxis() relativeStartComplex = None nextLocationComplex = self.getNextActiveLocationComplex() if nextLocationComplex is not None: if nextLocationComplex != locationComplex: relativeStartComplex = locationComplex - nextLocationComplex if relativeStartComplex is None: relativeStartComplex = complex( 19.9, 9.9 ) if self.oldLocation is not None: oldLocationComplex = self.oldLocation.dropAxis() if oldLocationComplex != locationComplex: relativeStartComplex = oldLocationComplex - locationComplex relativeStartComplex *= startupDistance / abs( relativeStartComplex ) startComplex = self.getStartInsideBoundingRectangle( locationComplex, relativeStartComplex ) feedRateMultiplier = feedRateMinute / self.operatingFeedRatePerSecond / 60.0 splodgeLayerThickness = self.layerThickness / math.sqrt( feedRateMultiplier ) extraLayerThickness = splodgeLayerThickness - self.layerThickness lift = extraLayerThickness * liftOverExtraThickness startLine = self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( self.feedRateMinute, startComplex, location.z + lift ) self.addLineUnlessIdenticalReactivate( startLine ) self.addLineUnlessIdenticalReactivate('M101') splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) lineLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.distanceFeedRate.addGcodeMovementZWithFeedRate( feedRateMinute, locationComplex, lineLocation.z + lift ) return '' def getStartInsideBoundingRectangle( self, locationComplex, relativeStartComplex ): "Get a start inside the bounding rectangle." startComplex = locationComplex + relativeStartComplex if self.boundingRectangle.isPointInside( startComplex ): return startComplex for rotation in self.rotations: rotatedRelativeStartComplex = relativeStartComplex * rotation startComplex = locationComplex + rotatedRelativeStartComplex if self.boundingRectangle.isPointInside( startComplex ): return startComplex return startComplex def isJustBeforeExtrusion(self): "Determine if activate command is before linear move command." for lineIndex in xrange(self.lineIndex + 1, len(self.lines)): line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1' or firstWord == 'M103': return False if firstWord == 'M101': return True return False def parseInitialization( self, splodgeRepository ): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.addLineUnlessIdenticalReactivate(gcodec.getTagBracketedProcedure('splodge')) return elif firstWord == '(': self.layerThickness = float(splitLine[1]) elif firstWord == '(': self.operatingFeedRatePerSecond = float(splitLine[1]) elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.minimumQuantityLength = 0.1 * self.perimeterWidth self.addLineUnlessIdenticalReactivate(line) def parseLine(self, line): "Parse a gcode line and add it to the bevel gcode." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) line = self.getSplodgeLine(line, location, splitLine) self.oldLocation = location elif firstWord == 'M101': self.isExtruderActive = True elif firstWord == 'M103': self.isExtruderActive = False self.addLineUnlessIdenticalReactivate(line) def setRotations(self): "Set the rotations." self.rootHalf = math.sqrt( 0.5 ) self.rotations = [] self.rotations.append( complex( self.rootHalf, self.rootHalf ) ) self.rotations.append( complex( self.rootHalf, - self.rootHalf ) ) self.rotations.append( complex( 0.0, 1.0 ) ) self.rotations.append( complex(0.0, -1.0) ) self.rotations.append( complex( - self.rootHalf, self.rootHalf ) ) self.rotations.append( complex( - self.rootHalf, - self.rootHalf ) ) def main(): "Display the splodge dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/stretch.py000066400000000000000000000521521167321211700305170ustar00rootroot00000000000000""" This page is in the table of contents. Stretch is very important Skeinforge plugin that allows you to partially compensate for the fact that extruded holes are smaller then they should be. It stretches the threads to partially compensate for filament shrinkage when extruded. The stretch manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Stretch Extruded holes are smaller than the model because while printing an arc the head is depositing filament on both sides of the arc but in the inside of the arc you actually need less material then on the outside of the arc. You can read more about this on the RepRap ArcCompensation page: http://reprap.org/bin/view/Main/ArcCompensation In general, stretch will widen holes and push corners out. In practice the filament contraction will not be identical to the algorithm, so even once the optimal parameters are determined, the stretch script will not be able to eliminate the inaccuracies caused by contraction, but it should reduce them. All the defaults assume that the thread sequence choice setting in fill is the perimeter being extruded first, then the loops, then the infill. If the thread sequence choice is different, the optimal thread parameters will also be different. In general, if the infill is extruded first, the infill would have to be stretched more so that even after the filament shrinkage, it would still be long enough to connect to the loop or perimeter. Holes should be made with the correct area for their radius. In other words, for example if your modeling program approximates a hole of radius one (area = pi) by making a square with the points at [(1,0), (0,1), (-1,0), (0,-1)] (area = 2), the radius should be increased by sqrt(pi/2). This can be done in fabmetheus xml by writing: radiusAreal='True' in the attributes of the object or any parent of that object. In other modeling programs, you'll have to this manually or make a script. If area compensation is not done, then changing the stretch parameters to over compensate for too small hole areas will lead to incorrect compensation in other shapes. ==Operation== The default 'Activate Stretch' checkbox is off. When it is on, the functions described below will work, when it is off, the functions will not be called. ==Settings== ===Loop Stretch Over Perimeter Width=== Default is 0.1. Defines the ratio of the maximum amount the loop aka inner shell threads will be stretched compared to the perimeter width, in general this value should be the same as the 'Perimeter Outside Stretch Over Perimeter Width' setting. ===Path Stretch Over Perimeter Width=== Default is zero. Defines the ratio of the maximum amount the threads which are not loops, like the infill threads, will be stretched compared to the perimeter width. ===Perimeter=== ====Perimeter Inside Stretch Over Perimeter Width==== Default is 0.32. Defines the ratio of the maximum amount the inside perimeter thread will be stretched compared to the perimeter width, this is the most important setting in stretch. The higher the value the more it will stretch the perimeter and the wider holes will be. If the value is too small, the holes could be drilled out after fabrication, if the value is too high, the holes would be too wide and the part would have to junked. ====Perimeter Outside Stretch Over Perimeter Width==== Default is 0.1. Defines the ratio of the maximum amount the outside perimeter thread will be stretched compared to the perimeter width, in general this value should be around a third of the 'Perimeter Inside Stretch Over Perimeter Width' setting. ===Stretch from Distance over Perimeter Width=== Default is two. The stretch algorithm works by checking at each turning point on the extrusion path what the direction of the thread is at a distance of 'Stretch from Distance over Perimeter Width' times the perimeter width, on both sides, and moves the thread in the opposite direction. So it takes the current turning-point, goes "Stretch from Distance over Perimeter Width" * "Perimeter Width" ahead, reads the direction at that point. Then it goes the same distance in back in time, reads the direction at that other point. It then moves the thread in the opposite direction, away from the center of the arc formed by these 2 points+directions. The magnitude of the stretch increases with: the amount that the direction of the two threads is similar and by the '..Stretch Over Perimeter Width' ratio. ==Examples== The following examples stretch the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and stretch.py. > python stretch.py This brings up the stretch dialog. > python stretch.py Screw Holder Bottom.stl The stretch tool is parsing the file: Screw Holder Bottom.stl .. The stretch tool has created the file: .. Screw Holder Bottom_stretch.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' #maybe speed up feedRate option def getCraftedText( fileName, gcodeText, stretchRepository = None ): "Stretch a gcode linear move text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, gcodeText), stretchRepository ) def getCraftedTextFromText( gcodeText, stretchRepository = None ): "Stretch a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'stretch'): return gcodeText if stretchRepository is None: stretchRepository = settings.getReadRepository( StretchRepository() ) if not stretchRepository.activateStretch.value: return gcodeText return StretchSkein().getCraftedGcode( gcodeText, stretchRepository ) def getNewRepository(): 'Get new repository.' return StretchRepository() def writeOutput(fileName, shouldAnalyze=True): "Stretch a gcode linear move file. Chain stretch the gcode if it is not already stretched." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'stretch', shouldAnalyze) class LineIteratorBackward: "Backward line iterator class." def __init__( self, isLoop, lineIndex, lines ): self.firstLineIndex = None self.isLoop = isLoop self.lineIndex = lineIndex self.lines = lines def getIndexBeforeNextDeactivate(self): "Get index two lines before the deactivate command." for lineIndex in xrange( self.lineIndex + 1, len(self.lines) ): line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'M103': return lineIndex - 2 print('This should never happen in stretch, no deactivate command was found for this thread.') raise StopIteration, "You've reached the end of the line." def getNext(self): "Get next line going backward or raise exception." while self.lineIndex > 3: if self.lineIndex == self.firstLineIndex: raise StopIteration, "You've reached the end of the line." if self.firstLineIndex is None: self.firstLineIndex = self.lineIndex nextLineIndex = self.lineIndex - 1 line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'M103': if self.isLoop: nextLineIndex = self.getIndexBeforeNextDeactivate() else: raise StopIteration, "You've reached the end of the line." if firstWord == 'G1': if self.isBeforeExtrusion(): if self.isLoop: nextLineIndex = self.getIndexBeforeNextDeactivate() else: raise StopIteration, "You've reached the end of the line." else: self.lineIndex = nextLineIndex return line self.lineIndex = nextLineIndex raise StopIteration, "You've reached the end of the line." def isBeforeExtrusion(self): "Determine if index is two or more before activate command." linearMoves = 0 for lineIndex in xrange( self.lineIndex + 1, len(self.lines) ): line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': linearMoves += 1 if firstWord == 'M101': return linearMoves > 0 if firstWord == 'M103': return False print('This should never happen in isBeforeExtrusion in stretch, no activate command was found for this thread.') return False class LineIteratorForward: "Forward line iterator class." def __init__( self, isLoop, lineIndex, lines ): self.firstLineIndex = None self.isLoop = isLoop self.lineIndex = lineIndex self.lines = lines def getIndexJustAfterActivate(self): "Get index just after the activate command." for lineIndex in xrange( self.lineIndex - 1, 3, - 1 ): line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'M101': return lineIndex + 1 print('This should never happen in stretch, no activate command was found for this thread.') raise StopIteration, "You've reached the end of the line." def getNext(self): "Get next line or raise exception." while self.lineIndex < len(self.lines): if self.lineIndex == self.firstLineIndex: raise StopIteration, "You've reached the end of the line." if self.firstLineIndex is None: self.firstLineIndex = self.lineIndex nextLineIndex = self.lineIndex + 1 line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'M103': if self.isLoop: nextLineIndex = self.getIndexJustAfterActivate() else: raise StopIteration, "You've reached the end of the line." self.lineIndex = nextLineIndex if firstWord == 'G1': return line raise StopIteration, "You've reached the end of the line." class StretchRepository: "A class to handle the stretch settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.stretch.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Stretch', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Stretch') self.activateStretch = settings.BooleanSetting().getFromValue('Activate Stretch to correct for diameter shrink in small diameter holes', self, False ) self.crossLimitDistanceOverPerimeterWidth = settings.FloatSpin().getFromValue( 3.0, 'Cross Limit Distance Over Perimeter Width (ratio):', self, 10.0, 5.0 ) self.loopStretchOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.05, 'Loop Stretch Over Perimeter Width (ratio):', self, 0.25, 0.11 ) self.pathStretchOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.0, 'Path Stretch Over Perimeter Width (ratio):', self, 0.2, 0.0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Perimeter -', self ) self.perimeterInsideStretchOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.12, 'Perimeter Inside Stretch Over Perimeter Width (ratio):', self, 0.52, 0.32 ) self.perimeterOutsideStretchOverPerimeterWidth = settings.FloatSpin().getFromValue( 0.05, 'Perimeter Outside Stretch Over Perimeter Width (ratio):', self, 0.25, 0.1 ) settings.LabelSeparator().getFromRepository(self) self.stretchFromDistanceOverPerimeterWidth = settings.FloatSpin().getFromValue( 1.0, 'Stretch From Distance Over Perimeter Width (ratio):', self, 3.0, 2.0 ) self.executeTitle = 'Stretch' def execute(self): "Stretch button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class StretchSkein: "A class to stretch a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.feedRateMinute = 959.0 self.isLoop = False self.layerCount = settings.LayerCount() self.lineIndex = 0 self.lines = None self.oldLocation = None self.perimeterWidth = 0.4 def getCraftedGcode( self, gcodeText, stretchRepository ): "Parse gcode text and store the stretch gcode." self.lines = archive.getTextLines(gcodeText) self.stretchRepository = stretchRepository self.parseInitialization() for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseStretch(line) return self.distanceFeedRate.output.getvalue() def getCrossLimitedStretch( self, crossLimitedStretch, crossLineIterator, locationComplex ): "Get cross limited relative stretch for a location." try: line = crossLineIterator.getNext() except StopIteration: return crossLimitedStretch splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) pointComplex = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine).dropAxis() pointMinusLocation = locationComplex - pointComplex pointMinusLocationLength = abs( pointMinusLocation ) if pointMinusLocationLength <= self.crossLimitDistanceFraction: return crossLimitedStretch parallelNormal = pointMinusLocation / pointMinusLocationLength parallelStretch = euclidean.getDotProduct( parallelNormal, crossLimitedStretch ) * parallelNormal if pointMinusLocationLength > self.crossLimitDistance: return parallelStretch crossNormal = complex( parallelNormal.imag, - parallelNormal.real ) crossStretch = euclidean.getDotProduct( crossNormal, crossLimitedStretch ) * crossNormal crossPortion = ( self.crossLimitDistance - pointMinusLocationLength ) / self.crossLimitDistanceRemainder return parallelStretch + crossStretch * crossPortion def getRelativeStretch( self, locationComplex, lineIterator ): "Get relative stretch for a location." lastLocationComplex = locationComplex oldTotalLength = 0.0 pointComplex = locationComplex totalLength = 0.0 while 1: try: line = lineIterator.getNext() except StopIteration: locationMinusPoint = locationComplex - pointComplex locationMinusPointLength = abs( locationMinusPoint ) if locationMinusPointLength > 0.0: return locationMinusPoint / locationMinusPointLength return complex() splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = splitLine[0] pointComplex = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine).dropAxis() locationMinusPoint = lastLocationComplex - pointComplex locationMinusPointLength = abs( locationMinusPoint ) totalLength += locationMinusPointLength if totalLength >= self.stretchFromDistance: distanceFromRatio = ( self.stretchFromDistance - oldTotalLength ) / locationMinusPointLength totalPoint = distanceFromRatio * pointComplex + ( 1.0 - distanceFromRatio ) * lastLocationComplex locationMinusTotalPoint = locationComplex - totalPoint return locationMinusTotalPoint / self.stretchFromDistance lastLocationComplex = pointComplex oldTotalLength = totalLength def getStretchedLine( self, splitLine ): "Get stretched gcode line." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) self.oldLocation = location if self.extruderActive and self.threadMaximumAbsoluteStretch > 0.0: return self.getStretchedLineFromIndexLocation( self.lineIndex - 1, self.lineIndex + 1, location ) if self.isJustBeforeExtrusion() and self.threadMaximumAbsoluteStretch > 0.0: return self.getStretchedLineFromIndexLocation( self.lineIndex - 1, self.lineIndex + 1, location ) return self.lines[self.lineIndex] def getStretchedLineFromIndexLocation( self, indexPreviousStart, indexNextStart, location ): "Get stretched gcode line from line index and location." crossIteratorForward = LineIteratorForward( self.isLoop, indexNextStart, self.lines ) crossIteratorBackward = LineIteratorBackward( self.isLoop, indexPreviousStart, self.lines ) iteratorForward = LineIteratorForward( self.isLoop, indexNextStart, self.lines ) iteratorBackward = LineIteratorBackward( self.isLoop, indexPreviousStart, self.lines ) locationComplex = location.dropAxis() relativeStretch = self.getRelativeStretch( locationComplex, iteratorForward ) + self.getRelativeStretch( locationComplex, iteratorBackward ) relativeStretch *= euclidean.globalQuarterPi relativeStretch = self.getCrossLimitedStretch( relativeStretch, crossIteratorForward, locationComplex ) relativeStretch = self.getCrossLimitedStretch( relativeStretch, crossIteratorBackward, locationComplex ) relativeStretchLength = abs( relativeStretch ) if relativeStretchLength > 1.0: relativeStretch /= relativeStretchLength absoluteStretch = relativeStretch * self.threadMaximumAbsoluteStretch stretchedPoint = location.dropAxis() + absoluteStretch return self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( self.feedRateMinute, stretchedPoint, location.z ) def isJustBeforeExtrusion(self): "Determine if activate command is before linear move command." for lineIndex in xrange( self.lineIndex + 1, len(self.lines) ): line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1' or firstWord == 'M103': return False if firstWord == 'M101': return True # print('This should never happen in isJustBeforeExtrusion in stretch, no activate or deactivate command was found for this thread.') return False def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('stretch') return elif firstWord == '(': perimeterWidth = float(splitLine[1]) self.crossLimitDistance = self.perimeterWidth * self.stretchRepository.crossLimitDistanceOverPerimeterWidth.value self.loopMaximumAbsoluteStretch = self.perimeterWidth * self.stretchRepository.loopStretchOverPerimeterWidth.value self.pathAbsoluteStretch = self.perimeterWidth * self.stretchRepository.pathStretchOverPerimeterWidth.value self.perimeterInsideAbsoluteStretch = self.perimeterWidth * self.stretchRepository.perimeterInsideStretchOverPerimeterWidth.value self.perimeterOutsideAbsoluteStretch = self.perimeterWidth * self.stretchRepository.perimeterOutsideStretchOverPerimeterWidth.value self.stretchFromDistance = self.stretchRepository.stretchFromDistanceOverPerimeterWidth.value * perimeterWidth self.threadMaximumAbsoluteStretch = self.pathAbsoluteStretch self.crossLimitDistanceFraction = 0.333333333 * self.crossLimitDistance self.crossLimitDistanceRemainder = self.crossLimitDistance - self.crossLimitDistanceFraction self.distanceFeedRate.addLine(line) def parseStretch(self, line): "Parse a gcode line and add it to the stretch skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': line = self.getStretchedLine(splitLine) elif firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False self.setStretchToPath() elif firstWord == '(': self.layerCount.printProgressIncrement('stretch') elif firstWord == '(': self.isLoop = True self.threadMaximumAbsoluteStretch = self.loopMaximumAbsoluteStretch elif firstWord == '()': self.setStretchToPath() elif firstWord == '(': self.isLoop = True self.threadMaximumAbsoluteStretch = self.perimeterInsideAbsoluteStretch if splitLine[1] == 'outer': self.threadMaximumAbsoluteStretch = self.perimeterOutsideAbsoluteStretch elif firstWord == '()': self.setStretchToPath() self.distanceFeedRate.addLine(line) def setStretchToPath(self): "Set the thread stretch to path stretch and is loop false." self.isLoop = False self.threadMaximumAbsoluteStretch = self.pathAbsoluteStretch def main(): "Display the stretch dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/temperature.py000066400000000000000000000222401167321211700313730ustar00rootroot00000000000000""" This page is in the table of contents. Temperature is a plugin to set the temperature for the entire extrusion. The temperature manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Temperature ==Operation== The default 'Activate Temperature' checkbox is on. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Rate=== The default cooling rate and heating rate for the extruder were both been derived from bothacker's graph at: http://bothacker.com/wp-content/uploads/2009/09/18h5m53s9.29.2009.png ====Cooling Rate==== Default is three degrees Celcius per second. Defines the cooling rate of the extruder. ====Heating Rate==== Default is ten degrees Celcius per second. Defines the heating rate of the extruder. ===Temperature=== ====Base Temperature==== Default for ABS is two hundred degrees Celcius. Defines the raft base temperature. ====Interface Temperature==== Default for ABS is two hundred degrees Celcius. Defines the raft interface temperature. ====Object First Layer Infill Temperature==== Default for ABS is 195 degrees Celcius. Defines the infill temperature of the first layer of the object. ====Object First Layer Perimeter Temperature==== Default for ABS is two hundred and twenty degrees Celcius. Defines the perimeter temperature of the first layer of the object. ====Object Next Layers Temperature==== Default for ABS is two hundred and thirty degrees Celcius. Defines the temperature of the next layers of the object. ====Support Layers Temperature==== Default for ABS is two hundred degrees Celcius. Defines the support layers temperature. ====Supported Layers Temperature==== Default for ABS is two hundred and thirty degrees Celcius. Defines the temperature of the supported layers of the object, those layers which are right above a support layer. ==Examples== The following examples add temperature information to the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and temperature.py. > python temperature.py This brings up the temperature dialog. > python temperature.py Screw Holder Bottom.stl The temperature tool is parsing the file: Screw Holder Bottom.stl .. The temperature tool has created the file: .. Screw Holder Bottom_temperature.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text='', repository=None): "Temperature the file or text." return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): "Temperature a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'temperature'): return gcodeText if repository is None: repository = settings.getReadRepository( TemperatureRepository() ) if not repository.activateTemperature.value: return gcodeText return TemperatureSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return TemperatureRepository() def writeOutput(fileName, shouldAnalyze=True): "Temperature a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'temperature', shouldAnalyze) class TemperatureRepository: "A class to handle the temperature settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.temperature.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Temperature', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Temperature') self.activateTemperature = settings.BooleanSetting().getFromValue('Activate Temperature', self, False ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Rate -', self ) self.coolingRate = settings.FloatSpin().getFromValue( 1.0, 'Cooling Rate (Celcius/second):', self, 20.0, 3.0 ) self.heatingRate = settings.FloatSpin().getFromValue( 1.0, 'Heating Rate (Celcius/second):', self, 20.0, 10.0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Temperature -', self ) self.baseTemperature = settings.FloatSpin().getFromValue( 140.0, 'Base Temperature (Celcius):', self, 260.0, 200.0 ) self.interfaceTemperature = settings.FloatSpin().getFromValue( 140.0, 'Interface Temperature (Celcius):', self, 260.0, 200.0 ) self.objectFirstLayerInfillTemperature = settings.FloatSpin().getFromValue( 140.0, 'Object First Layer Infill Temperature (Celcius):', self, 260.0, 195.0 ) self.objectFirstLayerPerimeterTemperature = settings.FloatSpin().getFromValue( 140.0, 'Object First Layer Perimeter Temperature (Celcius):', self, 260.0, 220.0 ) self.objectNextLayersTemperature = settings.FloatSpin().getFromValue( 140.0, 'Object Next Layers Temperature (Celcius):', self, 260.0, 230.0 ) self.supportLayersTemperature = settings.FloatSpin().getFromValue( 140.0, 'Support Layers Temperature (Celcius):', self, 260.0, 200.0 ) self.supportedLayersTemperature = settings.FloatSpin().getFromValue( 140.0, 'Supported Layers Temperature (Celcius):', self, 260.0, 230.0 ) self.executeTitle = 'Temperature' def execute(self): "Temperature button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class TemperatureSkein: "A class to temperature a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.lineIndex = 0 self.lines = None def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the temperature gcode." self.repository = repository self.lines = archive.getTextLines(gcodeText) if self.repository.coolingRate.value < 0.1: print('The cooling rate should be more than 0.1, any cooling rate less than 0.1 will be treated as 0.1.') self.repository.coolingRate.value = 0.1 if self.repository.heatingRate.value < 0.1: print('The heating rate should be more than 0.1, any heating rate less than 0.1 will be treated as 0.1.') self.repository.heatingRate.value = 0.1 self.parseInitialization() self.distanceFeedRate.addLines( self.lines[self.lineIndex :] ) return self.distanceFeedRate.output.getvalue() def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('temperature') return elif firstWord == '(': self.distanceFeedRate.addTagBracketedLine('coolingRate', self.repository.coolingRate.value ) self.distanceFeedRate.addTagBracketedLine('heatingRate', self.repository.heatingRate.value ) self.distanceFeedRate.addTagBracketedLine('baseTemperature', self.repository.baseTemperature.value ) self.distanceFeedRate.addTagBracketedLine('interfaceTemperature', self.repository.interfaceTemperature.value ) self.distanceFeedRate.addTagBracketedLine('objectFirstLayerInfillTemperature', self.repository.objectFirstLayerInfillTemperature.value ) self.distanceFeedRate.addTagBracketedLine('objectFirstLayerPerimeterTemperature', self.repository.objectFirstLayerPerimeterTemperature.value ) self.distanceFeedRate.addTagBracketedLine('objectNextLayersTemperature', self.repository.objectNextLayersTemperature.value ) self.distanceFeedRate.addTagBracketedLine('supportLayersTemperature', self.repository.supportLayersTemperature.value ) self.distanceFeedRate.addTagBracketedLine('supportedLayersTemperature', self.repository.supportedLayersTemperature.value ) self.distanceFeedRate.addLine(line) def main(): "Display the temperature dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/tower.py000066400000000000000000000401231167321211700301760ustar00rootroot00000000000000""" This page is in the table of contents. Tower commands the fabricator to extrude a disconnected region for a few layers, then go to another disconnected region and extrude there. Its purpose is to reduce the number of stringers between a shape and reduce extruder travel. The tower manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Tower ==Operation== The default 'Activate Tower' checkbox is off. The default is off because tower could result in the extruder colliding with an already extruded part of the shape and because extruding in one region for more than one layer could result in the shape melting. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Maximum Tower Height=== Default: 5 Defines the maximum number of layers that the extruder will extrude in one region before going to another. This is the most important value for tower. ===Extruder Possible Collision Cone Angle=== Default: 60 degrees Tower works by looking for islands in each layer and if it finds another island in the layer above, it goes to the next layer above instead of going across to other regions on the original layer. It checks for collision with shapes already extruded within a cone from the nozzle tip. The 'Extruder Possible Collision Cone Angle' setting is the angle of that cone. Realistic values for the cone angle range between zero and ninety. The higher the angle, the less likely a collision with the rest of the shape is, generally the extruder will stay in the region for only a few layers before a collision is detected with the wide cone. ===Tower Start Layer=== Default: 1 Defines the layer index which the script starts extruding towers, after the last raft layer which does not have support material. It is best to not tower at least the first layer because the temperature of the first layer is sometimes different than that of the other layers. ==Examples== The following examples tower the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and tower.py. > python tower.py This brings up the tower dialog. > python tower.py Screw Holder Bottom.stl The tower tool is parsing the file: Screw Holder Bottom.stl .. The tower tool has created the file: .. Screw Holder Bottom_tower.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, towerRepository = None ): "Tower a gcode linear move file or text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), towerRepository ) def getCraftedTextFromText( gcodeText, towerRepository = None ): "Tower a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'tower'): return gcodeText if towerRepository is None: towerRepository = settings.getReadRepository( TowerRepository() ) if not towerRepository.activateTower.value: return gcodeText return TowerSkein().getCraftedGcode( gcodeText, towerRepository ) def getNewRepository(): 'Get new repository.' return TowerRepository() def writeOutput(fileName, shouldAnalyze=True): "Tower a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'tower', shouldAnalyze) class Island: "A class to hold the boundary and lines." def __init__(self): self.boundary = [] self.boundingLoop = None self.lines = [] def addToBoundary( self, splitLine ): "Add to the boundary if it is not complete." if self.boundingLoop is None: location = gcodec.getLocationFromSplitLine(None, splitLine) self.boundary.append(location.dropAxis()) self.z = location.z def createBoundingLoop(self): "Create the bounding loop if it is not already created." if self.boundingLoop is None: self.boundingLoop = intercircle.BoundingLoop().getFromLoop( self.boundary ) class ThreadLayer: "A layer of loops and paths." def __init__(self): "Thread layer constructor." self.afterExtrusionLines = [] self.beforeExtrusionLines = [] self.islands = [] def __repr__(self): "Get the string representation of this thread layer." return '%s' % self.islands class TowerRepository: "A class to handle the tower settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.tower.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Tower', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Tower') self.activateTower = settings.BooleanSetting().getFromValue('Activate Tower', self, False ) self.extruderPossibleCollisionConeAngle = settings.FloatSpin().getFromValue( 40.0, 'Extruder Possible Collision Cone Angle (degrees):', self, 80.0, 60.0 ) self.maximumTowerHeight = settings.IntSpin().getFromValue( 2, 'Maximum Tower Height (layers):', self, 10, 5 ) self.towerStartLayer = settings.IntSpin().getFromValue( 1, 'Tower Start Layer (integer):', self, 5, 1 ) self.executeTitle = 'Tower' def execute(self): "Tower button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class TowerSkein: "A class to tower a skein of extrusions." def __init__(self): self.afterExtrusionLines = [] self.beforeExtrusionLines = [] self.distanceFeedRate = gcodec.DistanceFeedRate() self.highestZ = - 987654321.0 self.island = None self.layerIndex = 0 self.lineIndex = 0 self.lines = None self.minimumBelow = 0.1 self.oldLayerIndex = None self.oldLocation = None self.oldOrderedLocation = Vector3() self.perimeterWidth = 0.6 self.shutdownLineIndex = sys.maxint self.nestedRingCount = 0 self.threadLayer = None self.threadLayers = [] self.travelFeedRateMinute = None def addEntireLayer( self, threadLayer ): "Add entire thread layer." self.distanceFeedRate.addLines( threadLayer.beforeExtrusionLines ) for island in threadLayer.islands: self.distanceFeedRate.addLines( island.lines ) self.distanceFeedRate.addLines( threadLayer.afterExtrusionLines ) def addHighThread(self, location): "Add thread with a high move if necessary to clear the previous extrusion." if self.oldLocation is not None: if self.oldLocation.z + self.minimumBelow < self.highestZ: self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.travelFeedRateMinute, self.oldLocation.dropAxis(), self.highestZ ) if location.z + self.minimumBelow < self.highestZ: self.distanceFeedRate.addGcodeMovementZWithFeedRate( self.travelFeedRateMinute, location.dropAxis(), self.highestZ ) def addThreadLayerIfNone(self): "Add a thread layer if it is none." if self.threadLayer is not None: return self.threadLayer = ThreadLayer() self.threadLayers.append( self.threadLayer ) self.threadLayer.beforeExtrusionLines = self.beforeExtrusionLines self.beforeExtrusionLines = [] def addTowers(self): "Add towers." bottomLayerIndex = self.getBottomLayerIndex() if bottomLayerIndex is None: return removedIsland = self.getRemovedIslandAddLayerLinesIfDifferent( self.threadLayers[ bottomLayerIndex ].islands, bottomLayerIndex ) while 1: self.climbTower( removedIsland ) bottomLayerIndex = self.getBottomLayerIndex() if bottomLayerIndex is None: return removedIsland = self.getRemovedIslandAddLayerLinesIfDifferent( self.threadLayers[ bottomLayerIndex ].islands, bottomLayerIndex ) def climbTower( self, removedIsland ): "Climb up the island to any islands directly above." outsetDistance = 1.5 * self.perimeterWidth for step in xrange( self.towerRepository.maximumTowerHeight.value ): aboveIndex = self.oldLayerIndex + 1 if aboveIndex >= len( self.threadLayers ): return outsetRemovedLoop = removedIsland.boundingLoop.getOutsetBoundingLoop( outsetDistance ) islandsWithin = [] for island in self.threadLayers[ aboveIndex ].islands: if self.isInsideRemovedOutsideCone( island, outsetRemovedLoop, aboveIndex ): islandsWithin.append( island ) if len( islandsWithin ) < 1: return removedIsland = self.getRemovedIslandAddLayerLinesIfDifferent( islandsWithin, aboveIndex ) self.threadLayers[ aboveIndex ].islands.remove( removedIsland ) def getBottomLayerIndex(self): "Get the index of the first island layer which has islands." for islandLayerIndex in xrange( len( self.threadLayers ) ): if len( self.threadLayers[ islandLayerIndex ].islands ) > 0: return islandLayerIndex return None def getCraftedGcode( self, gcodeText, towerRepository ): "Parse gcode text and store the tower gcode." self.lines = archive.getTextLines(gcodeText) self.towerRepository = towerRepository self.parseInitialization() self.parseIfWordUntilWord('(') self.parseIfWordUntilWord('()') for lineIndex in xrange(self.lineIndex, len(self.lines)): self.parseLine( lineIndex ) concatenateEndIndex = min( len( self.threadLayers ), towerRepository.towerStartLayer.value ) for threadLayer in self.threadLayers[ : concatenateEndIndex ]: self.addEntireLayer( threadLayer ) self.threadLayers = self.threadLayers[ concatenateEndIndex : ] self.addTowers() self.distanceFeedRate.addLines( self.lines[ self.shutdownLineIndex : ] ) return self.distanceFeedRate.output.getvalue() def getRemovedIslandAddLayerLinesIfDifferent( self, islands, layerIndex ): "Add gcode lines for the layer if it is different than the old bottom layer index." threadLayer = None if layerIndex != self.oldLayerIndex: self.oldLayerIndex = layerIndex threadLayer = self.threadLayers[layerIndex] self.distanceFeedRate.addLines( threadLayer.beforeExtrusionLines ) removedIsland = self.getTransferClosestNestedRingLines( self.oldOrderedLocation, islands ) if threadLayer is not None: self.distanceFeedRate.addLines( threadLayer.afterExtrusionLines ) return removedIsland def getTransferClosestNestedRingLines( self, oldOrderedLocation, remainingNestedRings ): "Get and transfer the closest remaining nested ring." if len( remainingNestedRings ) > 0: oldOrderedLocation.z = remainingNestedRings[0].z closestDistance = 999999999987654321.0 closestNestedRing = None for remainingNestedRing in remainingNestedRings: distance = euclidean.getClosestDistanceIndexToLine(oldOrderedLocation.dropAxis(), remainingNestedRing.boundary).distance if distance < closestDistance: closestDistance = distance closestNestedRing = remainingNestedRing remainingNestedRings.remove(closestNestedRing) hasTravelledHighRoad = False for line in closestNestedRing.lines: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) if firstWord == 'G1': location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if not hasTravelledHighRoad: hasTravelledHighRoad = True self.addHighThread(location) if location.z > self.highestZ: self.highestZ = location.z self.oldLocation = location self.distanceFeedRate.addLine(line) return closestNestedRing def isInsideRemovedOutsideCone( self, island, removedBoundingLoop, untilLayerIndex ): "Determine if the island is entirely inside the removed bounding loop and outside the collision cone of the remaining islands." if not island.boundingLoop.isEntirelyInsideAnother( removedBoundingLoop ): return False bottomLayerIndex = self.getBottomLayerIndex() coneAngleTangent = math.tan( math.radians( self.towerRepository.extruderPossibleCollisionConeAngle.value ) ) for layerIndex in xrange( bottomLayerIndex, untilLayerIndex ): islands = self.threadLayers[layerIndex].islands outsetDistance = self.perimeterWidth * ( untilLayerIndex - layerIndex ) * coneAngleTangent + 0.5 * self.perimeterWidth for belowIsland in self.threadLayers[layerIndex].islands: outsetIslandLoop = belowIsland.boundingLoop.getOutsetBoundingLoop( outsetDistance ) if island.boundingLoop.isOverlappingAnother( outsetIslandLoop ): return False return True def parseIfWordUntilWord(self, word): "Parse gcode if there is a word until the word is reached." for self.lineIndex in xrange(self.lineIndex, gcodec.getFirstWordIndexReverse(word, self.lines, self.lineIndex)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.addLine(line) if firstWord == 'G1': self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.oldLocation.z > self.highestZ: self.highestZ = self.oldLocation.z def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('tower') elif firstWord == '(': return elif firstWord == '(': self.minimumBelow = 0.1 * float(splitLine[1]) elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) elif firstWord == '(': self.travelFeedRateMinute = 60.0 * float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine( self, lineIndex ): "Parse a gcode line." line = self.lines[lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] self.afterExtrusionLines.append(line) if firstWord == 'M103': self.afterExtrusionLines = [] elif firstWord == '()': self.island.createBoundingLoop() elif firstWord == '(': self.island.addToBoundary(splitLine) elif firstWord == '()': self.shutdownLineIndex = lineIndex elif firstWord == '(': self.beforeExtrusionLines = [ line ] self.island = None self.nestedRingCount = 0 self.threadLayer = None return elif firstWord == '()': if self.threadLayer is not None: self.threadLayer.afterExtrusionLines = self.afterExtrusionLines self.afterExtrusionLines = [] elif firstWord == '()': self.afterExtrusionLines = [] elif firstWord == '()': self.nestedRingCount += 1 if self.island is None: self.island = Island() self.addThreadLayerIfNone() self.threadLayer.islands.append( self.island ) elif firstWord == '()': self.afterExtrusionLines = [] if self.island is not None: self.island.lines.append(line) if firstWord == '()': self.afterExtrusionLines = [] self.nestedRingCount -= 1 if self.nestedRingCount == 0: self.island = None if len( self.beforeExtrusionLines ) > 0: self.beforeExtrusionLines.append(line) def main(): "Display the tower dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/unpause.py000066400000000000000000000167221167321211700305260ustar00rootroot00000000000000""" This page is in the table of contents. The unpause plugin is based on the Shane Hathaway's patch to speed up a line segment to compensate for the delay of the microprocessor. The description is at: http://shane.willowrise.com/archives/delay-compensation-in-firmware/ The unpause manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Unpause ==Operation== The default 'Activate Unpause' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Delay=== Default is 28 milliseconds, which Shane found for the Arduino. Defines the delay on the microprocessor that will be at least partially compensated for. ===Maximum Speed=== Default is 1.3. Defines the maximum amount that the feed rate will be sped up to, compared to the original feed rate. ==Examples== The following examples unpause the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and unpause.py. > python unpause.py This brings up the unpause dialog. > python unpause.py Screw Holder Bottom.stl The unpause tool is parsing the file: Screw Holder Bottom.stl .. The unpause tool has created the file: .. Screw Holder Bottom_unpause.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, gcodeText, repository=None): "Unpause a gcode linear move file or text." return getCraftedTextFromText( archive.getTextIfEmpty( fileName, gcodeText ), repository ) def getCraftedTextFromText(gcodeText, repository=None): "Unpause a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'unpause'): return gcodeText if repository is None: repository = settings.getReadRepository( UnpauseRepository() ) if not repository.activateUnpause.value: return gcodeText return UnpauseSkein().getCraftedGcode(gcodeText, repository) def getNewRepository(): 'Get new repository.' return UnpauseRepository() def getSelectedPlugin(repository): "Get the selected plugin." for plugin in repository.unpausePlugins: if plugin.value: return plugin return None def writeOutput(fileName, shouldAnalyze=True): "Unpause a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'unpause', shouldAnalyze) class UnpauseRepository: "A class to handle the unpause settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.unpause.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Unpause', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Unpause') self.activateUnpause = settings.BooleanSetting().getFromValue('Activate Unpause', self, False ) self.delay = settings.FloatSpin().getFromValue( 2.0, 'Delay (milliseconds):', self, 42.0, 28.0 ) self.maximumSpeed = settings.FloatSpin().getFromValue( 1.1, 'Maximum Speed (ratio):', self, 1.9, 1.3 ) self.executeTitle = 'Unpause' def execute(self): "Unpause button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class UnpauseSkein: "A class to unpause a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.feedRateMinute = 959.0 self.lineIndex = 0 self.lines = None self.oldLocation = None def getCraftedGcode(self, gcodeText, repository): "Parse gcode text and store the unpause gcode." self.delaySecond = repository.delay.value * 0.001 self.maximumSpeed = repository.maximumSpeed.value self.minimumSpeedUpReciprocal = 1.0 / self.maximumSpeed self.repository = repository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getUnpausedArcMovement( self, line, splitLine ): "Get an unpaused arc movement." self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) if self.oldLocation is None: return line relativeLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.oldLocation += relativeLocation distance = gcodec.getArcDistance(relativeLocation, splitLine) return self.getUnpausedMovement(distance, line, splitLine) def getUnpausedLinearMovement( self, line, splitLine ): "Get an unpaused linear movement." self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) if self.oldLocation is None: self.oldLocation = location return line distance = abs(self.oldLocation - location) self.oldLocation = location return self.getUnpausedMovement(distance, line, splitLine) def getUnpausedMovement(self, distance, line, splitLine): "Get an unpaused movement." if distance <= 0.0: return line resultantReciprocal = 1.0 - self.delaySecond / distance * self.feedRateMinute / 60.0 resultantReciprocal = max(self.minimumSpeedUpReciprocal, resultantReciprocal) return self.distanceFeedRate.getLineWithFeedRate(self.feedRateMinute / resultantReciprocal, line, splitLine) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('unpause') return self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': line = self.getUnpausedLinearMovement( line, splitLine ) if firstWord == 'G2' or firstWord == 'G3': line = self.getUnpausedArcMovement( line, splitLine ) self.distanceFeedRate.addLine(line) def main(): "Display the unpause dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/whittle.py000066400000000000000000000161771167321211700305320ustar00rootroot00000000000000""" This page is in the table of contents. Whittle will convert each polygon of a gcode file into a helix which has a vertical step down on each rotation. ==Operation== The default 'Activate Whittle' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called. If the cutting tool can cut the slab in one cut, the 'Activate Whittle' checkbox should be off, the default is off. ==Settings== ===Maximum Vertical Step'=== Default is 0.1 mm. Defines the maximum distance that the helix will step down on each rotation. The number of steps in the helix will be the layer thickness divided by the 'Maximum Vertical Step', rounded up. The amount the helix will step down is the layer thickness divided by the number of steps. The thinner the 'Maximum Vertical Step', the more times the cutting tool will circle around on its way to the bottom of the slab. ==Examples== The following examples whittle the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and whittle.py. > python whittle.py This brings up the whittle dialog. > python whittle.py Screw Holder Bottom.stl The whittle tool is parsing the file: Screw Holder Bottom.stl .. The whittle tool has created the file: .. Screw Holder Bottom_whittle.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/02/05 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text='', whittleRepository = None ): "Whittle the preface file or text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), whittleRepository ) def getCraftedTextFromText( gcodeText, whittleRepository = None ): "Whittle the preface gcode text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'whittle'): return gcodeText if whittleRepository is None: whittleRepository = settings.getReadRepository( WhittleRepository() ) if not whittleRepository.activateWhittle.value: return gcodeText return WhittleSkein().getCraftedGcode( whittleRepository, gcodeText ) def getNewRepository(): 'Get new repository.' return WhittleRepository() def writeOutput(fileName, shouldAnalyze=True): "Whittle the carving of a gcode file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'whittle', shouldAnalyze) class WhittleRepository: "A class to handle the whittle settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.whittle.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File to be Whittled', self, '') self.activateWhittle = settings.BooleanSetting().getFromValue('Activate Whittle', self, False ) self.maximumVerticalStep = settings.FloatSpin().getFromValue( 0.02, 'Maximum Vertical Step (mm):', self, 0.42, 0.1 ) self.executeTitle = 'Whittle' def execute(self): "Whittle button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class WhittleSkein: "A class to whittle a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.layerThickness = 0.3333333333 self.lineIndex = 0 self.movementLines = [] self.oldLocation = None def getCraftedGcode( self, whittleRepository, gcodeText ): "Parse gcode text and store the whittle gcode." self.whittleRepository = whittleRepository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() for line in self.lines[self.lineIndex :]: self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getLinearMove( self, line, splitLine ): "Get the linear move." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.movementLines.append(line) z = location.z + self.layerDeltas[0] self.oldLocation = location return self.distanceFeedRate.getLineWithZ( line, splitLine, z ) def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex].lstrip() splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('whittle') return elif firstWord == '(': self.setLayerThinknessVerticalDeltas(splitLine) self.distanceFeedRate.addTagBracketedLine('layerStep', self.layerStep ) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the whittle skein." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': line = self.getLinearMove( line, splitLine ) elif firstWord == 'M103': self.repeatLines() self.distanceFeedRate.addLine(line) def repeatLines(self): "Repeat the lines at decreasing altitude." for layerDelta in self.layerDeltas[1 :]: for movementLine in self.movementLines: splitLine = gcodec.getSplitLineBeforeBracketSemicolon(movementLine) location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) z = location.z + layerDelta self.distanceFeedRate.addLine( self.distanceFeedRate.getLineWithZ( movementLine, splitLine, z ) ) self.movementLines = [] def setLayerThinknessVerticalDeltas( self, splitLine ): "Set the layer thickness and the vertical deltas." self.layerThickness = float(splitLine[1]) numberOfSteps = int( math.ceil( self.layerThickness / self.whittleRepository.maximumVerticalStep.value ) ) self.layerStep = self.layerThickness / float( numberOfSteps ) self.layerDeltas = [] halfDeltaMinusHalfTop = 0.5 * self.layerStep * ( 1.0 - numberOfSteps ) for layerDeltaIndex in xrange( numberOfSteps - 1, - 1, - 1 ): layerDelta = layerDeltaIndex * self.layerStep + halfDeltaMinusHalfTop self.layerDeltas.append( layerDelta ) def main(): "Display the whittle dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/widen.py000066400000000000000000000215521167321211700301510ustar00rootroot00000000000000#! /usr/bin/env python """ This page is in the table of contents. Widen will widen the outside perimeters away from the inside perimeters, so that the outsides will be at least two perimeter widths away from the insides and therefore the outside filaments will not overlap the inside filaments. For example, if a mug has a very thin wall, widen would widen the outside of the mug so that the wall of the mug would be two perimeter widths wide, and the outside wall filament would not overlap the inside filament. For another example, if the outside of the object runs right next to a hole, widen would widen the wall around the hole so that the wall would bulge out around the hole, and the outside filament would not overlap the hole filament. The widen manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Widen ==Operation== The default 'Activate Widen' checkbox is off. When it is on, widen will work, when it is off, nothing will be done. ==Examples== The following examples widen the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and widen.py. > python widen.py This brings up the widen dialog. > python widen.py Screw Holder Bottom.stl The widen tool is parsing the file: Screw Holder Bottom.stl .. The widen tool has created the file: .. Screw Holder Bottom_widen.gcode """ from __future__ import absolute_import try: import psyco psyco.full() except: pass #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.geometry.geometry_utilities import boolean_solid from fabmetheus_utilities.geometry.solids import triangle_mesh from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import intercircle from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import os import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/28/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText(fileName, text='', repository=None): 'Widen the preface file or text.' return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository) def getCraftedTextFromText(gcodeText, repository=None): 'Widen the preface gcode text.' if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'widen'): return gcodeText if repository is None: repository = settings.getReadRepository( WidenRepository() ) if not repository.activateWiden.value: return gcodeText return WidenSkein().getCraftedGcode(gcodeText, repository) def getIntersectingWithinLoops(loop, loopList, outsetLoop): 'Get the loops which are intersecting or which it is within.' intersectingWithinLoops = [] for otherLoop in loopList: if getIsIntersectingWithinLoop(loop, otherLoop, outsetLoop): intersectingWithinLoops.append(otherLoop) return intersectingWithinLoops def getIsIntersectingWithinLoop(loop, otherLoop, outsetLoop): 'Determine if the loop is intersecting or is within the other loop.' if euclidean.isLoopIntersectingLoop(loop, otherLoop): return True return euclidean.isPathInsideLoop(otherLoop, loop) != euclidean.isPathInsideLoop(otherLoop, outsetLoop) def getIsPointInsideALoop(loops, point): 'Determine if a point is inside a loop of a loop list.' for loop in loops: if euclidean.isPointInsideLoop(loop, point): return True return False def getNewRepository(): 'Get new repository.' return WidenRepository() def getWidenedLoop(loop, loopList, outsetLoop, radius): 'Get the widened loop.' intersectingWithinLoops = getIntersectingWithinLoops(loop, loopList, outsetLoop) if len(intersectingWithinLoops) < 1: return loop loopsUnified = boolean_solid.getLoopsUnified(radius, [[loop], intersectingWithinLoops]) if len(loopsUnified) < 1: return loop return euclidean.getLargestLoop(loopsUnified) def writeOutput(fileName, shouldAnalyze=True): 'Widen the carving of a gcode file.' skeinforge_craft.writeChainTextWithNounMessage(fileName, 'widen', shouldAnalyze) class WidenRepository: 'A class to handle the widen settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.widen.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Widen', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute( 'http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Widen') self.activateWiden = settings.BooleanSetting().getFromValue('Activate Widen', self, False) self.executeTitle = 'Widen' def execute(self): 'Widen button has been clicked.' fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class WidenSkein: 'A class to widen a skein of extrusions.' def __init__(self): self.boundary = None self.distanceFeedRate = gcodec.DistanceFeedRate() self.layerCount = settings.LayerCount() self.lineIndex = 0 self.loopLayer = None def addWiden(self, loopLayer): 'Add widen to the layer.' triangle_mesh.sortLoopsInOrderOfArea(False, loopLayer.loops) widdershinsLoops = [] clockwiseInsetLoops = [] for loopIndex in xrange(len(loopLayer.loops)): loop = loopLayer.loops[loopIndex] if euclidean.isWiddershins(loop): otherLoops = loopLayer.loops[: loopIndex] + loopLayer.loops[loopIndex + 1 :] leftPoint = euclidean.getLeftPoint(loop) if getIsPointInsideALoop(otherLoops, leftPoint): self.distanceFeedRate.addGcodeFromLoop(loop, loopLayer.z) else: widdershinsLoops.append(loop) else: # clockwiseInsetLoop = intercircle.getLargestInsetLoopFromLoop(loop, self.doublePerimeterWidth) # clockwiseInsetLoop.reverse() # clockwiseInsetLoops.append(clockwiseInsetLoop) clockwiseInsetLoops += intercircle.getInsetLoopsFromLoop(loop, self.doublePerimeterWidth) self.distanceFeedRate.addGcodeFromLoop(loop, loopLayer.z) for widdershinsLoop in widdershinsLoops: outsetLoop = intercircle.getLargestInsetLoopFromLoop(widdershinsLoop, -self.doublePerimeterWidth) widenedLoop = getWidenedLoop(widdershinsLoop, clockwiseInsetLoops, outsetLoop, self.perimeterWidth) self.distanceFeedRate.addGcodeFromLoop(widenedLoop, loopLayer.z) def getCraftedGcode(self, gcodeText, repository): 'Parse gcode text and store the widen gcode.' self.repository = repository self.lines = archive.getTextLines(gcodeText) self.parseInitialization() for line in self.lines[self.lineIndex :]: self.parseLine(line) return self.distanceFeedRate.output.getvalue() def parseInitialization(self): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('widen') elif firstWord == '()': self.distanceFeedRate.addLine(line) return elif firstWord == '(': self.perimeterWidth = float(splitLine[1]) self.doublePerimeterWidth = 2.0 * self.perimeterWidth self.distanceFeedRate.addLine(line) def parseLine(self, line): 'Parse a gcode line and add it to the widen skein.' splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == '(': location = gcodec.getLocationFromSplitLine(None, splitLine) self.boundary.append(location.dropAxis()) elif firstWord == '(': self.layerCount.printProgressIncrement('widen') self.loopLayer = euclidean.LoopLayer(float(splitLine[1])) self.distanceFeedRate.addLine(line) elif firstWord == '()': self.addWiden( self.loopLayer ) self.loopLayer = None elif firstWord == '()': self.boundary = [] self.loopLayer.loops.append( self.boundary ) if self.loopLayer is None: self.distanceFeedRate.addLine(line) def main(): 'Display the widen dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/craft_plugins/wipe.py000066400000000000000000000260751167321211700300140ustar00rootroot00000000000000""" This page is in the table of contents. At the beginning of a layer, depending on the settings, wipe will move the nozzle with the extruder off to the arrival point, then to the wipe point, then to the departure point, then back to the layer. The wipe path is machine specific, so you'll probably have to change all the default locations. The wipe manual page is at: http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Wipe ==Operation== The default 'Activate Wipe' checkbox is off. When it is on, the functions described below will work, when it is off, nothing will be done. ==Settings== ===Location Arrival=== ====Location Arrival X==== Default is minus seventy millimeters. Defines the x coordinate of the arrival location. ====Location Arrival Y==== Default is minus fifty millimeters. Defines the y coordinate of the arrival location. ====Location Arrival Z==== Default is fifty millimeters. Defines the z coordinate of the arrival location. ===Location Departure=== ====Location Departure X==== Default is minus seventy millimeters. Defines the x coordinate of the departure location. ====Location Departure Y==== Default is minus forty millimeters. Defines the y coordinate of the departure location. ====Location Departure Z==== Default is fifty millimeters. Defines the z coordinate of the departure location. ===Location Wipe=== ====Location Wipe X==== Default is minus seventy millimeters. Defines the x coordinate of the wipe location. ====Location Wipe Y==== Default is minus seventy millimeters. Defines the y coordinate of the wipe location. ====Location Wipe Z==== Default is fifty millimeters. Defines the z coordinate of the wipe location. ===Wipe Period=== Default is three. Defines the number of layers between wipes. Wipe will always wipe just before layer zero, afterwards it will wipe every "Wipe Period" layers. With the default of three, wipe will wipe just before layer zero, layer three, layer six and so on. ==Examples== The following examples wipe the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and wipe.py. > python wipe.py This brings up the wipe dialog. > python wipe.py Screw Holder Bottom.stl The wipe tool is parsing the file: Screw Holder Bottom.stl .. The wipe tool has created the file: .. Screw Holder Bottom_wipe.gcode """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.vector3 import Vector3 from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import math import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftedText( fileName, text, wipeRepository = None ): "Wipe a gcode linear move text." return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), wipeRepository ) def getCraftedTextFromText( gcodeText, wipeRepository = None ): "Wipe a gcode linear move text." if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'wipe'): return gcodeText if wipeRepository is None: wipeRepository = settings.getReadRepository( WipeRepository() ) if not wipeRepository.activateWipe.value: return gcodeText return WipeSkein().getCraftedGcode( gcodeText, wipeRepository ) def getNewRepository(): 'Get new repository.' return WipeRepository() def writeOutput(fileName, shouldAnalyze=True): "Wipe a gcode linear move file." skeinforge_craft.writeChainTextWithNounMessage(fileName, 'wipe', shouldAnalyze) class WipeRepository: "A class to handle the wipe settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.wipe.html', self ) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Wipe', self, '') self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Wipe') self.activateWipe = settings.BooleanSetting().getFromValue('Activate Wipe', self, False ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Location Arrival -', self ) self.locationArrivalX = settings.FloatSpin().getFromValue( - 100.0, 'Location Arrival X (mm):', self, 100.0, - 70.0 ) self.locationArrivalY = settings.FloatSpin().getFromValue( - 100.0, 'Location Arrival Y (mm):', self, 100.0, - 50.0 ) self.locationArrivalZ = settings.FloatSpin().getFromValue( - 100.0, 'Location Arrival Z (mm):', self, 100.0, 50.0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Location Departure -', self ) self.locationDepartureX = settings.FloatSpin().getFromValue( - 100.0, 'Location Departure X (mm):', self, 100.0, - 70.0 ) self.locationDepartureY = settings.FloatSpin().getFromValue( - 100.0, 'Location Departure Y (mm):', self, 100.0, - 40.0 ) self.locationDepartureZ = settings.FloatSpin().getFromValue( - 100.0, 'Location Departure Z (mm):', self, 100.0, 50.0 ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Location Wipe -', self ) self.locationWipeX = settings.FloatSpin().getFromValue( - 100.0, 'Location Wipe X (mm):', self, 100.0, - 70.0 ) self.locationWipeY = settings.FloatSpin().getFromValue( - 100.0, 'Location Wipe Y (mm):', self, 100.0, - 70.0 ) self.locationWipeZ = settings.FloatSpin().getFromValue( - 100.0, 'Location Wipe Z (mm):', self, 100.0, 50.0 ) settings.LabelSeparator().getFromRepository(self) self.wipePeriod = settings.IntSpin().getFromValue( 1, 'Wipe Period (layers):', self, 5, 3 ) self.executeTitle = 'Wipe' def execute(self): "Wipe button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled) for fileName in fileNames: writeOutput(fileName) class WipeSkein: "A class to wipe a skein of extrusions." def __init__(self): self.distanceFeedRate = gcodec.DistanceFeedRate() self.extruderActive = False self.highestZ = None self.layerIndex = - 1 self.lineIndex = 0 self.lines = None self.oldLocation = None self.shouldWipe = False self.travelFeedRateMinute = 957.0 def addHop( self, begin, end ): "Add hop to highest point." beginEndDistance = begin.distance(end) if beginEndDistance < 3.0 * self.absolutePerimeterWidth: return alongWay = self.absolutePerimeterWidth / beginEndDistance closeToOldLocation = euclidean.getIntermediateLocation( alongWay, begin, end ) closeToOldLocation.z = self.highestZ self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( self.travelFeedRateMinute, closeToOldLocation ) ) closeToOldArrival = euclidean.getIntermediateLocation( alongWay, end, begin ) closeToOldArrival.z = self.highestZ self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( self.travelFeedRateMinute, closeToOldArrival ) ) def addWipeTravel( self, splitLine ): "Add the wipe travel gcode." location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) self.highestZ = max( self.highestZ, location.z ) if not self.shouldWipe: return self.shouldWipe = False if self.extruderActive: self.distanceFeedRate.addLine('M103') if self.oldLocation is not None: self.addHop( self.oldLocation, self.locationArrival ) self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( self.travelFeedRateMinute, self.locationArrival ) ) self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( self.travelFeedRateMinute, self.locationWipe ) ) self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( self.travelFeedRateMinute, self.locationDeparture ) ) self.addHop( self.locationDeparture, location ) if self.extruderActive: self.distanceFeedRate.addLine('M101') def getCraftedGcode( self, gcodeText, wipeRepository ): "Parse gcode text and store the wipe gcode." self.lines = archive.getTextLines(gcodeText) self.wipePeriod = wipeRepository.wipePeriod.value self.parseInitialization( wipeRepository ) self.locationArrival = Vector3( wipeRepository.locationArrivalX.value, wipeRepository.locationArrivalY.value, wipeRepository.locationArrivalZ.value ) self.locationDeparture = Vector3( wipeRepository.locationDepartureX.value, wipeRepository.locationDepartureY.value, wipeRepository.locationDepartureZ.value ) self.locationWipe = Vector3( wipeRepository.locationWipeX.value, wipeRepository.locationWipeY.value, wipeRepository.locationWipeZ.value ) for self.lineIndex in xrange(self.lineIndex, len(self.lines)): line = self.lines[self.lineIndex] self.parseLine(line) return self.distanceFeedRate.output.getvalue() def getLinearMoveWithFeedRate( self, feedRate, location ): "Get a linear move line with the feedRate." return self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( feedRate, location.dropAxis(), location.z ) def parseInitialization( self, wipeRepository ): 'Parse gcode initialization and store the parameters.' for self.lineIndex in xrange(len(self.lines)): line = self.lines[self.lineIndex] splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) firstWord = gcodec.getFirstWord(splitLine) self.distanceFeedRate.parseSplitLine(firstWord, splitLine) if firstWord == '()': self.distanceFeedRate.addTagBracketedProcedure('wipe') return elif firstWord == '(': self.absolutePerimeterWidth = abs(float(splitLine[1])) elif firstWord == '(': self.travelFeedRateMinute = 60.0 * float(splitLine[1]) self.distanceFeedRate.addLine(line) def parseLine(self, line): "Parse a gcode line and add it to the bevel gcode." splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line) if len(splitLine) < 1: return firstWord = splitLine[0] if firstWord == 'G1': self.addWipeTravel(splitLine) self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine) elif firstWord == '(': self.layerIndex += 1 settings.printProgress(self.layerIndex, 'wipe') if self.layerIndex % self.wipePeriod == 0: self.shouldWipe = True elif firstWord == 'M101': self.extruderActive = True elif firstWord == 'M103': self.extruderActive = False self.distanceFeedRate.addLine(line) def main(): "Display the wipe dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/help.py000066400000000000000000000075441167321211700251400ustar00rootroot00000000000000""" This page is in the table of contents. Help has buttons and menu items to open help, blog and forum pages in your primary browser. ==Link Buttons== ===Announcements=== ====Fabmetheus Blog==== The skeinforge announcements blog and the place to post questions, bugs and skeinforge requests. ===Documentation=== ====Index of Local Documentation==== The list of the pages in the documentation folder. ====Wiki Manual==== The skeinforge wiki with pictures and charts. It is the best and most readable source of skeinforge information and you are welcome to contribute. ====Skeinforge Overview==== A general description of skeinforge, has answers to frequently asked questions and has many links to skeinforge, fabrication and python pages. It is also the help page of the skeinforge tool. ===Forums=== ====Bits from Bytes Printing Board==== Board about printing questions, problems and solutions. Most of the people on that forum use the rapman, but many of the solutions apply to any reprap. ====Bits from Bytes Software Board==== Board about software, and has some skeinforge threads. ====Skeinforge Contributions Thread==== Forum thread about how to contribute to skeinforge development. ====Skeinforge Settings Thread==== Forum thread for people to post, download and discuss skeinforge settings. ==Settings== ===Wiki Manual Primary=== Default is on. The help menu has an item for each button on the help page. Also, at the very top, it has a link to the local documentation and if there is a separate page for that tool in the wiki manual, a link to that page on the manual. If the 'Wiki Manual Primary' checkbutton is selected and there is a separate wiki manual page, the wiki page will be the primary document page, otherwise the local page will be primary. The help button (? symbol button) on the tool page will open the primary page, as will pressing . For example, if you click the the help button from the chamber tool, which has a separate page in the wiki, and 'Wiki Manual Primary' is selected, the wiki manual chamber page will be opened. Clicking F1 will also open the wiki manual chamber page. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_help import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addToMenu( master, menu, repository, window ): "Add a tool plugin menu." path = settings.getPathInFabmetheusFromFileNameHelp( repository.fileNameHelp ) capitalizedBasename = os.path.basename(path).capitalize() helpRepository = settings.getReadRepository( skeinforge_help.HelpRepository() ) if repository.openWikiManualHelpPage is not None and helpRepository.wikiManualPrimary.value: menu.add_command( label = 'Local ' + capitalizedBasename, command = repository.openLocalHelpPage ) else: settings.addAcceleratorCommand('', repository.openLocalHelpPage, master, menu, 'Local ' + capitalizedBasename ) if repository.openWikiManualHelpPage is not None: if helpRepository.wikiManualPrimary.value: settings.addAcceleratorCommand('', repository.openWikiManualHelpPage, master, menu, 'Wiki Manual ' + capitalizedBasename ) else: menu.add_command( label = 'Wiki Manual ' + capitalizedBasename, command = repository.openWikiManualHelpPage ) menu.add_separator() settings.addMenuEntitiesToMenu( menu, helpRepository.menuEntities ) def getNewRepository(): 'Get new repository.' return skeinforge_help.HelpRepository() def main(): "Display the help dialog." settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/meta.py000066400000000000000000000022161167321211700251250ustar00rootroot00000000000000""" This page is in the table of contents. Meta is a script to access the plugins which handle meta information. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_meta __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addToMenu( master, menu, repository, window ): "Add a tool plugin menu." metaFilePath = archive.getSkeinforgePluginsPath('meta.py') settings.addPluginsParentToMenu(skeinforge_meta.getPluginsDirectoryPath(), menu, metaFilePath, skeinforge_meta.getPluginFileNames()) def getNewRepository(): 'Get new repository.' return skeinforge_meta.MetaRepository() def main(): "Display the meta dialog." settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/meta_plugins/000077500000000000000000000000001167321211700263135ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/meta_plugins/__init__.py000066400000000000000000000006571167321211700304340ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/skeinforge_application/skeinforge_plugins/meta_plugins/description.py000066400000000000000000000032431167321211700312120ustar00rootroot00000000000000""" This page is in the table of contents. Description is a script to store a description of the profile. ==Settings== ===Description Text=== Default is 'Write your profile description here.' The suggested format is a description, followed by a link to a profile post or web page. ==Example== Example of using description follows below. > python description.py This brings up the description dialog. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return DescriptionRepository() class DescriptionRepository: "A class to handle the description settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.meta_plugins.description.html', self) description = 'Write your description of the profile here.\n\nSuggested format is a description, followed by a link to the profile post or web page.' self.descriptionText = settings.TextSetting().getFromValue('Description Text:', self, description) def main(): "Display the file or directory dialog." settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/meta_plugins/polyfile.py000066400000000000000000000024471167321211700305170ustar00rootroot00000000000000""" This page is in the table of contents. Polyfile is a script to choose whether the skeinforge toolchain will operate on one file or all the files in a directory. ==Settings== ===Polyfile Choice=== Default is 'Execute File', ====Execute File==== When selected, the toolchain will operate on only the chosen file. ====Execute All Unmodified Files in a Directory'==== When selected, the toolchain will operate on all the unmodifed files in the directory that the chosen file is in. ==Example== Example of using polyfile follows below. > python polyfile.py This brings up the polyfile dialog. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from skeinforge_application.skeinforge_utilities import skeinforge_polyfile __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return skeinforge_polyfile.PolyfileRepository() def main(): "Display the file or directory dialog." settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/profile.py000066400000000000000000000112361167321211700256410ustar00rootroot00000000000000""" This page is in the table of contents. Profile is a script to set the craft types setting for the skeinforge chain. Profile presents the user with a choice of the craft types in the profile_plugins folder. The chosen craft type is used to determine the craft type profile for the skeinforge chain. The default craft type is extrusion. The setting is the selection. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. To change the profile setting, in a shell in the profile folder type: > python profile.py """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addSubmenus( craftTypeName, menu, pluginFileName, pluginPath, profileRadioVar ): "Add a tool plugin menu." submenu = settings.Tkinter.Menu( menu, tearoff = 0 ) menu.add_cascade( label = pluginFileName.capitalize(), menu = submenu ) settings.ToolDialog().addPluginToMenu( submenu, pluginPath ) submenu.add_separator() pluginModule = skeinforge_profile.getCraftTypePluginModule( pluginFileName ) profilePluginSettings = settings.getReadRepository( pluginModule.getNewRepository() ) isSelected = ( craftTypeName == pluginFileName ) for profileName in profilePluginSettings.profileList.value: value = isSelected and profileName == profilePluginSettings.profileListbox.value ProfileMenuRadio( pluginFileName, submenu, profileName, profileRadioVar, value ) def addToMenu( master, menu, repository, window ): "Add a tool plugin menu." ProfileMenuSaveListener( menu, window ) def addToProfileMenu( menu ): "Add a profile menu." settings.ToolDialog().addPluginToMenu(menu, archive.getUntilDot(archive.getSkeinforgePluginsPath('profile.py'))) menu.add_separator() directoryPath = skeinforge_profile.getPluginsDirectoryPath() pluginFileNames = skeinforge_profile.getPluginFileNames() craftTypeName = skeinforge_profile.getCraftTypeName() profileRadioVar = settings.Tkinter.StringVar() for pluginFileName in pluginFileNames: addSubmenus( craftTypeName, menu, pluginFileName, os.path.join( directoryPath, pluginFileName ), profileRadioVar ) def getNewRepository(): 'Get new repository.' return skeinforge_profile.ProfileRepository() class ProfileMenuRadio: "A class to display a profile menu radio button." def __init__( self, profilePluginFileName, menu, name, radioVar, value ): "Create a profile menu radio." self.activate = False self.menu = menu self.name = name self.profileJoinName = profilePluginFileName + '.& /' + name self.profilePluginFileName = profilePluginFileName self.radioVar = radioVar menu.add_radiobutton( label = name.replace('_', ' '), command = self.clickRadio, value = self.profileJoinName, variable = self.radioVar ) self.menuLength = menu.index( settings.Tkinter.END ) if value: self.radioVar.set( self.profileJoinName ) self.menu.invoke( self.menuLength ) self.activate = True def clickRadio(self): "Workaround for Tkinter bug, invoke and set the value when clicked." if not self.activate: return self.radioVar.set( self.profileJoinName ) pluginModule = skeinforge_profile.getCraftTypePluginModule( self.profilePluginFileName ) profilePluginSettings = settings.getReadRepository( pluginModule.getNewRepository() ) profilePluginSettings.profileListbox.value = self.name settings.writeSettings( profilePluginSettings ) profileSettings = skeinforge_profile.getReadProfileRepository() plugins = profileSettings.craftRadios for plugin in plugins: plugin.value = ( plugin.name == self.profilePluginFileName ) settings.writeSettings( profileSettings ) skeinforge_profile.updateProfileSaveListeners() class ProfileMenuSaveListener: "A class to update a profile menu." def __init__( self, menu, window ): "Set the menu." self.menu = menu addToProfileMenu( menu ) euclidean.addElementToListDictionaryIfNotThere( self, window, settings.globalProfileSaveListenerListTable ) def save(self): "Profile has been saved and profile menu should be updated." settings.deleteMenuItems( self.menu ) addToProfileMenu( self.menu ) def main(): "Display the profile dialog." settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/profile_plugins/000077500000000000000000000000001167321211700270255ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_plugins/profile_plugins/__init__.py000066400000000000000000000006571167321211700311460ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 3 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/skeinforge_application/skeinforge_plugins/profile_plugins/cutting.py000066400000000000000000000040721167321211700310570ustar00rootroot00000000000000""" This page is in the table of contents. Cutting is a script to set the cutting profile for the skeinforge chain. The displayed craft sequence is the sequence in which the tools craft the model and export the output. On the cutting dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm. The 'Delete Profile' button deletes the selected profile. The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles. To change the cutting profile, in a shell in the profile_plugins folder type: > python cutting.py """ from __future__ import absolute_import import __init__ from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftSequence(): "Get the cutting craft sequence." return 'chop preface outset multiply whittle drill lift flow feed home lash fillet limit unpause alteration export'.split() def getNewRepository(): 'Get new repository.' return CuttingRepository() class CuttingRepository: "A class to handle the cutting settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsSetCraftProfile( getCraftSequence(), 'end_mill', self, 'skeinforge_application.skeinforge_plugins.profile_plugins.cutting.html') def main(): "Display the export dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/profile_plugins/extrusion.py000066400000000000000000000042701167321211700314420ustar00rootroot00000000000000""" This page is in the table of contents. Extrusion is a script to set the extrusion profile for the skeinforge chain. The displayed craft sequence is the sequence in which the tools craft the model and export the output. On the extrusion dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if ABS is selected and the name ABS_black is in the input field, clicking the 'Add Profile' button will duplicate ABS and save it as ABS_black. The 'Delete Profile' button deletes the selected profile. The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles. To change the extrusion profile, in a shell in the profile_plugins folder type: > python extrusion.py """ from __future__ import absolute_import import __init__ from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftSequence(): 'Get the extrusion craft sequence.' return 'carve scale bottom preface widen inset fill multiply speed temperature raft skirt chamber tower jitter clip smooth stretch skin comb cool hop wipe oozebane splodge home lash fillet limit unpause dimension alteration export'.split() def getNewRepository(): 'Get new repository.' return ExtrusionRepository() class ExtrusionRepository: 'A class to handle the export settings.' def __init__(self): 'Set the default settings, execute title & settings fileName.' skeinforge_profile.addListsSetCraftProfile( getCraftSequence(), 'Default', self, 'skeinforge_application.skeinforge_plugins.profile_plugins.extrusion.html') def main(): 'Display the export dialog.' if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == '__main__': main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/profile_plugins/milling.py000066400000000000000000000040671167321211700310410ustar00rootroot00000000000000""" This page is in the table of contents. Milling is a script to set the milling profile for the skeinforge chain. The displayed craft sequence is the sequence in which the tools craft the model and export the output. On the milling dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm. The 'Delete Profile' button deletes the selected profile. The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles. To change the milling profile, in a shell in the profile_plugins folder type: > python milling.py """ from __future__ import absolute_import import __init__ from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftSequence(): "Get the milling craft sequence." return 'chop preface outset mill multiply drill lift flow feed home lash fillet limit unpause alteration export'.split() def getNewRepository(): 'Get new repository.' return MillingRepository() class MillingRepository: "A class to handle the milling settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsSetCraftProfile( getCraftSequence(), 'end_mill', self, 'skeinforge_application.skeinforge_plugins.profile_plugins.milling.html') def main(): "Display the export dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_plugins/profile_plugins/winding.py000066400000000000000000000040371167321211700310420ustar00rootroot00000000000000""" This page is in the table of contents. Winding is a script to set the winding profile for the skeinforge chain. The displayed craft sequence is the sequence in which the tools craft the model and export the output. On the winding dialog, clicking the 'Add Profile' button will duplicate the selected profile and give it the name in the input field. For example, if laser is selected and the name laser_10mm is in the input field, clicking the 'Add Profile' button will duplicate laser and save it as laser_10mm. The 'Delete Profile' button deletes the selected profile. The profile selection is the setting. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. However; adding and deleting a profile is a permanent action, for example 'Cancel' will not bring back any deleted profiles. To change the winding profile, in a shell in the profile_plugins folder type: > python winding.py """ from __future__ import absolute_import import __init__ from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile import sys __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getCraftSequence(): "Get the winding craft sequence." return 'cleave preface coil flow feed home lash fillet limit unpause alteration export'.split() def getNewRepository(): 'Get new repository.' return WindingRepository() class WindingRepository: "A class to handle the winding settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsSetCraftProfile( getCraftSequence(), 'free_wire', self, 'skeinforge_application.skeinforge_plugins.profile_plugins.winding.html') def main(): "Display the export dialog." if len(sys.argv) > 1: writeOutput(' '.join(sys.argv[1 :])) else: settings.startMainLoopFromConstructor(getNewRepository()) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_utilities/000077500000000000000000000000001167321211700241565ustar00rootroot00000000000000sfact-2011.12.18/skeinforge_application/skeinforge_utilities/__init__.py000066400000000000000000000006571167321211700262770ustar00rootroot00000000000000#This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module. import os import sys numberOfLevelsDeepInPackageHierarchy = 2 packageFilePath = os.path.abspath(__file__) for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ): packageFilePath = os.path.dirname( packageFilePath ) if packageFilePath not in sys.path: sys.path.insert( 0, packageFilePath ) sfact-2011.12.18/skeinforge_application/skeinforge_utilities/skeinforge_analyze.py000066400000000000000000000060001167321211700304030ustar00rootroot00000000000000""" Analyze is a script to access the plugins which analyze a gcode file. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import os import sys import traceback __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return AnalyzeRepository() def getPluginFileNames(): "Get analyze plugin fileNames." return archive.getPluginFileNamesFromDirectoryPath( getPluginsDirectoryPath() ) def getPluginsDirectoryPath(): "Get the plugins directory path." return archive.getAnalyzePluginsDirectoryPath() def writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText=''): "Analyze a gcode file." gcodeText = archive.getTextIfEmpty(fileName, gcodeText) pluginFileNames = getPluginFileNames() window = None for pluginFileName in pluginFileNames: analyzePluginsDirectoryPath = getPluginsDirectoryPath() pluginModule = archive.getModuleWithDirectoryPath( analyzePluginsDirectoryPath, pluginFileName ) if pluginModule is not None: try: newWindow = pluginModule.writeOutput(fileName, fileNamePenultimate, fileNameSuffix, filePenultimateWritten, gcodeText ) if newWindow is not None: window = newWindow except: print('Warning, the tool %s could not analyze the output.' % pluginFileName ) print('Exception traceback in writeOutput in skeinforge_analyze:') traceback.print_exc(file=sys.stdout) return window class AnalyzeRepository: "A class to handle the analyze settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_analyze.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( [ ('Gcode text files', '*.gcode') ], 'Open File for Analyze', self, '') importantFileNames = ['skeiniso', 'skeinlayer', 'statistic'] settings.getRadioPluginsAddPluginFrame( getPluginsDirectoryPath(), importantFileNames, getPluginFileNames(), self ) self.executeTitle = 'Analyze' def execute(self): "Analyze button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, [], self.fileNameInput.wasCancelled ) for fileName in fileNames: writeOutput( fileName, fileName ) def main(): "Write analyze output." fileName = ' '.join(sys.argv[1 :]) settings.startMainLoopFromWindow(writeOutput(fileName, fileName)) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_utilities/skeinforge_craft.py000066400000000000000000000216411167321211700300470ustar00rootroot00000000000000""" Craft is a script to access the plugins which craft a gcode file. The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_analyze from skeinforge_application.skeinforge_utilities import skeinforge_polyfile from skeinforge_application.skeinforge_utilities import skeinforge_profile import os import sys import time __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getChainText( fileName, procedure ): "Get a crafted shape file." text='' if fileName.endswith('.gcode') or fileName.endswith('.svg'): text = archive.getFileText(fileName) procedures = getProcedures( procedure, text ) return getChainTextFromProcedures( fileName, procedures, text ) def getChainTextFromProcedures(fileName, procedures, text): 'Get a crafted shape file from a list of procedures.' lastProcedureTime = time.time() for procedure in procedures: craftModule = getCraftModule(procedure) if craftModule is not None: text = craftModule.getCraftedText(fileName, text) if text == '': print('Warning, the text was not recognized in getChainTextFromProcedures in skeinforge_craft for') print(fileName) return '' if gcodec.isProcedureDone( text, procedure ): print('%s procedure took %s.' % (procedure.capitalize(), euclidean.getDurationString(time.time() - lastProcedureTime))) lastProcedureTime = time.time() return text def getCraftModule(pluginName): 'Get craft module.' return archive.getModuleWithDirectoryPath(getPluginsDirectoryPath(), pluginName) def getCraftPreferences(pluginName): 'Get craft preferences.' return settings.getReadRepository(getCraftModule(pluginName).getNewRepository()).preferences def getCraftValue(preferenceName, preferences): "Get craft preferences value." for preference in preferences: if preference.name.startswith(preferenceName): return preference.value return None def getLastModule(): "Get the last tool." craftSequence = getReadCraftSequence() if len( craftSequence ) < 1: return None return getCraftModule( craftSequence[-1] ) def getNewRepository(): 'Get new repository.' return CraftRepository() def getPluginFileNames(): "Get craft plugin fileNames." craftSequence = getReadCraftSequence() craftSequence.sort() return craftSequence def getPluginsDirectoryPath(): "Get the plugins directory path." return archive.getCraftPluginsDirectoryPath() def getProcedures( procedure, text ): "Get the procedures up to and including the given procedure." craftSequence = getReadCraftSequence() sequenceIndexPlusOneFromText = getSequenceIndexPlusOneFromText(text) sequenceIndexFromProcedure = getSequenceIndexFromProcedure(procedure) return craftSequence[ sequenceIndexPlusOneFromText : sequenceIndexFromProcedure + 1 ] def getReadCraftSequence(): "Get profile sequence." return skeinforge_profile.getCraftTypePluginModule().getCraftSequence() def getSequenceIndexFromProcedure(procedure): "Get the profile sequence index of the procedure. Return None if the procedure is not in the sequence" craftSequence = getReadCraftSequence() if procedure not in craftSequence: return 0 return craftSequence.index(procedure) def getSequenceIndexPlusOneFromText(fileText): "Get the profile sequence index of the file plus one. Return zero if the procedure is not in the file" craftSequence = getReadCraftSequence() for craftSequenceIndex in xrange( len( craftSequence ) - 1, - 1, - 1 ): procedure = craftSequence[ craftSequenceIndex ] if gcodec.isProcedureDone( fileText, procedure ): return craftSequenceIndex + 1 return 0 def writeChainTextWithNounMessage(fileName, procedure, shouldAnalyze=True): 'Get and write a crafted shape file.' print('') print('The %s tool is parsing the file:' % procedure) print(os.path.basename(fileName)) print('') startTime = time.time() fileNameSuffix = fileName[: fileName.rfind('.')] + '_' + procedure + '.gcode' craftText = getChainText(fileName, procedure) if craftText == '': print('Warning, there was no text output in writeChainTextWithNounMessage in skeinforge_craft for:') print(fileName) return archive.writeFileText(fileNameSuffix, craftText) window = None if shouldAnalyze: window = skeinforge_analyze.writeOutput(fileName, fileNameSuffix, fileNameSuffix, True, craftText) print('') print('The %s tool has created the file:' % procedure) print(fileNameSuffix) print('') print('It took %s to craft the file.' % euclidean.getDurationString(time.time() - startTime)) return window def writeOutput(fileName, shouldAnalyze=True): "Craft a gcode file with the last module." pluginModule = getLastModule() if pluginModule is not None: return pluginModule.writeOutput(fileName, shouldAnalyze) def writeSVGTextWithNounMessage(fileName, repository, shouldAnalyze=True): 'Get and write an svg text and print messages.' print('') print('The %s tool is parsing the file:' % repository.lowerName) print(os.path.basename(fileName)) print('') startTime = time.time() fileNameSuffix = fileName[: fileName.rfind('.')] + '_' + repository.lowerName + '.svg' craftText = getChainText(fileName, repository.lowerName) if craftText == '': return archive.writeFileText(fileNameSuffix, craftText) print('') print('The %s tool has created the file:' % repository.lowerName) print(fileNameSuffix) print('') print('It took %s to craft the file.' % euclidean.getDurationString(time.time() - startTime)) if shouldAnalyze: settings.getReadRepository(repository) settings.openSVGPage(fileNameSuffix, repository.svgViewer.value) class CraftRadioButtonsSaveListener: "A class to update the craft radio buttons." def addToDialog( self, gridPosition ): "Add this to the dialog." euclidean.addElementToListDictionaryIfNotThere( self, self.repository.repositoryDialog, settings.globalProfileSaveListenerListTable ) self.gridPosition = gridPosition.getCopy() self.gridPosition.row = gridPosition.rowStart self.gridPosition.increment() self.setRadioButtons() def getFromRadioPlugins( self, radioPlugins, repository ): "Initialize." self.name = 'CraftRadioButtonsSaveListener' self.radioPlugins = radioPlugins self.repository = repository repository.displayEntities.append(self) return self def save(self): "Profile has been saved and craft radio plugins should be updated." self.setRadioButtons() def setRadioButtons(self): "Profile has been saved and craft radio plugins should be updated." activeRadioPlugins = [] craftSequence = skeinforge_profile.getCraftTypePluginModule().getCraftSequence() gridPosition = self.gridPosition.getCopy() isRadioPluginSelected = False settings.getReadRepository(self.repository) for radioPlugin in self.radioPlugins: if radioPlugin.name in craftSequence: activeRadioPlugins.append(radioPlugin) radioPlugin.incrementGridPosition(gridPosition) if radioPlugin.value: radioPlugin.setSelect() isRadioPluginSelected = True else: radioPlugin.radiobutton.grid_remove() if not isRadioPluginSelected: radioPluginNames = self.repository.importantFileNames + [activeRadioPlugins[0].name] settings.getSelectedRadioPlugin(radioPluginNames , activeRadioPlugins).setSelect() self.repository.pluginFrame.update() class CraftRepository: "A class to handle the craft settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_craft.html', self) self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Craft', self, '') self.importantFileNames = ['carve', 'chop', 'feed', 'flow', 'lift', 'raft', 'speed'] allCraftNames = archive.getPluginFileNamesFromDirectoryPath(getPluginsDirectoryPath()) self.radioPlugins = settings.getRadioPluginsAddPluginFrame(getPluginsDirectoryPath(), self.importantFileNames, allCraftNames, self) CraftRadioButtonsSaveListener().getFromRadioPlugins(self.radioPlugins, self) self.executeTitle = 'Craft' def execute(self): "Craft button has been clicked." fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, [], self.fileNameInput.wasCancelled ) for fileName in fileNames: writeOutput(fileName) def main(): "Write craft output." writeOutput(' '.join(sys.argv[1 :]), False) if __name__ == "__main__": main() sfact-2011.12.18/skeinforge_application/skeinforge_utilities/skeinforge_help.py000066400000000000000000000072151167321211700277010ustar00rootroot00000000000000""" Help has buttons and menu items to open help, blog and forum pages in your primary browser. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return HelpRepository() class HelpRepository: "A class to handle the help settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_help.html', self) announcementsText = '- Announcements - ' announcementsLabel = settings.LabelDisplay().getFromName(announcementsText, self ) announcementsLabel.columnspan = 6 settings.LabelDisplay().getFromName('Fabmetheus Blog, Announcements & Questions:', self ) settings.HelpPage().getFromNameAfterHTTP('fabmetheus.blogspot.com/', 'Fabmetheus Blog', self ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Documentation -', self ) settings.LabelDisplay().getFromName('Local Documentation Table of Contents: ', self ) settings.HelpPage().getFromNameSubName('Contents', self, 'contents.html') settings.LabelDisplay().getFromName('Wiki Manual with Pictures & Charts: ', self ) settings.HelpPage().getFromNameAfterHTTP('fabmetheus.crsndoo.com/wiki/index.php/Skeinforge', 'Wiki Manual', self ) settings.LabelDisplay().getFromName('Skeinforge Overview: ', self ) settings.HelpPage().getFromNameSubName('Skeinforge Overview', self, 'skeinforge_application.skeinforge.html') settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('SFACT FAQs:', self) settings.HelpPage().getFromNameAfterHTTP('http://titanpad.com/XTUJXiNHmd', ' SFACT FAQs ', self ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Search -', self ) settings.LabelDisplay().getFromName('Reprap Search:', self ) settings.HelpPage().getFromNameAfterHTTP('members.axion.net/~enrique/search_reprap.html', 'Reprap Search', self ) settings.LabelDisplay().getFromName('Skeinforge Search:', self ) settings.HelpPage().getFromNameAfterHTTP('members.axion.net/~enrique/search_skeinforge.html', 'Skeinforge Search', self ) settings.LabelDisplay().getFromName('Web Search:', self ) settings.HelpPage().getFromNameAfterHTTP('members.axion.net/~enrique/search_web.html', 'Web Search', self ) settings.LabelSeparator().getFromRepository(self) settings.LabelDisplay().getFromName('- Troubleshooting -', self ) settings.LabelDisplay().getFromName('Skeinforge Forum:', self) settings.HelpPage().getFromNameAfterHTTP('forums.reprap.org/list.php?154', ' Skeinforge Forum ', self ) settings.LabelSeparator().getFromRepository(self) self.version = settings.LabelDisplay().getFromName('Version: ' + archive.getFileText(archive.getVersionFileName()), self) self.wikiManualPrimary = settings.BooleanSetting().getFromValue('Wiki Manual Primary', self, True ) self.wikiManualPrimary.setUpdateFunction( self.save ) def save(self): "Write the entities." settings.writeSettingsPrintMessage(self) sfact-2011.12.18/skeinforge_application/skeinforge_utilities/skeinforge_meta.py000066400000000000000000000026461167321211700277020ustar00rootroot00000000000000""" Meta is a script to access the plugins which handle meta information. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile import os __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getNewRepository(): 'Get new repository.' return MetaRepository() def getPluginFileNames(): "Get meta plugin file names." return archive.getPluginFileNamesFromDirectoryPath( getPluginsDirectoryPath() ) def getPluginsDirectoryPath(): "Get the plugins directory path." return archive.getSkeinforgePluginsPath('meta_plugins') class MetaRepository: "A class to handle the meta settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_meta.html', self) importantFileNames = ['polyfile'] settings.getRadioPluginsAddPluginFrame( getPluginsDirectoryPath(), importantFileNames, getPluginFileNames(), self ) sfact-2011.12.18/skeinforge_application/skeinforge_utilities/skeinforge_polyfile.py000066400000000000000000000061531167321211700305740ustar00rootroot00000000000000""" Polyfile is a script to choose whether the skeinforge toolchain will operate on one file or all the files in a directory. """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import settings from skeinforge_application.skeinforge_utilities import skeinforge_profile __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def getFileOrDirectoryTypes( fileName, fileTypes, wasCancelled ): "Get the gcode files in the directory the file is in if directory setting is true. Otherwise, return the file in a list." if isEmptyOrCancelled( fileName, wasCancelled ): return [] if isDirectorySetting(): return archive.getFilesWithFileTypesWithoutWords( fileTypes, [], fileName ) return [ fileName ] def getFileOrDirectoryTypesUnmodifiedGcode(fileName, fileTypes, wasCancelled): "Get the gcode files in the directory the file is in if directory setting is true. Otherwise, return the file in a list." if isEmptyOrCancelled(fileName, wasCancelled): return [] if isDirectorySetting(): return archive.getFilesWithFileTypesWithoutWords(fileTypes, [], fileName) return [fileName] def getFileOrGcodeDirectory( fileName, wasCancelled, words = [] ): "Get the gcode files in the directory the file is in if directory setting is true. Otherwise, return the file in a list." if isEmptyOrCancelled( fileName, wasCancelled ): return [] if isDirectorySetting(): dotIndex = fileName.rfind('.') if dotIndex < 0: print('The file name should have a suffix, like myfile.xml.') print('Since the file name does not have a suffix, nothing will be done') suffix = fileName[ dotIndex + 1 : ] return archive.getFilesWithFileTypeWithoutWords( suffix, words, fileName ) return [ fileName ] def getNewRepository(): 'Get new repository.' return PolyfileRepository() def isDirectorySetting(): "Determine if the directory setting is true." return settings.getReadRepository( PolyfileRepository() ).directorySetting.value def isEmptyOrCancelled( fileName, wasCancelled ): "Determine if the fileName is empty or the dialog was cancelled." return str(fileName) == '' or str(fileName) == '()' or wasCancelled class PolyfileRepository: "A class to handle the polyfile settings." def __init__(self): "Set the default settings, execute title & settings fileName." skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_polyfile.html', self) self.directoryOrFileChoiceLabel = settings.LabelDisplay().getFromName('Directory or File Choice: ', self ) directoryLatentStringVar = settings.LatentStringVar() self.directorySetting = settings.Radio().getFromRadio( directoryLatentStringVar, 'Execute All Unmodified Files in a Directory', self, False ) self.fileSetting = settings.Radio().getFromRadio( directoryLatentStringVar, 'Execute File', self, True ) sfact-2011.12.18/skeinforge_application/skeinforge_utilities/skeinforge_profile.py000066400000000000000000000425511167321211700304130ustar00rootroot00000000000000""" Profile is a script to set the craft types setting for the skeinforge chain. Profile presents the user with a choice of the craft types in the profile_plugins folder. The chosen craft type is used to determine the craft type profile for the skeinforge chain. The default craft type is extrusion. The setting is the selection. If you hit 'Save and Close' the selection will be saved, if you hit 'Cancel' the selection will not be saved. To change the profile setting, in a shell in the profile folder type: > python profile.py """ from __future__ import absolute_import #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module. import __init__ from fabmetheus_utilities import archive from fabmetheus_utilities import euclidean from fabmetheus_utilities import gcodec from fabmetheus_utilities import settings import os import shutil __author__ = 'Enrique Perez (perez_enrique@yahoo.com)' __date__ = '$Date: 2008/21/04 $' __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' def addListsSetCraftProfile( craftSequence, defaultProfile, repository, fileNameHelp ): "Set the craft profile repository." settings.addListsToRepository(fileNameHelp, repository) repository.craftSequenceLabel = settings.LabelDisplay().getFromName('Craft Sequence: ', repository ) craftToolStrings = [] for craftTool in craftSequence[ : - 1 ]: craftToolStrings.append( settings.getEachWordCapitalized( craftTool ) + '->') craftToolStrings.append( settings.getEachWordCapitalized( craftSequence[-1] ) ) for craftToolStringIndex in xrange( 0, len( craftToolStrings ), 5 ): craftLine = ' '.join( craftToolStrings[ craftToolStringIndex : craftToolStringIndex + 5 ] ) settings.LabelDisplay().getFromName( craftLine, repository ) settings.LabelDisplay().getFromName('', repository ) repository.profileList = ProfileList().getFromName('Profile List:', repository ) repository.profileListbox = ProfileListboxSetting().getFromListSetting( repository.profileList, 'Profile Selection:', repository, defaultProfile ) repository.addListboxSelection = AddProfile().getFromProfileListboxSettingRepository( repository.profileListbox, repository ) repository.deleteListboxSelection = DeleteProfile().getFromProfileListboxSettingRepository( repository.profileListbox, repository ) directoryName = archive.getProfilesPath() archive.makeDirectory(directoryName) repository.windowPosition.value = '0+400' def addListsToCraftTypeRepository(fileNameHelp, repository): "Add the value to the lists." settings.addListsToRepositoryByFunction(fileNameHelp, getProfileDirectory, repository) dotsMinusOne = fileNameHelp.count('.') - 1 x = 0 xAddition = 400 for step in xrange(dotsMinusOne): x += xAddition xAddition /= 2 repository.windowPosition.value = '%s+0' % x def cancelAll(): "Cancel all the dialogs." for globalRepositoryDialogValue in settings.getGlobalRepositoryDialogValues(): globalRepositoryDialogValue.cancel() def getCraftTypeName(subName=''): "Get the craft type from the profile." profileSettings = getReadProfileRepository() craftTypeName = settings.getSelectedPluginName( profileSettings.craftRadios ) if subName == '': return craftTypeName return os.path.join( craftTypeName, subName ) def getCraftTypePluginModule( craftTypeName = ''): "Get the craft type plugin module." if craftTypeName == '': craftTypeName = getCraftTypeName() profilePluginsDirectoryPath = getPluginsDirectoryPath() return archive.getModuleWithDirectoryPath( profilePluginsDirectoryPath, craftTypeName ) def getNewRepository(): 'Get new repository.' return ProfileRepository() def getPluginFileNames(): "Get analyze plugin fileNames." return archive.getPluginFileNamesFromDirectoryPath( getPluginsDirectoryPath() ) def getPluginsDirectoryPath(): "Get the plugins directory path." return archive.getSkeinforgePluginsPath('profile_plugins') def getProfileDirectory(): "Get the profile directory." craftTypeName = getCraftTypeName() return os.path.join( craftTypeName, getProfileName(craftTypeName) ) def getProfileName(craftTypeName): "Get the profile name from the craft type name." craftTypeSettings = getCraftTypePluginModule(craftTypeName).getNewRepository() settings.getReadRepository(craftTypeSettings) return craftTypeSettings.profileListbox.value def getReadProfileRepository(): "Get the read profile repository." return settings.getReadRepository( ProfileRepository() ) def updateProfileSaveListeners(): "Call the save function of all the update profile save listeners." for globalProfileSaveListener in euclidean.getListTableElements( settings.globalProfileSaveListenerListTable ): globalProfileSaveListener.save() cancelAll() class AddProfile: "A class to add a profile." def addSelection(self): "Add the selection of a listbox setting." entryText = self.entry.get() if entryText == '': print('To add to the profiles, enter the material name.') return self.profileListboxSetting.listSetting.setValueToFolders() if entryText in self.profileListboxSetting.listSetting.value: print('There is already a profile by the name of %s, so no profile will be added.' % entryText ) return self.entry.delete( 0, settings.Tkinter.END ) craftTypeProfileDirectory = archive.getProfilesPath( self.profileListboxSetting.listSetting.craftTypeName ) destinationDirectory = os.path.join( craftTypeProfileDirectory, entryText ) shutil.copytree( self.profileListboxSetting.getSelectedFolder(), destinationDirectory ) self.profileListboxSetting.listSetting.setValueToFolders() self.profileListboxSetting.value = entryText self.profileListboxSetting.setStateToValue() def addSelectionWithEvent(self, event): "Add the selection of a listbox setting, given an event." self.addSelection() def addToDialog( self, gridPosition ): "Add this to the dialog." gridPosition.increment() self.entry = settings.Tkinter.Entry( gridPosition.master ) self.entry.bind('', self.addSelectionWithEvent ) self.entry.grid( row = gridPosition.row, column = 1, columnspan = 3, sticky = settings.Tkinter.W ) self.addButton = settings.Tkinter.Button( gridPosition.master, activebackground = 'black', activeforeground = 'white', text = 'Add Profile', command = self.addSelection ) self.addButton.grid( row = gridPosition.row, column = 0 ) def getFromProfileListboxSettingRepository( self, profileListboxSetting, repository ): "Initialize." self.profileListboxSetting = profileListboxSetting self.repository = repository repository.displayEntities.append(self) return self class DeleteProfile( AddProfile ): "A class to delete the selection of a listbox profile." def addToDialog( self, gridPosition ): "Add this to the dialog." gridPosition.increment() self.deleteButton = settings.Tkinter.Button( gridPosition.master, activebackground = 'black', activeforeground = 'white', text = "Delete Profile", command = self.deleteSelection ) self.deleteButton.grid( row = gridPosition.row, column = 0 ) def deleteSelection(self): "Delete the selection of a listbox setting." DeleteProfileDialog( self.profileListboxSetting, settings.Tkinter.Tk() ) class DeleteProfileDialog: "A dialog to delete a profile." def __init__(self, profileListboxSetting, root): "Display a delete dialog." self.profileListboxSetting = profileListboxSetting self.root = root root.title('Delete Warning') rowIndex = 0 self.label = settings.Tkinter.Label(self.root, text = 'Do you want to delete the profile?') self.label.grid(row = rowIndex, column = 0, columnspan = 3, sticky = settings.Tkinter.W) rowIndex += 1 columnIndex = 1 deleteButton = settings.Tkinter.Button(root, activebackground = 'black', activeforeground = 'red', command = self.delete, fg = 'red', text = 'Delete') deleteButton.grid(row = rowIndex, column = columnIndex) columnIndex += 1 noButton = settings.Tkinter.Button(root, activebackground = 'black', activeforeground = 'darkgreen', command = self.no, fg = 'darkgreen', text = 'Do Nothing') noButton.grid(row = rowIndex, column = columnIndex) def delete(self): "Delete the selection of a listbox setting." self.profileListboxSetting.setToDisplay() self.profileListboxSetting.listSetting.setValueToFolders() if self.profileListboxSetting.value not in self.profileListboxSetting.listSetting.value: return lastSelectionIndex = 0 currentSelectionTuple = self.profileListboxSetting.listbox.curselection() if len(currentSelectionTuple) > 0: lastSelectionIndex = int(currentSelectionTuple[0]) else: print('No profile is selected, so no profile will be deleted.') return craftTypeName = self.profileListboxSetting.listSetting.craftTypeName settings.deleteDirectory(archive.getProfilesPath(craftTypeName), self.profileListboxSetting.value) settings.deleteDirectory(settings.getProfilesDirectoryInAboveDirectory(craftTypeName), self.profileListboxSetting.value) self.profileListboxSetting.listSetting.setValueToFolders() if len(self.profileListboxSetting.listSetting.value) < 1: defaultSettingsDirectory = archive.getProfilesPath(os.path.join(craftTypeName, self.profileListboxSetting.defaultValue)) archive.makeDirectory(defaultSettingsDirectory) self.profileListboxSetting.listSetting.setValueToFolders() lastSelectionIndex = min(lastSelectionIndex, len(self.profileListboxSetting.listSetting.value) - 1) self.profileListboxSetting.value = self.profileListboxSetting.listSetting.value[lastSelectionIndex] self.profileListboxSetting.setStateToValue() self.no() def no(self): "The dialog was closed." self.root.destroy() class ProfileList: "A class to list the profiles." def getFromName( self, name, repository ): "Initialize." self.craftTypeName = repository.lowerName self.name = name self.repository = repository self.setValueToFolders() return self def setValueToFolders(self): "Set the value to the folders in the profiles directories." self.value = settings.getFolders( archive.getProfilesPath( self.craftTypeName ) ) defaultFolders = settings.getFolders( settings.getProfilesDirectoryInAboveDirectory( self.craftTypeName ) ) for defaultFolder in defaultFolders: if defaultFolder not in self.value: self.value.append( defaultFolder ) self.value.sort() class ProfileListboxSetting( settings.StringSetting ): "A class to handle the profile listbox." def addToDialog( self, gridPosition ): "Add this to the dialog." #http://www.pythonware.com/library/tkinter/introduction/x5453-patterns.htm self.root = gridPosition.master gridPosition.increment() from fabmetheus_utilities.hidden_scrollbar import HiddenScrollbar scrollbar = HiddenScrollbar( gridPosition.master ) self.listbox = settings.Tkinter.Listbox( gridPosition.master, selectmode = settings.Tkinter.SINGLE, yscrollcommand = scrollbar.set ) self.listbox.bind('', self.buttonReleaseOne ) gridPosition.master.bind('', self.focusIn ) scrollbar.config( command = self.listbox.yview ) self.listbox.grid( row = gridPosition.row, column = 0, sticky = settings.Tkinter.N + settings.Tkinter.S ) scrollbar.grid( row = gridPosition.row, column = 1, sticky = settings.Tkinter.N + settings.Tkinter.S ) self.setStateToValue() self.repository.saveListenerTable['updateProfileSaveListeners'] = updateProfileSaveListeners def buttonReleaseOne(self, event): "Button one released." self.setValueToIndex( self.listbox.nearest(event.y) ) def focusIn(self, event): "The root has gained focus." settings.getReadRepository(self.repository) self.setStateToValue() def getFromListSetting( self, listSetting, name, repository, value ): "Initialize." self.getFromValueOnly( name, repository, value ) self.listSetting = listSetting repository.displayEntities.append(self) repository.preferences.append(self) return self def getSelectedFolder(self): "Get the selected folder." settingProfileSubfolder = settings.getSubfolderWithBasename( self.value, archive.getProfilesPath( self.listSetting.craftTypeName ) ) if settingProfileSubfolder is not None: return settingProfileSubfolder toolProfileSubfolder = settings.getSubfolderWithBasename( self.value, settings.getProfilesDirectoryInAboveDirectory( self.listSetting.craftTypeName ) ) return toolProfileSubfolder def setStateToValue(self): "Set the listbox items to the list setting." self.listbox.delete( 0, settings.Tkinter.END ) for item in self.listSetting.value: self.listbox.insert( settings.Tkinter.END, item ) if self.value == item: self.listbox.select_set( settings.Tkinter.END ) def setToDisplay(self): "Set the selection value to the listbox selection." currentSelectionTuple = self.listbox.curselection() if len( currentSelectionTuple ) > 0: self.setValueToIndex( int( currentSelectionTuple[0] ) ) def setValueToIndex( self, index ): "Set the selection value to the index." valueString = self.listbox.get( index ) self.setValueToString( valueString ) def setValueToString( self, valueString ): "Set the value to the value string." self.value = valueString if self.getSelectedFolder() is None: self.value = self.defaultValue if self.getSelectedFolder() is None: if len( self.listSetting.value ) > 0: self.value = self.listSetting.value[0] class ProfilePluginRadioButtonsSaveListener: "A class to update the profile radio buttons." def addToDialog( self, gridPosition ): "Add this to the dialog." euclidean.addElementToListDictionaryIfNotThere( self, self.repository.repositoryDialog, settings.globalProfileSaveListenerListTable ) def getFromRadioPlugins( self, radioPlugins, repository ): "Initialize." self.name = 'ProfilePluginRadioButtonsSaveListener' self.radioPlugins = radioPlugins self.repository = repository repository.displayEntities.append(self) return self def save(self): "Profile has been saved and profile radio plugins should be updated." craftTypeName = getCraftTypeName() for radioPlugin in self.radioPlugins: if radioPlugin.name == craftTypeName: if radioPlugin.setSelect(): self.repository.pluginFrame.update() return class ProfileRepository: "A class to handle the profile entities." def __init__(self): "Set the default entities, execute title & repository fileName." settings.addListsToRepository('skeinforge_application.skeinforge_utilities.skeinforge_profile.html', self) importantFileNames = ['extrusion'] self.craftRadios = settings.getRadioPluginsAddPluginFrame( getPluginsDirectoryPath(), importantFileNames, getPluginFileNames(), self ) ProfilePluginRadioButtonsSaveListener().getFromRadioPlugins( self.craftRadios, self ) for craftRadio in self.craftRadios: craftRadio.updateFunction = self.updateRelay directoryName = archive.getProfilesPath() archive.makeDirectory(directoryName) self.windowPosition.value = '0+200' def updateRelay(self): "Update the plugin frame then the ProfileSaveListeners." self.pluginFrame.update() updateProfileSaveListeners() class ProfileSelectionMenuRadio: "A class to display a profile selection menu radio button." def addToDialog( self, gridPosition ): "Add this to the dialog." self.activate = False self.menuButtonDisplay.setToNameAddToDialog( self.valueName, gridPosition ) self.menuButtonDisplay.menu.add_radiobutton( label = self.valueName, command = self.clickRadio, value = self.valueName, variable = self.menuButtonDisplay.radioVar ) self.menuLength = self.menuButtonDisplay.menu.index( settings.Tkinter.END ) if self.value: self.menuButtonDisplay.radioVar.set( self.valueName ) self.menuButtonDisplay.menu.invoke( self.menuLength ) euclidean.addElementToListDictionaryIfNotThere( self.repository, self.repository.repositoryDialog, settings.globalProfileSaveListenerListTable ) self.activate = True def clickRadio(self): "Workaround for Tkinter bug, invoke and set the value when clicked." if not self.activate: return settings.saveAll() self.menuButtonDisplay.radioVar.set( self.valueName ) pluginModule = getCraftTypePluginModule() profilePluginSettings = settings.getReadRepository( pluginModule.getNewRepository() ) profilePluginSettings.profileListbox.value = self.name settings.writeSettings( profilePluginSettings ) updateProfileSaveListeners() def getFromMenuButtonDisplay( self, menuButtonDisplay, name, repository, value ): "Initialize." self.setToMenuButtonDisplay( menuButtonDisplay, name, repository, value ) self.valueName = name.replace('_', ' ') return self def setToMenuButtonDisplay( self, menuButtonDisplay, name, repository, value ): "Initialize." self.menuButtonDisplay = menuButtonDisplay self.menuButtonDisplay.menuRadios.append(self) self.name = name self.repository = repository self.value = value repository.displayEntities.append(self) class ProfileTypeMenuRadio( ProfileSelectionMenuRadio ): "A class to display a profile type menu radio button." def clickRadio(self): "Workaround for Tkinter bug, invoke and set the value when clicked." if not self.activate: return settings.saveAll() self.menuButtonDisplay.radioVar.set( self.valueName ) profileSettings = getReadProfileRepository() plugins = profileSettings.craftRadios for plugin in plugins: plugin.value = ( plugin.name == self.name ) settings.writeSettings( profileSettings ) updateProfileSaveListeners() def getFromMenuButtonDisplay( self, menuButtonDisplay, name, repository, value ): "Initialize." self.setToMenuButtonDisplay( menuButtonDisplay, name, repository, value ) self.valueName = settings.getEachWordCapitalized( name ) return self sfact-2011.12.18/skeinforge_application/terminal.sh000066400000000000000000000014621167321211700221010ustar00rootroot00000000000000#!/bin/sh # # Script to open the bash terminal in this directory. # # Usage: set the executable property to true if it isn't already. Then double click the file. # echo 'Directory listing:' echo '' ls echo '' echo 'To run a python script (.py) listed above, try typing something like:' echo 'python filename' echo '' echo 'For example, in the skeinforge_application directory you could run skeinforge by typing:' echo 'python skeinforge.py' echo '' echo 'To skeinforge the test.stl file from the command line, in the skeinforge_application directory you could type:' echo 'python skeinforge.py test.stl' echo '' echo 'To run a script in a subdirectory, append the directory path. For example, to run skeinforge from the top directory you could type:' echo 'python skeinforge_application/skeinforge.py' echo '' bash sfact-2011.12.18/skeinforge_application/test.stl000066400000000000000000002252011167321211700214340ustar00rootroot00000000000000solid "Screw_Holder_Bottom"; Produced by Art of Illusion 2.4, Fri Oct 16 16:42:04 PDT 2009 facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.804173569059 0.110046151702 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 24.730643081307 0 vertex 14.883210818105 25.830303993361 0 vertex 15.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 23 0 vertex 54.002309837942 24.730643081307 0 vertex 60 40 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 54.002309837942 15.269356918694 0 vertex 48.011309837942 15.269356918694 0 vertex 54.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 15.830303993361 11.883210818105 0 vertex 16.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 43.737436867076 27.737436867076 0 vertex 43.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 43.169696006639 15.116789181895 0 vertex 42.5 15.25 0 vertex 41.422110817733 17 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 48.011309837942 24.730643081307 0 vertex 54.002309837942 24.730643081307 0 vertex 48.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 43.169696006639 28.116789181895 0 vertex 42.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 40 0 vertex 52 30 0 vertex 52 40 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 14.169696006639 0 vertex 14.75 13.5 0 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 27.169696006639 0 vertex 14.042553191489 30 0 vertex 15.262563132924 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 16.5 11.75 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 48.011309837942 15.195826430941 0.110046151702 vertex 54.002309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 17.169696006639 28.116789181895 0 vertex 16.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 14.75 13.5 0 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 17 0 vertex 60 17 0 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 42.5 11.75 0 vertex 43.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 15.262563132924 14.737436867076 0 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 14.464705848856 10 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 15.830303993361 28.116789181895 0 vertex 15.262563132924 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 15.262563132924 12.262563132924 0 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 16.5 28.25 0 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 24.730643081307 0 vertex 60 23 0 vertex 54.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 23 0 vertex 16.5 24.75 0 vertex 17.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 15.195826430941 0.110046151702 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.75 26.5 0 vertex 12.002309837942 24.730643081307 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 60 40 0 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.422110817733 17 0 vertex 48.011309837942 17 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 13.5 0 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 6.011309837942 17 0 vertex 6.011309837942 15.269356918694 0 vertex 0 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.422110817733 17 0 vertex 41.830303993361 15.116789181895 0 vertex 41.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 11.883210818105 0 vertex 17.737436867076 12.262563132924 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 15.269356918694 0 vertex 0 10 0 vertex 0 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 25.830303993361 0 vertex 12.002309837942 24.730643081307 0 vertex 14.75 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 52 30 0 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 17 0 vertex 43.737436867076 14.737436867076 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 15.25 0 vertex 41.830303993361 15.116789181895 0 vertex 41.422110817733 17 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 14.883210818105 12.830303993361 0 vertex 6.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 23 0 vertex 0 30 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 12.002309837942 15.269356918694 0 vertex 6.011309837942 15.269356918694 0 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 60 17 0 vertex 52 10 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 23 0 vertex 0 23 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 48.011309837942 15.269356918694 0 vertex 44.25 13.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 27.169696006639 0 vertex 41.262563132924 25.262563132924 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 25.830303993361 0 vertex 18.25 26.5 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 14.737436867076 0 vertex 41.262563132924 14.737436867076 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.830303993361 24.883210818105 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 25.262563132924 0 vertex 18.116789181895 25.830303993361 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 12.262563132924 0 vertex 18.116789181895 12.830303993361 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 12.262563132924 0 vertex 41.262563132924 12.262563132924 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 17.169696006639 28.116789181895 0 vertex 41.830303993361 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 11.75 0 vertex 14.464705848856 10 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.25 26.5 0 vertex 44.116789181895 27.169696006639 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 12.830303993361 0 vertex 41.262563132924 12.262563132924 0 vertex 17.737436867076 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 17.737436867076 25.262563132924 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 12.830303993361 0 vertex 44.25 13.5 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 12.830303993361 0 vertex 40.75 13.5 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.25 13.5 0 vertex 18.116789181895 14.169696006639 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 14.737436867076 0 vertex 17.737436867076 14.737436867076 0 vertex 17.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 14.169696006639 0 vertex 17.737436867076 14.737436867076 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 44.25 26.5 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 14.75 13.5 0.77775 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.75 13.5 0.77775 vertex 14.75 13.5 0 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 41.830303993361 28.116789181895 0 vertex 42.5 28.25 0.77775 vertex 41.830303993361 28.116789181895 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.830303993361 24.883210818105 0.77775 vertex 15.830303993361 24.883210818105 0 vertex 15.262563132924 25.262563132924 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 16.5 28.25 0 vertex 17.169696006639 28.116789181895 0.77775 vertex 16.5 28.25 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 43.169696006639 24.883210818105 0 vertex 42.5 24.75 0.77775 vertex 43.169696006639 24.883210818105 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 28.25 0.77775 vertex 15.830303993361 28.116789181895 0.77775 vertex 16.5 28.25 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 15.830303993361 28.116789181895 0.77775 vertex 15.830303993361 28.116789181895 0 vertex 16.5 28.25 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 23 0 vertex 6.011309837942 23 0.77775 vertex 0 23 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 60 0 0.77775 vertex 52 10 0.77775 vertex 52 0 0.77775 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 27.169696006639 0 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.75 26.5 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.169696006639 24.883210818105 0 vertex 16.5 24.75 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 0 0 vertex 52 0 0.77775 vertex 52 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.883210818105 12.830303993361 0.77775 vertex 40.75 13.5 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 42.5 24.75 0 vertex 41.830303993361 24.883210818105 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 0 0 vertex 60 0 0.77775 vertex 52 0 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 28.116789181895 0.77775 vertex 15.262563132924 27.737436867076 0.77775 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.262563132924 27.737436867076 0.77775 vertex 15.262563132924 27.737436867076 0 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0 1 0 outer loop vertex 6.011309837942 17 0.77775 vertex 6.011309837942 17 0 vertex 0 17 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 17 0 vertex 48.011309837942 17 0.77775 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 18.25 26.5 0 vertex 18.25 26.5 0.77775 vertex 18.116789181895 27.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.455907969142 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 54.002309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 44.25 26.5 0 vertex 44.25 26.5 0.77775 vertex 44.116789181895 27.169696006639 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 10 0 vertex 15.306548743796 10 0.77775 vertex 14.464705848856 10 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 26.5 0.77775 vertex 40.883210818105 25.830303993361 0 vertex 40.75 26.5 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 48.011309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 43.737436867076 27.737436867076 0.77775 vertex 44.116789181895 27.169696006639 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 43.737436867076 27.737436867076 0 vertex 44.116789181895 27.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 10 0 vertex 52 10 0.77775 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 23 0.77775 vertex 6.011309837942 23 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.883210818105 14.169696006639 0.77775 vertex 41.262563132924 14.737436867076 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 26.5 0 vertex 14.883210818105 25.830303993361 0.77775 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 6.011309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 18.116789181895 14.169696006639 0.77775 vertex 17.737436867076 14.737436867076 0.77775 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 17.737436867076 14.737436867076 0 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 42.5 15.25 0.77775 vertex 41.830303993361 15.116789181895 0.77775 vertex 42.5 15.25 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 41.830303993361 15.116789181895 0.77775 vertex 41.830303993361 15.116789181895 0 vertex 42.5 15.25 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 14.883210818105 14.169696006639 0.77775 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 14.883210818105 14.169696006639 0 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 43.169696006639 15.116789181895 0 vertex 43.737436867076 14.737436867076 0.77775 vertex 43.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 13.5 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.75 13.5 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 40.883210818105 14.169696006639 0.77775 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 11.75 0.77775 vertex 43.169696006639 11.883210818105 0.77775 vertex 43.169696006639 11.883210818105 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 17.169696006639 15.116789181895 0 vertex 17.737436867076 14.737436867076 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.730643081307 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 6.011309837942 23 0.77775 vertex 0 23 0 vertex 6.011309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 48.011309837942 23 0 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.195826430941 0.110046151702 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 10 0 vertex 6.011309837942 15.269356918694 0 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 -0 outer loop vertex 17.169696006639 28.116789181895 0.77775 vertex 16.5 28.25 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 44.116789181895 27.169696006639 0 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.25 26.5 0.77775 vertex 44.25 26.5 0 vertex 44.116789181895 25.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 40.75 26.5 0.77775 vertex 37.474084379442 23 0.77775 vertex 40.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.75 13.5 0.77775 vertex 40.883210818105 14.169696006639 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 17.169696006639 11.883210818105 0 vertex 16.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 52 30 0.77775 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 15.063011877768 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.75 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 48.011309837942 15.063011877768 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 24.883210818105 0.77775 vertex 42.5 24.75 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 24.730643081307 0 vertex 14.883210818105 27.169696006639 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.737436867076 14.737436867076 0.77775 vertex 43.169696006639 15.116789181895 0 vertex 43.737436867076 14.737436867076 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 41.866228156844 30 0.77775 vertex 43.169696006639 28.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 41.830303993361 15.116789181895 0.77775 vertex 42.5 15.25 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 11.75 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 0 23 0.77775 vertex 0 30 0 vertex 0 23 0 endloop endfacet facet normal -1 0 0 outer loop vertex 0 30 0 vertex 0 23 0.77775 vertex 0 30 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 52 10 0 vertex 52 0 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 11.883210818105 0 vertex 17.169696006639 11.883210818105 0.77775 vertex 17.737436867076 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 43.169696006639 28.116789181895 0.77775 vertex 41.866228156844 30 0.77775 vertex 42.5 28.25 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 14.042553191489 30 0 vertex 41.866228156844 30 0.77775 vertex 52 30 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 42.5 11.75 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 12.262563132924 0.77775 vertex 15.830303993361 11.883210818105 0 vertex 15.262563132924 12.262563132924 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 40.75 26.5 0.77775 vertex 40.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 27.169696006639 0 vertex 40.883210818105 25.830303993361 0 vertex 41.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 17.169696006639 28.116789181895 0 vertex 14.042553191489 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 15.262563132924 27.737436867076 0.77775 vertex 15.830303993361 28.116789181895 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 25.830303993361 0.77775 vertex 15.262563132924 25.262563132924 0.77775 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 15.262563132924 25.262563132924 0.77775 vertex 15.262563132924 25.262563132924 0 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 24.804173569059 0.110046151702 vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 43.737436867076 27.737436867076 0 vertex 52 30 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 25.830303993361 0 vertex 18.116789181895 25.830303993361 0.77775 vertex 18.25 26.5 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.195826430941 0.110046151702 vertex 54.002309837942 15.063011877768 0.77775 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 15.116789181895 0 vertex 41.830303993361 15.116789181895 0.77775 vertex 41.262563132924 14.737436867076 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 43.169696006639 28.116789181895 0.77775 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.169696006639 28.116789181895 0.77775 vertex 43.169696006639 28.116789181895 0 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 42.5 11.75 0.77775 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 23 0.77775 vertex 15.830303993361 24.883210818105 0.77775 vertex 15.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 41.262563132924 14.737436867076 0 vertex 41.830303993361 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 17 0 vertex 60 0 0 vertex 52 0 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 25.262563132924 0 vertex 15.262563132924 25.262563132924 0.77775 vertex 15.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 23 0 vertex 17.379510917074 23 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 6.011309837942 23 0.77775 vertex 6.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 11.883210818105 0 vertex 41.830303993361 11.883210818105 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 14.042553191489 30 0 vertex 52 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 43.169696006639 15.116789181895 0.77775 vertex 43.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 17 0.77775 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 18.116789181895 27.169696006639 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.75 26.5 0 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.75 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 0 30 0.77775 vertex 14.883210818105 27.169696006639 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 11.75 0.77775 vertex 43.169696006639 11.883210818105 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 15.830303993361 28.116789181895 0.77775 vertex 16.5 28.25 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 52 30 0.77775 vertex 52 30 0 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 17 0 vertex 52 0 0 vertex 52 10 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 0 outer loop vertex 44.116789181895 14.169696006639 0.77775 vertex 43.737436867076 14.737436867076 0.77775 vertex 43.737436867076 14.737436867076 0 endloop endfacet facet normal 0 1 0 outer loop vertex 14.607403236621 30 0.77775 vertex 41.866228156844 30 0.77775 vertex 14.042553191489 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 15.306548743796 10 0.77775 vertex 17.737436867076 12.262563132924 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.269356918694 0 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 17 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 16.5 24.75 0 vertex 16.5 24.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 43.169696006639 24.883210818105 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 6.011309837942 17 0.77775 vertex 0 17 0 vertex 0 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 16.5 28.25 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 17.737436867076 25.262563132924 0 vertex 17.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 24.75 0.77775 vertex 17.379510917074 23 0.77775 vertex 17.169696006639 24.883210818105 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 44.116789181895 27.169696006639 0 vertex 44.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.75 13.5 0 vertex 18.25 13.5 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 48.011309837942 24.730643081307 0 vertex 48.011309837942 23 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 10 0.77775 vertex 0 10 0 vertex 14.464705848856 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 15.306548743796 10 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.262563132924 12.262563132924 0.77775 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 28.116789181895 0 vertex 43.169696006639 28.116789181895 0.77775 vertex 42.5 28.25 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 16.5 11.75 0 vertex 16.5 11.75 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 18.25 13.5 0.77775 vertex 18.116789181895 14.169696006639 0.77775 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.737436867076 25.262563132924 0 vertex 17.169696006639 24.883210818105 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 10 0.77775 vertex 14.464705848856 10 0 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 17.737436867076 14.737436867076 0 vertex 17.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.866228156844 30 0.77775 vertex 41.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 16.5 11.75 0.77775 vertex 15.830303993361 11.883210818105 0 vertex 15.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.75 26.5 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 44.116789181895 14.169696006639 0.77775 vertex 43.737436867076 14.737436867076 0 vertex 44.116789181895 14.169696006639 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 60 17 0.77775 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 12.002309837942 15.195826430941 0.110046151702 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 23 0.77775 vertex 17.379510917074 23 0.77775 vertex 15.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.830303993361 24.883210818105 0.77775 vertex 17.379510917074 23 0.77775 vertex 16.5 24.75 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.25 26.5 0.77775 vertex 18.25 26.5 0 vertex 18.116789181895 25.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 25.262563132924 0.77775 vertex 37.474084379442 23 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 14.883210818105 27.169696006639 0.77775 vertex 15.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 15.455907969142 17 0.77775 vertex 17.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 34.416922535211 17 0.77775 vertex 15.455907969142 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.306548743796 10 0.77775 vertex 15.262563132924 12.262563132924 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.737436867076 25.262563132924 0.77775 vertex 17.737436867076 25.262563132924 0 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 15.25 0.77775 vertex 15.455907969142 17 0.77775 vertex 15.830303993361 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 42.5 28.25 0.77775 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 18.25 13.5 0.77775 vertex 18.25 13.5 0 endloop endfacet facet normal 0 1 0 outer loop vertex 60 17 0.77775 vertex 60 17 0 vertex 54.002309837942 17 0 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 12.002309837942 17 0 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 11.883210818105 0 vertex 43.737436867076 12.262563132924 0.77775 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 11.883210818105 0 vertex 43.169696006639 11.883210818105 0.77775 vertex 43.737436867076 12.262563132924 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 18.25 13.5 0.77775 vertex 18.116789181895 14.169696006639 0 vertex 18.25 13.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 41.830303993361 28.116789181895 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 23 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 15.455907969142 17 0.77775 vertex 16.5 15.25 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 17.737436867076 12.262563132924 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 52 40 0.77775 vertex 60 23 0.77775 vertex 60 40 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.75 13.5 0 vertex 18.116789181895 12.830303993361 0 vertex 18.25 13.5 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 28.116789181895 0 vertex 42.5 28.25 0.77775 vertex 42.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 12.002309837942 23 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 23 0.77775 vertex 60 23 0.77775 vertex 54.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 23 0.77775 vertex 6.011309837942 24.730643081307 0 vertex 6.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 17.169696006639 15.116789181895 0 vertex 16.5 15.25 0.77775 vertex 16.5 15.25 0 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 17 0.77775 vertex 6.011309837942 15.063011877768 0.77775 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 1 0 0 outer loop vertex 60 17 0.77775 vertex 60 0 0 vertex 60 17 0 endloop endfacet facet normal 1 0 0 outer loop vertex 60 0 0.77775 vertex 60 0 0 vertex 60 17 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 12.262563132924 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 43.737436867076 12.262563132924 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 12.002309837942 15.063011877768 0.77775 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.379510917074 23 0.77775 vertex 17.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 43.737436867076 12.262563132924 0.77775 vertex 43.169696006639 11.883210818105 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 42.5 28.25 0.77775 vertex 41.830303993361 28.116789181895 0 vertex 42.5 28.25 0 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 17 0 vertex 6.011309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 25.830303993361 0.77775 vertex 37.474084379442 23 0.77775 vertex 41.262563132924 25.262563132924 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 18.25 13.5 0 vertex 18.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 25.262563132924 0.77775 vertex 17.379510917074 23 0.77775 vertex 18.116789181895 25.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 41.262563132924 14.737436867076 0.77775 vertex 41.830303993361 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 30 0.77775 vertex 6.011309837942 24.936988122232 0.77775 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 17.379510917074 23 0.77775 vertex 37.474084379442 23 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 43.169696006639 11.883210818105 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 40.883210818105 14.169696006639 0 vertex 41.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 43.169696006639 24.883210818105 0 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.25 26.5 0.77775 vertex 44.116789181895 25.830303993361 0 vertex 44.116789181895 25.830303993361 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 60 17 0.77775 vertex 54.002309837942 17 0 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 42.5 24.75 0 vertex 43.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 44.116789181895 27.169696006639 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 18.116789181895 25.830303993361 0 vertex 17.737436867076 25.262563132924 0 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.195826430941 0.110046151702 vertex 54.002309837942 17 0.77775 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 14.75 26.5 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 0 0.77775 vertex 52 0 0 vertex 60 0 0.77775 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 14.75 26.5 0.77775 vertex 14.75 26.5 0 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.269356918694 0 vertex 54.002309837942 17 0.77775 vertex 54.002309837942 17 0 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 11.75 0.77775 vertex 15.306548743796 10 0.77775 vertex 17.169696006639 11.883210818105 0.77775 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 17.169696006639 15.116789181895 0 vertex 17.169696006639 15.116789181895 0.77775 vertex 16.5 15.25 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.195826430941 0.110046151702 vertex 12.002309837942 15.063011877768 0.77775 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 48.011309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 16.5 11.75 0.77775 vertex 16.5 11.75 0 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 48.011309837942 15.269356918694 0 vertex 48.011309837942 17 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 52 30 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 24.75 0.77775 vertex 43.169696006639 24.883210818105 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 26.5 0 vertex 14.75 26.5 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 43.737436867076 14.737436867076 0 vertex 48.011309837942 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 48.011309837942 17 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 41.830303993361 24.883210818105 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 42.5 24.75 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 1 0 outer loop vertex 52 40 0 vertex 52 40 0.77775 vertex 60 40 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 52 40 0 vertex 60 40 0.77775 vertex 60 40 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0.77775 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 15.830303993361 24.883210818105 0 vertex 15.830303993361 24.883210818105 0.77775 vertex 16.5 24.75 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 15.830303993361 24.883210818105 0 vertex 16.5 24.75 0.77775 vertex 16.5 24.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 24.936988122232 0.77775 vertex 12.002309837942 23 0.77775 vertex 15.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 24.936988122232 0.77775 vertex 15.262563132924 25.262563132924 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 60 40 0.77775 vertex 60 23 0.77775 vertex 60 23 0 endloop endfacet facet normal 1 0 0 outer loop vertex 60 40 0.77775 vertex 60 23 0 vertex 60 40 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 27.737436867076 0 vertex 15.262563132924 27.737436867076 0.77775 vertex 14.883210818105 27.169696006639 0.77775 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 27.737436867076 0 vertex 14.883210818105 27.169696006639 0.77775 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 1 outer loop vertex 37.474084379442 23 0.77775 vertex 48.011309837942 23 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 37.474084379442 23 0.77775 vertex 42.5 24.75 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 14.737436867076 0 vertex 12.002309837942 17 0 vertex 41.422110817733 17 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 15.116789181895 0.77775 vertex 42.5 15.25 0.77775 vertex 42.5 15.25 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 -0 outer loop vertex 43.169696006639 15.116789181895 0.77775 vertex 42.5 15.25 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 52 10 0.77775 vertex 60 0 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 60 0 0.77775 vertex 60 17 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 13.5 0.77775 vertex 40.883210818105 12.830303993361 0.77775 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 13.5 0.77775 vertex 40.883210818105 12.830303993361 0 vertex 40.75 13.5 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.737436867076 27.737436867076 0 vertex 17.737436867076 27.737436867076 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.737436867076 27.737436867076 0 vertex 17.169696006639 28.116789181895 0.77775 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 0 30 0.77775 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 14.75 26.5 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 12.262563132924 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 12.262563132924 0.77775 vertex 44.116789181895 12.830303993361 0 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 48.011309837942 23 0.77775 vertex 37.474084379442 23 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 15.25 0.77775 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.830303993361 15.116789181895 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 15.25 0.77775 vertex 15.830303993361 15.116789181895 0 vertex 16.5 15.25 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 41.262563132924 12.262563132924 0.77775 vertex 41.262563132924 12.262563132924 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 41.262563132924 12.262563132924 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 16.5 15.25 0 vertex 15.830303993361 15.116789181895 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 25.262563132924 0 vertex 43.737436867076 25.262563132924 0.77775 vertex 44.116789181895 25.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 25.262563132924 0 vertex 44.116789181895 25.830303993361 0.77775 vertex 44.116789181895 25.830303993361 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 14.169696006639 0.77775 vertex 40.75 13.5 0.77775 vertex 40.75 13.5 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 14.169696006639 0.77775 vertex 40.75 13.5 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 23 0 vertex 60 23 0.77775 vertex 54.002309837942 23 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 23 0 vertex 54.002309837942 23 0.77775 vertex 54.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 30 0 vertex 14.042553191489 30 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 30 0 vertex 14.883210818105 27.169696006639 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.262563132924 25.262563132924 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.830303993361 24.883210818105 0.77775 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.262563132924 27.737436867076 0.77775 vertex 41.262563132924 27.737436867076 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.262563132924 27.737436867076 0 vertex 41.830303993361 28.116789181895 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 24.883210818105 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 24.883210818105 0.77775 vertex 43.737436867076 25.262563132924 0 vertex 43.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 43.169696006639 11.883210818105 0 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 43.737436867076 12.262563132924 0 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 60 23 0.77775 vertex 52 40 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 52 40 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 34.416922535211 17 0.77775 vertex 41.422110817733 17 0 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 41.422110817733 17 0 vertex 12.002309837942 17 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 12.002309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 12.002309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.730643081307 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 15.455907969142 17 0.77775 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 12.002309837942 17 0.77775 vertex 14.883210818105 14.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 25.830303993361 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 17 0.77775 vertex 0 10 0.77775 vertex 6.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 17 0.77775 vertex 6.011309837942 15.063011877768 0.77775 vertex 6.011309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 34.416922535211 17 0.77775 vertex 42.5 15.25 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 42.5 15.25 0.77775 vertex 43.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 12.002309837942 15.063011877768 0.77775 vertex 14.75 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 0 30 0.77775 vertex 0 23 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 0 23 0.77775 vertex 6.011309837942 23 0.77775 endloop endfacet facet normal -0 -0 -1 outer loop vertex 40.75 26.5 0 vertex 40.883210818105 25.830303993361 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 44.25 13.5 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 44.116789181895 14.169696006639 0 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 44.25 13.5 0.77775 vertex 44.116789181895 14.169696006639 0 vertex 44.25 13.5 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 17.737436867076 12.262563132924 0 vertex 17.737436867076 12.262563132924 0.77775 vertex 18.116789181895 12.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 17.737436867076 12.262563132924 0 vertex 18.116789181895 12.830303993361 0.77775 vertex 18.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 0 10 0.77775 vertex 15.306548743796 10 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 54.002309837942 24.936988122232 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.936988122232 0.77775 vertex 48.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 12.830303993361 0 vertex 14.883210818105 12.830303993361 0.77775 vertex 15.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 12.830303993361 0 vertex 15.262563132924 12.262563132924 0.77775 vertex 15.262563132924 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 43.737436867076 12.262563132924 0 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 44.116789181895 12.830303993361 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 1 0 outer loop vertex 0 30 0 vertex 0 30 0.77775 vertex 14.607403236621 30 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 0 30 0 vertex 14.607403236621 30 0.77775 vertex 14.042553191489 30 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 12.262563132924 0 vertex 41.262563132924 12.262563132924 0.77775 vertex 41.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 12.262563132924 0 vertex 41.830303993361 11.883210818105 0.77775 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal -1 0 0 outer loop vertex 0 10 0 vertex 0 10 0.77775 vertex 0 17 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 0 10 0 vertex 0 17 0.77775 vertex 0 17 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.116789181895 12.830303993361 0.77775 vertex 44.25 13.5 0.77775 vertex 44.25 13.5 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.116789181895 12.830303993361 0.77775 vertex 44.25 13.5 0 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal 0 1 0 outer loop vertex 41.422110817733 17 0 vertex 34.416922535211 17 0.77775 vertex 48.011309837942 17 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 41.422110817733 17 0 vertex 48.011309837942 17 0.77775 vertex 48.011309837942 17 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 30 0.77775 vertex 52 40 0.77775 vertex 52 40 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 30 0.77775 vertex 52 40 0 vertex 52 30 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.830303993361 24.883210818105 0 vertex 16.5 24.75 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 40.883210818105 27.169696006639 0 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 17.737436867076 27.737436867076 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 0 10 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 12.002309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 43.737436867076 14.737436867076 0.77775 vertex 44.116789181895 14.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.262563132924 25.262563132924 0 vertex 15.830303993361 24.883210818105 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.262563132924 25.262563132924 0 vertex 12.002309837942 23 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 44.25 26.5 0.77775 vertex 44.116789181895 25.830303993361 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 27.169696006639 0 vertex 40.75 26.5 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 27.169696006639 0 vertex 18.116789181895 27.169696006639 0 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 41.262563132924 14.737436867076 0 vertex 17.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 17.169696006639 15.116789181895 0 vertex 16.5 15.25 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 15.116789181895 0 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.262563132924 14.737436867076 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 15.116789181895 0 vertex 15.262563132924 14.737436867076 0.77775 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.883210818105 27.169696006639 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0 vertex 41.262563132924 27.737436867076 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 37.474084379442 23 0.77775 vertex 17.379510917074 23 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 17.379510917074 23 0.77775 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 15.830303993361 15.116789181895 0 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 15.262563132924 14.737436867076 0 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 40.883210818105 25.830303993361 0.77775 vertex 41.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 41.262563132924 25.262563132924 0.77775 vertex 41.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 12.830303993361 0 vertex 15.262563132924 12.262563132924 0 vertex 14.464705848856 10 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 12.830303993361 0 vertex 14.464705848856 10 0 vertex 0 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 41.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 17.169696006639 28.116789181895 0.77775 vertex 17.737436867076 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.936988122232 0.77775 vertex 43.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 43.169696006639 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 44.25 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 44.25 26.5 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 48.011309837942 24.936988122232 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 23 0.77775 vertex 54.002309837942 24.936988122232 0.77775 vertex 54.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 41.866228156844 30 0.77775 vertex 14.607403236621 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 14.607403236621 30 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.25 13.5 0.77775 vertex 44.116789181895 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 14.169696006639 0.77775 vertex 18.25 13.5 0.77775 vertex 41.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.25 26.5 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 18.116789181895 27.169696006639 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 24.730643081307 0 vertex 54.002309837942 23 0 vertex 54.002309837942 23 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 24.730643081307 0 vertex 54.002309837942 23 0.77775 vertex 54.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 41.262563132924 12.262563132924 0.77775 vertex 18.25 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 18.25 13.5 0.77775 vertex 18.116789181895 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 17.737436867076 12.262563132924 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 42.5 11.75 0.77775 vertex 41.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 15.306548743796 10 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 52 10 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 18.116789181895 14.169696006639 0.77775 vertex 41.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.25 26.5 0.77775 vertex 40.75 26.5 0.77775 vertex 40.883210818105 27.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 37.474084379442 23 0.77775 vertex 40.75 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 40.75 26.5 0.77775 vertex 18.25 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 34.416922535211 17 0.77775 vertex 17.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 17.737436867076 14.737436867076 0.77775 vertex 18.116789181895 14.169696006639 0.77775 endloop endfacet endsolid sfact-2011.12.18/terminal.sh000066400000000000000000000011261167321211700153570ustar00rootroot00000000000000#!/bin/sh # # Script to open the bash terminal in this directory. # # Usage: set the executable property to true if it isn't already. Then double click the file. # echo 'Directory listing:' echo '' ls echo '' echo 'To run a python script (.py) listed above, try typing something like:' echo 'python filename' echo '' echo 'For example, in the skeinforge directory you could run skeinforge.py by typing:' echo 'python skeinforge.py' echo '' echo 'To skeinforge the test.stl file from the command line, in the skeinforge directory you could type:' echo 'python skeinforge.py test.stl' echo '' bash sfact-2011.12.18/test.stl000066400000000000000000002252011167321211700147150ustar00rootroot00000000000000solid "Screw_Holder_Bottom"; Produced by Art of Illusion 2.4, Fri Oct 16 16:42:04 PDT 2009 facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.804173569059 0.110046151702 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 24.730643081307 0 vertex 14.883210818105 25.830303993361 0 vertex 15.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 23 0 vertex 54.002309837942 24.730643081307 0 vertex 60 40 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 54.002309837942 15.269356918694 0 vertex 48.011309837942 15.269356918694 0 vertex 54.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 15.830303993361 11.883210818105 0 vertex 16.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 43.737436867076 27.737436867076 0 vertex 43.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 43.169696006639 15.116789181895 0 vertex 42.5 15.25 0 vertex 41.422110817733 17 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 48.011309837942 24.730643081307 0 vertex 54.002309837942 24.730643081307 0 vertex 48.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 43.169696006639 28.116789181895 0 vertex 42.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 40 0 vertex 52 30 0 vertex 52 40 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 14.169696006639 0 vertex 14.75 13.5 0 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 27.169696006639 0 vertex 14.042553191489 30 0 vertex 15.262563132924 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 16.5 11.75 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 48.011309837942 15.195826430941 0.110046151702 vertex 54.002309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 17.169696006639 28.116789181895 0 vertex 16.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 14.75 13.5 0 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 17 0 vertex 60 17 0 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 42.5 11.75 0 vertex 43.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 15.262563132924 14.737436867076 0 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 14.464705848856 10 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 15.830303993361 28.116789181895 0 vertex 15.262563132924 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.464705848856 10 0 vertex 15.262563132924 12.262563132924 0 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.042553191489 30 0 vertex 16.5 28.25 0 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 24.730643081307 0 vertex 60 23 0 vertex 54.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 23 0 vertex 16.5 24.75 0 vertex 17.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 15.195826430941 0.110046151702 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.75 26.5 0 vertex 12.002309837942 24.730643081307 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 30 0 vertex 60 40 0 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.422110817733 17 0 vertex 48.011309837942 17 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 13.5 0 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 6.011309837942 17 0 vertex 6.011309837942 15.269356918694 0 vertex 0 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.422110817733 17 0 vertex 41.830303993361 15.116789181895 0 vertex 41.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 11.883210818105 0 vertex 17.737436867076 12.262563132924 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 15.269356918694 0 vertex 0 10 0 vertex 0 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 25.830303993361 0 vertex 12.002309837942 24.730643081307 0 vertex 14.75 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 52 30 0 vertex 54.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 17 0 vertex 43.737436867076 14.737436867076 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 15.25 0 vertex 41.830303993361 15.116789181895 0 vertex 41.422110817733 17 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 12.002309837942 15.269356918694 0 vertex 14.883210818105 12.830303993361 0 vertex 6.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 23 0 vertex 0 30 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0.831469612301 0.555570233022 outer loop vertex 12.002309837942 15.269356918694 0 vertex 6.011309837942 15.269356918694 0 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 60 17 0 vertex 52 10 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 23 0 vertex 0 23 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 48.011309837942 15.269356918694 0 vertex 44.25 13.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 27.169696006639 0 vertex 41.262563132924 25.262563132924 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 25.830303993361 0 vertex 18.25 26.5 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 14.737436867076 0 vertex 41.262563132924 14.737436867076 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal -0 -0 -1 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.830303993361 24.883210818105 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 25.262563132924 0 vertex 18.116789181895 25.830303993361 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 12.262563132924 0 vertex 18.116789181895 12.830303993361 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.737436867076 12.262563132924 0 vertex 41.262563132924 12.262563132924 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 17.169696006639 28.116789181895 0 vertex 41.830303993361 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 11.75 0 vertex 14.464705848856 10 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.25 26.5 0 vertex 44.116789181895 27.169696006639 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 12.830303993361 0 vertex 41.262563132924 12.262563132924 0 vertex 17.737436867076 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 17.737436867076 25.262563132924 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 12.830303993361 0 vertex 44.25 13.5 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 12.830303993361 0 vertex 40.75 13.5 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.25 13.5 0 vertex 18.116789181895 14.169696006639 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 14.737436867076 0 vertex 17.737436867076 14.737436867076 0 vertex 17.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 14.169696006639 0 vertex 17.737436867076 14.737436867076 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 44.25 26.5 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 14.75 13.5 0.77775 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.75 13.5 0.77775 vertex 14.75 13.5 0 vertex 14.883210818105 14.169696006639 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 41.830303993361 28.116789181895 0 vertex 42.5 28.25 0.77775 vertex 41.830303993361 28.116789181895 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.830303993361 24.883210818105 0.77775 vertex 15.830303993361 24.883210818105 0 vertex 15.262563132924 25.262563132924 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 16.5 28.25 0 vertex 17.169696006639 28.116789181895 0.77775 vertex 16.5 28.25 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 43.169696006639 24.883210818105 0 vertex 42.5 24.75 0.77775 vertex 43.169696006639 24.883210818105 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 28.25 0.77775 vertex 15.830303993361 28.116789181895 0.77775 vertex 16.5 28.25 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 15.830303993361 28.116789181895 0.77775 vertex 15.830303993361 28.116789181895 0 vertex 16.5 28.25 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 23 0 vertex 6.011309837942 23 0.77775 vertex 0 23 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 60 0 0.77775 vertex 52 10 0.77775 vertex 52 0 0.77775 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 27.169696006639 0 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.75 26.5 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.169696006639 24.883210818105 0 vertex 16.5 24.75 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 0 0 vertex 52 0 0.77775 vertex 52 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.883210818105 12.830303993361 0.77775 vertex 40.75 13.5 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 42.5 24.75 0 vertex 41.830303993361 24.883210818105 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 0 0 vertex 60 0 0.77775 vertex 52 0 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 28.116789181895 0.77775 vertex 15.262563132924 27.737436867076 0.77775 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.262563132924 27.737436867076 0.77775 vertex 15.262563132924 27.737436867076 0 vertex 15.830303993361 28.116789181895 0 endloop endfacet facet normal 0 1 0 outer loop vertex 6.011309837942 17 0.77775 vertex 6.011309837942 17 0 vertex 0 17 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 17 0 vertex 48.011309837942 17 0.77775 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 18.25 26.5 0 vertex 18.25 26.5 0.77775 vertex 18.116789181895 27.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.455907969142 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 54.002309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 44.25 26.5 0 vertex 44.25 26.5 0.77775 vertex 44.116789181895 27.169696006639 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 10 0 vertex 15.306548743796 10 0.77775 vertex 14.464705848856 10 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 26.5 0.77775 vertex 40.883210818105 25.830303993361 0 vertex 40.75 26.5 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 48.011309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 43.737436867076 27.737436867076 0.77775 vertex 44.116789181895 27.169696006639 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 43.737436867076 27.737436867076 0 vertex 44.116789181895 27.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 10 0 vertex 52 10 0.77775 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 23 0.77775 vertex 6.011309837942 23 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.883210818105 14.169696006639 0.77775 vertex 41.262563132924 14.737436867076 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 26.5 0 vertex 14.883210818105 25.830303993361 0.77775 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 6.011309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 18.116789181895 14.169696006639 0.77775 vertex 17.737436867076 14.737436867076 0.77775 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 17.737436867076 14.737436867076 0 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 42.5 15.25 0.77775 vertex 41.830303993361 15.116789181895 0.77775 vertex 42.5 15.25 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 41.830303993361 15.116789181895 0.77775 vertex 41.830303993361 15.116789181895 0 vertex 42.5 15.25 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 14.883210818105 14.169696006639 0.77775 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 14.883210818105 14.169696006639 0 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 43.169696006639 15.116789181895 0 vertex 43.737436867076 14.737436867076 0.77775 vertex 43.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 13.5 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.75 13.5 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 40.883210818105 14.169696006639 0.77775 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 11.75 0.77775 vertex 43.169696006639 11.883210818105 0.77775 vertex 43.169696006639 11.883210818105 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 17.169696006639 15.116789181895 0 vertex 17.737436867076 14.737436867076 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.730643081307 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 6.011309837942 23 0.77775 vertex 0 23 0 vertex 6.011309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 48.011309837942 23 0 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.195826430941 0.110046151702 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 10 0 vertex 6.011309837942 15.269356918694 0 vertex 14.883210818105 12.830303993361 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 -0 outer loop vertex 17.169696006639 28.116789181895 0.77775 vertex 16.5 28.25 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 44.116789181895 27.169696006639 0 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.25 26.5 0.77775 vertex 44.25 26.5 0 vertex 44.116789181895 25.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 40.75 26.5 0.77775 vertex 37.474084379442 23 0.77775 vertex 40.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 40.75 13.5 0.77775 vertex 40.883210818105 14.169696006639 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 17.169696006639 11.883210818105 0 vertex 16.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 52 30 0.77775 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 15.063011877768 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 14.75 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 48.011309837942 15.063011877768 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 24.883210818105 0.77775 vertex 42.5 24.75 0 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 6.011309837942 24.730643081307 0 vertex 14.883210818105 27.169696006639 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.737436867076 14.737436867076 0.77775 vertex 43.169696006639 15.116789181895 0 vertex 43.737436867076 14.737436867076 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 41.866228156844 30 0.77775 vertex 43.169696006639 28.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 41.830303993361 15.116789181895 0.77775 vertex 42.5 15.25 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 11.75 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 0 23 0.77775 vertex 0 30 0 vertex 0 23 0 endloop endfacet facet normal -1 0 0 outer loop vertex 0 30 0 vertex 0 23 0.77775 vertex 0 30 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 52 10 0 vertex 52 0 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 11.883210818105 0 vertex 17.169696006639 11.883210818105 0.77775 vertex 17.737436867076 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 43.169696006639 28.116789181895 0.77775 vertex 41.866228156844 30 0.77775 vertex 42.5 28.25 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 14.042553191489 30 0 vertex 41.866228156844 30 0.77775 vertex 52 30 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 42.5 11.75 0 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 12.262563132924 0.77775 vertex 15.830303993361 11.883210818105 0 vertex 15.262563132924 12.262563132924 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 40.75 26.5 0.77775 vertex 40.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 18.116789181895 27.169696006639 0 vertex 40.883210818105 25.830303993361 0 vertex 41.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 17.169696006639 28.116789181895 0 vertex 14.042553191489 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 15.262563132924 27.737436867076 0.77775 vertex 15.830303993361 28.116789181895 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 25.830303993361 0.77775 vertex 15.262563132924 25.262563132924 0.77775 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 15.262563132924 25.262563132924 0.77775 vertex 15.262563132924 25.262563132924 0 vertex 14.883210818105 25.830303993361 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 24.804173569059 0.110046151702 vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 24.730643081307 0 vertex 43.737436867076 27.737436867076 0 vertex 52 30 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 25.830303993361 0 vertex 18.116789181895 25.830303993361 0.77775 vertex 18.25 26.5 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.195826430941 0.110046151702 vertex 54.002309837942 15.063011877768 0.77775 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 15.116789181895 0 vertex 41.830303993361 15.116789181895 0.77775 vertex 41.262563132924 14.737436867076 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 43.169696006639 28.116789181895 0.77775 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 -0 outer loop vertex 43.169696006639 28.116789181895 0.77775 vertex 43.169696006639 28.116789181895 0 vertex 43.737436867076 27.737436867076 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 42.5 11.75 0.77775 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 23 0.77775 vertex 15.830303993361 24.883210818105 0.77775 vertex 15.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 41.262563132924 14.737436867076 0 vertex 41.830303993361 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 17 0 vertex 60 0 0 vertex 52 0 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 25.262563132924 0 vertex 15.262563132924 25.262563132924 0.77775 vertex 15.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 23 0 vertex 17.379510917074 23 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 6.011309837942 23 0.77775 vertex 6.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 11.883210818105 0 vertex 41.830303993361 11.883210818105 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 14.042553191489 30 0 vertex 52 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 43.169696006639 15.116789181895 0.77775 vertex 43.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 17 0.77775 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 18.116789181895 27.169696006639 0 vertex 18.25 26.5 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.75 26.5 0 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.75 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 0 30 0.77775 vertex 14.883210818105 27.169696006639 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 11.75 0.77775 vertex 43.169696006639 11.883210818105 0 vertex 42.5 11.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 15.830303993361 28.116789181895 0.77775 vertex 16.5 28.25 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 52 30 0.77775 vertex 52 30 0 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 60 17 0 vertex 52 0 0 vertex 52 10 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 0 outer loop vertex 44.116789181895 14.169696006639 0.77775 vertex 43.737436867076 14.737436867076 0.77775 vertex 43.737436867076 14.737436867076 0 endloop endfacet facet normal 0 1 0 outer loop vertex 14.607403236621 30 0.77775 vertex 41.866228156844 30 0.77775 vertex 14.042553191489 30 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 15.306548743796 10 0.77775 vertex 17.737436867076 12.262563132924 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.269356918694 0 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 17 0 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 16.5 24.75 0 vertex 16.5 24.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 43.169696006639 24.883210818105 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 6.011309837942 17 0.77775 vertex 0 17 0 vertex 0 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 16.5 28.25 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 17.737436867076 25.262563132924 0 vertex 17.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 24.75 0.77775 vertex 17.379510917074 23 0.77775 vertex 17.169696006639 24.883210818105 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 44.116789181895 27.169696006639 0 vertex 44.25 26.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.75 13.5 0 vertex 18.25 13.5 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 25.830303993361 0 vertex 48.011309837942 24.730643081307 0 vertex 48.011309837942 23 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 10 0.77775 vertex 0 10 0 vertex 14.464705848856 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 15.306548743796 10 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.262563132924 12.262563132924 0.77775 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 28.116789181895 0 vertex 43.169696006639 28.116789181895 0.77775 vertex 42.5 28.25 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 17.169696006639 11.883210818105 0.77775 vertex 16.5 11.75 0 vertex 16.5 11.75 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 18.25 13.5 0.77775 vertex 18.116789181895 14.169696006639 0.77775 vertex 18.116789181895 14.169696006639 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.737436867076 25.262563132924 0 vertex 17.169696006639 24.883210818105 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 0 10 0.77775 vertex 14.464705848856 10 0 vertex 15.306548743796 10 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 17.737436867076 14.737436867076 0 vertex 17.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.866228156844 30 0.77775 vertex 41.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 16.5 11.75 0.77775 vertex 15.830303993361 11.883210818105 0 vertex 15.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.75 26.5 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 44.116789181895 14.169696006639 0.77775 vertex 43.737436867076 14.737436867076 0 vertex 44.116789181895 14.169696006639 0 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 23 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 60 17 0.77775 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 12.002309837942 15.195826430941 0.110046151702 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 23 0.77775 vertex 17.379510917074 23 0.77775 vertex 15.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.830303993361 24.883210818105 0.77775 vertex 17.379510917074 23 0.77775 vertex 16.5 24.75 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.25 26.5 0.77775 vertex 18.25 26.5 0 vertex 18.116789181895 25.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 25.262563132924 0.77775 vertex 37.474084379442 23 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.607403236621 30 0.77775 vertex 14.883210818105 27.169696006639 0.77775 vertex 15.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 15.455907969142 17 0.77775 vertex 17.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 14.737436867076 0.77775 vertex 34.416922535211 17 0.77775 vertex 15.455907969142 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.306548743796 10 0.77775 vertex 15.262563132924 12.262563132924 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.737436867076 25.262563132924 0.77775 vertex 17.737436867076 25.262563132924 0 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 15.25 0.77775 vertex 15.455907969142 17 0.77775 vertex 15.830303993361 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 42.5 28.25 0.77775 vertex 41.866228156844 30 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 18.25 13.5 0.77775 vertex 18.25 13.5 0 endloop endfacet facet normal 0 1 0 outer loop vertex 60 17 0.77775 vertex 60 17 0 vertex 54.002309837942 17 0 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 12.002309837942 17 0 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 11.883210818105 0 vertex 43.737436867076 12.262563132924 0.77775 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 11.883210818105 0 vertex 43.169696006639 11.883210818105 0.77775 vertex 43.737436867076 12.262563132924 0.77775 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 18.25 13.5 0.77775 vertex 18.116789181895 14.169696006639 0 vertex 18.25 13.5 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 42.5 28.25 0 vertex 41.830303993361 28.116789181895 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 23 0 vertex 48.011309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 15.116789181895 0.77775 vertex 15.455907969142 17 0.77775 vertex 16.5 15.25 0.77775 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 17.737436867076 12.262563132924 0 vertex 17.169696006639 11.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 52 40 0.77775 vertex 60 23 0.77775 vertex 60 40 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.75 13.5 0 vertex 18.116789181895 12.830303993361 0 vertex 18.25 13.5 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 28.116789181895 0 vertex 42.5 28.25 0.77775 vertex 42.5 28.25 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 12.002309837942 23 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 23 0.77775 vertex 60 23 0.77775 vertex 54.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 23 0.77775 vertex 6.011309837942 24.730643081307 0 vertex 6.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 17.169696006639 15.116789181895 0 vertex 16.5 15.25 0.77775 vertex 16.5 15.25 0 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 17 0.77775 vertex 6.011309837942 15.063011877768 0.77775 vertex 6.011309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 1 0 0 outer loop vertex 60 17 0.77775 vertex 60 0 0 vertex 60 17 0 endloop endfacet facet normal 1 0 0 outer loop vertex 60 0 0.77775 vertex 60 0 0 vertex 60 17 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 15.262563132924 12.262563132924 0.77775 vertex 15.830303993361 11.883210818105 0.77775 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 43.737436867076 12.262563132924 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 12.002309837942 15.063011877768 0.77775 vertex 12.002309837942 15.195826430941 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 17.169696006639 24.883210818105 0.77775 vertex 17.379510917074 23 0.77775 vertex 17.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 43.737436867076 12.262563132924 0.77775 vertex 43.169696006639 11.883210818105 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 42.5 28.25 0.77775 vertex 41.830303993361 28.116789181895 0 vertex 42.5 28.25 0 endloop endfacet facet normal 1 0 0 outer loop vertex 6.011309837942 15.269356918694 0 vertex 6.011309837942 17 0 vertex 6.011309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 25.830303993361 0.77775 vertex 37.474084379442 23 0.77775 vertex 41.262563132924 25.262563132924 0.77775 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 18.25 13.5 0 vertex 18.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 25.262563132924 0.77775 vertex 17.379510917074 23 0.77775 vertex 18.116789181895 25.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 34.416922535211 17 0.77775 vertex 41.262563132924 14.737436867076 0.77775 vertex 41.830303993361 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 30 0.77775 vertex 6.011309837942 24.936988122232 0.77775 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 17.379510917074 23 0.77775 vertex 37.474084379442 23 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 12.002309837942 24.804173569059 0.110046151702 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 52 10 0.77775 vertex 43.169696006639 11.883210818105 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 14.737436867076 0.77775 vertex 40.883210818105 14.169696006639 0 vertex 41.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 43.169696006639 24.883210818105 0 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.25 26.5 0.77775 vertex 44.116789181895 25.830303993361 0 vertex 44.116789181895 25.830303993361 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 60 17 0.77775 vertex 54.002309837942 17 0 vertex 54.002309837942 17 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 48.011309837942 23 0 vertex 42.5 24.75 0 vertex 43.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0 1 outer loop vertex 43.737436867076 27.737436867076 0.77775 vertex 44.116789181895 27.169696006639 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 18.116789181895 25.830303993361 0 vertex 17.737436867076 25.262563132924 0 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.195826430941 0.110046151702 vertex 54.002309837942 17 0.77775 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 14.75 26.5 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 52 0 0.77775 vertex 52 0 0 vertex 60 0 0.77775 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 14.75 26.5 0.77775 vertex 14.75 26.5 0 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 15.269356918694 0 vertex 54.002309837942 17 0.77775 vertex 54.002309837942 17 0 endloop endfacet facet normal 0 0 1 outer loop vertex 16.5 11.75 0.77775 vertex 15.306548743796 10 0.77775 vertex 17.169696006639 11.883210818105 0.77775 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 17.169696006639 15.116789181895 0 vertex 17.169696006639 15.116789181895 0.77775 vertex 16.5 15.25 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 12.002309837942 15.195826430941 0.110046151702 vertex 12.002309837942 15.063011877768 0.77775 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal 0 0.980785280403 0.195090322015 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 48.011309837942 15.195826430941 0.110046151702 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 16.5 11.75 0.77775 vertex 16.5 11.75 0 vertex 15.830303993361 11.883210818105 0 endloop endfacet facet normal 1 0 0 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 48.011309837942 15.269356918694 0 vertex 48.011309837942 17 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 52 30 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal -0.195090322016 0.980785280403 0 outer loop vertex 42.5 24.75 0.77775 vertex 43.169696006639 24.883210818105 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 14.75 26.5 0 vertex 14.75 26.5 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 43.737436867076 14.737436867076 0 vertex 48.011309837942 17 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 44.116789181895 14.169696006639 0 vertex 48.011309837942 17 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 41.830303993361 24.883210818105 0 vertex 42.5 24.75 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 17.169696006639 24.883210818105 0 vertex 42.5 24.75 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 1 0 outer loop vertex 52 40 0 vertex 52 40 0.77775 vertex 60 40 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 52 40 0 vertex 60 40 0.77775 vertex 60 40 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0.77775 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal -0.831469612302 -0.555570233021 -0 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 15.830303993361 24.883210818105 0 vertex 15.830303993361 24.883210818105 0.77775 vertex 16.5 24.75 0.77775 endloop endfacet facet normal 0.195090322016 0.980785280403 0 outer loop vertex 15.830303993361 24.883210818105 0 vertex 16.5 24.75 0.77775 vertex 16.5 24.75 0 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 24.936988122232 0.77775 vertex 12.002309837942 23 0.77775 vertex 15.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 12.002309837942 24.936988122232 0.77775 vertex 15.262563132924 25.262563132924 0.77775 vertex 14.883210818105 25.830303993361 0.77775 endloop endfacet facet normal 1 0 0 outer loop vertex 60 40 0.77775 vertex 60 23 0.77775 vertex 60 23 0 endloop endfacet facet normal 1 0 0 outer loop vertex 60 40 0.77775 vertex 60 23 0 vertex 60 40 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 27.737436867076 0 vertex 15.262563132924 27.737436867076 0.77775 vertex 14.883210818105 27.169696006639 0.77775 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 15.262563132924 27.737436867076 0 vertex 14.883210818105 27.169696006639 0.77775 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 1 outer loop vertex 37.474084379442 23 0.77775 vertex 48.011309837942 23 0.77775 vertex 42.5 24.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 37.474084379442 23 0.77775 vertex 42.5 24.75 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 14.737436867076 0 vertex 12.002309837942 17 0 vertex 41.422110817733 17 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 0 outer loop vertex 43.169696006639 15.116789181895 0.77775 vertex 42.5 15.25 0.77775 vertex 42.5 15.25 0 endloop endfacet facet normal -0.195090322016 -0.980785280403 -0 outer loop vertex 43.169696006639 15.116789181895 0.77775 vertex 42.5 15.25 0 vertex 43.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 52 10 0.77775 vertex 60 0 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 15.063011877768 0.77775 vertex 60 0 0.77775 vertex 60 17 0.77775 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 13.5 0.77775 vertex 40.883210818105 12.830303993361 0.77775 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0.980785280403 0.195090322016 0 outer loop vertex 40.75 13.5 0.77775 vertex 40.883210818105 12.830303993361 0 vertex 40.75 13.5 0 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.737436867076 27.737436867076 0 vertex 17.737436867076 27.737436867076 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal -0.555570233021 -0.831469612302 0 outer loop vertex 17.737436867076 27.737436867076 0 vertex 17.169696006639 28.116789181895 0.77775 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 0 30 0.77775 vertex 12.002309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 27.169696006639 0.77775 vertex 12.002309837942 24.936988122232 0.77775 vertex 14.75 26.5 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 12.262563132924 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 12.262563132924 0.77775 vertex 44.116789181895 12.830303993361 0 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 48.011309837942 23 0.77775 vertex 37.474084379442 23 0.77775 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 15.25 0.77775 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.830303993361 15.116789181895 0 endloop endfacet facet normal 0.195090322016 -0.980785280403 0 outer loop vertex 16.5 15.25 0.77775 vertex 15.830303993361 15.116789181895 0 vertex 16.5 15.25 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 41.262563132924 12.262563132924 0.77775 vertex 41.262563132924 12.262563132924 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 41.262563132924 12.262563132924 0 vertex 40.883210818105 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 16.5 15.25 0 vertex 15.830303993361 15.116789181895 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 25.262563132924 0 vertex 43.737436867076 25.262563132924 0.77775 vertex 44.116789181895 25.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 43.737436867076 25.262563132924 0 vertex 44.116789181895 25.830303993361 0.77775 vertex 44.116789181895 25.830303993361 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 14.169696006639 0.77775 vertex 40.75 13.5 0.77775 vertex 40.75 13.5 0 endloop endfacet facet normal 0.980785280403 -0.195090322016 0 outer loop vertex 40.883210818105 14.169696006639 0.77775 vertex 40.75 13.5 0 vertex 40.883210818105 14.169696006639 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 23 0 vertex 60 23 0.77775 vertex 54.002309837942 23 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 60 23 0 vertex 54.002309837942 23 0.77775 vertex 54.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 30 0 vertex 14.042553191489 30 0 vertex 14.883210818105 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 0 30 0 vertex 14.883210818105 27.169696006639 0 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.262563132924 25.262563132924 0.77775 vertex 41.830303993361 24.883210818105 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 25.262563132924 0 vertex 41.830303993361 24.883210818105 0.77775 vertex 41.830303993361 24.883210818105 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.262563132924 27.737436867076 0.77775 vertex 41.262563132924 27.737436867076 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 41.830303993361 28.116789181895 0.77775 vertex 41.262563132924 27.737436867076 0 vertex 41.830303993361 28.116789181895 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 24.883210818105 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 43.737436867076 25.262563132924 0 endloop endfacet facet normal -0.555570233021 0.831469612302 0 outer loop vertex 43.169696006639 24.883210818105 0.77775 vertex 43.737436867076 25.262563132924 0 vertex 43.169696006639 24.883210818105 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 43.169696006639 11.883210818105 0 vertex 43.737436867076 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 52 10 0 vertex 43.737436867076 12.262563132924 0 vertex 54.002309837942 15.269356918694 0 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 60 23 0.77775 vertex 52 40 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 54.002309837942 24.936988122232 0.77775 vertex 52 40 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 34.416922535211 17 0.77775 vertex 41.422110817733 17 0 endloop endfacet facet normal 0 1 0 outer loop vertex 15.455907969142 17 0.77775 vertex 41.422110817733 17 0 vertex 12.002309837942 17 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 12.002309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.730643081307 0 endloop endfacet facet normal 0 -0.831469612304 0.555570233017 outer loop vertex 12.002309837942 24.804173569059 0.110046151702 vertex 6.011309837942 24.730643081307 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 15.455907969142 17 0.77775 vertex 12.002309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 15.262563132924 14.737436867076 0.77775 vertex 12.002309837942 17 0.77775 vertex 14.883210818105 14.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 25.830303993361 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 17 0.77775 vertex 0 10 0.77775 vertex 6.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 0 17 0.77775 vertex 6.011309837942 15.063011877768 0.77775 vertex 6.011309837942 17 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 34.416922535211 17 0.77775 vertex 42.5 15.25 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 42.5 15.25 0.77775 vertex 43.169696006639 15.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 12.002309837942 17 0.77775 vertex 12.002309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 14.883210818105 14.169696006639 0.77775 vertex 12.002309837942 15.063011877768 0.77775 vertex 14.75 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 0 30 0.77775 vertex 0 23 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 24.936988122232 0.77775 vertex 0 23 0.77775 vertex 6.011309837942 23 0.77775 endloop endfacet facet normal -0 -0 -1 outer loop vertex 40.75 26.5 0 vertex 40.883210818105 25.830303993361 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal -0.980785280403 -0.195090322016 0 outer loop vertex 44.25 13.5 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 44.116789181895 14.169696006639 0 endloop endfacet facet normal -0.980785280403 -0.195090322016 -0 outer loop vertex 44.25 13.5 0.77775 vertex 44.116789181895 14.169696006639 0 vertex 44.25 13.5 0 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 17.737436867076 12.262563132924 0 vertex 17.737436867076 12.262563132924 0.77775 vertex 18.116789181895 12.830303993361 0.77775 endloop endfacet facet normal -0.831469612302 0.555570233021 0 outer loop vertex 17.737436867076 12.262563132924 0 vertex 18.116789181895 12.830303993361 0.77775 vertex 18.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 1 outer loop vertex 0 10 0.77775 vertex 15.306548743796 10 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 54.002309837942 24.936988122232 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 -0.980785280403 0.195090322015 outer loop vertex 54.002309837942 24.804173569059 0.110046151702 vertex 48.011309837942 24.936988122232 0.77775 vertex 48.011309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 12.830303993361 0 vertex 14.883210818105 12.830303993361 0.77775 vertex 15.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 14.883210818105 12.830303993361 0 vertex 15.262563132924 12.262563132924 0.77775 vertex 15.262563132924 12.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 43.737436867076 12.262563132924 0 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 54.002309837942 15.269356918694 0 vertex 44.116789181895 12.830303993361 0 vertex 48.011309837942 15.269356918694 0 endloop endfacet facet normal 0 1 0 outer loop vertex 0 30 0 vertex 0 30 0.77775 vertex 14.607403236621 30 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 0 30 0 vertex 14.607403236621 30 0.77775 vertex 14.042553191489 30 0 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 12.262563132924 0 vertex 41.262563132924 12.262563132924 0.77775 vertex 41.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0.555570233021 0.831469612302 0 outer loop vertex 41.262563132924 12.262563132924 0 vertex 41.830303993361 11.883210818105 0.77775 vertex 41.830303993361 11.883210818105 0 endloop endfacet facet normal -1 0 0 outer loop vertex 0 10 0 vertex 0 10 0.77775 vertex 0 17 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 0 10 0 vertex 0 17 0.77775 vertex 0 17 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.116789181895 12.830303993361 0.77775 vertex 44.25 13.5 0.77775 vertex 44.25 13.5 0 endloop endfacet facet normal -0.980785280403 0.195090322016 0 outer loop vertex 44.116789181895 12.830303993361 0.77775 vertex 44.25 13.5 0 vertex 44.116789181895 12.830303993361 0 endloop endfacet facet normal 0 1 0 outer loop vertex 41.422110817733 17 0 vertex 34.416922535211 17 0.77775 vertex 48.011309837942 17 0.77775 endloop endfacet facet normal 0 1 0 outer loop vertex 41.422110817733 17 0 vertex 48.011309837942 17 0.77775 vertex 48.011309837942 17 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 30 0.77775 vertex 52 40 0.77775 vertex 52 40 0 endloop endfacet facet normal -1 0 0 outer loop vertex 52 30 0.77775 vertex 52 40 0 vertex 52 30 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.830303993361 24.883210818105 0 vertex 16.5 24.75 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 40.883210818105 27.169696006639 0 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 41.262563132924 27.737436867076 0 vertex 17.737436867076 27.737436867076 0 vertex 17.169696006639 28.116789181895 0 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 0 10 0.77775 vertex 14.883210818105 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 6.011309837942 15.063011877768 0.77775 vertex 14.883210818105 12.830303993361 0.77775 vertex 12.002309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 43.737436867076 14.737436867076 0.77775 vertex 44.116789181895 14.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 17 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 48.011309837942 15.063011877768 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.262563132924 25.262563132924 0 vertex 15.830303993361 24.883210818105 0 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 15.262563132924 25.262563132924 0 vertex 12.002309837942 23 0 vertex 12.002309837942 24.730643081307 0 endloop endfacet facet normal 0 0 1 outer loop vertex 44.25 26.5 0.77775 vertex 44.116789181895 25.830303993361 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 27.169696006639 0 vertex 40.75 26.5 0 vertex 18.116789181895 27.169696006639 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 40.883210818105 27.169696006639 0 vertex 18.116789181895 27.169696006639 0 vertex 17.737436867076 27.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 41.262563132924 14.737436867076 0 vertex 17.169696006639 15.116789181895 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 17.169696006639 15.116789181895 0 vertex 16.5 15.25 0 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 15.116789181895 0 vertex 15.830303993361 15.116789181895 0.77775 vertex 15.262563132924 14.737436867076 0.77775 endloop endfacet facet normal 0.555570233021 -0.831469612302 0 outer loop vertex 15.830303993361 15.116789181895 0 vertex 15.262563132924 14.737436867076 0.77775 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 40.883210818105 27.169696006639 0 endloop endfacet facet normal 0.831469612302 -0.555570233021 0 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0 vertex 41.262563132924 27.737436867076 0 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 37.474084379442 23 0.77775 vertex 17.379510917074 23 0.77775 endloop endfacet facet normal 0 -1 0 outer loop vertex 48.011309837942 23 0 vertex 17.379510917074 23 0.77775 vertex 12.002309837942 23 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 15.830303993361 15.116789181895 0 vertex 15.262563132924 14.737436867076 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 12.002309837942 17 0 vertex 15.262563132924 14.737436867076 0 vertex 12.002309837942 15.269356918694 0 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 40.883210818105 25.830303993361 0.77775 vertex 41.262563132924 25.262563132924 0.77775 endloop endfacet facet normal 0.831469612302 0.555570233021 0 outer loop vertex 40.883210818105 25.830303993361 0 vertex 41.262563132924 25.262563132924 0.77775 vertex 41.262563132924 25.262563132924 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 12.830303993361 0 vertex 15.262563132924 12.262563132924 0 vertex 14.464705848856 10 0 endloop endfacet facet normal 0 0 -1 outer loop vertex 14.883210818105 12.830303993361 0 vertex 14.464705848856 10 0 vertex 0 10 0 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 27.737436867076 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 41.262563132924 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 17.169696006639 28.116789181895 0.77775 vertex 17.737436867076 27.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 48.011309837942 24.936988122232 0.77775 vertex 43.737436867076 25.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 23 0.77775 vertex 43.737436867076 25.262563132924 0.77775 vertex 43.169696006639 24.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.116789181895 14.169696006639 0.77775 vertex 44.25 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 44.25 26.5 0.77775 vertex 48.011309837942 24.936988122232 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 44.116789181895 27.169696006639 0.77775 vertex 48.011309837942 24.936988122232 0.77775 vertex 52 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 27.169696006639 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 17.737436867076 27.737436867076 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 23 0.77775 vertex 54.002309837942 24.936988122232 0.77775 vertex 54.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 41.866228156844 30 0.77775 vertex 14.607403236621 30 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.262563132924 27.737436867076 0.77775 vertex 14.607403236621 30 0.77775 vertex 17.169696006639 28.116789181895 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.25 13.5 0.77775 vertex 44.116789181895 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 48.011309837942 15.063011877768 0.77775 vertex 44.116789181895 12.830303993361 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 14.169696006639 0.77775 vertex 18.25 13.5 0.77775 vertex 41.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.25 26.5 0.77775 vertex 40.883210818105 27.169696006639 0.77775 vertex 18.116789181895 27.169696006639 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 24.730643081307 0 vertex 54.002309837942 23 0 vertex 54.002309837942 23 0.77775 endloop endfacet facet normal -1 0 0 outer loop vertex 54.002309837942 24.730643081307 0 vertex 54.002309837942 23 0.77775 vertex 54.002309837942 24.804173569059 0.110046151702 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 41.262563132924 12.262563132924 0.77775 vertex 18.25 13.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 41.830303993361 11.883210818105 0.77775 vertex 18.25 13.5 0.77775 vertex 18.116789181895 12.830303993361 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 17.737436867076 12.262563132924 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 12.830303993361 0.77775 vertex 42.5 11.75 0.77775 vertex 41.830303993361 11.883210818105 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 15.306548743796 10 0.77775 vertex 52 10 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 17.737436867076 12.262563132924 0.77775 vertex 52 10 0.77775 vertex 42.5 11.75 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 18.116789181895 14.169696006639 0.77775 vertex 41.262563132924 12.262563132924 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.25 26.5 0.77775 vertex 40.75 26.5 0.77775 vertex 40.883210818105 27.169696006639 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 37.474084379442 23 0.77775 vertex 40.75 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 18.116789181895 25.830303993361 0.77775 vertex 40.75 26.5 0.77775 vertex 18.25 26.5 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 34.416922535211 17 0.77775 vertex 17.737436867076 14.737436867076 0.77775 endloop endfacet facet normal 0 0 1 outer loop vertex 40.883210818105 12.830303993361 0.77775 vertex 17.737436867076 14.737436867076 0.77775 vertex 18.116789181895 14.169696006639 0.77775 endloop endfacet endsolid