From 892b5b9494486ad4058d5935949f9be334002b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sun, 29 Jan 2012 18:17:37 +0100 Subject: [PATCH 01/27] Created transversal areas curve plot tool --- src/Mod/Ship/CMakeLists.txt | 1 + src/Mod/Ship/Makefile.am | 1 + src/Mod/Ship/shipAreasCurve/Plot.py | 211 +++++++++++++++++++++++ src/Mod/Ship/shipAreasCurve/TaskPanel.py | 9 +- 4 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 src/Mod/Ship/shipAreasCurve/Plot.py diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index 9f86e5e4a..7d5794e62 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -51,6 +51,7 @@ SOURCE_GROUP("shipoutlinedraw" FILES ${ShipOutlineDraw_SRCS}) SET(ShipAreasCurve_SRCS shipAreasCurve/__init__.py + shipAreasCurve/Plot.py shipAreasCurve/Preview.py shipAreasCurve/TaskPanel.py shipAreasCurve/TaskPanel.ui diff --git a/src/Mod/Ship/Makefile.am b/src/Mod/Ship/Makefile.am index ed2efda8d..113b0f04f 100644 --- a/src/Mod/Ship/Makefile.am +++ b/src/Mod/Ship/Makefile.am @@ -40,6 +40,7 @@ nobase_data_DATA = \ shipOutlineDraw/TaskPanel.py \ shipOutlineDraw/TaskPanel.ui \ shipAreasCurve/__init__.py \ + shipAreasCurve/Plot.py \ shipAreasCurve/Preview.py \ shipAreasCurve/TaskPanel.py \ shipAreasCurve/TaskPanel.ui \ diff --git a/src/Mod/Ship/shipAreasCurve/Plot.py b/src/Mod/Ship/shipAreasCurve/Plot.py new file mode 100644 index 000000000..6e0fdb536 --- /dev/null +++ b/src/Mod/Ship/shipAreasCurve/Plot.py @@ -0,0 +1,211 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2011, 2012 * +#* Jose Luis Cercos Pita * +#* * +#* This program is free software; you can redistribute it and/or modify * +#* it under the terms of the GNU Lesser General Public License (LGPL) * +#* as published by the Free Software Foundation; either version 2 of * +#* the License, or (at your option) any later version. * +#* for detail see the LICENCE text file. * +#* * +#* 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 Library General Public License for more details. * +#* * +#* You should have received a copy of the GNU Library General Public * +#* License along with this program; if not, write to the Free Software * +#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +#* USA * +#* * +#*************************************************************************** + +import os +# FreeCAD modules +import FreeCAD,FreeCADGui +from FreeCAD import Part, Base +from FreeCAD import Image, ImageGui +# FreeCADShip modules +from shipUtils import Paths, Translator + +header = """ ################################################################# + + ##### #### ### #### ##### # # ### #### + # # # # # # # # # # # # + # ## #### #### # # # # # # # # # # # + #### # # # # # # # ##### # # ## ## ##### # #### + # # #### #### # # # # # # # # # # + # # # # # # # # # # # # # # + # # #### #### ### # # #### ##### # # ### # + + ################################################################# +""" + +class Plot(object): + def __init__(self, x, y, disp, xcb, ship): + """ Constructor. performs plot and show it (Using pyxplot). + @param x X coordinates. + @param y Transversal areas. + @param disp Ship displacement. + @param xcb Bouyancy center length. + @param ship Active ship instance. + """ + if self.createDirectory(): + return + if self.saveData(x,y,ship): + return + if self.saveLayout(x,y,disp,xcb,ship): + return + if self.execute(): + return + ImageGui.open(self.path + 'areas.png') + + def createDirectory(self): + """ Create needed folder to write data and scripts. + @return True if error happens. + """ + self.path = FreeCAD.ConfigGet("UserAppData") + "ShipOutput/" + if not os.path.exists(self.path): + os.makedirs(self.path) + if not os.path.exists(self.path): + msg = Translator.translate("Can't create '" + self.path + "' folder.\n") + FreeCAD.Console.PrintError(msg) + return False + + def saveData(self,x,y,ship): + """ Write data file. + @param x X coordinates. + @param y Transversal areas. + @param ship Active ship instance. + @return True if error happens. + """ + # Open the file + filename = self.path + 'areas.dat' + try: + Output = open(filename, "w") + except IOError: + msg = Translator.translate("Can't write '" + filename + "' file.\n") + FreeCAD.Console.PrintError(msg) + return True + # Print header + Output.write(header) + Output.write(" #\n") + Output.write(" # File automatically exported by FreeCAD-Ship\n") + Output.write(" # This file contains transversal areas data, filled with following columns:\n") + Output.write(" # 1: X coordiante [m]\n") + Output.write(" # 2: Transversal area [m2]\n") + Output.write(" # 3: X FP coordinate [m]\n") + Output.write(" # 4: Y FP coordinate (bounds in order to draw it)\n") + Output.write(" # 3: X AP coordinate [m]\n") + Output.write(" # 4: Y AP coordinate (bounds in order to draw it)\n") + Output.write(" #\n") + Output.write(" #################################################################\n") + # Get perpendiculars data + Lpp = ship.Length + FPx = 0.5*Lpp + APx = -0.5*Lpp + maxArea = max(y) + # Print data + if len(x) < 2: + msg = Translator.translate("Not enough data to plot.\n") + FreeCAD.Console.PrintError(msg) + string = "%f %f %f %f %f %f\n" % (x[0], y[0], FPx, 0.0, APx, 0.0) + Output.write(string) + for i in range(1, len(x)): + string = "%f %f %f %f %f %f\n" % (x[i], y[i], FPx, maxArea, APx, maxArea) + Output.write(string) + # Close file + Output.close() + self.dataFile = filename + msg = Translator.translate("Data saved at '" + self.dataFile + "'.\n") + FreeCAD.Console.PrintMessage(msg) + return False + + def saveLayout(self, x, y, disp, xcb, ship): + """ Prints the data output. + @param x X coordinates. + @param y Transversal areas. + @param disp Ship displacement. + @param xcb Bouyancy center length. + @param ship Active ship instance. + @return True if error happens. + """ + filename = self.path + 'areas.pyxplot' + # Open the file + try: + Output = open(filename, "w") + except IOError: + msg = Translator.translate("Can't write '" + filename + "' file.\n") + FreeCAD.Console.PrintError(msg) + return True + # Write header + Output.write(header) + Output.write(" #\n") + Output.write(" # File automatically exported by FreeCAD-Ship\n") + Output.write(" # This file contains a script to plot transversal areas curve.\n") + Output.write(" # To use it execute:\n") + Output.write(" #\n") + Output.write(" # pyxplot %s\n" % (filename)) + Output.write(" #\n") + Output.write(" #################################################################\n") + # Write general options for hydrostatics + Output.write("set numeric display latex\n") + Output.write("set output '%s'\n" % (self.path + 'areas.eps')) + Output.write("set nokey\n") + Output.write("set grid\n") + Output.write("# X axis\n") + Output.write("set xlabel 'x / $m$'\n") + Output.write("set xtic\n") + Output.write("# Y axis\n") + Output.write("set ylabel 'Area / $m^2$'\n") + Output.write("set ytic\n") + Output.write("# Line styles\n") + Output.write("set style 1 line linetype 1 linewidth 1 colour rgb (0):(0):(0)\n") + Output.write("set style 2 line linetype 1 linewidth 2 colour rgb (0):(0):(0)\n") + # Get perpendiculars data + Lpp = ship.Length + FPx = 0.5*Lpp + APx = -0.5*Lpp + maxArea = max(y) + # Perpendicular labels + Output.write("# Perpendiculars labels\n") + Output.write("set label (1) AP %f,%f\n" % (APx+0.01*Lpp, 0.01*maxArea)) + Output.write("set label (2) AP %f,%f\n" % (APx+0.01*Lpp, 0.95*maxArea)) + Output.write("set label (3) FP %f,%f\n" % (FPx+0.01*Lpp, 0.01*maxArea)) + Output.write("set label (4) FP %f,%f\n" % (FPx+0.01*Lpp, 0.95*maxArea)) + # Additional data + Output.write("# Additional data\n") + Output.write("set label (5) 'XCB = %g m' %f,%f\n" % (xcb, -0.25*Lpp, 0.25*maxArea)) + Output.write("set label (6) 'Maximum area = %g m2' %f,%f\n" % (maxArea, -0.25*Lpp, 0.15*maxArea)) + Output.write("set label (7) 'Displacement = %g tons' %f,%f\n" % (disp, -0.25*Lpp, 0.05*maxArea)) + # Write plot call + Output.write("# Plot\n") + Output.write("plot '%s' using 1:2 title 'Transversal areas' axes x1y1 with lines style 1, \\\n" % (self.dataFile)) + Output.write(" '%s' using 3:4 title 'FP' axes x1y1 with lines style 2, \\\n" % (self.dataFile)) + Output.write(" '%s' using 5:6 title 'AP' axes x1y1 with lines style 2\n" % (self.dataFile)) + # Close file + self.layoutFile = filename + Output.close() + return False + + def execute(self): + """ Calls pyxplot in order to plot an save an image. + @return True if error happens. + """ + filename = self.path + 'areas' + comm = "pyxplot %s" % (self.layoutFile) + if os.system(comm): + msg = Translator.translate("Can't execute pyxplot. Maybe is not installed?\n") + FreeCAD.Console.PrintError(msg) + msg = Translator.translate("Plot will not generated\n") + FreeCAD.Console.PrintError(msg) + return True + comm = "gs -r300 -dEPSCrop -dTextAlphaBits=4 -sDEVICE=png16m -sOutputFile=%s.png -dBATCH -dNOPAUSE %s.eps" % (filename,filename) + if os.system(comm): + msg = Translator.translate("Can't execute ghostscript. Maybe is not installed?\n") + FreeCAD.Console.PrintError(msg) + msg = Translator.translate("Generated image will not converted to png\n") + FreeCAD.Console.PrintError(msg) + return True + return False diff --git a/src/Mod/Ship/shipAreasCurve/TaskPanel.py b/src/Mod/Ship/shipAreasCurve/TaskPanel.py index 3a5dab2fc..af4764e12 100644 --- a/src/Mod/Ship/shipAreasCurve/TaskPanel.py +++ b/src/Mod/Ship/shipAreasCurve/TaskPanel.py @@ -28,7 +28,7 @@ import FreeCADGui as Gui # Qt library from PyQt4 import QtGui,QtCore # Module -import Preview +import Preview, Plot import Instance from shipUtils import Paths, Translator from surfUtils import Geometry @@ -44,6 +44,13 @@ class TaskPanel: if not self.ship: return False self.save() + # Plot data + data = Hydrostatics.Displacement(self.ship,self.form.draft.value(),self.form.trim.value()) + x = self.ship.xSection[:] + y = data[0] + disp = data[1] + xcb = data[2] + Plot.Plot(x,y,disp,xcb, self.ship) self.preview.clean() return True From 9aa506130d9c5f5d661b54a124b395554cea69cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sun, 29 Jan 2012 18:31:09 +0100 Subject: [PATCH 02/27] Changed create ship error to suggest create geometry or download it --- src/Mod/Ship/shipCreateShip/TaskPanel.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Mod/Ship/shipCreateShip/TaskPanel.py b/src/Mod/Ship/shipCreateShip/TaskPanel.py index bee6c6964..3162702f1 100644 --- a/src/Mod/Ship/shipCreateShip/TaskPanel.py +++ b/src/Mod/Ship/shipCreateShip/TaskPanel.py @@ -119,7 +119,9 @@ class TaskPanel: self.faces = None selObjs = Geometry.getSelectedObjs() if not selObjs: - msg = Translator.translate("All ship surfaces must be selected (Any object has been selected)\n") + msg = Translator.translate("Ship objects can only be created on top of hull geometry (any object selected).\n" + App.Console.PrintError(msg) + msg = Translator.translate("Please create or download a ship hull geometry before using this tool\n") App.Console.PrintError(msg) return True self.faces = [] @@ -128,7 +130,9 @@ class TaskPanel: for j in range(0, len(faces)): self.faces.append(faces[j]) if not self.faces: - msg = Translator.translate("All ship surfaces must be selected (Any face found into selected objects)\n") + msg = Translator.translate("Ship objects can only be created on top of hull geometry (any face object selected).\n" + App.Console.PrintError(msg) + msg = Translator.translate("Please create or download a ship hull geometry before using this tool\n") App.Console.PrintError(msg) return True # Get bounds From 5a344ed796f304e5c0f0b7462ef2f9adacb28286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sun, 29 Jan 2012 18:48:45 +0100 Subject: [PATCH 03/27] Added icons to examples loader tool --- src/Mod/Ship/CMakeLists.txt | 3 + src/Mod/Ship/Icons/LoadIco.png | Bin 0 -> 13785 bytes src/Mod/Ship/Icons/LoadIco.xcf | Bin 0 -> 51515 bytes src/Mod/Ship/Icons/LoadIco.xpm | 1985 ++++++++++++++++++++++++++++++++ src/Mod/Ship/Makefile.am | 3 + 5 files changed, 1991 insertions(+) create mode 100644 src/Mod/Ship/Icons/LoadIco.png create mode 100644 src/Mod/Ship/Icons/LoadIco.xcf create mode 100644 src/Mod/Ship/Icons/LoadIco.xpm diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index 7d5794e62..494ce8d0a 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -21,6 +21,9 @@ SET(ShipIcons_SRCS Icons/Ico.png Icons/Ico.xcf Icons/Ico.xpm + Icons/LoadIco.png + Icons/LoadIco.xcf + Icons/LoadIco.xpm Icons/OutlineDrawIco.png Icons/OutlineDrawIco.xcf Icons/OutlineDrawIco.xpm diff --git a/src/Mod/Ship/Icons/LoadIco.png b/src/Mod/Ship/Icons/LoadIco.png new file mode 100644 index 0000000000000000000000000000000000000000..5d7037fcb24d2b94c10af98a5e3c854aac9fb603 GIT binary patch literal 13785 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 c #D3D3D3", +", c #D1D1D0", +"' c #CCCBCB", +") c #9E9E9E", +"! c #636363", +"~ c #2C2C2C", +"{ c #020202", +"] c #161616", +"^ c #1F1F1F", +"/ c #B2B3B3", +"( c #CCCDCD", +"_ c #CACACA", +": c #C8C8C7", +"< c #C6C6C5", +"[ c #C3C3C3", +"} c #B3B3B3", +"| c #7F8080", +"1 c #494949", +"2 c #151515", +"3 c #464646", +"4 c #6A6A6A", +"5 c #999899", +"6 c #969696", +"7 c #9A9A9A", +"8 c #959595", +"9 c #8F8F90", +"0 c #797879", +"a c #5F5E5F", +"b c #414141", +"c c #181818", +"d c #1E1E1E", +"e c #101010", +"f c #040404", +"g c #7D7C7C", +"h c #C6C6C6", +"i c #C3C3C4", +"j c #C1C1C2", +"k c #BFBFBF", +"l c #BDBDBD", +"m c #BABBBA", +"n c #B8B8B8", +"o c #B6B6B6", +"p c #979796", +"q c #323232", +"r c #353535", +"s c #828282", +"t c #BEBDBD", +"u c #D1D2D1", +"v c #D1D1D1", +"w c #D1D0D1", +"x c #D0D0D0", +"y c #CFCFD0", +"z c #D0D0CF", +"A c #CFCFCF", +"B c #CECECE", +"C c #CECECD", +"D c #CDCDCD", +"E c #BEBEBE", +"F c #8B8B8B", +"G c #535353", +"H c #B9B9B9", +"I c #282828", +"J c #7F7F7F", +"K c #C0C0BF", +"L c #BBBBBB", +"M c #B9B8B9", +"N c #B4B4B4", +"O c #B2B2B2", +"P c #AFAFAF", +"Q c #ADADAD", +"R c #ABABAB", +"S c #A2A2A2", +"T c #7B7B7B", +"U c #4B4B4B", +"V c #1D1D1D", +"W c #444444", +"X c #AEAEAE", +"Y c #D0CFD0", +"Z c #CECFCE", +"` c #CECDCD", +" . c #CCCCCD", +".. c #CCCCCC", +"+. c #CCCCCB", +"@. c #CBCCCB", +"#. c #CBCBCB", +"$. c #CACBCB", +"%. c #CBCACA", +"&. c #A6A5A6", +"*. c #5B5B5B", +"=. c #090909", +"-. c #0F0F0F", +";. c #B0B0B0", +">. c #C5C5C5", +",. c #595959", +"'. c #B7B7B7", +"). c #B4B5B5", +"!. c #6767D0", +"~. c #7171C9", +"{. c #9898B3", +"]. c #A9A9A9", +"^. c #A6A7A7", +"/. c #A4A4A5", +"(. c #A2A2A1", +"_. c #9FA0A0", +":. c #9D9D9D", +"<. c #8C8C8C", +"[. c #606060", +"}. c #080808", +"|. c #989999", +"1. c #CDCDCE", +"2. c #CDCCCC", +"3. c #CCCBCC", +"4. c #CBCBCA", +"5. c #CACBCA", +"6. c #C9CAC9", +"7. c #CAC9C9", +"8. c #C9C8C9", +"9. c #C9C8C8", +"0. c #C8C9C8", +"a. c #C8C8C8", +"b. c #C7C7C7", +"c. c #727272", +"d. c #3A3A3B", +"e. c #C1C0C1", +"f. c #595859", +"g. c #B5B5B5", +"h. c #B3B3B2", +"i. c #B1B1B0", +"j. c #ACACAE", +"k. c #0B0BF9", +"l. c #0000FF", +"m. c #1313F4", +"n. c #3838DF", +"o. c #5B5BC8", +"p. c #7F7FB1", +"q. c #99999C", +"r. c #9A999A", +"s. c #979797", +"t. c #949595", +"u. c #929292", +"v. c #212121", +"w. c #BCBCBD", +"x. c #CBCCCC", +"y. c #CACAC9", +"z. c #C9CACA", +"A. c #C9C9C9", +"B. c #C8C9C9", +"C. c #C7C8C8", +"D. c #C8C7C7", +"E. c #C6C6C7", +"F. c #C7C7C6", +"G. c #C4C5C5", +"H. c #333333", +"I. c #888787", +"J. c #797979", +"K. c #1A1A1A", +"L. c #BABABA", +"M. c #898989", +"N. c #AFAEAE", +"O. c #ACACAC", +"P. c #A4A4AC", +"Q. c #5656D1", +"R. c #3030E4", +"S. c #0A0AF9", +"T. c #0707F9", +"U. c #2727E3", +"V. c #4747C9", +"W. c #6667AF", +"X. c #8E8E8E", +"Y. c #171717", +"Z. c #949494", +"`. c #C9C9CA", +" + c #C7C6C7", +".+ c #C5C4C4", +"++ c #C5C5C4", +"@+ c #C4C5C4", +"#+ c #C4C4C4", +"$+ c #C3C4C3", +"%+ c #C4C3C3", +"&+ c #C3C3C2", +"*+ c #C2C3C3", +"=+ c #141414", +"-+ c #A5A6A5", +";+ c #C1C1C1", +">+ c #808081", +",+ c #422626", +"'+ c #955454", +")+ c #542E2E", +"!+ c #2D2D2D", +"~+ c #B8B9B9", +"{+ c #878787", +"]+ c #A8A8A8", +"^+ c #A5A6A6", +"/+ c #A4A3A4", +"(+ c #A1A1A1", +"_+ c #9E9E9F", +":+ c #8181AD", +"<+ c #5C5CC2", +"[+ c #3838D8", +"}+ c #1616EF", +"|+ c #0E0EF2", +"1+ c #807F7F", +"2+ c #070707", +"3+ c #C6C5C5", +"4+ c #C4C4C3", +"5+ c #C2C2C2", +"6+ c #C1C2C1", +"7+ c #C1C2C2", +"8+ c #C2C1C1", +"9+ c #C0C1C0", +"0+ c #090808", +"a+ c #BFBEBE", +"b+ c #BEBEBD", +"c+ c #646565", +"d+ c #301A1A", +"e+ c #AA5B5B", +"f+ c #A45555", +"g+ c #0D0707", +"h+ c #767675", +"i+ c #B5B4B4", +"j+ c #AFB0B0", +"k+ c #434343", +"l+ c #595958", +"m+ c #A4A4A4", +"n+ c #9E9D9D", +"o+ c #9B9B9B", +"p+ c #989998", +"q+ c #929192", +"r+ c #828299", +"s+ c #6060B1", +"t+ c #3E3ECA", +"u+ c #4142C5", +"v+ c #5A5A5A", +"w+ c #C3C4C4", +"x+ c #C3C2C3", +"y+ c #C0C0C1", +"z+ c #C1C0C0", +"A+ c #C0C0C0", +"B+ c #BEBFBE", +"C+ c #BFBEBF", +"D+ c #818282", +"E+ c #303030", +"F+ c #BCBDBD", +"G+ c #BDBCBC", +"H+ c #BCBCBC", +"I+ c #BCBBBC", +"J+ c #292929", +"K+ c #522A2A", +"L+ c #A65252", +"M+ c #723737", +"N+ c #131313", +"O+ c #B2B3B2", +"P+ c #ABACAC", +"Q+ c #6B6B6C", +"R+ c #343535", +"S+ c #A0A0A0", +"T+ c #999999", +"U+ c #929293", +"V+ c #908F90", +"W+ c #8D8D8D", +"X+ c #868787", +"Y+ c #858584", +"Z+ c #383838", +"`+ c #616162", +" @ c #C3C2C2", +".@ c #C2C1C2", +"+@ c #C0C1C1", +"@@ c #C0BFBF", +"#@ c #BEBFBF", +"$@ c #BFBFBE", +"%@ c #BEBDBE", +"&@ c #BDBCBD", +"*@ c #BCBCBB", +"=@ c #BBBCBC", +"-@ c #4F4F4F", +";@ c #5D5D5C", +">@ c #BBBABB", +",@ c #B9B9BA", +"'@ c #B9B9B8", +")@ c #969797", +"!@ c #632F2F", +"~@ c #A24A49", +"{@ c #492020", +"]@ c #515151", +"^@ c #AAAAAA", +"/@ c #A8A7A8", +"(@ c #878686", +"_@ c #9C9C9C", +":@ c #9A9A99", +"<@ c #929392", +"[@ c #909090", +"}@ c #8B8C8C", +"|@ c #858585", +"1@ c #919090", +"2@ c #C1C1C0", +"3@ c #C0BFC0", +"4@ c #BBBCBB", +"5@ c #BBBBBA", +"6@ c #BAB9BA", +"7@ c #B7B8B8", +"8@ c #B8B7B7", +"9@ c #B7B6B6", +"0@ c #B6B7B6", +"a@ c #373737", +"b@ c #733131", +"c@ c #9D4141", +"d@ c #2C1111", +"e@ c #737372", +"f@ c #A8A9A8", +"g@ c #A6A6A6", +"h@ c #A3A3A3", +"i@ c #030303", +"j@ c #989898", +"k@ c #969695", +"l@ c #939393", +"m@ c #919091", +"n@ c #8E8F8E", +"o@ c #89898A", +"p@ c #878788", +"q@ c #838383", +"r@ c #808180", +"s@ c #808080", +"t@ c #777777", +"u@ c #010101", +"v@ c #BDBEBE", +"w@ c #BDBEBD", +"x@ c #BCBBBB", +"y@ c #BBBBBC", +"z@ c #BAB9B9", +"A@ c #B9BABA", +"B@ c #B9B8B8", +"C@ c #B7B7B8", +"D@ c #0A0A0A", +"E@ c #B6B6B5", +"F@ c #B6B5B5", +"G@ c #B5B5B4", +"H@ c #B4B5B4", +"I@ c #B3B4B4", +"J@ c #8D8D8E", +"K@ c #813132", +"L@ c #983839", +"M@ c #1A0909", +"N@ c #A7A7A7", +"O@ c #9F9FA0", +"P@ c #0B0B0B", +"Q@ c #949394", +"R@ c #8F8F8F", +"S@ c #8D8D8C", +"T@ c #8A8A8A", +"U@ c #888988", +"V@ c #868586", +"W@ c #848383", +"X@ c #818281", +"Y@ c #7C7C7C", +"Z@ c #BCBDBC", +"`@ c #BABAB9", +" # c #B6B7B7", +".# c #B7B7B6", +"+# c #B5B6B5", +"@# c #6A696A", +"## c #3C3C3C", +"$# c #B4B4B3", +"%# c #B3B4B3", +"&# c #B4B3B3", +"*# c #B3B2B3", +"=# c #B2B2B3", +"-# c #B3B2B2", +";# c #B1B2B1", +"># c #B1B1B1", +",# c #202020", +"'# c #903131", +")# c #94302F", +"!# c #0C0303", +"~# c #A09FA0", +"{# c #9E9D9E", +"]# c #908F8F", +"^# c #8E8D8E", +"/# c #898988", +"(# c #848485", +"_# c #707070", +":# c #3D3D3D", +"<# c #BABABB", +"[# c #B8B5AD", +"}# c #B4B4B5", +"|# c #2E2E2E", +"1# c #6F6F6F", +"2# c #B1B1B2", +"3# c #B0B1B0", +"4# c #B1B0B1", +"5# c #B0AFB0", +"6# c #B0AFAF", +"7# c #5F605F", +"8# c #0A0303", +"9# c #912A2B", +"0# c #8F2827", +"a# c #020000", +"b# c #9C9C9D", +"c# c #9B9C9C", +"d# c #979798", +"e# c #959594", +"f# c #1F1E1F", +"g# c #6D6D6D", +"h# c #848584", +"i# c #828382", +"j# c #7E7E7E", +"k# c #262626", +"l# c #2F2F2F", +"m# c #505050", +"n# c #8F8E8F", +"o# c #B8B8B7", +"p# c #B6B6B7", +"q# c #B5B4B5", +"r# c #B3B3B4", +"s# c #B2B2B1", +"t# c #B1B2B2", +"u# c #B0B1B1", +"v# c #AEAFAE", +"w# c #ADAEAD", +"x# c #ADADAE", +"y# c #ACACAD", +"z# c #1A0606", +"A# c #8D2121", +"B# c #871D1D", +"C# c #9D9C9C", +"D# c #919191", +"E# c #252525", +"F# c #656565", +"G# c #808181", +"H# c #737373", +"I# c #424242", +"J# c #404040", +"K# c #B5B6B6", +"L# c #B6B5B6", +"M# c #B0B0AF", +"N# c #AFAFB0", +"O# c #ACADAD", +"P# c #ADACAC", +"Q# c #ACABAB", +"R# c #AAABAB", +"S# c #290808", +"T# c #881918", +"U# c #7E1414", +"V# c #939494", +"W# c #929291", +"X# c #8C8D8C", +"Y# c #5D5E5D", +"Z# c #838483", +"`# c #5F5F5F", +" $ c #2B2B2B", +".$ c #626162", +"+$ c #A7A6A6", +"@$ c #B2B1B2", +"#$ c #B1B0B0", +"$$ c #AFAFAE", +"%$ c #AEAFAF", +"&$ c #ADACAD", +"*$ c #ABAAAB", +"=$ c #AAAAAB", +"-$ c #ABAAAA", +";$ c #A9A8A9", +">$ c #A8A8A9", +",$ c #A7A8A7", +"'$ c #360708", +")$ c #851313", +"!$ c #771111", +"~$ c #090101", +"{$ c #919292", +"]$ c #90908F", +"^$ c #898888", +"/$ c #474747", +"($ c #393939", +"_$ c #AFAEAF", +":$ c #AEAEAF", +"<$ c #AEADAE", +"[$ c #ACADAC", +"}$ c #A3A2A3", +"|$ c #A8A7A7", +"1$ c #A7A6A7", +"2$ c #9D9E9E", +"3$ c #450909", +"4$ c #711010", +"5$ c #1C0404", +"6$ c #2A2A2A", +"7$ c #656665", +"8$ c #010000", +"9$ c #9F9F9F", +"0$ c #B2B1B1", +"a$ c #ADADAC", +"b$ c #ACACAB", +"c$ c #A6A6A5", +"d$ c #A5A5A6", +"e$ c #A5A5A5", +"f$ c #A5A4A4", +"g$ c #4E4F4E", +"h$ c #4C4D4D", +"i$ c #313131", +"j$ c #AFB0AF", +"k$ c #ADAEAE", +"l$ c #AAAAA9", +"m$ c #AAA9A9", +"n$ c #A9A9A8", +"o$ c #A9A8A8", +"p$ c #A8A8A7", +"q$ c #AAA7A1", +"r$ c #A7A7A6", +"s$ c #A6A5A5", +"t$ c #0E0E0E", +"u$ c #7D7D7D", +"v$ c #A2A1A1", +"w$ c #6E6D6D", +"x$ c #E9BA3C", +"y$ c #E9BA3D", +"z$ c #E8B93D", +"A$ c #E8BA3E", +"B$ c #E8BA3D", +"C$ c #E9B93E", +"D$ c #EABA3D", +"E$ c #787878", +"F$ c #AEAEAD", +"G$ c #ABABAC", +"H$ c #A8A9A9", +"I$ c #A7A8A8", +"J$ c #A5A5A4", +"K$ c #A3A3A4", +"L$ c #6E6D6E", +"M$ c #A1A2A1", +"N$ c #A1A0A1", +"O$ c #EABA3C", +"P$ c #E9B93D", +"Q$ c #E8BB3F", +"R$ c #E7BA3E", +"S$ c #E8BA3F", +"T$ c #E9BB3E", +"U$ c #E9BB3D", +"V$ c #444545", +"W$ c #706F70", +"X$ c #ACABAC", +"Y$ c #ABABAA", +"Z$ c #A9AAA9", +"`$ c #A6A6A7", +" % c #A1A1A2", +".% c #A1A1A0", +"+% c #1B1B1B", +"@% c #EBBB3D", +"#% c #EABB3E", +"$% c #E7BB3F", +"%% c #E7BB40", +"&% c #E7BA40", +"*% c #E7BA3F", +"=% c #E9BB3F", +"-% c #3A3A3A", +";% c #4A4A4A", +">% c #A4A3A3", +",% c #A3A2A2", +"'% c #A0A1A0", +")% c #E8BB40", +"!% c #E7BB41", +"~% c #A9AAAA", +"{% c #A3A3A2", +"]% c #A0A1A1", +"^% c #A0A0A1", +"/% c #E9BA3E", +"(% c #E7BC41", +"_% c #E7BB42", +":% c #E8BA40", +"<% c #A9A9AA", +"[% c #A3A4A3", +"}% c #A2A3A2", +"|% c #6E6E6E", +"1% c #5C5C5C", +"2% c #525252", +"3% c #484848", +"4% c #6C6C6C", +"5% c #5D5D5D", +"6% c #EABC3E", +"7% c #E6BC41", +"8% c #E6BC42", +"9% c #E6BB42", +"0% c #E7BC42", +"a% c #A6A7A6", +"b% c #A5A4A5", +"c% c #3E2D2D", +"d% c #543D3D", +"e% c #634646", +"f% c #6F4D4D", +"g% c #775252", +"h% c #77504F", +"i% c #724B4B", +"j% c #684443", +"k% c #543535", +"l% c #3C2525", +"m% c #36332E", +"n% c #616161", +"o% c #E6BB41", +"p% c #E7BC43", +"q% c #E6BC43", +"r% c #E8B93E", +"s% c #010100", +"t% c #A1A0A0", +"u% c #555555", +"v% c #191919", +"w% c #4B3A3A", +"x% c #725657", +"y% c #997373", +"z% c #BC8A89", +"A% c #D19797", +"B% c #CF9393", +"C% c #CD8F8F", +"D% c #CB8B8B", +"E% c #CA8888", +"F% c #C88383", +"G% c #C68080", +"H% c #C57C7C", +"I% c #C37878", +"J% c #C27474", +"K% c #BF7170", +"L% c #BE6D6D", +"M% c #BC6969", +"N% c #AC5D5D", +"O% c #763E3E", +"P% c #351B1B", +"Q% c #7A7A7A", +"R% c #767676", +"S% c #E9BC3F", +"T% c #E6BD44", +"U% c #E6BC44", +"V% c #E6BD43", +"W% c #E8BB41", +"X% c #EABB3D", +"Y% c #050401", +"Z% c #A2A3A3", +"`% c #A1A2A2", +" & c #626262", +".& c #5B4747", +"+& c #927171", +"@& c #C39494", +"#& c #D49F9E", +"$& c #D29B9A", +"%& c #D19696", +"&& c #CE9393", +"*& c #CE8F8E", +"=& c #CC8B8B", +"-& c #CA8787", +";& c #C88384", +">& c #C57B7C", +",& c #C07070", +"'& c #BE6C6C", +")& c #BD6969", +"!& c #BA6565", +"~& c #B96161", +"{& c #B75E5D", +"]& c #B65A59", +"^& c #B35556", +"/& c #5E2A2B", +"(& c #E6BD45", +"_& c #2B2109", +":& c #737374", +"<& c #242424", +"[& c #493A3A", +"}& c #866968", +"|& c #C19594", +"1& c #D6A2A1", +"2& c #D49D9E", +"3& c #D29A9A", +"4& c #D19796", +"5& c #CF9293", +"6& c #CD8E8F", +"7& c #C6807F", +"8& c #C37877", +"9& c #C17474", +"0& c #BF7070", +"a& c #BA6564", +"b& c #B96160", +"c& c #B75D5D", +"d& c #B55A59", +"e& c #B35656", +"f& c #B25252", +"g& c #B04D4D", +"h& c #A64646", +"i& c #0D0505", +"j& c #3E3E3E", +"k& c #E5BE46", +"l& c #E5BD45", +"m& c #E5BD44", +"n& c #EBBA3C", +"o& c #060401", +"p& c #575757", +"q& c #564444", +"r& c #9C7A7A", +"s& c #D2A1A1", +"t& c #D5A2A2", +"u& c #D49E9D", +"v& c #D2999A", +"w& c #CF9292", +"x& c #CB8B8A", +"y& c #C98787", +"z& c #C67F80", +"A& c #C47C7B", +"B& c #C17473", +"C& c #BD6C6C", +"D& c #BC6868", +"E& c #BA6464", +"F& c #B96060", +"G& c #B75C5D", +"H& c #B55959", +"I& c #B45555", +"J& c #B25152", +"K& c #AE4A49", +"L& c #AC4546", +"M& c #AB4242", +"N& c #592020", +"O& c #281010", +"P& c #A34141", +"Q& c #030200", +"R& c #E5BC43", +"S& c #E6BE45", +"T& c #E7BB3E", +"U& c #E9BA3B", +"V& c #EAB93C", +"W& c #EAB93A", +"X& c #E9B839", +"Y& c #EAB739", +"Z& c #EAB738", +"`& c #EAB737", +" * c #E9B536", +".* c #E7B335", +"+* c #E3B033", +"@* c #DFAC33", +"#* c #C6982C", +"$* c #BF9229", +"%* c #C2942B", +"&* c #D3A43B", +"** c #DEAF45", +"=* c #DFAF44", +"-* c #DFAE44", +";* c #DFAE43", +">* c #DFAE42", +",* c #DFAD42", +"'* c #DFAE41", +")* c #E0AC41", +"!* c #DEAC3F", +"~* c #D4A134", +"{* c #CA9628", +"]* c #C49023", +"^* c #D29A2C", +"/* c #E0A537", +"(* c #EBAC3D", +"_* c #EBAB3D", +":* c #ECAA3B", +"<* c #EBAA3A", +"[* c #EAA839", +"}* c #EBA737", +"|* c #EBA736", +"1* c #EAA634", +"2* c #EAA434", +"3* c #EBA432", +"4* c #EAA231", +"5* c #EAA230", +"6* c #EAA02E", +"7* c #EA9F2D", +"8* c #EA9F2C", +"9* c #EA9E2B", +"0* c #EA9D29", +"a* c #EA9D27", +"b* c #E5952C", +"c* c #BC6356", +"d* c #B25251", +"e* c #AE4949", +"f* c #AD4546", +"g* c #A93E3E", +"h* c #A83A3A", +"i* c #9C3333", +"j* c #7B2B2B", +"k* c #A73B3A", +"l* c #5B1F1F", +"m* c #0C0901", +"n* c #AA7A15", +"o* c #B78316", +"p* c #B98115", +"q* c #B98114", +"r* c #B98113", +"s* c #BA8113", +"t* c #BB8113", +"u* c #BB8112", +"v* c #BC8010", +"w* c #BA7F10", +"x* c #BF800E", +"y* c #E5BE45", +"z* c #E9B93C", +"A* c #E8B93B", +"B* c #EAB93B", +"C* c #E9B83B", +"D* c #EAB839", +"E* c #EAB838", +"F* c #EBB636", +"G* c #ECB536", +"H* c #ECB535", +"I* c #EBB535", +"J* c #ECB534", +"K* c #EDB533", +"L* c #ECB332", +"M* c #ECB431", +"N* c #EDB331", +"O* c #EDB330", +"P* c #EDB32F", +"Q* c #EEB32E", +"R* c #EEB22E", +"S* c #EFB22D", +"T* c #EEB12D", +"U* c #EFB12C", +"V* c #EFB02B", +"W* c #F0B02A", +"X* c #F0B028", +"Y* c #F0AF27", +"Z* c #F0AE27", +"`* c #F1AF26", +" = c #F1AE26", +".= c #F2AE24", +"+= c #F1AD24", +"@= c #F2AD23", +"#= c #F3AC22", +"$= c #F3AD21", +"%= c #F3AC21", +"&= c #F3AB20", +"*= c #F3AB1F", +"== c #F4AB1E", +"-= c #F4AA1E", +";= c #F4AA1D", +">= c #F4AA1C", +",= c #F5AA1C", +"'= c #F5A91C", +")= c #F6AA1B", +"!= c #F2A41D", +"~= c #CB713B", +"{= c #B04E4D", +"]= c #AC4645", +"^= c #A73A3A", +"/= c #A63636", +"(= c #A43232", +"_= c #A22E2F", +":= c #4E1414", +"<= c #270C0B", +"[= c #A53430", +"}= c #A22F30", +"|= c #962A2B", +"1= c #110C02", +"2= c #AB7A16", +"3= c #B58118", +"4= c #B68016", +"5= c #B68015", +"6= c #B77F15", +"7= c #B77F14", +"8= c #B87F13", +"9= c #B87F12", +"0= c #B87F11", +"a= c #B97E10", +"b= c #EBB737", +"c= c #EBB635", +"d= c #ECB533", +"e= c #ECB433", +"f= c #ECB432", +"g= c #EDB22E", +"h= c #EEB12B", +"i= c #EFB12B", +"j= c #EFB02A", +"k= c #F0B029", +"l= c #F0AF29", +"m= c #F0AF26", +"n= c #F2AE25", +"o= c #F1AE24", +"p= c #F2AD24", +"q= c #F2AC23", +"r= c #F2AC22", +"s= c #F3AB21", +"t= c #F4AB1F", +"u= c #F4A91C", +"v= c #F6A91A", +"w= c #F5A81A", +"x= c #E08B26", +"y= c #B7513B", +"z= c #A93E3D", +"A= c #A8393A", +"B= c #A32E2F", +"C= c #A12B2B", +"D= c #9F2727", +"E= c #8C1F1F", +"F= c #7B1E1F", +"G= c #9E2626", +"H= c #9F2525", +"I= c #9E2424", +"J= c #170505", +"K= c #130E02", +"L= c #AB7A18", +"M= c #B38018", +"N= c #B47F18", +"O= c #B57F17", +"P= c #B57F16", +"Q= c #B57F15", +"R= c #B57E15", +"S= c #B57E14", +"T= c #B67E12", +"U= c #B77D11", +"V= c #BC7E0F", +"W= c #E5BC44", +"X= c #E8B93C", +"Y= c #E9B93B", +"Z= c #E9B739", +"`= c #EBB738", +" - c #EAB637", +".- c #ECB635", +"+- c #EDB432", +"@- c #EEB330", +"#- c #EEB32F", +"$- c #EFB12D", +"%- c #EFB12A", +"&- c #EFAF2A", +"*- c #F0AF28", +"=- c #F1AF28", +"-- c #F1AE25", +";- c #F3AC23", +">- c #F3AC20", +",- c #F5A91B", +"'- c #EF9E1B", +")- c #C5642A", +"!- c #A32E2E", +"~- c #A12B2A", +"{- c #9F2626", +"]- c #9D2323", +"^- c #9B1E1F", +"/- c #9A1B1B", +"(- c #350808", +"_- c #330A0A", +":- c #9B1C1D", +"<- c #991A1A", +"[- c #5E0F0F", +"}- c #191203", +"|- c #B07D18", +"1- c #B58119", +"2- c #B58018", +"3- c #B68018", +"4- c #B68017", +"5- c #B67F15", +"6- c #B67F14", +"7- c #B77E13", +"8- c #B67D12", +"9- c #B97D10", +"0- c #BC7F0E", +"a- c #E7BC40", +"b- c #E9B83A", +"c- c #E9B73A", +"d- c #EBB533", +"e- c #EDB433", +"f- c #ECB331", +"g- c #ECB330", +"h- c #EEB22F", +"i- c #EEB22D", +"j- c #F1AF27", +"k- c #F2AD22", +"l- c #F5A91A", +"m- c #F6A819", +"n- c #D97D1E", +"o- c #9D2222", +"p- c #9C1F1F", +"q- c #981717", +"r- c #961314", +"s- c #700B0B", +"t- c #050000", +"u- c #851010", +"v- c #951212", +"w- c #951111", +"x- c #4A0708", +"y- c #281D05", +"z- c #B37F19", +"A- c #B68118", +"B- c #B77F13", +"C- c #B87C10", +"D- c #BD7F0F", +"E- c #EBBB3E", +"F- c #E8BB3E", +"G- c #EAB83B", +"H- c #EBB638", +"I- c #EBB637", +"J- c #EEB22C", +"K- c #F1B029", +"L- c #F5AA1B", +"M- c #DF861A", +"N- c #A22719", +"O- c #961313", +"P- c #950F0F", +"Q- c #930B0B", +"R- c #8E0607", +"S- c #190000", +"T- c #470404", +"U- c #910808", +"V- c #8C0606", +"W- c #320202", +"X- c #020302", +"Y- c #6E9794", +"Z- c #BBFFFB", +"`- c #B77E12", +" ; c #B77D12", +".; c #B77C11", +"+; c #BD7F0E", +"@; c #EAB83A", +"#; c #EBB536", +"$; c #EDB431", +"%; c #EFB22E", +"&; c #F3AD22", +"*; c #F5AA1D", +"=; c #F7A81A", +"-; c #ED9717", +";; c #B84612", +">; c #910807", +",; c #8F0304", +"'; c #8E0001", +"); c #4A0000", +"!; c #130000", +"~; c #890000", +"{; c #790000", +"]; c #090D0C", +"^; c #6E96BD", +"/; c #4A65FD", +"(; c #3E55FD", +"_; c #4761FD", +":; c #506EFD", +"<; c #5D80FC", +"[; c #6E97FC", +"}; c #81B1FC", +"|; c #96CDFB", +"1; c #AEEEFB", +"2; c #BC7F10", +"3; c #E9BA3F", +"4; c #EBB534", +"5; c #ECB532", +"6; c #EEB331", +"7; c #EEB12C", +"8; c #F1AF29", +"9; c #F1AD23", +"0; c #F3AC1F", +"a; c #F4A91B", +"b; c #F5A81B", +"c; c #F6A919", +"d; c #F5A417", +"e; c #D57111", +"f; c #9D1903", +"g; c #8E0101", +"h; c #8E0100", +"i; c #740000", +"j; c #680000", +"k; c #5B0000", +"l; c #070000", +"m; c #9AD3CF", +"n; c #99CDF4", +"o; c #0D12FE", +"p; c #2837FE", +"q; c #4863FD", +"r; c #6B92FC", +"s; c #8FC3FB", +"t; c #B2F4FB", +"u; c #EBB739", +"v; c #EBB434", +"w; c #EEB42F", +"x; c #EFB22C", +"y; c #F0AE26", +"z; c #F6A91B", +"A; c #F6A81A", +"B; c #F5A819", +"C; c #F7A818", +"D; c #EE9915", +"E; c #B13908", +"F; c #1A0000", +"G; c #161003", +"H; c #120D03", +"I; c #3F5654", +"J; c #B0F1ED", +"K; c #B5F8FB", +"L; c #6990FC", +"M; c #79A5FC", +"N; c #719BFC", +"O; c #688EFC", +"P; c #5C7EFD", +"Q; c #364AFD", +"R; c #1F2BFE", +"S; c #080CFE", +"T; c #0305FE", +"U; c #2939FE", +"V; c #5A7BFD", +"W; c #94CBFB", +"X; c #EEB12E", +"Y; c #EFB029", +"Z; c #F4AB20", +"`; c #F3AB1E", +" > c #F6A818", +".> c #C3540C", +"+> c #340000", +"@> c #0E1417", +"#> c #050822", +"$> c #000037", +"%> c #060957", +"&> c #4761BE", +"*> c #7099FC", +"=> c #7CAAFC", +"-> c #8CC0FB", +";> c #9CD6FB", +">> c #B2F3FB", +",> c #A9E7FB", +"'> c #8ABDFC", +")> c #6B93FC", +"!> c #4762FD", +"~> c #202CFE", +"{> c #0203FE", +"]> c #1822FE", +"^> c #6084FC", +"/> c #89BBFC", +"(> c #9BD4FB", +"_> c #F0B027", +":> c #F1AE27", +"<> c #F1AD25", +"[> c #F7A718", +"}> c #D6B363", +"|> c #3F4697", +"1> c #0000A1", +"2> c #0000D4", +"3> c #0000F9", +"4> c #1016FE", +"5> c #2E40FD", +"6> c #5270FD", +"7> c #76A2FC", +"8> c #A2DEFB", +"9> c #A1DCFB", +"0> c #678DFC", +"a> c #2F41FD", +"b> c #0B0FFE", +"c> c #0D13FE", +"d> c #2E3FFE", +"e> c #EAB73A", +"f> c #F3AA1F", +"g> c #F6A718", +"h> c #F7A717", +"i> c #D79134", +"j> c #5539AF", +"k> c #0604F9", +"l> c #0C11F7", +"m> c #2432FE", +"n> c #3245FD", +"o> c #445EFD", +"p> c #445DFD", +"q> c #4A66FD", +"r> c #384DFD", +"s> c #2C3DFE", +"t> c #1C27FE", +"u> c #0102FE", +"v> c #1A24FE", +"w> c #4F6CFD", +"x> c #2330FE", +"y> c #2C3CFE", +"z> c #3144FD", +"A> c #2634FE", +"B> c #0609FE", +"C> c #E8B83C", +"D> c #E9B83C", +"E> c #EEB230", +"F> c #F4AB1D", +"G> c #F8A917", +"H> c #F6A717", +"I> c #AE805B", +"J> c #353682", +"K> c #729CCF", +"L> c #B3F5FB", +"M> c #A4E0FB", +"N> c #84B4FC", +"O> c #3549FD", +"P> c #080BFE", +"Q> c #0204FE", +"R> c #394FFD", +"S> c #B6F9FB", +"T> c #A7E5FB", +"U> c #82B2FC", +"V> c #5575FD", +"W> c #1E2AFE", +"X> c #EBBA3B", +"Y> c #E8B83B", +"Z> c #EAB636", +"`> c #EDB532", +" , c #F2AC21", +"., c #F8A716", +"+, c #F4AC23", +"@, c #C38B1A", +"#, c #B4821A", +"$, c #B78016", +"%, c #B8FCFB", +"&, c #91C6FB", +"*, c #5676FD", +"=, c #1B25FE", +"-, c #0001FE", +";, c #3C53FD", +">, c #9CD5FB", +",, c #EBB93A", +"', c #EBB83B", +"), c #E9B93A", +"!, c #ECB636", +"~, c #EDB230", +"{, c #EFB12E", +"], c #F4AC20", +"^, c #F5A919", +"/, c #F6A715", +"(, c #F8A715", +"_, c #CD9019", +":, c #B4821B", +"<, c #B5811A", +"[, c #8FC4FB", +"}, c #435CFD", +"|, c #4E6BFD", +"1, c #B0F0FB", +"2, c #ECB939", +"3, c #EBB839", +"4, c #EAB939", +"5, c #EAB638", +"6, c #EBB634", +"7, c #F4AA1F", +"8, c #F7A617", +"9, c #F7A715", +"0, c #DE9817", +"a, c #B9851A", +"b, c #B4811A", +"c, c #B58017", +"d, c #B87D12", +"e, c #A5E2FB", +"f, c #4C68FD", +"g, c #161EFE", +"h, c #A2DDFB", +"i, c #F0B12A", +"j, c #F6A719", +"k, c #F7A716", +"l, c #F8A714", +"m, c #F0A214", +"n, c #CA8E18", +"o, c #B87E12", +"p, c #B87C11", +"q, c #B97C10", +"r, c #97CEFB", +"s, c #3143FD", +"t, c #EBB938", +"u, c #ECB838", +"v, c #F1B028", +"w, c #F3AB22", +"x, c #F6A817", +"y, c #F7A615", +"z, c #F8A514", +"A, c #E09916", +"B, c #B98318", +"C, c #B87D11", +"D, c #B97C0F", +"E, c #B87B0E", +"F, c #B7FAFB", +"G, c #ECB837", +"H, c #EEB32D", +"I, c #F0B02B", +"J, c #F4A91D", +"K, c #F7A616", +"L, c #F7A514", +"M, c #F8A613", +"N, c #F6A413", +"O, c #BC8518", +"P, c #B77E14", +"Q, c #B97C0E", +"R, c #B87B0D", +"S, c #ECB737", +"T, c #EBB736", +"U, c #ECB634", +"V, c #EDB22F", +"W, c #EBAE2D", +"X, c #C99626", +"Y, c #846118", +"Z, c #2B1F07", +"`, c #503B0E", +" ' c #E0A527", +".' c #F3AD23", +"+' c #F5AA1E", +"@' c #F7A614", +"#' c #F9A612", +"$' c #C78A16", +"%' c #B67E15", +"&' c #B67E14", +"*' c #B87E11", +"=' c #B87C0F", +"-' c #B97B0C", +";' c #BC7C0B", +">' c #EDB836", +",' c #ECB736", +"'' c #E5AC2C", +")' c #735616", +"!' c #140F03", +"~' c #070501", +"{' c #5F4510", +"]' c #BC8A20", +"^' c #F6A716", +"/' c #F8A513", +"(' c #F8A512", +"_' c #DE9714", +":' c #BA8217", +"<' c #B97C0D", +"[' c #B97A0B", +"}' c #BD7C0A", +"|' c #ECB735", +"1' c #ECB434", +"2' c #EDB332", +"3' c #EBAF2C", +"4' c #3D2D0B", +"5' c #020200", +"6' c #2F2308", +"7' c #815F17", +"8' c #8B6718", +"9' c #0E0B02", +"0' c #191204", +"a' c #DAA024", +"b' c #F6A616", +"c' c #F8A614", +"d' c #F9A513", +"e' c #F09F11", +"f' c #CB8B15", +"g' c #B67E13", +"h' c #B87B0C", +"i' c #BA7A0A", +"j' c #BE7C0A", +"k' c #EEB734", +"l' c #EDB430", +"m' c #BE8C23", +"n' c #352709", +"o' c #906A19", +"p' c #654A10", +"q' c #856015", +"r' c #F2AE23", +"s' c #F7A817", +"t' c #F9A511", +"u' c #E29812", +"v' c #B68116", +"w' c #B87D10", +"x' c #B97C0C", +"y' c #B87A0C", +"z' c #BA7A09", +"A' c #BF7C09", +"B' c #EDB633", +"C' c #B48621", +"D' c #241B06", +"E' c #CD9824", +"F' c #C89221", +"G' c #0E0A02", +"H' c #211805", +"I' c #D19721", +"J' c #F2AE26", +"K' c #F5A719", +"L' c #F9A411", +"M' c #B88114", +"N' c #B97B0E", +"O' c #B97B0D", +"P' c #BB7A09", +"Q' c #C07C08", +"R' c #EEB633", +"S' c #2C2108", +"T' c #BA8A20", +"U' c #EEB028", +"V' c #62470F", +"W' c #61460F", +"X' c #EEAB25", +"Y' c #F8A615", +"Z' c #F8A515", +"`' c #F7A513", +" ) c #FAA410", +".) c #C68813", +"+) c #B97A0C", +"@) c #BA7B0B", +"#) c #BC7A09", +"$) c #BF7C07", +"%) c #EEB531", +"&) c #EDB531", +"*) c #9B731B", +"=) c #49350C", +"-) c #D19923", +";) c #D89D23", +">) c #342608", +",) c #996E17", +"') c #F8A413", +")) c #F8A412", +"!) c #F9A310", +"~) c #DE9511", +"{) c #B9790B", +"]) c #B9790A", +"^) c #BB7B09", +"/) c #C07D07", +"() c #EEB431", +"_) c #EDB32E", +":) c #E4A728", +"<) c #745513", +"[) c #150F03", +"}) c #795814", +"|) c #E0A325", +"1) c #815D14", +"2) c #392909", +"3) c #080601", +"4) c #211705", +"5) c #3D2C09", +"6) c #4C360B", +"7) c #F8A612", +"8) c #F9A512", +"9) c #F9A410", +"0) c #FBA60F", +"a) c #F29E0F", +"b) c #CC8A11", +"c) c #BC7A08", +"d) c #EFB430", +"e) c #EFB330", +"f) c #E5A927", +"g) c #B3801A", +"h) c #F9A30F", +"i) c #FAA20F", +"j) c #E3970F", +"k) c #BA7A0C", +"l) c #BA7A0B", +"m) c #B97909", +"n) c #BB7908", +"o) c #BF7B06", +"p) c #F0B12B", +"q) c #EFAF29", +"r) c #EDAD28", +"s) c #DDA124", +"t) c #040300", +"u) c #342507", +"v) c #7E5A12", +"w) c #C48C1C", +"x) c #EEA922", +"y) c #F9A413", +"z) c #FAA40F", +"A) c #FAA30F", +"B) c #F6A00E", +"C) c #BA790B", +"D) c #BA790A", +"E) c #BA7809", +"F) c #BC7908", +"G) c #BE7907", +"H) c #EFB32E", +"I) c #EFB42E", +"J) c #B9871E", +"K) c #312408", +"L) c #120D02", +"M) c #0C0801", +"N) c #936915", +"O) c #F2AB21", +"P) c #F4AA1B", +"Q) c #F8A411", +"R) c #F9A40F", +"S) c #FAA20E", +"T) c #F8A00E", +"U) c #C8860F", +"V) c #BA7909", +"W) c #BB7909", +"X) c #BC7907", +"Y) c #EBAB27", +"Z) c #9F7319", +"`) c #221905", +" ! c #845F14", +".! c #C9911E", +"+! c #CD931E", +"@! c #F4AC1F", +"#! c #F3AA1E", +"$! c #FAA30E", +"%! c #F9A30D", +"&! c #E0920E", +"*! c #BB7B0B", +"=! c #BA7808", +"-! c #C07C04", +";! c #F0AF2A", +">! c #2E2106", +",! c #B78219", +"'! c #F1AB21", +")! c #F8A511", +"!! c #F8A410", +"~! c #F9A30E", +"{! c #FAA30D", +"]! c #FAA10D", +"^! c #F19D0C", +"/! c #CD880E", +"(! c #B97A0A", +"_! c #BA7807", +":! c #BD7906", +"~ c #CD8D17", +",~ c #F5A818", +"'~ c #92640D", +")~ c #060400", +"!~ c #6B4809", +"~~ c #E99E14", +"{~ c #FBA00A", +"]~ c #FCA10A", +"^~ c #FBA009", +"/~ c #FCA008", +"(~ c #E69309", +"_~ c #BC7706", +":~ c #BE7703", +"<~ c #C27800", +"[~ c #F3AF27", +"}~ c #F3AA20", +"|~ c #916410", +"1~ c #583C0A", +"2~ c #E19B19", +"3~ c #F5A516", +"4~ c #6F4B0A", +"5~ c #140D01", +"6~ c #A36E0D", +"7~ c #F9A20D", +"8~ c #FCA009", +"9~ c #FCA007", +"0~ c #F19907", +"a~ c #CB8408", +"b~ c #BB7907", +"c~ c #BB7704", +"d~ c #BD7703", +"e~ c #C07801", +"f~ c #F2AF26", +"g~ c #E19C19", +"h~ c #5A3E09", +"i~ c #080500", +"j~ c #895E0E", +"k~ c #F1A316", +"l~ c #C08212", +"m~ c #5E4008", +"n~ c #563906", +"o~ c #FBA20B", +"p~ c #FBA008", +"q~ c #FC9F08", +"r~ c #FB9D07", +"s~ c #DF8E07", +"t~ c #BB7605", +"u~ c #BB7603", +"v~ c #BE7603", +"w~ c #C17901", +"x~ c #F3AF25", +"y~ c #CB8C16", +"z~ c #070500", +"A~ c #1B1202", +"B~ c #EEA318", +"C~ c #F6A617", +"D~ c #0A0700", +"E~ c #C68510", +"F~ c #F6A514", +"G~ c #FAA20B", +"H~ c #FD9F07", +"I~ c #F29906", +"J~ c #CB8207", +"K~ c #BC7704", +"L~ c #BB7604", +"M~ c #BE7602", +"N~ c #C17800", +"O~ c #F3AE24", +"P~ c #553A09", +"Q~ c #6B490B", +"R~ c #614209", +"S~ c #B07711", +"T~ c #D28E13", +"U~ c #734D0A", +"V~ c #251903", +"W~ c #1E1402", +"X~ c #80560A", +"Y~ c #FDA007", +"Z~ c #FE9F06", +"`~ c #D58707", +" { c #BC7906", +".{ c #BC7604", +"+{ c #BE7702", +"@{ c #BC7603", +"#{ c #F4AE24", +"${ c #F2A81C", +"%{ c #EFA61C", +"&{ c #E89E18", +"*{ c #A16E11", +"={ c #412C06", +"-{ c #2F2004", +";{ c #895C0C", +">{ c #302004", +",{ c #2C1D03", +"'{ c #BD7E0F", +"){ c #FDA006", +"!{ c #FD9F06", +"~{ c #FD9E06", +"{{ c #FE9F04", +"]{ c #E08E05", +"^{ c #BD7601", +"/{ c #C07600", +"({ c #C37600", +"_{ c #F4AD22", +":{ c #F0A71D", +"<{ c #3A2806", +"[{ c #9A6A11", +"}{ c #ECA31B", +"|{ c #F1A619", +"1{ c #422D06", +"2{ c #A16C0D", +"3{ c #D99111", +"4{ c #FD9E05", +"5{ c #FE9E05", +"6{ c #F19603", +"7{ c #CC8105", +"8{ c #BD7603", +"9{ c #BD7602", +"0{ c #BD7600", +"a{ c #C57700", +"b{ c #7F580E", +"c{ c #0F0A01", +"d{ c #2C1E04", +"e{ c #281B04", +"f{ c #523809", +"g{ c #C38514", +"h{ c #875C0E", +"i{ c #704D0B", +"j{ c #C38513", +"k{ c #2A1C04", +"l{ c #241803", +"m{ c #D38D11", +"n{ c #F9A412", +"o{ c #FC9F06", +"p{ c #FD9F05", +"q{ c #FC9C04", +"r{ c #DF8C04", +"s{ c #BC7601", +"t{ c #BF7500", +"u{ c #C37700", +"v{ c #C67700", +"w{ c #F5AD21", +"x{ c #F4AD21", +"y{ c #DA9618", +"z{ c #543A09", +"A{ c #140D02", +"B{ c #473005", +"C{ c #D89111", +"D{ c #FBA108", +"E{ c #FC9E06", +"F{ c #FE9E03", +"G{ c #FF9E03", +"H{ c #F49702", +"I{ c #C67D03", +"J{ c #BD7502", +"K{ c #BD7501", +"L{ c #F0A519", +"M{ c #E69D18", +"N{ c #6C490A", +"O{ c #A77210", +"P{ c #7A530B", +"Q{ c #B57A10", +"R{ c #150E01", +"S{ c #724D0A", +"T{ c #181002", +"U{ c #020100", +"V{ c #774F09", +"W{ c #ED9F13", +"X{ c #FC9F07", +"Y{ c #FE9F05", +"Z{ c #FE9E04", +"`{ c #FD9D03", +" ] c #FE9E02", +".] c #FF9D02", +"+] c #CB7E03", +"@] c #BD7500", +"#] c #C17500", +"$] c #EDA217", +"%] c #F0A316", +"&] c #DE9613", +"*] c #E99C13", +"=] c #FD9E04", +"-] c #FD9E03", +";] c #FE9D03", +">] c #FE9D02", +",] c #DD8902", +"'] c #BF7702", +")] c #BE7501", +"!] c #BE7500", +"~] c #F6AC1F", +"{] c #F5AB1E", +"]] c #F5A91D", +"^] c #F7A512", +"/] c #FCA109", +"(] c #FC9E05", +"_] c #FE9C01", +":] c #FF9D01", +"<] c #F09400", +"[] c #CB7E02", +"}] c #BE7400", +"|] c #BF7400", +"1] c #F6AB1D", +"2] c #F9A40E", +"3] c #F9A20E", +"4] c #FD9E07", +"5] c #FC9A00", +"6] c #DF8A00", +"7] c #BF7700", +"8] c #BF7300", +"9] c #C57500", +"0] c #F6AC1D", +"a] c #F5AB1C", +"b] c #FBA00B", +"c] c #FE9C02", +"d] c #FF9C00", +"e] c #F69600", +"f] c #BE7600", +"g] c #C17400", +"h] c #C67600", +"i] c #F6AA1C", +"j] c #C47900", +"k] c #C27400", +"l] c #FD9F08", +"m] c #FE9D01", +"n] c #DC8700", +"o] c #BF7600", +"p] c #C07400", +"q] c #C37500", +"r] c #F8AB1A", +"s] c #F7A91A", +"t] c #FD9F04", +"u] c #FF9C01", +"v] c #F19400", +"w] c #CB7D00", +"x] c #C47600", +"y] c #FAA310", +"z] c #FF9C02", +"A] c #FF9D00", +"B] c #FD9A00", +"C] c #E08A00", +"D] c #C07500", +"E] c #F7A515", +"F] c #FCA00A", +"G] c #F79800", +"H] c #C47500", +"I] c #F7A918", +"J] c #F8A817", +"K] c #C67900", +"L] c #DD8800", +"M] c #C67500", +"N] c #F9A816", +"O] c #F8A616", +"P] c #CC7C00", +"Q] c #C27500", +"R] c #F9A715", +"S] c #FCA006", +"T] c #FC9B00", +"U] c #E18900", +"V] c #FAA614", +"W] c #FE9C00", +"X] c #F59700", +"Y] c #C07300", +"Z] c #FBA713", +"`] c #FE9D04", +" ^ c #FA9900", +".^ c #C87A00", +"+^ c #C57600", +"@^ c #FAA512", +"#^ c #DD8700", +"$^ c #FAA411", +"%^ c #F8A311", +"&^ c #FE9B00", +"*^ c #F19300", +"=^ c #D07D00", +"-^ c #C57400", +";^ c #F8A30F", +">^ c #FD9C00", +",^ c #EA8F00", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" . . . . . ", +" . . + @ . . . . . . ", +" . . # . $ % & * . . . . . . . . . . . . . . . . ", +" . = - . ; > , ' ) ! ~ { . . . . . . . . . . . . . . . . . . . . . . . . ", +" . ] ) . ^ / ( _ : < [ } | 1 2 . . . . . . . . . . . ^ 3 4 % 5 6 7 8 9 0 a b c . . . . . . . ", +" . . ^ d e f g h i j k l m n o p ! q @ . . . . . . . . . r s t u v w x x y z A A A B C D E F G c . . . . . . . ", +" . . f H I . . J K t L M o N O P Q R S T U V . . . . . . . . W X Y y A A Z Z B C ` D ( ...+.+.@.#.$.%._ &.*.=.. . . . . . ", +" . . -.;.>.,.. -.;.H '.).O !.~.{.].^./.(._.:.<.[.r }.. . c |.B B 1.D 2.( ..3.3.#.4.#.5._ 6.7.7.8.9.0.a.: b.b.; . c.Q d.. . . ", +" . . . . U e.E I . f.g.h.i.j.k.l.l.m.n.o.p.q.r.s.t.u.v.. c w...x.+.#.#.%.5.y.7.z.A.A.B.a.a.C.D.E.F.E.h >.>.G.>.H.. I.[ [ J.. . . ", +" . . . . . . K.l L.M.. 2 ;.N.O.P.Q.R.S.l.l.l.l.T.U.V.W.X.Y.. Z._ y.`.A.9.0.a.a.: b. +F.h h h >.>..+++@+#+$+%+[ &+*+=+. -+;+;+;+>+. . . ", +" . . ,+'+)+. !+~+o } e . {+R ]+^+/+(+_+:+<+[+}+l.l.l.|+1+. 2+[ : C.b.b.h h h 3+>.>.@+#+4+4+%+[ *+[ 5+6+7+8+;+;+9+P . 0+l k a+E b+c+. . ", +" . d+e+f+g+. h+i+O j+k+. l+^.m+(._.n+o+p+6 Z.q+r+s+t+u+v+. H.h >.>.++#+#+#+w+%+[ x+5+5+7+;+;+y+z+A+A+k k B+C+E E D+. E+F+G+G+H+I+L.J+. . ", +" . . K+L+M+. N+O+;.X P+Q+. R+S S+) o+T+s.t.U+V+W+F M.X+Y+Z+. `+$+[ [ &+ @5+.@;++@9+z+A+@@k k #@$@E t %@l l &@H+*@=@-@. ;@>@L.L.L.,@'@)@. . ", +" . . !@~@{@. ]@X O.^@/@(@. Y.) _@:@s.8 <@[@X.}@M.{+|@s >+c . 1@2@e.9+A+3@k k C+$@B+E l l l G+F+H+I+H+4@L 5@m 6@,@H V . F n 7@'.8@'.9@0@a@. . ", +" . . b@c@d@. e@^@f@g@h@o+. i@T+j@k@l@m@n@<.o@p@|@q@r@s@t@u@f n $@#@E v@b+w@l H+H+x@4@y@L 5@m L.z@A@z@H M B@7@C@'.(+. D@O E@F@g.g.G@H@I@J@. . ", +" . . K@L@M@. {+N@m+S O@:.P@. {+Q@u.R@S@T@U@V@W@X@s@s@Y@# . ~ Z@&@H+H+4@L L L.L.`@A@z@H ~+M n n 8@8@ #.#0@+#F@F@g.@#. ##$#%#&#*#=#-#O ;#>#,#. . ", +" . . '#)#!#. k@S ~#{#o+T+] . 0 ]#^#F /#(@(#s s@s@_#:#* = . # <#L.A@,@H H n B@7@8@'..#9@ #o [#+#g.).}#}#$#} &#} O+|#. 1#2#>#3#4#;.;.5#6#P 7#. . ", +" . 8#9#0#a#. b#) c#7 d#e#f#. g#F M.{+h#i#s@j#v+k#u@. . l#m#n#n 7@o#'. #9@p#o E@g.g.q#N N r#r#} *#h.O s#t#>#u#4#S i@i@S P P v#X w#x#w#Q y#7 u@. ", +" . z#A#B#. i@C#7 j@8 l@D#E#. F#p@|@q@G#H#I#-.. . f J#F 9@9@K#L#+#g.).g.N %#I@} } / O O 2#>#>#>#u#;.j+M#N#P P v#F#. q Q O#P#O.Q#Q#Q#R R#^@^@Y.. ", +" . S#T#U#. =.j@6 V#W#n@X#I . Y#Z#s@`# ${ . . c .$+$g.}#N N %#%#} *#} O @$t#>#u#>##$;.P P P $$%$X X Q Q &$O#O.O.E#. 1#*$=$-$^@].].].;$>$,$t@. . ", +" . '$)$!$~$f {+{$]$J@F ^$E+. v+/$N+. . { ($s O &#} h.O+O O ;#>#>#4#;.j+P P _$:$:$<$Q Q Q [$O.O.O.R R R *$=$^@X.. =.}$].]+|$/@|$N@1$+$&.2$=+. . ", +" . . 3$4$5$. . 6$W+F M.{+(#7$8$. . . N+,.9$0$O >#>#3#3#;.P 6#P _$_$X X X Q a$O.O.b$Q#R R *$-$^@^@^@].;$]+]+]+|$-@. I#g@c$g@d$e$e$f$m+m+m+b . . ", +" . . . . . D@D@. g$p@j#h$c . . u@i$0 x#;.5#j$P %$v#:$k$<$Q O#P#O.O.R b$R R ^@^@^@l$m$n$].o$p$/@N@q$r$+$g@g@s$S t$. u$m+h@h@h@h@}$S S v$w$. . ", +" x$y$z$A$B$A$A$B$A$A$A$A$B$B$C$D$ . . . q N@E$. i@~ 2+. . -.m#s.N.:$X F$w#Q [$y#[$Q#P+G$R R ^@^@].m$].H$>$f@I$p$N@N@+$+$g@c$s$e$J$m+m+m+K$h@L$. K.S M$v$(+N$(+S+S+S+M.}.. . ", +" O$P$z$A$A$A$A$Q$R$S$Q$S$A$A$R$A$T$U$ . . I#X j+P V$. . . 6$W$]+Q a$[$O.Q#X$R *$Y$^@l$].Z$].H$]+p$/@|$N@1$`$g@g@^+e$e$m+m+m+K$h@h@h@S S S %(+.%k#. v+S+S+S+S+S+S+S+S+s.+%. . ", +" @%y$#%S$S$S$Q$$%$%%%&%%%&%*%%%*%S$=%#% . . a@a$k$<$Q &.-%;%X.G$R R -$^@^@].].].f@]+>$N@/@N@N@N@g@&.&.s$e$/.f$m+m+>%h@h@,%S S S v$(+N$'%S+S+S+S+S+% . 2+8 S+S+S+S+S+S+S+9$E+. . ", +" y$A$A$*%%%%%%%)%)%%%!%%%!%!%%%S$$%$%A$T$ . . =+m+b$G$R R Y$^@~%m$].;$o$]+|$/@N@N@g@g@g@c$c$e$e$e$m+m+h@K$h@{%S S S M$(+(+]%^%S+S+S+S+S+S+S+S+S+S+S+S+:#. W S+S+S+S+S+S+S+S+U . . ", +" /%=%Q$$%%%!%!%%%!%(%_%_%(%%%%%:%$%$%A$T$y$ . . E$Z$<%H$H$o$]+p$,$N@`$g@g@^+^+d$e$e$m+m+m+[%h@{%}%S (.(.(+N$N$^%S+S+S+6 % |%1%2%3%J#J#k+;%,.4%q@:.S+S+u.+ u@M.S+S+S+S+S+S+S+5%. . ", +" 6%#%A$:%%%%%!%(%7%8%8%9%7%0%_%!%(%)%:%*%S$/%A$ . D@p$,$N@r$a%s$&.-+e$b%m+m+/+m+h@}$,%S S (.(+(+(+.%^%S+S+S+S+) s ! 3 6$-.2+V c%d%e%f%g%h%i%j%k%l%c 2+m%n%;%. i$S+S+S+S+S+S+S+4 u@. . ", +" /%Q$S$&%!%o%7%8%p%p%q%q%p%8%8%8%(%%%%%Q$S$A$r%D$ s%. J#s$e$e$/.m+/+h@h@}$}%}% %S v$(+]%t%S+S+S+S+S+S+S+S+) s@u%!+}.v%w%x%y%z%A%B%C%D%E%F%G%H%I%J%K%L%M%N%O%P%. . Q%S+S+S+S+S+S+R%i@. . ", +" /%Q$S%)%%%(%8%0%q%q%T%T%U%q%V%p%0%_%(%W%&%$%S$A$z$X% Y%. a@Z%}%}$`%S (+(+^%S+S+S+S+S+S+S+S+S+S+S+S+S+S+D# &r P@v%.&+&@&#&$&%&&&*&=&-&;&G%>&I%J%,&'&)&!&~&{&]&^&/&. D@T+S+S+S+S+S+u$2+. . ", +" y$R$*%&%%%0%0%q%q%U%T%(&T%(&U%q%p%o%!%%%%%Q$S$A$C$D$O$ _&. . :&S+S+S+S+S+S+S+S+S+S+S+S+S+S+S+S+S+S+F # <&D@[&}&|&1&2&3&4&5&6&D%-&F%7&H%8&9&0&'&M%a&b&c&d&e&f&g&h&i&. J+j&S+S+S+S+s@2+. . ", +" #%S$*%%%%%7%8%p%q%T%(&(&k&l&m&m&V%8%8%!%%%%%Q$A$A$y$P$n& o&. . 3 T+S+S+S+S+S+S+S+S+S+S+S+S+S+X.p&v.P@q&r&s&t&u&v&%&w&C%x&y&F%z&A&I%B&,&C&D&E&F&G&H&I&J&g&K&L&M&N&. O&P&-.% S+S+s@D@. Q& ", +" A$#%S$S$%%!%(%8%q%R&T%S&l&k&l&m&U%q%8%0%!%%%%%T&A$z$y$O$U&V&W&X&Y&Z&`& *.*+*@*#*$*$*%*&*****=*-*;*>*,*'*)*!*~*{*]*^*/*(*_*:*<*[*}*|*1*2*3*4*5*6*7*8*9*0*a*b*c*H&I&d*g&e*f*M&g*h*i*8#. j*k*l*Z+S+J D@. m*n*o*p*p*q*q*q*r*s*t*u*v*w*x* ", +" A$A$Q$%%%%_%p%q%q%m&(&l&S&y*T%q%q%0%7%!%)%*%*%A$A$y$z*A*B*C*D*E*Z&`&F*F*G*H*I*J*K*L*M*N*O*P*Q*R*S*T*U*V*V*W*W*X*Y*Z*`* =.=.=+=@=#=$=%=&=*===-=;=>=,='=)=!=~={=e*]=M&g*^=/=(=_=:=. <=[=}=|=+ t@}.. 1=2=3=4=5=6=6=6=7=8=8=8=9=0=a=v* ", +" #%T$=%%%%%!%8%8%q%U%T%m&m&T%T%V%8%p%(%!%%%S$S$A$r%z$z*C*B*C*D*Z&Z&`&b=F*I*c=J*d=e=f=M*O*P*P*g=R*S*U*h=i=j=W*k=l=Y*m=`* =n=o=p=q=q=r=s=%=t=t===;=u=u=u=v=w=x=y=z=A=/=(=B=C=D=E=a#. F=G=H=I=J=. . K=L=M=N=N=O=P=P=Q=R=S=S=S=T=U=a=V= ", +" =%Q$&%%%(%(%_%0%q%V%q%U%W=q%q%0%!%!%W%&%*%S$A$B$X=X=z*Y=Z=Y&Z&`=`= -F*.-I*J*d=+-f=+-O*@-#-g=R*S*$-U*i=V*%-&-*-=-Y*`*--n=.=@=;-@=r=%=>-&=*=-=;=;='=,=,-v='-)-(=!-~-{-]-^-/-(-. _-:-/-<-[-a#. }-|-1-3=2-3-4-4=4=5-5-6-7=7-8-U=9-0- ", +" T$T$$%&%a-!%9%0%p%q%8%8%p%0%0%8%o%)%:%*%*%A$z$z$x$z*Y=C*b-c-Z&Z&`&F*F*I*H*d-e-e=+-f-g-@-#-h-i-i-U*i=i=%-W*l=k=j-j- =----o=@=@=k-$=%=&=t=t=-=;=>=u=,-,-l-m-n-{-o-p-/-q-r-s-. t-u-v-w-x-. . y-z-1-3=A-3-4-4-4=5=5-6-7=B-7-8-U=C-D- ", +" E-=%Q$*%)%!%!%(%8%8%0%0%9%7%8%0%%%%%)%S$F-A$/%x$X=Y=Y=G-c-D*`=H-`&I-.-H*H*d-d=e=f=N*O*P*#-R*R*J-J-U*V*V*W*k=K-Y* =`*n=+=.=@=@=r=#=%=%=t=t===;=u=L-,-,-w=m-M-N-q-O-P-Q-R-S-. T-U-V-W-. X-Y-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-6-7-7-`- ;.;a=+; ", +" /%=%=%&%%%%%a-%%!%9%_%!%!%o%!%%%$%$%S$A$P$z$P$z*C*C*b-@;Z&Z& -F*#;F*I*I*d=e=e=+-$;@-#-g=R*%;i-U*i=i=W*%-*-=-Y*j-`*--.=.=@=@=q=&;%=>-*=t=;=*;,=u=,-l-w==;-;;;Q->;,;';);. !;~;{;S-. ];^;/;(;(;(;_;:;<;[;};|;1;Z-Z-Z-Z-Z-Z-Z-2; ", +" X%y$3;S$S$*%)%)%)%%%W%)%%%)%*%Q$S$S$/%y$P$z*z*Y=C*b-D*Y&`&b=I-F*F*I*4;J*d=5;f=M*6;@-h-h-R*i-7;7;U*V*j=k=8;Y*j-`* =n=o=9;q=q=#=r=%=0;*=-=;=;=,='=a;b;l-c;d;e;f;g;h;i;a#. j;k;l;. Q&m;n;l.l.l.l.l.l.l.l.l.l.l.o;p;q;r;s;t;Z-Z-Z-Z- ", +" y$B$S$S$Q$:%:%&%Q$$%$%*%*%*%S$A$B$r%z$z*X=C*C*b-D*D*D*u; -I-c=I*c=J*v;d=5;f=$;$;w;R*R*i-J-x;U*i=j=j=j=*-*-Y*y;----p=p=p=#=$=%=%=&=-===-=;=>=a;,-z;A;B;C;D;E;g;~;F;. G;H;. . I;J;Z-K;L;M;M;M;N;O;P;/;Q;R;S;l.l.l.l.l.T;U;V;W;Z-Z-Z-Z-Z-Z-Z-Z-Z- ", +" x$/%A$A$S$*%S$S$$%S$S$S$A$S$A$A$B$P$X=X=z*C*G-b-D*Y&Z& -I-F*c=c=H*J*e=d=f=$;N*@-P*R*R*X;T*$-h=V*V*W*Y;=-=-j-`*----+=@=@=k-%=%=>-Z;t=`;;=>=*;a;,-l-B;m- >C;.>g;+>. @>#>$>%>&>*>*>*>*>=>->;>>>Z-Z-Z-Z-Z-Z-Z-,>'>)>!>~>{>l.l.l.]>^>/>/>/>->(>>>Z-Z-Z-Z-", +" @%X%B$z$P$A$A$r%A$/%A$B$B$B$z$P$P$z*z*C*C*@;b-b-D*D*Z&b=I-F*F*I*J*J*d=f=L*$;N*#-Q*#-%;i-T*U*i=i=j=W*Y;_>Y*:> =--<>.=@=k-#=&;%=>-*=`;-=;=*;>=a;,-l-c; > >[>}>|>1>2>3>l.l.l.l.l.l.l.l.l.l.l.l.4>5>6>7>8>Z-Z-Z-Z-Z-Z-9>0>a>b>l.l.l.l.l.l.l.l.l.c>d>V;/>", +" z*z*z*z$X=y$y$z$z$y$z$P$z$X=z*Y=Y=B*W&b-e>Y&D*Y&`=H-F*c=I*J*J*d=d=e=+-+-$;O*h-h-Q*i-S*x;U*i=j=W*Y;X*_>j- = =n=<>@=@=@=k-%=>-&=Z;f>-=;=u=,-,-,-A;m-m-g>h>i>j>k>l.l.l>m>n>o>p>q>q>!>r>s>t>u>l.l.l.l.l.v>w>/>t;N;U;l.l.l.l.l.o;x>y>z>z>A>]>B>l.l.l.l.", +" B*B*z*z*C>P$y$P$z*X=z*z*z*D>C*C*G-G-b-b-Y&D*Z&`=`&I-F*I*c=I*J*d=e=5;+-N*f-O*E>Q*R*i-7;x;i=V*j=k=l=l=Y*:>`* =--.=p=@=r=%=%=>->-t===F>;=>=,-,-w=A;m-m-C;G>H>I>J>K>L>Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-M>N>^>O>P>l.l.l.T;l.l.Q>R>[;|;S>Z-Z-Z-Z-Z-Z-Z-Z-T>U>V>W>", +" X>B*C*Y=D>D>z*z*D>Y=Y>C*D>Y=G-@;D*D*D*Y&Z&b=b= -Z>c=c=4;4;e=d=`>f=+-O*O*#-h-R*i-$-7;U*i=%-j=k=l=X*j-m=`*--n=p=+=@=r=#= ,>-*=t=`;-=>=u=,-,-,-m-m- > >[>.,+,@,Z-Z-Z-#,#,1-1-3=2-2-4-$,4=Z-Z-Z-Z-Z-%,&,*,=,l.l.-,;,>,Z-Z-Z-Z- Z-Z-Z-Z-Z-", +" ,,',b-b-),C*@;Y=@;G-C*b-@;@;e>Y&Y&Y&Z&Z&b=I-I-F*!,I*J*4;d=e=e=e-L*N*O*~,P*R*R*{,i-i=i=i=W*j=k=*-*-j- = =--.=9;@=r=r=%=%=],t=t=F>>='=,-,-l-^,m-m- >g>h>/,(,_,:,:,:,#,<,1-3=3=2-3-4-4=4=5-5-6-6-Z-Z-Z-Z-Z-[,},-,l.Q>|,1,Z-Z- Z-", +" 2,3,4,@;@;D*@;b-@;@;Y&D*Z=Y&Z&Z&`=5,5, - -F*F*c=c=6,J*J*d=`>f=N*N*N*O*O*P*R*i-T*J-V*i=j=W*k=X**-j-Y* =--o=.=@=@=#= ,%=&=>-7,7,;=;=,='=,-v=v=m- > >g>8,9,9,0,a,#,b,b,1-2-2-2-c,4-4=5=5-5-6-6-B-`-`- ;d,Z-Z-Z-e,f,-,l.g,h,Z- ", +" 3,Y&X&D*D*D*X&Y&D*X&Z&Y&Z&Z&Z&`= -b=`&F*F*I*c=c=H*e=e=e=+-M*$;N*O*P*h-#-i-U*7;U*i=i,i,W*k=X*Y*j-j---<>o=p=@=q=r=%=>->->-t===;='='=,-,-l-m-m-j,g>H>k,k,l,m,n,1-1-1-1-2-2-4-4-4=4=5-5-7=B-B-B-`-o,d,d,p,q,Z-Z-Z-r,~>s,%,Z- ", +" t,u,`=`=`=Z&Z&Z&Y&Y&Y&Z&Z&5, -F*I-F*!,F*c=I*I*J*d=d=f=+-+-f-N*@-O*P*#-R*S*U*U*i=i=j=j=k=l=*-v,Y*m=--<>.=@=q=@= ,w,s=&=*=t=;=;=>=a;,-,-l-B;m-m-x,h>k,y,(,z,A,B,1-3=2-3-4-4-4=5=5-5-6-7-7-7-`-`-d,C,p,C-D,D,E,Z-Z-F,1;Z-Z- ", +" I-G,`& -`&5,5,I-I- -I- -F*F*F*F*c=I*c=4;4;J*d=e=+-+-N*N*O*@-#-Q*#-H,i-U*U*U*V*I,W*k=k=X*Y*:>y;`*--p=@=q=r=#= ,%=],t=t=-===J,,=L-l-l-v=m- >g>H>8,k,K,L,M,N,O,3=2-3-4-4-4=4=5=5-5-P,7-7- ; ;d,C,C,C-D,D,D,Q,R,Z-Z-Z-Z- ", +" S,T,I-F*F*F*F*Z>I-I-F*F*F*c=F*.-H*H*U,J*d=d=e-f=+-$;N*N*O*V,h-h-R*W,X,Y,Z,`, 'W*W*l=*-*-Y*`* =n=+=o=@=.'&;#=%=>->-t=t===+'>=u=,-b;A;A;m- >[>H>k,9,@'L,M,#'$'c,3-4-4=4=5=5-5-%'&'7-*' ; ; ;p,C-C-='D,D,Q,R,-';' ", +" >','F*F*F*F*F*F*F*c=#;F*!,I*4;.-.-J*4;d=d=d=f=M*N*N*O*P*~,g=h-'')'!'. . . . ~'{']'l=*-Y*j-:> =<>o=@=@=q=r=%=%=&=&=*===;=F>'=,-,-,-B;m-j,[>h>^'^'k,z,L,/'('_':'4-4=4=5=5-5-6-P,7-7-`- ;d,C,C-q,D,D,D,Q,<'R,['}' ", +" |'U,4;I*c=c=I*I*H*U,J*J*J*1'd=d=d=e=5;f=+-2'$;N*P*#-h-h-h-R*3'4'5'. 6'7'8'9'. 0'a'j-`*Z*`*----.=@=@=&;#= ,>-*=*===-=;=,=>='=b;l-m-m-m-x,h>b'k,@'c'z,/'d'e'f'4=4=5=5-5-6-g'7- ; ; ;U=C,C-='D,D,Q,Q,<'h'h'i'j' ", +" k'U,J*H*U,I*J*J*J*J*J*v;e=d=d=f=+-f=+-M*N*l'O*O*@-Q*Q*R*i-i-m'n'. o'i=j=Y;l=p'. q'Z* =----<>r'9;q=&;%=%=>-*=*=t=-=F>;=J,,-,-v=w=B; > >s'^'k,K,c'@'/'('('t'u'v'5=5=5-5-&'7-7- ; ;d,C,w'C-D,D,D,Q,<'<'x'y'z'A' ", +" B'B'e=d=d=d=e=d=d=d=d=`>K*f=+-f=+-M*$;$;O*O*#-#-g=V,R*i-T*i-C'. D'E'W*W*l=*-F'G'H'I' =J'o=p=9;9;&;#= ,%=Z;>-*=f>-=;=;=,=,-,-l-w=K'm-x,h>^'y,y,y,/'/'d'('t'L'M'5=5-6-&'7- ; ; ; ;C,C-='='D,D,N'O'O'-'-'['P'Q' ", +" K*R'e=e=5;5;e=5;e-K*f=+-+-M*N*$;$;O*O*O*O*h-h-Q*i-i-S*U*J-7;S'. T'U'l=X*l=Y*V'. W'X'--<>p=@=k-&; ,%=>-&=&=====F>;=>='=,-w=l-B;m- >H>h>K,y,Y'Z'`'/'('('t' ).)5-5-6-7-`- ; ;d,C,C-D,='D,D,D,N'O'-'-'+)@)#)$) ", +" %)&)+-+-$;f=f=f-$;N*$;$;N*N*O*l'O*O*O*#-Q*R*R*i-T*x;7;U*i=i=*)H;=)-)*-=-j-;)>). ,)+=n=.=@=q=&; ,>-&=*=*=*=-=-=;=*;,=l-v=w=m-j,g>H>h>^'y,y,y,c'M,')))L'L'!)~)s*&'g'`- ; ;C,C,C-C-='Q,D,Q,N'O'-'-'+){)])^)/) ", +" %)()N*N*N*$;$;l'l'6;@-O*O*O*V,h-R*#-_)R*S*i-S*7;U*i=i=i=j=:)<). [)})|)1)2)3). 4)5)6)@=@=&;r=%=&=*=*=======;=u=;='=,-l-m-m- >g>h>h>K,9,y,@'z,7)8)t'L'9)0)a)b)7- ; ; ;C,C,C-C-='D,D,Q,N'O'-'+)+)['i'P'c) ", +" d)e)l'O*O*O*O*@-@-O*@-#-h-h-R*h-Q*R*R*S*$-U*x;i=i=V*V*j=%-l=f)=). . . . . . . . . ~'g)k-r=$=%=&=Z;*=*=-=;=;=u='=,-,-w=B;g>g>H>h>^'K,y,@'c'/'))))L'L'9)h)i)j)`- ;d,C,C-C-q,D,D,D,Q,O'O'-'-'k)l){)m)n)o) ", +" d)#-#-#-#-#-~,h-h-P*V,h-R*R*R*R*R*R*S*T*U*U*i=i=i=i,p)j=q)k=r)s)5)s%. . s%. t)u)v)w)x)r=&;s=%=&=*=*===-=;=;=,=a;,-l-m-j,g>C;H>h>k,k,y,@'z,M,y)t'L' )!)z)A)B) ;U=C,p,C-='D,D,D,Q,N'O'-'+)+)l)C)D)E)F)G) ", +" H)I)P*R*g=R*Q*R*R*R*R*i-i-$-$-7;x;7;x;i=i=j=V*j=j=k=*-X*X*J)K). . . G;L)M)N)@=q=r=#=%=O)%=*=t===-=;=;=>='=P),-l-^, > >[>H>k,K,K,@'c'z,`'('8)Q)L'9)R)A)S)T)U)C,w'C-='D,D,Q,Q,<'O'-'+)+)l)i'D)V)W)X)o) ", +" %;R*H)i-R*R*i-i-i-S*T*S*$-U*x;U*i=i=i=%-j=W*Y;k=q)k=l=*-_>Y)Z)`) !.!n=+!. y-@=&;k- ,%=s=@!t=-=#!-=*;'='=,-,-l-l- >m- >h>h>k,y,y,c'c'z,/'('))L'9)A)h)$!S)%!&!D-C-D,D,D,Q,Q,O'O'-'*!+)['l)i'V)V)=!X)-! ", +" S*i-i-i-i-T*T*x;J-J-U*i=7;i=U*i=p)i=j=W*Y;;!Y;k=l=Y*Y*:>`* =------<>+=>!. ,!'!#= ,%=0;t=t===;=;=,=,=a;,-l-v=w=B;g>g>H>^'k,y,y,c'/'/'(')!!!9)!)z)h)~!{!]!^!/!D,D,Q,Q,Q,<'-'-'+)['(!D)D)V)V)=!_!:!='=L-L-,-,-A;w=B; >H>b'k,9,y,c'c'z,/'('('L'L'R)z)h)~!{!{!3!4!5!D,Q,N'O'O'O'-'k)l)l)D)D)V)W)W)=!6!7!8! ", +" p)p)i=i=i=V*i=j=V*%-i=j=j=j=j=k=k=k=k=*-=-*-j-Y*`* = =----<>p=p=@=q=r=9!0!. a!Z;>-*=-=-=F>;=>=,='=,-l-w=v=m-m-H>h>k,K,9,y,L,c'/'d'('8)9)!)!)h)A)S){!b!4!c!d!Q,Q,O'O'-'+)k)l)l)D)V)V)W)W)n)_!6!e! ", +" W*p)%-i=W*j=j=W*W*Y;Y;W*Y;k=k=l=l=*-*-=-m= = = = = =--+=p=r'@=@=q=f!&;g!. 5'h!t=t===-=;=,=>='=a;,-l-m-m-m- >h>H>k,K,y,z,L,/'/')))))!i!!)A)A)$!{!3!j!k!l!m!n!O'O'+)+)k)C)C)D)D)W)W)W)n)o!p!q!r! ", +" s!s!i,W*W*W*k=Y;l=l=k=k=l=k=X*_>j-Y*j-y; =`* =t!--<>p=p=p=u!k-k- ,#=%=s=v!. w!x!7,;=;=*;'=,-'=l-y!m-c; >g> >h>K,k,Y'Y'c'/'/'/'8)L'!!!!h)h)$!3!3!z!A!A!B!C!D!E!-'+)l)l)D)V)V)V)W)W)n)X)F!7!G!8! ", +" K-X*k=k=*-l=X**-=-*-*-Y*Y*Y*:>Z*:> =------H!.=+=p=p=q=q=&;#=%=s=&=>-&=I!J!K!L!;=*;J,L-,-,-A;l-m- >j,g>[>H>k,K,Y'L,c'/'/'/'))Q)9)!)9)M!S)$!3!3!z!A!N!N!O!P!Q!+)+)l)i'D)V)V)V)W)R!S!T!U!7!V!W! ", +" *-v,*-j-X*Y*=-=-*-Y*Y*Z*j-j-j-------.=n=.=p=X!p=@=q=k-r=%=%=>->->-&=t=Y!Z!. `!;=;='=,-,-w=l-B;m-B;[> ~.~K,k,9,Z'c'+~M,d'('L'Q)9)9)A)R){!3!3!A!4!k!N!N!@~#~$~l)l)D)D)V)V)W)n)n)T!%~7!6!q!&~*~ ", +" =~=-j-Y*j-Y*Y*`*Z* = = =y; =-~----n=.=.=p=@=@=@=@=#=f!f! ,>-&=0;t=f>*=-=F>;~. >~,='=,-l-w=m-m-,~ >'~)~!~~~y,y,@'/'/'('))Q)L'9)9)h)R)~!$!3!3!j!j!N!{~]~^~/~(~l)D)D)V)W)W)n)o!T!T!_~_~6!q!:~<~ ", +" [~=~y; = = =:> =------J'----n=<>@=@=p=@=@=r=r=%= ,%=%=s=t=}~}~*=*=====;=|~. 1~2~,-l-w=m-B; > >3~4~. 5~6~K,@'z,/'(')))!t'9)9)h)A)$!7~j!j!A!k!]~]~O!8~8~9~0~a~V)V)n)n)b~b~7!7!7!_~q!c~d~e~ ", +" --f~J'n=------.=--n=<>.=p=p=@=p=q=k-r=r=#=#=#=%=%=%=&=0;t=*=#!#!;=+';=u=g~h~i~j~m-A;m- > >[>k~l~m~. t)n~L,M,M,('8)t'L'9)9)!)h)~!$!3!z!j!o~k!]~{~8~p~q~#~r~s~Q'W)n)b~F!7!7!7!_~q!t~u~v~w~ ", +" x~+=.=.=o=--<>p=p=r'@=@=@=@=.'r=&;#= ,%=s=s=&=&=>-*=t=f>-=-=;=;=,=,=>='=y~z~A~B~B;m-g>g>H>C~D~. . E~F~/'/'/'8)L't'L'9)h)h)A)$!{!3!A!G~k!N!]~^~^~p~/~/~H~I~J~n)b~b~7!7!7!_~q!K~L~u~M~N~ ", +" O~.=p=.=o=p=p=+=p=@=@=.'k-.'k-#=#=%=%=s=>-&=Z;*=t=*=====;=-=*;>=,='=>=,-,-P~. Q~R~S~H>T~U~V~. W~X~~)z,z,/'('L'L'L'L'9)R)h)$!S)z!z!o~k!k!N!{~8~/~/~9~Y~Z~Z~`~b~ {7!7!_~_~q!q!.{+{@{M~<~ ", +" #{.'@=@=#=;-#=r=k-#=#=r=%= ,%=s=&=&=],0;t=*=t=t=-===${%{>='=,=,-,-b;w=&{*{={. . . . -{;{>{. . ,{'{+~/'/'('8)L'9)!)9)A)$!~!$!3!z!A!k!N!N!N!8~^~/~q~){!{~{{{]{e!7!7!_~q!q!K~K~@{@{^{/{({ ", +" &;&;_{r= ,&;r=f!%=%=%= ,%=>-&=&=*=*=&=*=*=`;==-=;=:{<{5'[{}{,-,-z;A;B;|{1{. . . . . . . t)2{3{c'z,z,/'('L'L'L'9)z)h)A)$!S){!b!j!j!N!N!N!O!/~q~/~H~!{!{4{5{6{7{%~q!q!K~.{@{@{8{9{0{/{a{ ", +" &;$=_{r=%=s=%=>-s=>->->-Z;&=*=Z;*=-=t=`;==-=-=;=J,b{c{. d{e{f{g{h{i{j{k{. . . . . . . l{m{z,`'/'('n{('t'L'!)R)A)A)S)$!3!b!j!4!o~l!N!^~8~/~/~9~o{!{p{5{{{q{r{r!q!K~K~@{@{8{8{s{t{u{v{ ", +" w{x{s=>->->-*=&=&=&=>-*=&=7,*=f>==-=;=F>;=;=;=J,'=y{z{t)A{. . . . . . s%. . . . . B{C{Y'@'z,/'/'8)('('!)!)9)z)h)3!$!3!3!3!z!o~]~^~D{/~/~#~9~!{!{E{p{4{F{G{H{I{K~@{@{8{8{9{J{K{t{({ ", +" ],Z;&=*=*=t=*=t=t=-=-=#!==;=;=*;;=*;>='=L-a;,-,-v=L{B~M{N{O{. d{P{Q{R{d{S{T{U{>{V{W{/'/'/'('n{))Q)!)R)h)$!$!$!S)3!z!G~k!k!k!]~^~8~/~H~X{X{o{p{Y{5{Z{`{ ].]+]@{8{8{8{9{9{K{@]t{#] ", +" t=t=t=*=`;-===`;-===-=F>;=*;;='=>=u=,='=,-,-,-l-b;l-B;m-m- >$]C~H>^'%]k,y,&]*]F~@'/'/'('8)8)Q)Q)9)9)A)h)$!$!$!b!j!j!j!k!N!N!O!8~/~/~X{X{!{!{5{4{=]-];]>].],]']8{9{9{^{)]!]@]t{v{ ", +" ~]{]{]-===#!-=;=;=;=;=*;]]u=,=,=,-,-,-,-,-v=w=w=B;B;m-g>C;[>x,H>H>k,k,y,9,y,Z'c'z,^]d'('('L'L'!!!)9)A)$!$!{!3!3!4!C!k!N!N!/]/]8~Y~q~X{!{(]!{5{Z{=];];]_]:]<][]^{9{^{)]!]!]}]|]({ ", +" *;1]>=;=;=,=>=;=u='=,=a;,-,=,-A;v=y!A;A;A;m- >m-[>H>H>^'b'k,K,K,K,K,Y'Y'z,M,('8)8)L'L'Q)9)!)!)!)2]3]3!3!3!A!o~k!k!N!N!8~^~q~9~o{X{4]4{~{4{Z{F{ ].]>]_]:]5]6]7]^{!]!]!]}]}]8]9] ", +" 0]a]'=u=u='='=,-,=,-,-,-,-w=A;A;m-B;m-m-,~m- >H>g>h>h>k,k,k,9,y,c'z,c'L,+~/'n{8)n{L'9)i!!)h)A)~!$!3!3!3!z!A!k!k!b]]~^~8~/~Y~X{H~!{p{4{=]Z{=]`{>]>]c]:]d]d]e]N~f]!]!]!]|]8]g]h] ", +" '=i]a;a;,-,-,-l-l-b;w=l-B;B;B;B; >B;m- >x,g>H>k,^'K,k,9,y,Y'y,L,M,@'/'/'('))L'L'L'9)!)h)h)A)$!$!b!3!A!j!k!o~]~O!]~/]/~q~9~H~!{p{4{5{Z{Z{;] ]>]:]>]d]d]d]d]j]!]!]!]t{|]8]k] ", +" )=z;y!z;,-l-l-v=A;l-c;m-m- > >m- > > >H>g>h>h>b'K,y,y,y,c'@'@'z,`'/'/'))))t'9)9)!)h)z)A)$!S)S)3!z!j!k!o~k!N!N!O!8~8~l]X{o{!{p{4{=]=];];];]>].]m]:]d]d]d]d]n]o]!]t{t{t{p]q] ", +" r]s]s]^,A;A;m-m-j, > > >[>g>g>H>H>H>h>b'k,K,K,Y'y,L,@'/'/'M,/'d'('))n{Q)9)9)R)!)A)A)$!S)$!b!b!j!C!k!N!N!{~8~8~/~/~Y~X{o{X{p{t]=]Z{;]F{;]>]c]u]u]d]d]d]d]d]v]w]t{t{t{}]p]x] ", +" v=m-B;,~ >m- > >[> > >H>H>k,h>k,C~k,K,9,y,y,y,c'z,z,c'/'/'')8)('L')!9)9)!)y]h)~!$!S)$!3!b!z!j!C!N!N!]~O!8~/~/~/~9~!{o{p{p{=]=]Z{;]>]>]z]u]A]d]d]d]d]d]A]B]C]t{t{D]|]p]x] ", +" j,j,m- >C;C;H>[> >H>H>k,k,k,k,k,k,k,y,y,Y'E]c'L,c'/'/'('8)('))L'Q)9)9) )h)h)$!$!$!{!3!j!j!j!G~k!]~{~F]8~/~/~q~X{!{!{4{Y{Z{=]-]F{.]>]_]:]d]d]d]d]d]d]d]d]d]G]D]D]|]|]p]H] ", +" I]J]G>H>H>H>H>H>h>b'K,8,k,k,y,y,y,Z'@'+~M,L,z,('('/'('n{)!Q))!L' ) )h)A)h)A){!$!3!3!3!z!z!o~k!/]{~/]8~p~/~9~Y~~{!{!{4{=]Z{Z{;];]c]>]u]:]u]d]d]d]d]d]d]d]d]A]K]D]D]|]g]v{ ", +" J]h>K,k,k,k,K,K,k,y,y,@'Y'y,Y'L,M,M,z,M,('n{(')!L't'9)L'9)!)h)h)A)A)3!3!3!3!j!j!z!o~G~k!N!N!8~/~/~/~/~X{H~o{o{p{4{5{=]-];]>]:]u]:]u]d]d]d]d]d]d]d]d]d]d]d]L]D]|]p]g]M] ", +" N]O]k,y,y,y,y,9,Y'c'L,@'z,@'c'M,`'/'/'8))))!))))L'L'9)!)!)A)z)h)A){!{!3!3!b!z!A!k!k!l!k!]~O!8~/~#~H~H~!{!{~{p{5{=]=]F{;]>].]u]m]d]d]d]d]d]d]d]d]d]d]d]d]A]v]P]8]p]Q] ", +" Y'R]9,Y'y,Y'c'L,z,/'@'/'/'/'/'/'('))('L't'Q)!!9)9)y]h)h)R)~!$!S){!z!z!z!j!A!k!N!N!N!N!F]p~/~/~X{X{S]!{~{!{p{=]=]Z{-]>].]:]u]d]d]d]d]d]d]d]d]d]d]d]d]d]d]T]U]|]p]Q] ", +" V]c'c'M,z,z,/'/'/'/'))8)n{)))!L'L'Q)L'!)9)h)R)z)h)$!$!S){!{!3!3!4!j!A!o~k!N!{~]~8~8~8~/~/~Y~o{o{!{!{4{4{=]=]Z{F{;].]_]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]W]X]|]Y]q] ", +" Z]M,/'/'/'('('/'))('('t't'n{L'L'L'9)9)9)h)h)h)$!~!~!3!{!3!b!z!z!o~o~k!k!N!{~{~8~8~/~/~/~Y~H~o{4{4{4{Y{5{Z{`];];]m]:]d]u]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d] ^.^g]+^ ", +" 8)@^8)d'('))8)t'L't't'Q)9)9)9)!)9)h)h)h)$!A)$!7~{!3!3!3!j!4!A!k!k!k!N!/]N!^~/~8~/~9~X{9~!{o{p{p{=]=]`{;] ]F{.]>]z]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]5]#^g]+^ ", +" $^%^@^L'n{L'L'L'Q)9)9)9)!)!)9)y]z)A)~!3!~!{!$!3!]!j!z!4!4!C!o~N!N!/]N!^~/~8~/~q~X{X{H~o{!{4{5{=]=]=];]F{ ]>].]m]:]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]&^*^=^-^ ", +" ;^L'9)L'L'9)!)y]R)A)h)~!~!$!~!S){!3!3!{!z!A!j!z!o~k!k!k!N!]~^~8~^~8~/~/~q~X{X{!{!{4{p{5{Z{=]-]-]>]>]>]>]m]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]d]>^,^ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/Mod/Ship/Makefile.am b/src/Mod/Ship/Makefile.am index 113b0f04f..85137539d 100644 --- a/src/Mod/Ship/Makefile.am +++ b/src/Mod/Ship/Makefile.am @@ -22,6 +22,9 @@ nobase_data_DATA = \ Icons/Ico.png \ Icons/Ico.xcf \ Icons/Ico.xpm \ + Icons/LoadIco.png \ + Icons/LoadIco.xcf \ + Icons/LoadIco.xpm \ Icons/OutlineDrawIco.png \ Icons/OutlineDrawIco.xcf \ Icons/OutlineDrawIco.xpm \ From 13fb0e2ccadc9b08749339e70773a1e5d588cad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sun, 29 Jan 2012 19:11:55 +0100 Subject: [PATCH 04/27] Added examples loader tool (without functionality yet) --- src/Mod/Ship/CMakeLists.txt | 15 ++- src/Mod/Ship/InitGui.py | 4 +- src/Mod/Ship/Makefile.am | 3 + src/Mod/Ship/ShipGui.py | 13 +++ src/Mod/Ship/shipLoadExample/TaskPanel.py | 97 ++++++++++++++++++ src/Mod/Ship/shipLoadExample/TaskPanel.ui | 115 ++++++++++++++++++++++ src/Mod/Ship/shipLoadExample/__init__.py | 36 +++++++ 7 files changed, 280 insertions(+), 3 deletions(-) create mode 100644 src/Mod/Ship/shipLoadExample/TaskPanel.py create mode 100644 src/Mod/Ship/shipLoadExample/TaskPanel.ui create mode 100644 src/Mod/Ship/shipLoadExample/__init__.py diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index 494ce8d0a..8768d92a1 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -35,6 +35,13 @@ SET(ShipIcons_SRCS ) SOURCE_GROUP("shipicons" FILES ${ShipIcons_SRCS}) +SET(ShipLoadExample_SRCS + shipLoadExample/__init__.py + shipLoadExample/TaskPanel.py + shipLoadExample/TaskPanel.ui +) +SOURCE_GROUP("shiploadexample" FILES ${ShipLoadExample_SRCS}) + SET(ShipCreateShip_SRCS shipCreateShip/__init__.py shipCreateShip/Preview.py @@ -75,7 +82,7 @@ SET(ShipUtils_SRCS ) SOURCE_GROUP("shiputils" FILES ${ShipUtils_SRCS}) -SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS}) +SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS}) ADD_CUSTOM_TARGET(Ship ALL SOURCES ${all_files} @@ -89,6 +96,12 @@ INSTALL( DESTINATION Mod/Ship/Icons ) +INSTALL( + FILES + ${ShipLoadExample_SRCS} + DESTINATION + Mod/Ship/shipLoadExample +) INSTALL( FILES ${ShipCreateShip_SRCS} diff --git a/src/Mod/Ship/InitGui.py b/src/Mod/Ship/InitGui.py index 01d08f55c..5d0a87efe 100644 --- a/src/Mod/Ship/InitGui.py +++ b/src/Mod/Ship/InitGui.py @@ -32,11 +32,11 @@ class ShipWorkbench ( Workbench ): def Initialize(self): # ToolBar - list = ["Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve"] + list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve"] self.appendToolbar("Ship design",list) # Menu - list = ["Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve"] + list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve"] self.appendMenu("Ship design",list) Gui.addWorkbench(ShipWorkbench()) diff --git a/src/Mod/Ship/Makefile.am b/src/Mod/Ship/Makefile.am index 85137539d..4d61e41f2 100644 --- a/src/Mod/Ship/Makefile.am +++ b/src/Mod/Ship/Makefile.am @@ -33,6 +33,9 @@ nobase_data_DATA = \ Icons/ReparametrizeIco.xpm \ Icons/Ship.xcf \ Icons/Ship.xpm \ + shipLoadExample/__init__.py \ + shipLoadExample/TaskPanel.py \ + shipLoadExample/TaskPanel.ui \ shipCreateShip/__init__.py \ shipCreateShip/Preview.py \ shipCreateShip/TaskPanel.py \ diff --git a/src/Mod/Ship/ShipGui.py b/src/Mod/Ship/ShipGui.py index 2059565bf..c59a43c71 100644 --- a/src/Mod/Ship/ShipGui.py +++ b/src/Mod/Ship/ShipGui.py @@ -24,6 +24,18 @@ from PyQt4 import QtCore, QtGui import FreeCAD, FreeCADGui, os +class LoadExample: + def Activated(self): + import shipLoadExample + shipLoadExample.load() + + def GetResources(self): + from shipUtils import Paths, Translator + IconPath = Paths.iconsPath() + "/LoadIco.png" + MenuText = str(Translator.translate('Load an example ship geometry')) + ToolTip = str(Translator.translate('Load an example ship geometry able to be converted into a ship.')) + return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip} + class CreateShip: def Activated(self): import shipCreateShip @@ -60,6 +72,7 @@ class AreasCurve: ToolTip = str(Translator.translate('Plot transversal areas curve')) return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip} +FreeCADGui.addCommand('Ship_LoadExample', LoadExample()) FreeCADGui.addCommand('Ship_CreateShip', CreateShip()) FreeCADGui.addCommand('Ship_OutlineDraw', OutlineDraw()) FreeCADGui.addCommand('Ship_AreasCurve', AreasCurve()) diff --git a/src/Mod/Ship/shipLoadExample/TaskPanel.py b/src/Mod/Ship/shipLoadExample/TaskPanel.py new file mode 100644 index 000000000..23f5f85b1 --- /dev/null +++ b/src/Mod/Ship/shipLoadExample/TaskPanel.py @@ -0,0 +1,97 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2011, 2012 * +#* Jose Luis Cercos Pita * +#* * +#* This program is free software; you can redistribute it and/or modify * +#* it under the terms of the GNU Lesser General Public License (LGPL) * +#* as published by the Free Software Foundation; either version 2 of * +#* the License, or (at your option) any later version. * +#* for detail see the LICENCE text file. * +#* * +#* 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 Library General Public License for more details. * +#* * +#* You should have received a copy of the GNU Library General Public * +#* License along with this program; if not, write to the Free Software * +#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +#* USA * +#* * +#*************************************************************************** + +# FreeCAD modules +import FreeCAD as App +import FreeCADGui as Gui +# Qt library +from PyQt4 import QtGui,QtCore +# Module +from shipUtils import Paths, Translator +from surfUtils import Geometry + +class TaskPanel: + def __init__(self): + self.ui = Paths.modulePath() + "/shipLoadExample/TaskPanel.ui" + + def accept(self): + return True + + def reject(self): + return True + + def clicked(self, index): + pass + + def open(self): + pass + + def needsFullSpace(self): + return True + + def isAllowedAlterSelection(self): + return False + + def isAllowedAlterView(self): + return True + + def isAllowedAlterDocument(self): + return False + + def helpRequested(self): + pass + + def setupUi(self): + mw = self.getMainWindow() + form = mw.findChild(QtGui.QWidget, "TaskPanel") + form.ship = form.findChild(QtGui.QComboBox, "Ship") + form.mainLogo = form.findChild(QtGui.QLabel, "MainLogo") + iconPath = Paths.iconsPath() + "/Ico.xpm" + form.mainLogo.setPixmap(QtGui.QPixmap(iconPath)) + self.form = form + self.retranslateUi() + + def getMainWindow(self): + "returns the main window" + # using QtGui.qApp.activeWindow() isn't very reliable because if another + # widget than the mainwindow is active (e.g. a dialog) the wrong widget is + # returned + toplevel = QtGui.qApp.topLevelWidgets() + for i in toplevel: + if i.metaObject().className() == "Gui::MainWindow": + return i + raise Exception("No main window found") + + def retranslateUi(self): + """ Set user interface locale strings. + """ + self.form.setWindowTitle(Translator.translate("Load example ship")) + self.form.findChild(QtGui.QGroupBox, "ShipSelectionBox").setTitle(Translator.translate("Select ship example geometry")) + +def createTask(): + panel = TaskPanel() + Gui.Control.showDialog(panel) + if panel.setupUi(): + Gui.Control.closeDialog(panel) + return None + return panel diff --git a/src/Mod/Ship/shipLoadExample/TaskPanel.ui b/src/Mod/Ship/shipLoadExample/TaskPanel.ui new file mode 100644 index 000000000..b9f7aeffe --- /dev/null +++ b/src/Mod/Ship/shipLoadExample/TaskPanel.ui @@ -0,0 +1,115 @@ + + + TaskPanel + + + + 0 + 0 + 260 + 397 + + + + Load example ship + + + + + + + + + + + 128 + 128 + + + + + 128 + 128 + + + + + + + ../Icons/Ico.xpm + + + true + + + Qt::AlignHCenter|Qt::AlignTop + + + + + + + + + + 240 + 80 + + + + Qt::LeftToRight + + + Select ship example geometry + + + + + 0 + 20 + 241 + 101 + + + + + + + + Serie 60 from Iowa University + + + + + Barehull 5145 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + + + + + + + diff --git a/src/Mod/Ship/shipLoadExample/__init__.py b/src/Mod/Ship/shipLoadExample/__init__.py new file mode 100644 index 000000000..cbfb57d75 --- /dev/null +++ b/src/Mod/Ship/shipLoadExample/__init__.py @@ -0,0 +1,36 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2011, 2012 * +#* Jose Luis Cercos Pita * +#* * +#* This program is free software; you can redistribute it and/or modify * +#* it under the terms of the GNU Lesser General Public License (LGPL) * +#* as published by the Free Software Foundation; either version 2 of * +#* the License, or (at your option) any later version. * +#* for detail see the LICENCE text file. * +#* * +#* 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 Library General Public License for more details. * +#* * +#* You should have received a copy of the GNU Library General Public * +#* License along with this program; if not, write to the Free Software * +#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +#* USA * +#* * +#*************************************************************************** + +# FreeCAD modules +import FreeCAD +import FreeCADGui + +# Qt libraries +from PyQt4 import QtGui,QtCore + +# Main object +import TaskPanel + +def load(): + """ Loads the tool """ + TaskPanel.createTask() From e9ea84439bcf057273ab1eb82ce8415d9ddae1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sun, 29 Jan 2012 19:28:24 +0100 Subject: [PATCH 05/27] Small syntax error fix --- src/Mod/Ship/shipCreateShip/TaskPanel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Ship/shipCreateShip/TaskPanel.py b/src/Mod/Ship/shipCreateShip/TaskPanel.py index 3162702f1..0fbbd9718 100644 --- a/src/Mod/Ship/shipCreateShip/TaskPanel.py +++ b/src/Mod/Ship/shipCreateShip/TaskPanel.py @@ -119,7 +119,7 @@ class TaskPanel: self.faces = None selObjs = Geometry.getSelectedObjs() if not selObjs: - msg = Translator.translate("Ship objects can only be created on top of hull geometry (any object selected).\n" + msg = Translator.translate("Ship objects can only be created on top of hull geometry (any object selected).\n") App.Console.PrintError(msg) msg = Translator.translate("Please create or download a ship hull geometry before using this tool\n") App.Console.PrintError(msg) From 9e325abf70d03e25aa78eb22d135198495b091be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sun, 29 Jan 2012 19:29:25 +0100 Subject: [PATCH 06/27] Small syntax error fix --- src/Mod/Ship/shipCreateShip/TaskPanel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Ship/shipCreateShip/TaskPanel.py b/src/Mod/Ship/shipCreateShip/TaskPanel.py index 0fbbd9718..ad995a175 100644 --- a/src/Mod/Ship/shipCreateShip/TaskPanel.py +++ b/src/Mod/Ship/shipCreateShip/TaskPanel.py @@ -130,7 +130,7 @@ class TaskPanel: for j in range(0, len(faces)): self.faces.append(faces[j]) if not self.faces: - msg = Translator.translate("Ship objects can only be created on top of hull geometry (any face object selected).\n" + msg = Translator.translate("Ship objects can only be created on top of hull geometry (any face object selected).\n") App.Console.PrintError(msg) msg = Translator.translate("Please create or download a ship hull geometry before using this tool\n") App.Console.PrintError(msg) From 70636dfe1437dbeb75afae4394fcd52285d11627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sun, 29 Jan 2012 19:41:27 +0100 Subject: [PATCH 07/27] Added s60 & Combatant 5415 hull examples --- src/Mod/Ship/CMakeLists.txt | 14 +++++++++++++- src/Mod/Ship/Examples/barehull5415.fcstd | Bin 0 -> 18069 bytes src/Mod/Ship/Examples/s60.fcstd | Bin 0 -> 31956 bytes src/Mod/Ship/Makefile.am | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/Mod/Ship/Examples/barehull5415.fcstd create mode 100644 src/Mod/Ship/Examples/s60.fcstd diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index 8768d92a1..8f379a0bc 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -35,6 +35,12 @@ SET(ShipIcons_SRCS ) SOURCE_GROUP("shipicons" FILES ${ShipIcons_SRCS}) +SET(ShipExamples_SRCS + Examples/s60.fcstd + Examples/barehull5415.fcstd +) +SOURCE_GROUP("shipexamples" FILES ${ShipExamples_SRCS}) + SET(ShipLoadExample_SRCS shipLoadExample/__init__.py shipLoadExample/TaskPanel.py @@ -82,7 +88,7 @@ SET(ShipUtils_SRCS ) SOURCE_GROUP("shiputils" FILES ${ShipUtils_SRCS}) -SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS}) +SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipExamples_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS}) ADD_CUSTOM_TARGET(Ship ALL SOURCES ${all_files} @@ -96,6 +102,12 @@ INSTALL( DESTINATION Mod/Ship/Icons ) +INSTALL( + FILES + ${ShipExamples_SRCS} + DESTINATION + Mod/Ship/Examples +) INSTALL( FILES ${ShipLoadExample_SRCS} diff --git a/src/Mod/Ship/Examples/barehull5415.fcstd b/src/Mod/Ship/Examples/barehull5415.fcstd new file mode 100644 index 0000000000000000000000000000000000000000..e6f36ae4bdb1cd9970ccee58cfe112f474a16979 GIT binary patch literal 18069 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 literal 0 HcmV?d00001 diff --git a/src/Mod/Ship/Makefile.am b/src/Mod/Ship/Makefile.am index 4d61e41f2..0c8ff3229 100644 --- a/src/Mod/Ship/Makefile.am +++ b/src/Mod/Ship/Makefile.am @@ -33,6 +33,8 @@ nobase_data_DATA = \ Icons/ReparametrizeIco.xpm \ Icons/Ship.xcf \ Icons/Ship.xpm \ + Examples/s60.fcstd \ + Examples/barehull5415.fcstd \ shipLoadExample/__init__.py \ shipLoadExample/TaskPanel.py \ shipLoadExample/TaskPanel.ui \ From 58dc011e3891b001c2aebae86c946e05f256b188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sun, 29 Jan 2012 19:43:35 +0100 Subject: [PATCH 08/27] Fixed bad bounds calculation when several surfaces have been selected --- src/Mod/Ship/shipCreateShip/TaskPanel.py | 30 +++++++++++++++++------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/Mod/Ship/shipCreateShip/TaskPanel.py b/src/Mod/Ship/shipCreateShip/TaskPanel.py index ad995a175..e56827df4 100644 --- a/src/Mod/Ship/shipCreateShip/TaskPanel.py +++ b/src/Mod/Ship/shipCreateShip/TaskPanel.py @@ -138,17 +138,29 @@ class TaskPanel: # Get bounds bounds = [0.0, 0.0, 0.0] bbox = self.faces[0].BoundBox - bounds[0] = bbox.XLength - bounds[1] = bbox.YLength - bounds[2] = bbox.ZLength + minX = bbox.XMin + maxX = bbox.XMax + minY = bbox.YMin + maxY = bbox.YMax + minZ = bbox.ZMin + maxZ = bbox.ZMax for i in range(1,len(self.faces)): bbox = self.faces[i].BoundBox - if bounds[0] < bbox.XLength: - bounds[0] = bbox.XLength - if bounds[1] < bbox.YLength: - bounds[1] = bbox.YLength - if bounds[2] < bbox.ZLength: - bounds[2] = bbox.ZLength + if minX > bbox.XMin: + minX = bbox.XMin + if maxX < bbox.XMax: + maxX = bbox.XMax + if minY > bbox.YMin: + minY = bbox.YMin + if maxY < bbox.YMax: + maxY = bbox.YMax + if minZ > bbox.ZMin: + minZ = bbox.ZMin + if maxZ < bbox.ZMax: + maxZ = bbox.ZMax + bounds[0] = maxX - minX + bounds[1] = maxY - minY + bounds[2] = maxZ - minZ # Set UI fields self.form.length.setMaximum(bounds[0]) self.form.length.setValue(bounds[0]) From a0d0c68162be9ea8ea2f6d28c0c376cc95e6e27d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sun, 29 Jan 2012 19:44:03 +0100 Subject: [PATCH 09/27] Added examples loader functionality --- src/Mod/Ship/shipLoadExample/TaskPanel.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Mod/Ship/shipLoadExample/TaskPanel.py b/src/Mod/Ship/shipLoadExample/TaskPanel.py index 23f5f85b1..1f6cd9f93 100644 --- a/src/Mod/Ship/shipLoadExample/TaskPanel.py +++ b/src/Mod/Ship/shipLoadExample/TaskPanel.py @@ -35,6 +35,11 @@ class TaskPanel: self.ui = Paths.modulePath() + "/shipLoadExample/TaskPanel.ui" def accept(self): + path = Paths.modulePath() + "/Examples/" + if(self.form.ship.currentIndex() == 0): # s60 from Iowa University + App.open(path + "s60.fcstd") + elif(self.form.ship.currentIndex() == 1): # Barehull 5415 + App.open(path + "barehull5415.fcstd") return True def reject(self): From 97959133347be97277d238041728366482124ef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20Pita?= Date: Tue, 31 Jan 2012 09:34:42 +0100 Subject: [PATCH 10/27] Fixed bad warning message aboput empty sections. --- src/Mod/Ship/Instance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Ship/Instance.py b/src/Mod/Ship/Instance.py index be4481ed8..7e9fe5977 100644 --- a/src/Mod/Ship/Instance.py +++ b/src/Mod/Ship/Instance.py @@ -134,7 +134,7 @@ class Ship: wires = shape.slice(Vector(1.0,0.0,0.0), x) if not wires: if (i != 0) or (i != nS-1): - msg = 'Found empty section at x=%g\n' + msg = 'Found empty section at x=%g\n' % (x) msg = Translator.translate(msg) FreeCAD.Console.PrintWarning(msg) FreeCAD.Console.PrintWarning('\tThis may happens if a bad defined (or really complex) surface has been provided.\n') From f3556210dc7488948bd8cf87b46a4e6373374a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20Pita?= Date: Tue, 31 Jan 2012 09:35:42 +0100 Subject: [PATCH 11/27] Fixed 0 length dimensions error related --- src/Mod/Ship/shipCreateShip/TaskPanel.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Mod/Ship/shipCreateShip/TaskPanel.py b/src/Mod/Ship/shipCreateShip/TaskPanel.py index e56827df4..c323957a8 100644 --- a/src/Mod/Ship/shipCreateShip/TaskPanel.py +++ b/src/Mod/Ship/shipCreateShip/TaskPanel.py @@ -163,12 +163,15 @@ class TaskPanel: bounds[2] = maxZ - minZ # Set UI fields self.form.length.setMaximum(bounds[0]) + self.form.length.setMinimum(0.001) self.form.length.setValue(bounds[0]) self.L = bounds[0] self.form.beam.setMaximum(2.0*bounds[1]) + self.form.beam.setMinimum(0.001) self.form.beam.setValue(2.0*bounds[1]) self.B = 2.0*bounds[1] self.form.draft.setMaximum(bounds[2]) + self.form.draft.setMinimum(0.001) self.form.draft.setValue(0.5*bounds[2]) self.T = 0.5*bounds[2] msg = Translator.translate("Ready to work\n") From 395ae7036ef5e1813de78631857d9222461c8ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20Pita?= Date: Tue, 31 Jan 2012 09:39:09 +0100 Subject: [PATCH 12/27] Error saving data fixed --- src/Mod/Ship/shipAreasCurve/TaskPanel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Mod/Ship/shipAreasCurve/TaskPanel.py b/src/Mod/Ship/shipAreasCurve/TaskPanel.py index af4764e12..54d1ecff0 100644 --- a/src/Mod/Ship/shipAreasCurve/TaskPanel.py +++ b/src/Mod/Ship/shipAreasCurve/TaskPanel.py @@ -215,12 +215,12 @@ class TaskPanel: props.index("AreaCurveDraft") except ValueError: self.ship.addProperty("App::PropertyFloat","AreaCurveDraft","Ship", str(Translator.translate("Areas curve draft selected [m]"))) - self.ship.AreaCurveDraft = self.form.draft.value() + self.ship.AreaCurveDraft = self.form.draft.value() try: props.index("AreaCurveTrim") except ValueError: self.ship.addProperty("App::PropertyFloat","AreaCurveTrim","Ship", str(Translator.translate("Areas curve trim selected [m]"))) - self.ship.AreaCurveTrim = self.form.draft.value() + self.ship.AreaCurveTrim = self.form.trim.value() def createTask(): panel = TaskPanel() From c59ae2a84344302a1722be23a172321e4f52d1a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20Pita?= Date: Tue, 31 Jan 2012 10:02:30 +0100 Subject: [PATCH 13/27] Solved ghost empty sections --- src/Mod/Ship/Instance.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Mod/Ship/Instance.py b/src/Mod/Ship/Instance.py index 7e9fe5977..26f28aabe 100644 --- a/src/Mod/Ship/Instance.py +++ b/src/Mod/Ship/Instance.py @@ -140,6 +140,7 @@ class Ship: FreeCAD.Console.PrintWarning('\tThis may happens if a bad defined (or really complex) surface has been provided.\n') FreeCAD.Console.PrintWarning('\tPlease, ensure that this section is correct, or fix surfaces and create a new ship.\n') nPoints.append(0) + continue # Desarrollate wires into edges list edges = [] for j in range(0,len(wires)): From 0e090ee032dd696d7cf1d948eb477b34582d362c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20Pita?= Date: Tue, 31 Jan 2012 10:30:24 +0100 Subject: [PATCH 14/27] Fixed bad points sort algorithm --- src/Mod/Ship/Instance.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/Mod/Ship/Instance.py b/src/Mod/Ship/Instance.py index 26f28aabe..49cb37a51 100644 --- a/src/Mod/Ship/Instance.py +++ b/src/Mod/Ship/Instance.py @@ -152,18 +152,22 @@ class Ship: for j in range(0,len(edges)): for k in range(0,nP): aux = self.lineFaceSection(edges[j], planes[k]) - if not aux: + if not aux: # No section points.append(Vector(x,0,z0 + k*dz)) - for l in range(0,len(aux)): - points.append(Vector(aux[l].X, aux[l].Y, aux[l].Z)) - # Sort section points at Y direction - aux = [] - for j in range(0,len(points)): - aux.append(points[j].y) - aux.sort() - for j in range(0,len(points)): - section.append(Vector(points[j].x, aux[j], points[j].z)) + if len(aux) == 1: # Single point section + points.append(Vector(aux[0].X, aux[0].Y, aux[0].Z)) + else: # Several points, so ship has more than one body + # Get Y coordinates + auxY = [] + for l in range(0,len(aux)): + auxY.append(aux[l].Y) + # Sort them + auxY.sort() + # And store + for l in range(0,len(aux)): + points.append(Vector(aux[l].X, auxY[l], aux[l].Z)) # Store points + section = points[:] nPoints.append(len(section)) for j in range(0,len(section)): mSections.append(section[j]) From 93255307789ecdec922c6a1cfca9b4e42c5bceb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20Pita?= Date: Tue, 31 Jan 2012 16:33:12 +0100 Subject: [PATCH 15/27] Reduced tolerance looking for aproximately variables --- src/Mod/Ship/shipUtils/Math.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Mod/Ship/shipUtils/Math.py b/src/Mod/Ship/shipUtils/Math.py index f8c583bef..018467c58 100644 --- a/src/Mod/Ship/shipUtils/Math.py +++ b/src/Mod/Ship/shipUtils/Math.py @@ -21,7 +21,7 @@ #* * #*************************************************************************** -def isAprox(a,b,tol=0.0001): +def isAprox(a,b,tol=0.000001): """returns if a value is into (b-tol,b+tol) @param a Value to compare. @param b Center of valid interval @@ -32,7 +32,7 @@ def isAprox(a,b,tol=0.0001): return True return False -def isSamePoint(a,b,tol=0.0001): +def isSamePoint(a,b,tol=0.000001): """returns if two points are the same with a provided tolerance @param a Point to compare. @param b Reference point. From 1a88ead7ab6e57e5f2e633530280c324fd8d4f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20Pita?= Date: Wed, 1 Feb 2012 14:02:27 +0100 Subject: [PATCH 16/27] Added multibody support. --- src/Mod/Ship/Instance.py | 37 ++++----- src/Mod/Ship/shipCreateShip/TaskPanel.py | 2 +- src/Mod/Ship/shipHydrostatics/Tools.py | 96 +++++++++++++++++++++--- 3 files changed, 105 insertions(+), 30 deletions(-) diff --git a/src/Mod/Ship/Instance.py b/src/Mod/Ship/Instance.py index 49cb37a51..64eecd5cc 100644 --- a/src/Mod/Ship/Instance.py +++ b/src/Mod/Ship/Instance.py @@ -120,7 +120,7 @@ class Ship: for j in range(0,nP): z = z0 + j*dz rX = x1 - x0 - rY = y1 - y0 + rY = max(y1 - y0, abs(y1), abs(y0)) planes.append(Part.makePlane(4*rX,4*rY,Base.Vector(-2*rX,-2*rY,z),Base.Vector(0,0,1))) # Division are performed at x axis dx = (x1 - x0) / (nS - 1.0) @@ -149,23 +149,23 @@ class Ship: edges.append(wire[k]) # Slice curves to get points (Length based) points = [] - for j in range(0,len(edges)): - for k in range(0,nP): + for k in range(0,nP): + planePoints = [] + for j in range(0,len(edges)): aux = self.lineFaceSection(edges[j], planes[k]) - if not aux: # No section - points.append(Vector(x,0,z0 + k*dz)) - if len(aux) == 1: # Single point section - points.append(Vector(aux[0].X, aux[0].Y, aux[0].Z)) - else: # Several points, so ship has more than one body - # Get Y coordinates - auxY = [] - for l in range(0,len(aux)): - auxY.append(aux[l].Y) - # Sort them - auxY.sort() - # And store - for l in range(0,len(aux)): - points.append(Vector(aux[l].X, auxY[l], aux[l].Z)) + for l in range(0,len(aux)): + planePoints.append(Vector(aux[l].X, aux[l].Y, aux[l].Z)) + if not planePoints: # No section found, symmetry plane point will used + planePoints.append(Vector(x,0,z0 + k*dz)) + # Get Y coordinates + auxY = [] + for l in range(0,len(planePoints)): + auxY.append(planePoints[l].y) + # Sort them + auxY.sort() + # And store + for l in range(0,len(planePoints)): + points.append(Vector(planePoints[l].x, auxY[l], planePoints[l].z)) # Store points section = points[:] nPoints.append(len(section)) @@ -177,6 +177,9 @@ class Ship: self.obj.nPoints = nPoints[:] self.obj.xSection = xSection[:] self.obj.mSections = mSections[:] + msg = '%d Discretization points performed\n' % (len(mSections)) + msg = Translator.translate(msg) + FreeCAD.Console.PrintMessage(msg) class ViewProviderShip: def __init__(self, obj): diff --git a/src/Mod/Ship/shipCreateShip/TaskPanel.py b/src/Mod/Ship/shipCreateShip/TaskPanel.py index c323957a8..7fab02097 100644 --- a/src/Mod/Ship/shipCreateShip/TaskPanel.py +++ b/src/Mod/Ship/shipCreateShip/TaskPanel.py @@ -159,7 +159,7 @@ class TaskPanel: if maxZ < bbox.ZMax: maxZ = bbox.ZMax bounds[0] = maxX - minX - bounds[1] = maxY - minY + bounds[1] = max(maxY - minY, abs(maxY), abs(minY)) bounds[2] = maxZ - minZ # Set UI fields self.form.length.setMaximum(bounds[0]) diff --git a/src/Mod/Ship/shipHydrostatics/Tools.py b/src/Mod/Ship/shipHydrostatics/Tools.py index 32ce25dc0..3792708c9 100644 --- a/src/Mod/Ship/shipHydrostatics/Tools.py +++ b/src/Mod/Ship/shipHydrostatics/Tools.py @@ -27,6 +27,7 @@ import FreeCAD as App import FreeCADGui as Gui # Module import Instance +from shipUtils import Math def Displacement(ship, draft, trim): """ Calculate ship displacement. @@ -75,20 +76,91 @@ def Displacement(ship, draft, trim): z0 = section[n-1].z y1 = section[n].y z1 = section[n].z - factor = (Z - z0) / (z1 - z0) - y = y0 + factor*(y1 - y0) - points.append(App.Base.Vector(x,y,Z)) + if (Z > z0) and not (Math.isAprox(Z,z0)): + factor = (Z - z0) / (z1 - z0) + y = y0 + factor*(y1 - y0) + points.append(App.Base.Vector(x,y,Z)) + # Convert into array with n elements (Number of points by sections) + # with m elements into them (Number of points with the same height, + # typical of multibody) + section = [] + nPoints = 0 + j = 0 + while j < len(points)-1: + section.append([points[j]]) + k = j+1 + while(Math.isAprox(points[j].z, points[k].z)): + section[nPoints].append(points[k]) + k = k+1 + nPoints = nPoints + 1 + j = k # Integrate area area = 0.0 - for j in range(0, len(points)-1): - y0 = abs(points[j].y) - z0 = points[j].z - y1 = abs(points[j+1].y) - z1 = points[j+1].z - y = 0.5 * (y0 + y1) - dz = z1 - z0 - area = area + 2.0*y*dz # 2x because only half ship is represented - areas.append(area) + for j in range(0, len(section)-1): + for k in range(0, min(len(section[j])-1, len(section[j+1])-1)): + # y11,z11 ------- y01,z01 + # | | + # | | + # | | + # y10,z10 ------- y00,z00 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = 0.5*((y00 - y10) + (y01 - y11)) + dz = 0.5*((z01 - z00) + (z11 - z10)) + area = area + dy*dz + if(len(section[j]) < len(section[j+1])): + # y01,z01 ------- y11,z11 + # | __/ + # | __/ + # | / + # y00,z00 + k = len(section[j])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = y01 - y11 + dz = z01 - z00 + area = area + 0.5*dy*dz + elif(len(section[j]) > len(section[j+1])): + # y01,z01 + # | \__ + # | \__ + # | \ + # y00,z00 ------- y10,z10 + k = len(section[j+1])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + dy = y00 - y10 + dz = z01 - z00 + area = area + 0.5*dy*dz + elif(len(section[j]) == 1): + # y1,z1 ------- + # | + # | + # | + # y0,z0 ------- + k = 0 + y0 = abs(section[j][k].y) + z0 = section[j][k].z + y1 = abs(section[j+1][k].y) + z1 = section[j+1][k].z + dy = 0.5 * (y0 + y1) + dz = z1 - z0 + area = area + dy*dz + areas.append(2.0*area) # 2x because only half ship is represented # Add volume & moment if proceed if i > 0: dx = xCoord[i] - xCoord[i-1] From 84c33bffde8c0fdb721eb40b62e38ef873c00a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20Pita?= Date: Wed, 1 Feb 2012 14:10:53 +0100 Subject: [PATCH 17/27] Added s60 katamaran model geometry example --- src/Mod/Ship/CMakeLists.txt | 1 + src/Mod/Ship/Examples/s60_katamaran.fcstd | Bin 0 -> 59901 bytes src/Mod/Ship/Makefile.am | 1 + 3 files changed, 2 insertions(+) create mode 100644 src/Mod/Ship/Examples/s60_katamaran.fcstd diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index 8f379a0bc..71aea43f0 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -38,6 +38,7 @@ SOURCE_GROUP("shipicons" FILES ${ShipIcons_SRCS}) SET(ShipExamples_SRCS Examples/s60.fcstd Examples/barehull5415.fcstd + Examples/s60_katamaran.fcstd ) SOURCE_GROUP("shipexamples" FILES ${ShipExamples_SRCS}) diff --git a/src/Mod/Ship/Examples/s60_katamaran.fcstd b/src/Mod/Ship/Examples/s60_katamaran.fcstd new file mode 100644 index 0000000000000000000000000000000000000000..a7d72df9401f1ca3997555950179bb6200cddfda GIT binary patch literal 59901 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 Date: Wed, 1 Feb 2012 14:14:16 +0100 Subject: [PATCH 18/27] Updated examples loader in order to allow load s60 katamaran version. --- src/Mod/Ship/shipLoadExample/TaskPanel.py | 2 ++ src/Mod/Ship/shipLoadExample/TaskPanel.ui | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/Mod/Ship/shipLoadExample/TaskPanel.py b/src/Mod/Ship/shipLoadExample/TaskPanel.py index 1f6cd9f93..3c9b483c1 100644 --- a/src/Mod/Ship/shipLoadExample/TaskPanel.py +++ b/src/Mod/Ship/shipLoadExample/TaskPanel.py @@ -40,6 +40,8 @@ class TaskPanel: App.open(path + "s60.fcstd") elif(self.form.ship.currentIndex() == 1): # Barehull 5415 App.open(path + "barehull5415.fcstd") + elif(self.form.ship.currentIndex() == 2): # s60 (Katamaran) + App.open(path + "s60_katamaran.fcstd") return True def reject(self): diff --git a/src/Mod/Ship/shipLoadExample/TaskPanel.ui b/src/Mod/Ship/shipLoadExample/TaskPanel.ui index b9f7aeffe..77d744189 100644 --- a/src/Mod/Ship/shipLoadExample/TaskPanel.ui +++ b/src/Mod/Ship/shipLoadExample/TaskPanel.ui @@ -84,6 +84,11 @@ Barehull 5145 + + + Serie 60 (Katamaran) + + From f0955a3f4605124fe2bd710ebe6014445670442c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20Pita?= Date: Wed, 1 Feb 2012 15:28:12 +0100 Subject: [PATCH 19/27] Fix error when try to fuse border into constant sections edges. Now constant edges are fused into border. --- src/Mod/Ship/shipOutlineDraw/Plot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Mod/Ship/shipOutlineDraw/Plot.py b/src/Mod/Ship/shipOutlineDraw/Plot.py index 155b6b0b6..7d21b2fbc 100644 --- a/src/Mod/Ship/shipOutlineDraw/Plot.py +++ b/src/Mod/Ship/shipOutlineDraw/Plot.py @@ -57,7 +57,8 @@ def Plot(scale, sections, shape): border = border.oldFuse(edges[i]) # Only group objects, don't try to build more complex entities border = border.oldFuse(edges[i].mirror(Vector(0.0, 0.0, 0.0),Vector(0.0, 1.0, 0.0))) # Fuse sections & borders - obj = sections.oldFuse(border) + # obj = sections.oldFuse(border) + obj = border.oldFuse(sections) # Send to 3D view Part.show(obj) objs = FreeCAD.ActiveDocument.Objects From 079e3e5cb50fde29a56ac54a6916d83eee2cf332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sat, 4 Feb 2012 18:50:14 +0100 Subject: [PATCH 20/27] Fixed some messages --- src/Mod/Ship/shipAreasCurve/TaskPanel.py | 4 ++-- src/Mod/Ship/shipCreateShip/TaskPanel.py | 4 ++-- src/Mod/Ship/shipOutlineDraw/TaskPanel.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Mod/Ship/shipAreasCurve/TaskPanel.py b/src/Mod/Ship/shipAreasCurve/TaskPanel.py index 54d1ecff0..dbd3271bb 100644 --- a/src/Mod/Ship/shipAreasCurve/TaskPanel.py +++ b/src/Mod/Ship/shipAreasCurve/TaskPanel.py @@ -112,7 +112,7 @@ class TaskPanel: # Get objects selObjs = Geometry.getSelectedObjs() if not selObjs: - msg = Translator.translate("Ship instance must be selected (any object selected)\n") + msg = Translator.translate("Ship instance must be selected (no object selected)\n") App.Console.PrintError(msg) return True for i in range(0,len(selObjs)): @@ -132,7 +132,7 @@ class TaskPanel: self.ship = obj # Test if any valid ship was selected if not self.ship: - msg = Translator.translate("Ship instance must be selected (any valid ship found at selected objects)\n") + msg = Translator.translate("Ship instance must be selected (no valid ship found at selected objects)\n") App.Console.PrintError(msg) return True # Get bounds diff --git a/src/Mod/Ship/shipCreateShip/TaskPanel.py b/src/Mod/Ship/shipCreateShip/TaskPanel.py index 7fab02097..bec74302a 100644 --- a/src/Mod/Ship/shipCreateShip/TaskPanel.py +++ b/src/Mod/Ship/shipCreateShip/TaskPanel.py @@ -119,7 +119,7 @@ class TaskPanel: self.faces = None selObjs = Geometry.getSelectedObjs() if not selObjs: - msg = Translator.translate("Ship objects can only be created on top of hull geometry (any object selected).\n") + msg = Translator.translate("Ship objects can only be created on top of hull geometry (no object selected).\n") App.Console.PrintError(msg) msg = Translator.translate("Please create or download a ship hull geometry before using this tool\n") App.Console.PrintError(msg) @@ -130,7 +130,7 @@ class TaskPanel: for j in range(0, len(faces)): self.faces.append(faces[j]) if not self.faces: - msg = Translator.translate("Ship objects can only be created on top of hull geometry (any face object selected).\n") + msg = Translator.translate("Ship objects can only be created on top of hull geometry (no face object selected).\n") App.Console.PrintError(msg) msg = Translator.translate("Please create or download a ship hull geometry before using this tool\n") App.Console.PrintError(msg) diff --git a/src/Mod/Ship/shipOutlineDraw/TaskPanel.py b/src/Mod/Ship/shipOutlineDraw/TaskPanel.py index a745263c6..834738a0c 100644 --- a/src/Mod/Ship/shipOutlineDraw/TaskPanel.py +++ b/src/Mod/Ship/shipOutlineDraw/TaskPanel.py @@ -118,7 +118,7 @@ class TaskPanel: # Get selected objects selObjs = Geometry.getSelectedObjs() if not selObjs: - msg = Translator.translate("Ship instance must be selected (any object selected)\n") + msg = Translator.translate("Ship instance must be selected (no object selected)\n") App.Console.PrintError(msg) return True for i in range(0,len(selObjs)): @@ -138,7 +138,7 @@ class TaskPanel: self.ship = obj # Test if any valid ship was selected if not self.ship: - msg = Translator.translate("Ship instance must be selected (any valid ship found at selected objects)\n") + msg = Translator.translate("Ship instance must be selected (no valid ship found at selected objects)\n") App.Console.PrintError(msg) return True # Load sections (if exist) From 6c870f2ebd9bbc40196f4385f9f0e358fce9e5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Fri, 17 Feb 2012 11:41:41 +0100 Subject: [PATCH 21/27] Created loadable hydrostatics task panel. --- src/Mod/Ship/CMakeLists.txt | 2 + src/Mod/Ship/InitGui.py | 4 +- src/Mod/Ship/Makefile.am | 2 + src/Mod/Ship/ShipGui.py | 13 ++ src/Mod/Ship/shipHydrostatics/TaskPanel.py | 223 +++++++++++++++++++++ src/Mod/Ship/shipHydrostatics/TaskPanel.ui | 205 +++++++++++++++++++ src/Mod/Ship/shipHydrostatics/__init__.py | 14 ++ 7 files changed, 461 insertions(+), 2 deletions(-) create mode 100644 src/Mod/Ship/shipHydrostatics/TaskPanel.py create mode 100644 src/Mod/Ship/shipHydrostatics/TaskPanel.ui diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index 71aea43f0..d2cd46991 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -77,6 +77,8 @@ SOURCE_GROUP("shipareascurve" FILES ${ShipAreasCurve_SRCS}) SET(ShipHydrostatics_SRCS shipHydrostatics/__init__.py + shipHydrostatics/TaskPanel.py + shipHydrostatics/TaskPanel.ui shipHydrostatics/Tools.py ) SOURCE_GROUP("shiphydrostatics" FILES ${ShipHydrostatics_SRCS}) diff --git a/src/Mod/Ship/InitGui.py b/src/Mod/Ship/InitGui.py index 5d0a87efe..b20c552af 100644 --- a/src/Mod/Ship/InitGui.py +++ b/src/Mod/Ship/InitGui.py @@ -32,11 +32,11 @@ class ShipWorkbench ( Workbench ): def Initialize(self): # ToolBar - list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve"] + list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"] self.appendToolbar("Ship design",list) # Menu - list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve"] + list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"] self.appendMenu("Ship design",list) Gui.addWorkbench(ShipWorkbench()) diff --git a/src/Mod/Ship/Makefile.am b/src/Mod/Ship/Makefile.am index 87f2a4759..d572d41d6 100644 --- a/src/Mod/Ship/Makefile.am +++ b/src/Mod/Ship/Makefile.am @@ -54,6 +54,8 @@ nobase_data_DATA = \ shipAreasCurve/TaskPanel.py \ shipAreasCurve/TaskPanel.ui \ shipHydrostatics/__init__.py \ + shipHydrostatics/TaskPanel.py \ + shipHydrostatics/TaskPanel.ui \ shipHydrostatics/Tools.py \ shipUtils/__init__.py \ shipUtils/Math.py \ diff --git a/src/Mod/Ship/ShipGui.py b/src/Mod/Ship/ShipGui.py index c59a43c71..8f50b4be0 100644 --- a/src/Mod/Ship/ShipGui.py +++ b/src/Mod/Ship/ShipGui.py @@ -71,8 +71,21 @@ class AreasCurve: MenuText = str(Translator.translate('Areas curve')) ToolTip = str(Translator.translate('Plot transversal areas curve')) return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip} + +class Hydrostatics: + def Activated(self): + import shipHydrostatics + shipHydrostatics.load() + + def GetResources(self): + from shipUtils import Paths, Translator + IconPath = Paths.iconsPath() + "/HydrostaticsIco.png" + MenuText = str(Translator.translate('Hydrostatics')) + ToolTip = str(Translator.translate('Plot ship hydrostatics')) + return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip} FreeCADGui.addCommand('Ship_LoadExample', LoadExample()) FreeCADGui.addCommand('Ship_CreateShip', CreateShip()) FreeCADGui.addCommand('Ship_OutlineDraw', OutlineDraw()) FreeCADGui.addCommand('Ship_AreasCurve', AreasCurve()) +FreeCADGui.addCommand('Ship_Hydrostatics', Hydrostatics()) diff --git a/src/Mod/Ship/shipHydrostatics/TaskPanel.py b/src/Mod/Ship/shipHydrostatics/TaskPanel.py new file mode 100644 index 000000000..d0feb40dc --- /dev/null +++ b/src/Mod/Ship/shipHydrostatics/TaskPanel.py @@ -0,0 +1,223 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2011, 2012 * +#* Jose Luis Cercos Pita * +#* * +#* This program is free software; you can redistribute it and/or modify * +#* it under the terms of the GNU Lesser General Public License (LGPL) * +#* as published by the Free Software Foundation; either version 2 of * +#* the License, or (at your option) any later version. * +#* for detail see the LICENCE text file. * +#* * +#* 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 Library General Public License for more details. * +#* * +#* You should have received a copy of the GNU Library General Public * +#* License along with this program; if not, write to the Free Software * +#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +#* USA * +#* * +#*************************************************************************** + +import math +# FreeCAD modules +import FreeCAD as App +import FreeCADGui as Gui +# Qt library +from PyQt4 import QtGui,QtCore +# Module +# import Plot +import Instance +from shipUtils import Paths, Translator +from surfUtils import Geometry +import Tools + +class TaskPanel: + def __init__(self): + self.ui = Paths.modulePath() + "/shipHydrostatics/TaskPanel.ui" + self.ship = None + + def accept(self): + if not self.ship: + return False + self.save() + return True + + def reject(self): + return True + + def clicked(self, index): + pass + + def open(self): + pass + + def needsFullSpace(self): + return True + + def isAllowedAlterSelection(self): + return False + + def isAllowedAlterView(self): + return True + + def isAllowedAlterDocument(self): + return False + + def helpRequested(self): + pass + + def setupUi(self): + mw = self.getMainWindow() + form = mw.findChild(QtGui.QWidget, "TaskPanel") + form.trim = form.findChild(QtGui.QDoubleSpinBox, "Trim") + form.minDraft = form.findChild(QtGui.QDoubleSpinBox, "MinDraft") + form.maxDraft = form.findChild(QtGui.QDoubleSpinBox, "MaxDraft") + form.nDraft = form.findChild(QtGui.QSpinBox, "NDraft") + self.form = form + # Initial values + if self.initValues(): + return True + self.retranslateUi() + # Connect Signals and Slots + QtCore.QObject.connect(form.trim, QtCore.SIGNAL("valueChanged(double)"), self.onData) + QtCore.QObject.connect(form.minDraft, QtCore.SIGNAL("valueChanged(double)"), self.onData) + QtCore.QObject.connect(form.maxDraft, QtCore.SIGNAL("valueChanged(double)"), self.onData) + + def getMainWindow(self): + "returns the main window" + # using QtGui.qApp.activeWindow() isn't very reliable because if another + # widget than the mainwindow is active (e.g. a dialog) the wrong widget is + # returned + toplevel = QtGui.qApp.topLevelWidgets() + for i in toplevel: + if i.metaObject().className() == "Gui::MainWindow": + return i + raise Exception("No main window found") + + def initValues(self): + """ Set initial values for fields + """ + # Get objects + selObjs = Geometry.getSelectedObjs() + if not selObjs: + msg = Translator.translate("Ship instance must be selected (no object selected)\n") + App.Console.PrintError(msg) + return True + for i in range(0,len(selObjs)): + obj = selObjs[i] + # Test if is a ship instance + props = obj.PropertiesList + try: + props.index("IsShip") + except ValueError: + continue + if obj.IsShip: + # Test if another ship already selected + if self.ship: + msg = Translator.translate("More than one ship selected (extra ship will be neglected)\n") + App.Console.PrintWarning(msg) + break + self.ship = obj + # Test if any valid ship was selected + if not self.ship: + msg = Translator.translate("Ship instance must be selected (no valid ship found at selected objects)\n") + App.Console.PrintError(msg) + return True + # Get bounds + bbox = self.ship.Shape.BoundBox + # Set trim + flag = True + try: + props.index("HydrostaticsTrim") + except ValueError: + flag = False + if flag: + self.form.trim.setValue(self.ship.HydrostaticsTrim) + # Set drafts + self.form.maxDraft.setValue(1.1*self.ship.Draft) + self.form.minDraft.setValue(0.9*self.ship.Draft) + # Try to use saved values + props = self.ship.PropertiesList + flag = True + try: + props.index("HydrostaticsMinDraft") + except ValueError: + flag = False + if flag: + self.form.minDraft.setValue(self.ship.HydrostaticsMinDraft) + flag = True + try: + props.index("HydrostaticsMaxDraft") + except ValueError: + flag = False + if flag: + self.form.maxDraft.setValue(self.ship.HydrostaticsMaxDraft) + self.form.maxDraft.setMaximum(bbox.ZMax) + self.form.minDraft.setMinimum(bbox.ZMin) + self.form.maxDraft.setMinimum(self.form.minDraft.value()) + self.form.minDraft.setMaximum(self.form.maxDraft.value()) + flag = True + try: + props.index("HydrostaticsNDraft") + except ValueError: + flag = False + if flag: + self.form.nDraft.setValue(self.ship.HydrostaticsNDraft) + # Update GUI + msg = Translator.translate("Ready to work\n") + App.Console.PrintMessage(msg) + return False + + def retranslateUi(self): + """ Set user interface locale strings. + """ + self.form.setWindowTitle(Translator.translate("Plot hydrostatics")) + self.form.findChild(QtGui.QLabel, "TrimLabel").setText(Translator.translate("Trim")) + self.form.findChild(QtGui.QLabel, "MinDraftLabel").setText(Translator.translate("Minimum draft")) + self.form.findChild(QtGui.QLabel, "MaxDraftLabel").setText(Translator.translate("Maximum draft")) + self.form.findChild(QtGui.QLabel, "NDraftLabel").setText(Translator.translate("Number of points")) + + def onData(self, value): + """ Method called when input data is changed. + @param value Changed value. + """ + if not self.ship: + return + self.form.maxDraft.setMinimum(self.form.minDraft.value()) + self.form.minDraft.setMaximum(self.form.maxDraft.value()) + + def save(self): + """ Saves data into ship instance. + """ + props = self.ship.PropertiesList + try: + props.index("HydrostaticsTrim") + except ValueError: + self.ship.addProperty("App::PropertyFloat","HydrostaticsTrim","Ship", str(Translator.translate("Hydrostatics trim selected [m]"))) + self.ship.HydrostaticsTrim = self.form.trim.value() + try: + props.index("HydrostaticsMinDraft") + except ValueError: + self.ship.addProperty("App::PropertyFloat","HydrostaticsMinDraft","Ship", str(Translator.translate("Hydrostatics minimum draft selected [m]"))) + self.ship.HydrostaticsMinDraft = self.form.minDraft.value() + try: + props.index("HydrostaticsMaxDraft") + except ValueError: + self.ship.addProperty("App::PropertyFloat","HydrostaticsMaxDraft","Ship", str(Translator.translate("Hydrostatics maximum draft selected [m]"))) + self.ship.HydrostaticsMaxDraft = self.form.maxDraft.value() + try: + props.index("HydrostaticsNDraft") + except ValueError: + self.ship.addProperty("App::PropertyInteger","HydrostaticsNDraft","Ship", str(Translator.translate("Hydrostatics number of points selected [m]"))) + self.ship.HydrostaticsNDraft = self.form.nDraft.value() + +def createTask(): + panel = TaskPanel() + Gui.Control.showDialog(panel) + if panel.setupUi(): + Gui.Control.closeDialog(panel) + return None + return panel diff --git a/src/Mod/Ship/shipHydrostatics/TaskPanel.ui b/src/Mod/Ship/shipHydrostatics/TaskPanel.ui new file mode 100644 index 000000000..d4b4f0639 --- /dev/null +++ b/src/Mod/Ship/shipHydrostatics/TaskPanel.ui @@ -0,0 +1,205 @@ + + + TaskPanel + + + + 0 + 0 + 260 + 256 + + + + Create new ship + + + + + + + + + 0 + 0 + + + + Trim + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + -45.000000000000000 + + + 45.000000000000000 + + + + + + + + 24 + 16777215 + + + + Deg + + + + + + + + + + 0 + 0 + + + + Drafts + + + + + 9 + 19 + 231 + 181 + + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + Minimum draft + + + + + + + 3 + + + 0.010000000000000 + + + + + + + + 0 + 0 + + + + Maximum draft + + + + + + + + 0 + 0 + + + + 3 + + + 0.010000000000000 + + + + + + + + 0 + 0 + + + + Number of points + + + + + + + + 0 + 0 + + + + m + + + + + + + + 0 + 0 + + + + m + + + + + + + + 0 + 0 + + + + 1 + + + 9999 + + + 11 + + + + + + + + + + + + diff --git a/src/Mod/Ship/shipHydrostatics/__init__.py b/src/Mod/Ship/shipHydrostatics/__init__.py index 55ed9aee5..5b9a3c477 100644 --- a/src/Mod/Ship/shipHydrostatics/__init__.py +++ b/src/Mod/Ship/shipHydrostatics/__init__.py @@ -21,3 +21,17 @@ #* * #*************************************************************************** + +# FreeCAD modules +import FreeCAD +import FreeCADGui + +# Qt libraries +from PyQt4 import QtGui,QtCore + +# Main object +import TaskPanel + +def load(): + """ Loads the tool """ + TaskPanel.createTask() From 87782c32cbd348ef1e7bc716fc24b105367a7036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Fri, 17 Feb 2012 13:41:50 +0100 Subject: [PATCH 22/27] Added some hydrostatics computation. --- src/Mod/Ship/CMakeLists.txt | 1 + src/Mod/Ship/Makefile.am | 1 + src/Mod/Ship/shipHydrostatics/Plot.py | 194 +++++++++++++++++++++ src/Mod/Ship/shipHydrostatics/TaskPanel.py | 9 +- src/Mod/Ship/shipHydrostatics/Tools.py | 193 +++++++++++++++++++- 5 files changed, 396 insertions(+), 2 deletions(-) create mode 100644 src/Mod/Ship/shipHydrostatics/Plot.py diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index d2cd46991..6542ddda2 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -77,6 +77,7 @@ SOURCE_GROUP("shipareascurve" FILES ${ShipAreasCurve_SRCS}) SET(ShipHydrostatics_SRCS shipHydrostatics/__init__.py + shipHydrostatics/Plot.py shipHydrostatics/TaskPanel.py shipHydrostatics/TaskPanel.ui shipHydrostatics/Tools.py diff --git a/src/Mod/Ship/Makefile.am b/src/Mod/Ship/Makefile.am index d572d41d6..380d8aed8 100644 --- a/src/Mod/Ship/Makefile.am +++ b/src/Mod/Ship/Makefile.am @@ -54,6 +54,7 @@ nobase_data_DATA = \ shipAreasCurve/TaskPanel.py \ shipAreasCurve/TaskPanel.ui \ shipHydrostatics/__init__.py \ + shipHydrostatics/Plot.py \ shipHydrostatics/TaskPanel.py \ shipHydrostatics/TaskPanel.ui \ shipHydrostatics/Tools.py \ diff --git a/src/Mod/Ship/shipHydrostatics/Plot.py b/src/Mod/Ship/shipHydrostatics/Plot.py new file mode 100644 index 000000000..72e81a0a8 --- /dev/null +++ b/src/Mod/Ship/shipHydrostatics/Plot.py @@ -0,0 +1,194 @@ +#*************************************************************************** +#* * +#* Copyright (c) 2011, 2012 * +#* Jose Luis Cercos Pita * +#* * +#* This program is free software; you can redistribute it and/or modify * +#* it under the terms of the GNU Lesser General Public License (LGPL) * +#* as published by the Free Software Foundation; either version 2 of * +#* the License, or (at your option) any later version. * +#* for detail see the LICENCE text file. * +#* * +#* 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 Library General Public License for more details. * +#* * +#* You should have received a copy of the GNU Library General Public * +#* License along with this program; if not, write to the Free Software * +#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +#* USA * +#* * +#*************************************************************************** + +import os +# FreeCAD modules +import FreeCAD,FreeCADGui +from FreeCAD import Part, Base +from FreeCAD import Image, ImageGui +# FreeCADShip modules +from shipUtils import Paths, Translator +import Tools + +header = """ ################################################################# + + ##### #### ### #### ##### # # ### #### + # # # # # # # # # # # # + # ## #### #### # # # # # # # # # # # + #### # # # # # # # ##### # # ## ## ##### # #### + # # #### #### # # # # # # # # # # + # # # # # # # # # # # # # # + # # #### #### ### # # #### ##### # # ### # + + ################################################################# +""" + +class Plot(object): + def __init__(self, ship, trim, drafts): + """ Constructor. performs plot and show it (Using pyxplot). + @param ship Selected ship instance + @param trim Trim in degrees. + @param drafts List of drafts to be performed. + """ + if self.createDirectory(): + return + if self.saveData(ship, trim, drafts): + return + if self.saveLayout(trim): + return + if self.execute(): + return + ImageGui.open(self.path + 'volume.png') + + def createDirectory(self): + """ Create needed folder to write data and scripts. + @return True if error happens. + """ + self.path = FreeCAD.ConfigGet("UserAppData") + "ShipOutput/" + if not os.path.exists(self.path): + os.makedirs(self.path) + if not os.path.exists(self.path): + msg = Translator.translate("Can't create '" + self.path + "' folder.\n") + FreeCAD.Console.PrintError(msg) + return False + + def saveData(self, ship, trim, drafts): + """ Write data file. + @param ship Selected ship instance + @param trim Trim in degrees. + @param drafts List of drafts to be performed. + @return True if error happens. + """ + # Open the file + filename = self.path + 'hydrostatics.dat' + try: + Output = open(filename, "w") + except IOError: + msg = Translator.translate("Can't write '" + filename + "' file.\n") + FreeCAD.Console.PrintError(msg) + return True + # Print header + Output.write(header) + Output.write(" #\n") + Output.write(" # File automatically exported by FreeCAD-Ship\n") + Output.write(" # This file contains transversal areas data, filled with following columns:\n") + Output.write(" # 1: Ship displacement [ton]\n") + Output.write(" # 2: Draft [m]\n") + Output.write(" # 3: Wetted surface [m2]\n") + Output.write(" # 4: 1cm triming ship moment [ton m]\n") + Output.write(" # 5: Bouyance center x coordinate\n") + Output.write(" #\n") + Output.write(" #################################################################\n") + # Print data + for i in range(0,len(drafts)): + draft = drafts[i] + point = Tools.Point(ship,draft,trim) + string = "%f %f %f %f %f\n" % (point.disp, point.draft, point.wet, point.mom, point.xcb) + Output.write(string) + # Close file + Output.close() + self.dataFile = filename + msg = Translator.translate("Data saved at '" + self.dataFile + "'.\n") + FreeCAD.Console.PrintMessage(msg) + return False + + def saveLayout(self, trim): + """ Prints the pyxplot layout. + @param trim Trim in degrees. + @return True if error happens. + """ + filename = self.path + 'volume.pyxplot' + # Open the file + try: + Output = open(filename, "w") + except IOError: + msg = Translator.translate("Can't write '" + filename + "' file.\n") + FreeCAD.Console.PrintError(msg) + return True + # Write header + Output.write(header) + Output.write(" #\n") + Output.write(" # File automatically exported by FreeCAD-Ship\n") + Output.write(" # This file contains a script to plot transversal areas curve.\n") + Output.write(" # To use it execute:\n") + Output.write(" #\n") + Output.write(" # pyxplot %s\n" % (filename)) + Output.write(" #\n") + Output.write(" #################################################################\n") + # Write general options for hydrostatics + Output.write("set numeric display latex\n") + Output.write("set output '%s'\n" % (self.path + 'volume.eps')) + Output.write("set title '$trim$ = %g [degrees]'\n" % (trim)) + Output.write("set key below\n") + Output.write("set grid\n") + # Configure axis + Output.write("# Y axis\n") + Output.write("set ylabel '$\\bigtriangleup$ / $\\mathrm{ton}$'\n") + Output.write("set ytic\n") + Output.write("# X axis\n") + Output.write("set xlabel '$Draft$ / $\\mathrm{m}$'\n") + Output.write("set xtic\n") + Output.write("set x2label '\\textit{Wetted area} / $\\mathrm{m}^2$'\n") + Output.write("set x2tic\n") + Output.write("set x3label '\\textit{1cm trim moment} / $\\mathrm{ton} \\times \\mathrm{m}$'\n") + Output.write("set x3tic\n") + Output.write("set x4label '$XCB$ / $\\mathrm{m}$'\n") + Output.write("set x4tic\n") + Output.write("set axis x2 top\n") + Output.write("set axis x4 top\n") + Output.write("# Line styles\n") + Output.write("set style 1 line linetype 1 linewidth 1 colour rgb (0):(0):(0)\n") + Output.write("set style 2 line linetype 1 linewidth 1 colour rgb (1):(0):(0)\n") + Output.write("set style 3 line linetype 1 linewidth 1 colour rgb (0):(0):(1)\n") + Output.write("set style 4 line linetype 1 linewidth 1 colour rgb (1):(0):(1)\n") + # Write plot call + Output.write("# Plot\n") + Output.write("plot '%s' using 2:1 title '$\\bigtriangleup$' axes x1y1 with lines style 1, \\\n" % (self.dataFile)) + Output.write(" '' using 3:1 title 'Wetted area' axes x2y1 with lines style 2, \\\n") + Output.write(" '' using 4:1 title '1cm trim moment' axes x3y1 with lines style 3, \\\n") + Output.write(" '' using 5:1 title 'XCB' axes x4y1 with lines style 4\n") + # Close file + self.layoutFile = filename + Output.close() + return False + + def execute(self): + """ Calls pyxplot in order to plot an save an image. + @return True if error happens. + """ + filename = self.path + 'volume' + comm = "pyxplot %s" % (self.layoutFile) + if os.system(comm): + msg = Translator.translate("Can't execute pyxplot. Maybe is not installed?\n") + FreeCAD.Console.PrintError(msg) + msg = Translator.translate("Plot will not generated\n") + FreeCAD.Console.PrintError(msg) + return True + comm = "gs -r300 -dEPSCrop -dTextAlphaBits=4 -sDEVICE=png16m -sOutputFile=%s.png -dBATCH -dNOPAUSE %s.eps" % (filename,filename) + if os.system(comm): + msg = Translator.translate("Can't execute ghostscript. Maybe is not installed?\n") + FreeCAD.Console.PrintError(msg) + msg = Translator.translate("Generated image will not converted to png\n") + FreeCAD.Console.PrintError(msg) + return True + return False diff --git a/src/Mod/Ship/shipHydrostatics/TaskPanel.py b/src/Mod/Ship/shipHydrostatics/TaskPanel.py index d0feb40dc..665e7edaf 100644 --- a/src/Mod/Ship/shipHydrostatics/TaskPanel.py +++ b/src/Mod/Ship/shipHydrostatics/TaskPanel.py @@ -28,7 +28,7 @@ import FreeCADGui as Gui # Qt library from PyQt4 import QtGui,QtCore # Module -# import Plot +import Plot import Instance from shipUtils import Paths, Translator from surfUtils import Geometry @@ -43,6 +43,13 @@ class TaskPanel: if not self.ship: return False self.save() + draft = self.form.minDraft.value() + drafts = [draft] + dDraft = (self.form.maxDraft.value() - self.form.minDraft.value())/self.form.nDraft.value() + for i in range(1,self.form.nDraft.value()): + draft = draft + dDraft + drafts.append(draft) + Plot.Plot(self.ship, self.form.trim.value(), drafts) return True def reject(self): diff --git a/src/Mod/Ship/shipHydrostatics/Tools.py b/src/Mod/Ship/shipHydrostatics/Tools.py index 3792708c9..d3bf8698d 100644 --- a/src/Mod/Ship/shipHydrostatics/Tools.py +++ b/src/Mod/Ship/shipHydrostatics/Tools.py @@ -32,7 +32,7 @@ from shipUtils import Math def Displacement(ship, draft, trim): """ Calculate ship displacement. @param ship Selected ship instance - @param traft Draft. + @param draft Draft. @param trim Trim in degrees. @return [areas,disp,xcb]: \n areas : Area of each section \n @@ -174,3 +174,194 @@ def Displacement(ship, draft, trim): if vol > 0.0: xcb = moment / vol return [areas,disp,xcb] + +def WettedArea(ship, draft, trim): + """ Calculate wetted ship area. + @param ship Selected ship instance + @param draft Draft. + @param trim Trim in degrees. + @return Wetted ship area. + """ + angle = math.radians(trim) + sections = Instance.sections(ship) + xCoord = ship.xSection[:] + lines = [] + area = 0.0 + if not sections: + return 0.0 + for i in range(0, len(sections)): + # Get the section + section = sections[i] + if len(section) < 2: # Empty section + lines.append(0.0) + continue + # Get the position of the section + x = xCoord[i] + # Get the maximum Z value + Z = draft - x*math.tan(angle) + # Count the number of valid points + n = 0 + for j in range(0,len(section)): + z = section[j].z + if z > Z: + break + n = n+1 + # Discard invalid sections + if n == 0: + lines.append(0.0) + continue + # Truncate only valid points + points = section[0:n] + # Study if additional point is needed + if n < len(section): + y0 = section[n-1].y + z0 = section[n-1].z + y1 = section[n].y + z1 = section[n].z + if (Z > z0) and not (Math.isAprox(Z,z0)): + factor = (Z - z0) / (z1 - z0) + y = y0 + factor*(y1 - y0) + points.append(App.Base.Vector(x,y,Z)) + # Convert into array with n elements (Number of points by sections) + # with m elements into them (Number of points with the same height, + # typical of multibody) + section = [] + nPoints = 0 + j = 0 + while j < len(points)-1: + section.append([points[j]]) + k = j+1 + while(Math.isAprox(points[j].z, points[k].z)): + section[nPoints].append(points[k]) + k = k+1 + nPoints = nPoints + 1 + j = k + # Integrate line area + line = 0.0 + for j in range(0, len(section)-1): + for k in range(0, min(len(section[j])-1, len(section[j+1])-1)): + # y11,z11 ------- y01,z01 + # | | + # | | + # | | + # y10,z10 ------- y00,z00 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = y11 - y10 + dz = z11 - z10 + line = line + math.sqrt(dy*dy + dz*dz) + dy = y01 - y00 + dz = z01 - z00 + line = line + math.sqrt(dy*dy + dz*dz) + if(len(section[j]) < len(section[j+1])): + # y01,z01 ------- y11,z11 + # | __/ + # | __/ + # | / + # y00,z00 + k = len(section[j])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = y11 - y00 + dz = z11 - z00 + line = line + math.sqrt(dy*dy + dz*dz) + dy = y01 - y00 + dz = z01 - z00 + line = line + math.sqrt(dy*dy + dz*dz) + elif(len(section[j]) > len(section[j+1])): + # y01,z01 + # | \__ + # | \__ + # | \ + # y00,z00 ------- y10,z10 + k = len(section[j+1])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + dy = y01 - y00 + dz = z01 - z00 + line = line + math.sqrt(dy*dy + dz*dz) + dy = y01 - y10 + dz = z01 - z10 + line = line + math.sqrt(dy*dy + dz*dz) + elif(len(section[j]) == 1): + # y1,z1 ------- + # | + # | + # | + # y0,z0 ------- + k = 0 + y0 = abs(section[j][k].y) + z0 = section[j][k].z + y1 = abs(section[j+1][k].y) + z1 = section[j+1][k].z + dy = y1 - y0 + dz = z1 - z0 + line = line + math.sqrt(dy*dy + dz*dz) + lines.append(2.0*line) # 2x because only half ship is represented + # Add area if proceed + if i > 0: + dx = xCoord[i] - xCoord[i-1] + x = 0.5*(xCoord[i] + xCoord[i-1]) + line = 0.5*(lines[i] + lines[i-1]) + area = area + line*dx + return area + +def Moment(ship, draft, trim, disp, xcb): + """ Calculate triming 1cm ship moment. + @param ship Selected ship instance + @param draft Draft. + @param trim Trim in degrees. + @param disp Displacement at selected draft and trim. + @param xcb Bouyance center at selected draft and trim. + @return Moment to trim ship 1cm (ton m). + @note Moment is positive when produce positive trim. + """ + angle = math.degrees(math.atan2(0.01,0.5*ship.Length)) + newTrim = trim + angle + data = Displacement(ship,draft,newTrim) + mom0 = -disp*xcb + mom1 = -data[1]*data[2] + return mom1 - mom0 + +class Point: + """ Hydrostatics point, that conatins: \n + draft Ship draft [m]. \n + trim Ship trim [deg]. \n + disp Ship displacement [ton]. \n + xcb Bouyance center X coordinate [m]. + wet Wetted ship area [m2]. + mom triming 1cm ship moment [ton m]. + @note Moment is positive when produce positive trim. + """ + def __init__(self, ship, draft, trim): + """ Use all hydrostatics tools to define a hydrostatics + point. + @param ship Selected ship instance + @param draft Draft. + @param trim Trim in degrees. + """ + # Hydrostatics computation + areasData = Displacement(ship,draft,trim) + wettedArea = WettedArea(ship,draft,trim) + moment = Moment(ship,draft,trim,areasData[1],areasData[2]) + # Store final data + self.draft = draft + self.trim = trim + self.disp = areasData[1] + self.xcb = areasData[2] + self.wet = wettedArea + self.mom = moment From e73665fe1ac1fd48f876476b013a15dc92fa5b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Fri, 9 Mar 2012 10:51:43 +0100 Subject: [PATCH 23/27] Fixed copy directory --- src/Mod/Ship/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index 45b2916d2..058b9aec1 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -98,7 +98,7 @@ ADD_CUSTOM_TARGET(Ship ALL SOURCES ${all_files} ) -fc_copy_sources(Ship "${CMAKE_BINARY_DIR}/Mod/Ship" ${all_files}) +fc_copy_sources(Mod/Ship "${CMAKE_BINARY_DIR}/Mod/Ship" ${all_files}) INSTALL( FILES From a8621c26218034ba22b4917565bc0fa13bee7fe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Fri, 9 Mar 2012 10:52:18 +0100 Subject: [PATCH 24/27] Fixed some hydrostatics computation at monohull ships --- src/Mod/Ship/shipHydrostatics/Tools.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Mod/Ship/shipHydrostatics/Tools.py b/src/Mod/Ship/shipHydrostatics/Tools.py index d3bf8698d..ecef88028 100644 --- a/src/Mod/Ship/shipHydrostatics/Tools.py +++ b/src/Mod/Ship/shipHydrostatics/Tools.py @@ -64,6 +64,7 @@ def Displacement(ship, draft, trim): if z > Z: break n = n+1 + print('orig-> ', section[n-2:n], Z) # Discard invalid sections if n == 0: areas.append(0.0) @@ -80,6 +81,7 @@ def Displacement(ship, draft, trim): factor = (Z - z0) / (z1 - z0) y = y0 + factor*(y1 - y0) points.append(App.Base.Vector(x,y,Z)) + print('dest-> ', points[-3:]) # Convert into array with n elements (Number of points by sections) # with m elements into them (Number of points with the same height, # typical of multibody) @@ -89,11 +91,18 @@ def Displacement(ship, draft, trim): while j < len(points)-1: section.append([points[j]]) k = j+1 - while(Math.isAprox(points[j].z, points[k].z)): + last=False # In order to identify if last point has been append + while(k < len(points)): + if not Math.isAprox(points[j].z, points[k].z): + break section[nPoints].append(points[k]) + last=True k = k+1 nPoints = nPoints + 1 j = k + if not last: # Last point has not been added + section.append([points[len(points)-1]]) + print('Zeq-> ', section[-3:]) # Integrate area area = 0.0 for j in range(0, len(section)-1): From 58f55b4a2be15e384da297337a2848665ff5df58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Fri, 9 Mar 2012 11:38:43 +0100 Subject: [PATCH 25/27] Fixed hydrostatics virtual last point addition --- src/Mod/Ship/shipHydrostatics/Tools.py | 171 +++++++++++++------------ 1 file changed, 90 insertions(+), 81 deletions(-) diff --git a/src/Mod/Ship/shipHydrostatics/Tools.py b/src/Mod/Ship/shipHydrostatics/Tools.py index ecef88028..25737e7de 100644 --- a/src/Mod/Ship/shipHydrostatics/Tools.py +++ b/src/Mod/Ship/shipHydrostatics/Tools.py @@ -29,6 +29,88 @@ import FreeCADGui as Gui import Instance from shipUtils import Math +def convertSection(section, x, z): + """ Transform linear points distribution of full section + into double list, where points are gropued by height, and + reachs z maximum height. + @param section Ship section. + @param x Ship section x coordinate. + @param z Maximum section height. + @return Converted section, None if no valid section (i.e.- All section are over z) + """ + # Convert into array with n elements (Number of points by sections) + # with m elements into them (Number of points with the same height, + # that is typical of multibody) + points = [] + nPoints = 0 + j = 0 + while j < len(section)-1: + points.append([section[j]]) + k = j+1 + last=False # In order to identify if last point has been append + while(k < len(section)): + if not Math.isAprox(section[j].z, section[k].z): + break + points[nPoints].append(section[k]) + last=True + k = k+1 + nPoints = nPoints + 1 + j = k + if not last: # Last point has not been added + points.append([section[len(section)-1]]) + # Count the number of valid points + n = 0 + for j in range(0,len(points)): + Z = points[j][0].z + if Z > z: + break + n = n+1 + # Discard invalid sections + if n == 0: + return None + # Truncate only valid points + l = points[0:n] + # Study if additional point is needed + if n < len(points): + # Get last sections + pts1 = points[n] + pts0 = points[n-1] + if len(pts1) == len(pts0): + # Simple interpolation between points + # \----\-----|--------| + # \ | | / + # \ \ | | + # \----|--|-----/ + pts = [] + for i in range(0,len(pts1)): + y0 = pts0[i].y + z0 = pts0[i].z + y1 = pts1[i].y + z1 = pts1[i].z + factor = (z - z0) / (z1 - z0) + y = y0 + factor*(y1 - y0) + pts.append(App.Base.Vector(x,y,z)) + l.append(pts) + if len(pts1) > len(pts0): + # pts0 has been multiplied + # \---|---| + # \ | | + # \ | | + # \|---| + # @todo Only katamaran are involved, multiple points multiplication must be study + pts = [] + for i in range(0,len(pts1)): + y0 = pts0[min(len(pts0)-1,i)].y + z0 = pts0[min(len(pts0)-1,i)].z + y1 = pts1[i].y + z1 = pts1[i].z + factor = (z - z0) / (z1 - z0) + y = y0 + factor*(y1 - y0) + pts.append(App.Base.Vector(x,y,z)) + l.append(pts) + # @todo Only katamaran are involved, multiple points creation/destruction must be study + return l + def Displacement(ship, draft, trim): """ Calculate ship displacement. @param ship Selected ship instance @@ -57,52 +139,11 @@ def Displacement(ship, draft, trim): x = xCoord[i] # Get the maximum Z value Z = draft - x*math.tan(angle) - # Count the number of valid points - n = 0 - for j in range(0,len(section)): - z = section[j].z - if z > Z: - break - n = n+1 - print('orig-> ', section[n-2:n], Z) - # Discard invalid sections - if n == 0: + # Format section + section = convertSection(section, x, Z) + if not section: areas.append(0.0) - continue - # Truncate only valid points - points = section[0:n] - # Study if additional point is needed - if n < len(section): - y0 = section[n-1].y - z0 = section[n-1].z - y1 = section[n].y - z1 = section[n].z - if (Z > z0) and not (Math.isAprox(Z,z0)): - factor = (Z - z0) / (z1 - z0) - y = y0 + factor*(y1 - y0) - points.append(App.Base.Vector(x,y,Z)) - print('dest-> ', points[-3:]) - # Convert into array with n elements (Number of points by sections) - # with m elements into them (Number of points with the same height, - # typical of multibody) - section = [] - nPoints = 0 - j = 0 - while j < len(points)-1: - section.append([points[j]]) - k = j+1 - last=False # In order to identify if last point has been append - while(k < len(points)): - if not Math.isAprox(points[j].z, points[k].z): - break - section[nPoints].append(points[k]) - last=True - k = k+1 - nPoints = nPoints + 1 - j = k - if not last: # Last point has not been added - section.append([points[len(points)-1]]) - print('Zeq-> ', section[-3:]) + continue # Integrate area area = 0.0 for j in range(0, len(section)-1): @@ -208,43 +249,11 @@ def WettedArea(ship, draft, trim): x = xCoord[i] # Get the maximum Z value Z = draft - x*math.tan(angle) - # Count the number of valid points - n = 0 - for j in range(0,len(section)): - z = section[j].z - if z > Z: - break - n = n+1 - # Discard invalid sections - if n == 0: + # Format section + section = convertSection(section, x, Z) + if not section: lines.append(0.0) - continue - # Truncate only valid points - points = section[0:n] - # Study if additional point is needed - if n < len(section): - y0 = section[n-1].y - z0 = section[n-1].z - y1 = section[n].y - z1 = section[n].z - if (Z > z0) and not (Math.isAprox(Z,z0)): - factor = (Z - z0) / (z1 - z0) - y = y0 + factor*(y1 - y0) - points.append(App.Base.Vector(x,y,Z)) - # Convert into array with n elements (Number of points by sections) - # with m elements into them (Number of points with the same height, - # typical of multibody) - section = [] - nPoints = 0 - j = 0 - while j < len(points)-1: - section.append([points[j]]) - k = j+1 - while(Math.isAprox(points[j].z, points[k].z)): - section[nPoints].append(points[k]) - k = k+1 - nPoints = nPoints + 1 - j = k + continue # Integrate line area line = 0.0 for j in range(0, len(section)-1): From 223e49af2f5ab501d69a4becee76bbe22a6bf9e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Fri, 9 Mar 2012 13:38:55 +0100 Subject: [PATCH 26/27] Added stability hydrostatics --- src/Mod/Ship/shipHydrostatics/Plot.py | 36 ++- src/Mod/Ship/shipHydrostatics/Tools.py | 355 ++++++++++++++++++++++++- 2 files changed, 387 insertions(+), 4 deletions(-) diff --git a/src/Mod/Ship/shipHydrostatics/Plot.py b/src/Mod/Ship/shipHydrostatics/Plot.py index 72e81a0a8..5e4f4d327 100644 --- a/src/Mod/Ship/shipHydrostatics/Plot.py +++ b/src/Mod/Ship/shipHydrostatics/Plot.py @@ -59,6 +59,7 @@ class Plot(object): if self.execute(): return ImageGui.open(self.path + 'volume.png') + ImageGui.open(self.path + 'stability.png') def createDirectory(self): """ Create needed folder to write data and scripts. @@ -97,13 +98,16 @@ class Plot(object): Output.write(" # 3: Wetted surface [m2]\n") Output.write(" # 4: 1cm triming ship moment [ton m]\n") Output.write(" # 5: Bouyance center x coordinate\n") + Output.write(" # 6: Floating area\n") + Output.write(" # 7: KBt\n") + Output.write(" # 8: BMt\n") Output.write(" #\n") Output.write(" #################################################################\n") # Print data for i in range(0,len(drafts)): draft = drafts[i] point = Tools.Point(ship,draft,trim) - string = "%f %f %f %f %f\n" % (point.disp, point.draft, point.wet, point.mom, point.xcb) + string = "%f %f %f %f %f %f %f %f\n" % (point.disp, point.draft, point.wet, point.mom, point.xcb, point.farea, point.KBt, point.BMt) Output.write(string) # Close file Output.close() @@ -160,13 +164,28 @@ class Plot(object): Output.write("set style 1 line linetype 1 linewidth 1 colour rgb (0):(0):(0)\n") Output.write("set style 2 line linetype 1 linewidth 1 colour rgb (1):(0):(0)\n") Output.write("set style 3 line linetype 1 linewidth 1 colour rgb (0):(0):(1)\n") - Output.write("set style 4 line linetype 1 linewidth 1 colour rgb (1):(0):(1)\n") + Output.write("set style 4 line linetype 1 linewidth 1 colour rgb (0.1):(0.5):(0.1)\n") # Write plot call Output.write("# Plot\n") - Output.write("plot '%s' using 2:1 title '$\\bigtriangleup$' axes x1y1 with lines style 1, \\\n" % (self.dataFile)) + Output.write("plot '%s' using 2:1 title 'Draft' axes x1y1 with lines style 1, \\\n" % (self.dataFile)) Output.write(" '' using 3:1 title 'Wetted area' axes x2y1 with lines style 2, \\\n") Output.write(" '' using 4:1 title '1cm trim moment' axes x3y1 with lines style 3, \\\n") Output.write(" '' using 5:1 title 'XCB' axes x4y1 with lines style 4\n") + # Prepare second plot + Output.write("set output '%s'\n" % (self.path + 'stability.eps')) + Output.write("# X axis\n") + Output.write("set x2label '\\textit{Floating area} / $\\mathrm{m}^2$'\n") + Output.write("set x2tic\n") + Output.write("set x3label '$KB_{T}$ / $\\mathrm{m}$'\n") + Output.write("set x3tic\n") + Output.write("set x4label '$BM_{T}$ / $\\mathrm{m}$'\n") + Output.write("set x4tic\n") + # Write plot call + Output.write("# Plot\n") + Output.write("plot '%s' using 2:1 title 'Draft' axes x1y1 with lines style 1, \\\n" % (self.dataFile)) + Output.write(" '' using 6:1 title 'Floating area' axes x2y1 with lines style 2, \\\n") + Output.write(" '' using 7:1 title '$KB_{T}$' axes x3y1 with lines style 3, \\\n") + Output.write(" '' using 8:1 title '$BM_{T}$' axes x4y1 with lines style 4\n") # Close file self.layoutFile = filename Output.close() @@ -176,6 +195,7 @@ class Plot(object): """ Calls pyxplot in order to plot an save an image. @return True if error happens. """ + # Plot filename = self.path + 'volume' comm = "pyxplot %s" % (self.layoutFile) if os.system(comm): @@ -184,6 +204,16 @@ class Plot(object): msg = Translator.translate("Plot will not generated\n") FreeCAD.Console.PrintError(msg) return True + # Convert volume + comm = "gs -r300 -dEPSCrop -dTextAlphaBits=4 -sDEVICE=png16m -sOutputFile=%s.png -dBATCH -dNOPAUSE %s.eps" % (filename,filename) + if os.system(comm): + msg = Translator.translate("Can't execute ghostscript. Maybe is not installed?\n") + FreeCAD.Console.PrintError(msg) + msg = Translator.translate("Generated image will not converted to png\n") + FreeCAD.Console.PrintError(msg) + return True + # Convert stability + filename = self.path + 'stability' comm = "gs -r300 -dEPSCrop -dTextAlphaBits=4 -sDEVICE=png16m -sOutputFile=%s.png -dBATCH -dNOPAUSE %s.eps" % (filename,filename) if os.system(comm): msg = Translator.translate("Can't execute ghostscript. Maybe is not installed?\n") diff --git a/src/Mod/Ship/shipHydrostatics/Tools.py b/src/Mod/Ship/shipHydrostatics/Tools.py index 25737e7de..b36ed8d2e 100644 --- a/src/Mod/Ship/shipHydrostatics/Tools.py +++ b/src/Mod/Ship/shipHydrostatics/Tools.py @@ -355,6 +355,350 @@ def Moment(ship, draft, trim, disp, xcb): mom1 = -data[1]*data[2] return mom1 - mom0 +def FloatingArea(ship, draft, trim): + """ Calculate ship floating area. + @param ship Selected ship instance + @param draft Draft. + @param trim Trim in degrees. + @return Ship floating area. + """ + angle = math.radians(trim) + sections = Instance.sections(ship) + xCoord = ship.xSection[:] + lines = [] + area = 0.0 + if not sections: + return 0.0 + for i in range(0, len(sections)): + # Get the section + section = sections[i] + if len(section) < 2: # Empty section + lines.append(0.0) + continue + # Get the position of the section + x = xCoord[i] + # Get the maximum Z value + Z = draft - x*math.tan(angle) + # Format section + section = convertSection(section, x, Z) + if not section: + lines.append(0.0) + continue + # Get floating line length + line = 0.0 + flag = True # Even lines compute for floating areas, odd no + j = len(section)-1 + k = len(section[j])-1 + while k>0: + k = k-1 + if flag: + y0 = abs(section[j][k-1].y) + y1 = abs(section[j][k].y) + line = line + (y1 - y0) + flag = not flag + if flag: # Central body computation lefts + y = abs(section[j][0].y) + line = line + y + lines.append(2.0*line) # 2x because only half ship is represented + # Add area if proceed + if i > 0: + dx = xCoord[i] - xCoord[i-1] + x = 0.5*(xCoord[i] + xCoord[i-1]) + line = 0.5*(lines[i] + lines[i-1]) + area = area + line*dx + return area + +def KBT(ship, draft, trim, roll=0.0): + """ Calculate ship Keel to Bouyance center transversal distance. + @param ship Selected ship instance + @param draft Draft. + @param trim Trim in degrees. + @param roll Roll angle in degrees. + @return [KBTx, KBTy]: \n + KBTy : TRansversal KB y coordinate \n + KBTz : TRansversal KB z coordinate + """ + angle = math.radians(trim) + rAngle = math.radians(roll) + sections = Instance.sections(ship) + xCoord = ship.xSection[:] + areas = [] + vol = 0.0 + vMy = 0.0 + vMz = 0.0 + My = [] + Mz = [] + kb = [0.0,0.0] + if not sections: + return [[],0.0,0.0] + for i in range(0, len(sections)): + # ------------------------------------ + # Board + # ------------------------------------ + # Get the section + section = sections[i] + if len(section) < 2: # Empty section + areas.append(0.0) + continue + # Get the position of the section + x = xCoord[i] + # Get the maximum Z value + Z = draft - x*math.tan(angle) + # Format section + aux = convertSection(section, x, Z) + if not aux: + areas.append(0.0) + My.append(0.0) + Mz.append(0.0) + continue + # Correct by roll angle + pts = aux[len(aux)-1] + beam = pts[0].y + for i in range(1,len(pts)): + beam = max(beam, pts[i].y) + Z = Z - beam*math.tan(rAngle) + # Format section + section = convertSection(section, x, Z) + if not section: + areas.append(0.0) + My.append(0.0) + Mz.append(0.0) + continue + # Integrate area + area = 0.0 + momy = 0.0 + momz = 0.0 + for j in range(0, len(section)-1): + for k in range(0, min(len(section[j])-1, len(section[j+1])-1)): + # y11,z11 ------- y01,z01 + # | | + # | | + # | | + # y10,z10 ------- y00,z00 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = 0.5*((y00 - y10) + (y01 - y11)) + dz = 0.5*((z01 - z00) + (z11 - z10)) + y = 0.25*(y00 + y10 + y01 + y11) + z = 0.25*(z01 + z00 + z11 + z10) + area = area + dy*dz + momy = momy + y*dy*dz + momz = momz + z*dy*dz + if(len(section[j]) < len(section[j+1])): + # y01,z01 ------- y11,z11 + # | __/ + # | __/ + # | / + # y00,z00 + k = len(section[j])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = y01 - y11 + dz = z01 - z00 + y = 0.33*(y00 + y01 + y11) + z = 0.33*(z01 + z00 + z11) + area = area + 0.5*dy*dz + momy = momy + y*0.5*dy*dz + momz = momz + z*0.5*dy*dz + elif(len(section[j]) > len(section[j+1])): + # y01,z01 + # | \__ + # | \__ + # | \ + # y00,z00 ------- y10,z10 + k = len(section[j+1])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + dy = y00 - y10 + dz = z01 - z00 + y = 0.33*(y00 + y01 + y10) + z = 0.33*(z01 + z00 + z10) + area = area + 0.5*dy*dz + momy = momy + y*0.5*dy*dz + momz = momz + z*0.5*dy*dz + elif(len(section[j]) == 1): + # y1,z1 ------- + # | + # | + # | + # y0,z0 ------- + k = 0 + y0 = abs(section[j][k].y) + z0 = section[j][k].z + y1 = abs(section[j+1][k].y) + z1 = section[j+1][k].z + dy = 0.5 * (y0 + y1) + dz = z1 - z0 + y = 0.25*(y1 + y0) + z = 0.25*(z1 + z0) + area = area + dy*dz + momy = momy + y*dy*dz + momz = momz + z*dy*dz + # ------------------------------------ + # StarBoard + # ------------------------------------ + # Get the section + section = sections[i] + # Get the maximum Z value + Z = draft - x*math.tan(angle) + # Format section + aux = convertSection(section, x, Z) + if not aux: + areas.append(0.0) + My.append(0.0) + Mz.append(0.0) + continue + # Correct by roll angle + pts = aux[len(aux)-1] + beam = pts[0].y + for i in range(1,len(pts)): + beam = max(beam, pts[i].y) + Z = Z + beam*math.tan(rAngle) + # Format section + section = convertSection(section, x, Z) + if not section: + areas.append(0.0) + My.append(0.0) + Mz.append(0.0) + continue + # Integrate area + for j in range(0, len(section)-1): + for k in range(0, min(len(section[j])-1, len(section[j+1])-1)): + # y11,z11 ------- y01,z01 + # | | + # | | + # | | + # y10,z10 ------- y00,z00 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = 0.5*((y00 - y10) + (y01 - y11)) + dz = 0.5*((z01 - z00) + (z11 - z10)) + y = 0.25*(y00 + y10 + y01 + y11) + z = 0.25*(z01 + z00 + z11 + z10) + area = area + dy*dz + momy = momy - y*dy*dz + momz = momz + z*dy*dz + if(len(section[j]) < len(section[j+1])): + # y01,z01 ------- y11,z11 + # | __/ + # | __/ + # | / + # y00,z00 + k = len(section[j])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = y01 - y11 + dz = z01 - z00 + y = 0.33*(y00 + y01 + y11) + z = 0.33*(z01 + z00 + z11) + area = area + 0.5*dy*dz + momy = momy - y*0.5*dy*dz + momz = momz + z*0.5*dy*dz + elif(len(section[j]) > len(section[j+1])): + # y01,z01 + # | \__ + # | \__ + # | \ + # y00,z00 ------- y10,z10 + k = len(section[j+1])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + dy = y00 - y10 + dz = z01 - z00 + y = 0.33*(y00 + y01 + y10) + z = 0.33*(z01 + z00 + z10) + area = area + 0.5*dy*dz + momy = momy - y*0.5*dy*dz + momz = momz + z*0.5*dy*dz + elif(len(section[j]) == 1): + # y1,z1 ------- + # | + # | + # | + # y0,z0 ------- + k = 0 + y0 = abs(section[j][k].y) + z0 = section[j][k].z + y1 = abs(section[j+1][k].y) + z1 = section[j+1][k].z + dy = 0.5 * (y0 + y1) + dz = z1 - z0 + y = 0.25*(y1 + y0) + z = 0.25*(z1 + z0) + area = area + dy*dz + momy = momy - y*dy*dz + momz = momz + z*dy*dz + areas.append(area) + My.append(momy) + Mz.append(momz) + # Add volume & moment if proceed + if i > 0: + dx = xCoord[i] - xCoord[i-1] + x = 0.5*(xCoord[i] + xCoord[i-1]) + area = 0.5*(areas[i] + areas[i-1]) + momy = 0.5*(My[i] + My[i-1]) + momz = 0.5*(Mz[i] + Mz[i-1]) + vol = vol + area*dx + vMy = vMy + momy*dx + vMz = vMz + momz*dx + # Compute KBT + kb[0] = vMy / vol + kb[1] = vMz / vol + return kb + +def BMT(ship, draft, trim): + """ Calculate ship Bouyance center transversal distance. + @param ship Selected ship instance + @param draft Draft. + @param trim Trim in degrees. + @return BM Bouyance to metacenter height. + """ + nRoll = 2 + maxRoll = 7.0 + kb0 = KBT(ship,draft,trim) + BM = 0.0 + for i in range(0,nRoll): + roll = (maxRoll/nRoll)*(i+1) + kb = KBT(ship,draft,trim,roll) + # * M + # / \ + # / \ BM ==|> BM = (BB/2) / tan(alpha/2) + # / \ + # *-------* + # BB + BB = [kb[0] - kb0[0], kb[1] - kb0[1]] + BB = math.sqrt(BB[0]*BB[0] + BB[1]*BB[1]) + BM = BM + 0.5*BB/math.tan(math.radians(0.5*roll)) / nRoll # nRoll is the weight function + return BM + class Point: """ Hydrostatics point, that conatins: \n draft Ship draft [m]. \n @@ -362,7 +706,10 @@ class Point: disp Ship displacement [ton]. \n xcb Bouyance center X coordinate [m]. wet Wetted ship area [m2]. - mom triming 1cm ship moment [ton m]. + mom Triming 1cm ship moment [ton m]. + farea Floating area [m2]. + KBt Transversal KB height [m]. + BMt Transversal BM height [m]. @note Moment is positive when produce positive trim. """ def __init__(self, ship, draft, trim): @@ -376,10 +723,16 @@ class Point: areasData = Displacement(ship,draft,trim) wettedArea = WettedArea(ship,draft,trim) moment = Moment(ship,draft,trim,areasData[1],areasData[2]) + farea = FloatingArea(ship,draft,trim) + kb = KBT(ship,draft,trim) + bm = BMT(ship,draft,trim) # Store final data self.draft = draft self.trim = trim self.disp = areasData[1] self.xcb = areasData[2] self.wet = wettedArea + self.farea = farea self.mom = moment + self.KBt = kb[1] + self.BMt = bm From 8ae0c9ca7b4aa4a6f9b84224f64caa0cf25f0781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Sat, 10 Mar 2012 18:18:28 +0100 Subject: [PATCH 27/27] Hydrostatic coeffcients added. --- src/Mod/Ship/shipHydrostatics/Plot.py | 50 ++++++-- src/Mod/Ship/shipHydrostatics/Tools.py | 156 +++++++++++++++++++++++-- 2 files changed, 186 insertions(+), 20 deletions(-) diff --git a/src/Mod/Ship/shipHydrostatics/Plot.py b/src/Mod/Ship/shipHydrostatics/Plot.py index 5e4f4d327..8d5338e10 100644 --- a/src/Mod/Ship/shipHydrostatics/Plot.py +++ b/src/Mod/Ship/shipHydrostatics/Plot.py @@ -60,6 +60,7 @@ class Plot(object): return ImageGui.open(self.path + 'volume.png') ImageGui.open(self.path + 'stability.png') + ImageGui.open(self.path + 'coeffs.png') def createDirectory(self): """ Create needed folder to write data and scripts. @@ -93,21 +94,24 @@ class Plot(object): Output.write(" #\n") Output.write(" # File automatically exported by FreeCAD-Ship\n") Output.write(" # This file contains transversal areas data, filled with following columns:\n") - Output.write(" # 1: Ship displacement [ton]\n") - Output.write(" # 2: Draft [m]\n") - Output.write(" # 3: Wetted surface [m2]\n") - Output.write(" # 4: 1cm triming ship moment [ton m]\n") - Output.write(" # 5: Bouyance center x coordinate\n") - Output.write(" # 6: Floating area\n") - Output.write(" # 7: KBt\n") - Output.write(" # 8: BMt\n") + Output.write(" # 1: Ship displacement [ton]\n") + Output.write(" # 2: Draft [m]\n") + Output.write(" # 3: Wetted surface [m2]\n") + Output.write(" # 4: 1cm triming ship moment [ton m]\n") + Output.write(" # 5: Bouyance center x coordinate\n") + Output.write(" # 6: Floating area\n") + Output.write(" # 7: KBt\n") + Output.write(" # 8: BMt\n") + Output.write(" # 9: Cb (block coefficient)\n") + Output.write(" # 10: Cf (Floating coefficient)\n") + Output.write(" # 11: Cm (Main frame coefficient)\n") Output.write(" #\n") Output.write(" #################################################################\n") # Print data for i in range(0,len(drafts)): draft = drafts[i] point = Tools.Point(ship,draft,trim) - string = "%f %f %f %f %f %f %f %f\n" % (point.disp, point.draft, point.wet, point.mom, point.xcb, point.farea, point.KBt, point.BMt) + string = "%f %f %f %f %f %f %f %f %f %f %f\n" % (point.disp, point.draft, point.wet, point.mom, point.xcb, point.farea, point.KBt, point.BMt, point.Cb, point.Cf, point.Cm) Output.write(string) # Close file Output.close() @@ -186,6 +190,21 @@ class Plot(object): Output.write(" '' using 6:1 title 'Floating area' axes x2y1 with lines style 2, \\\n") Output.write(" '' using 7:1 title '$KB_{T}$' axes x3y1 with lines style 3, \\\n") Output.write(" '' using 8:1 title '$BM_{T}$' axes x4y1 with lines style 4\n") + # Prepare third plot + Output.write("set output '%s'\n" % (self.path + 'coeffs.eps')) + Output.write("# X axis\n") + Output.write("set x2label '$C_{B}$'\n") + Output.write("set x2tic\n") + Output.write("set x3label '$C_{F}$'\n") + Output.write("set x3tic\n") + Output.write("set x4label '$C_{M}$'\n") + Output.write("set x4tic\n") + # Write plot call + Output.write("# Plot\n") + Output.write("plot '%s' using 2:1 title 'Draft' axes x1y1 with lines style 1, \\\n" % (self.dataFile)) + Output.write(" '' using 9:1 title '$C_{B}$' axes x2y1 with lines style 2, \\\n") + Output.write(" '' using 10:1 title '$C_{F}$' axes x3y1 with lines style 3, \\\n") + Output.write(" '' using 11:1 title '$C_{M}$' axes x4y1 with lines style 4\n") # Close file self.layoutFile = filename Output.close() @@ -204,7 +223,7 @@ class Plot(object): msg = Translator.translate("Plot will not generated\n") FreeCAD.Console.PrintError(msg) return True - # Convert volume + # Convert volume image comm = "gs -r300 -dEPSCrop -dTextAlphaBits=4 -sDEVICE=png16m -sOutputFile=%s.png -dBATCH -dNOPAUSE %s.eps" % (filename,filename) if os.system(comm): msg = Translator.translate("Can't execute ghostscript. Maybe is not installed?\n") @@ -212,9 +231,18 @@ class Plot(object): msg = Translator.translate("Generated image will not converted to png\n") FreeCAD.Console.PrintError(msg) return True - # Convert stability + # Convert stability image filename = self.path + 'stability' comm = "gs -r300 -dEPSCrop -dTextAlphaBits=4 -sDEVICE=png16m -sOutputFile=%s.png -dBATCH -dNOPAUSE %s.eps" % (filename,filename) + if os.system(comm): + msg = Translator.translate("Can't execute ghostscript. Maybe is not installed?\n") + FreeCAD.Console.PrintError(msg) + msg = Translator.translate("Generated image will not converted to png\n") + FreeCAD.Console.PrintError(msg) + return True + # Convert coefficients image + filename = self.path + 'coeffs' + comm = "gs -r300 -dEPSCrop -dTextAlphaBits=4 -sDEVICE=png16m -sOutputFile=%s.png -dBATCH -dNOPAUSE %s.eps" % (filename,filename) if os.system(comm): msg = Translator.translate("Can't execute ghostscript. Maybe is not installed?\n") FreeCAD.Console.PrintError(msg) diff --git a/src/Mod/Ship/shipHydrostatics/Tools.py b/src/Mod/Ship/shipHydrostatics/Tools.py index b36ed8d2e..a2b1f2c65 100644 --- a/src/Mod/Ship/shipHydrostatics/Tools.py +++ b/src/Mod/Ship/shipHydrostatics/Tools.py @@ -120,15 +120,19 @@ def Displacement(ship, draft, trim): areas : Area of each section \n disp: Ship displacement \n xcb: X bouyance center coordinate + Cb: Block coefficient """ angle = math.radians(trim) sections = Instance.sections(ship) xCoord = ship.xSection[:] + minX = None + maxX = None + maxY = 0.0 areas = [] vol = 0.0 moment = 0.0 if not sections: - return [[],0.0,0.0] + return [[],0.0,0.0,0.0] for i in range(0, len(sections)): # Get the section section = sections[i] @@ -143,7 +147,10 @@ def Displacement(ship, draft, trim): section = convertSection(section, x, Z) if not section: areas.append(0.0) - continue + continue + maxX = x + if not minX: + minX = x # Integrate area area = 0.0 for j in range(0, len(section)-1): @@ -164,6 +171,7 @@ def Displacement(ship, draft, trim): dy = 0.5*((y00 - y10) + (y01 - y11)) dz = 0.5*((z01 - z00) + (z11 - z10)) area = area + dy*dz + maxY = max([maxY,y00,y10,y01,y11]) if(len(section[j]) < len(section[j+1])): # y01,z01 ------- y11,z11 # | __/ @@ -180,6 +188,7 @@ def Displacement(ship, draft, trim): dy = y01 - y11 dz = z01 - z00 area = area + 0.5*dy*dz + maxY = max([maxY,y00,y01,y11]) elif(len(section[j]) > len(section[j+1])): # y01,z01 # | \__ @@ -196,6 +205,7 @@ def Displacement(ship, draft, trim): dy = y00 - y10 dz = z01 - z00 area = area + 0.5*dy*dz + maxY = max([maxY,y00,y10,y01]) elif(len(section[j]) == 1): # y1,z1 ------- # | @@ -210,6 +220,7 @@ def Displacement(ship, draft, trim): dy = 0.5 * (y0 + y1) dz = z1 - z0 area = area + dy*dz + maxY = max([maxY,y0,y1]) areas.append(2.0*area) # 2x because only half ship is represented # Add volume & moment if proceed if i > 0: @@ -219,11 +230,14 @@ def Displacement(ship, draft, trim): vol = vol + area*dx moment = moment + area*dx*x # Compute displacement and xcb - disp = vol / 1.025 # rho = 1.025 ton/m3 (salt water density) - xcb = 0.0 + disp = vol / 1.025 # rho = 1.025 ton/m3 (salt water density) + xcb = 0.0 + cb = 0.0 if vol > 0.0: xcb = moment / vol - return [areas,disp,xcb] + block = (maxX-minX)*2.0*maxY*draft + cb = vol / block + return [areas,disp,xcb,cb] def WettedArea(ship, draft, trim): """ Calculate wetted ship area. @@ -360,15 +374,19 @@ def FloatingArea(ship, draft, trim): @param ship Selected ship instance @param draft Draft. @param trim Trim in degrees. - @return Ship floating area. + @return Ship floating area, and floating coefficient. """ angle = math.radians(trim) sections = Instance.sections(ship) xCoord = ship.xSection[:] lines = [] area = 0.0 + minX = None + maxX = None + maxY = 0.0 + cf = 0.0 if not sections: - return 0.0 + return [0.0, 0.0] for i in range(0, len(sections)): # Get the section section = sections[i] @@ -384,6 +402,9 @@ def FloatingArea(ship, draft, trim): if not section: lines.append(0.0) continue + maxX = x + if not minX: + minX = x # Get floating line length line = 0.0 flag = True # Even lines compute for floating areas, odd no @@ -395,10 +416,12 @@ def FloatingArea(ship, draft, trim): y0 = abs(section[j][k-1].y) y1 = abs(section[j][k].y) line = line + (y1 - y0) + maxY = max([maxY,y1,y0]) flag = not flag if flag: # Central body computation lefts y = abs(section[j][0].y) line = line + y + maxY = max([maxY,y]) lines.append(2.0*line) # 2x because only half ship is represented # Add area if proceed if i > 0: @@ -406,7 +429,9 @@ def FloatingArea(ship, draft, trim): x = 0.5*(xCoord[i] + xCoord[i-1]) line = 0.5*(lines[i] + lines[i-1]) area = area + line*dx - return area + if area: + cf = area / ( (maxX-minX) * 2.0*maxY ) + return [area, cf] def KBT(ship, draft, trim, roll=0.0): """ Calculate ship Keel to Bouyance center transversal distance. @@ -699,6 +724,112 @@ def BMT(ship, draft, trim): BM = BM + 0.5*BB/math.tan(math.radians(0.5*roll)) / nRoll # nRoll is the weight function return BM +def MainFrameCoeff(ship, draft): + """ Calculate main frame coefficient. + @param ship Selected ship instance + @param draft Draft. + @return Main frame coefficient + """ + sections = Instance.sections(ship) + xCoord = ship.xSection[:] + cm = 0.0 + if not sections: + return 0.0 + # Look for nearest to main frame section + sectionID = 0 + X = xCoord[0] + for i in range(1, len(sections)): + # Get the position of the section + x = xCoord[i] + if abs(x) < abs(X): + sectionID = i + X = x + # Get the section + section = sections[sectionID] + if len(section) < 2: # Empty section + return 0.0 + x = X + # Get the maximum Z value + Z = draft + # Format section + section = convertSection(section, x, Z) + if not section: + return 0.0 + # Integrate area + area = 0.0 + maxY = 0.0 + for j in range(0, len(section)-1): + for k in range(0, min(len(section[j])-1, len(section[j+1])-1)): + # y11,z11 ------- y01,z01 + # | | + # | | + # | | + # y10,z10 ------- y00,z00 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = 0.5*((y00 - y10) + (y01 - y11)) + dz = 0.5*((z01 - z00) + (z11 - z10)) + area = area + dy*dz + maxY = max([maxY,y00,y10,y01,y11]) + if(len(section[j]) < len(section[j+1])): + # y01,z01 ------- y11,z11 + # | __/ + # | __/ + # | / + # y00,z00 + k = len(section[j])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = y01 - y11 + dz = z01 - z00 + area = area + 0.5*dy*dz + maxY = max([maxY,y00,y01,y11]) + elif(len(section[j]) > len(section[j+1])): + # y01,z01 + # | \__ + # | \__ + # | \ + # y00,z00 ------- y10,z10 + k = len(section[j+1])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + dy = y00 - y10 + dz = z01 - z00 + area = area + 0.5*dy*dz + maxY = max([maxY,y00,y10,y01]) + elif(len(section[j]) == 1): + # y1,z1 ------- + # | + # | + # | + # y0,z0 ------- + k = 0 + y0 = abs(section[j][k].y) + z0 = section[j][k].z + y1 = abs(section[j+1][k].y) + z1 = section[j+1][k].z + dy = 0.5 * (y0 + y1) + dz = z1 - z0 + area = area + dy*dz + maxY = max([maxY,y0,y1]) + if maxY*draft > 0.0: + cm = area / (maxY*draft) + return cm + class Point: """ Hydrostatics point, that conatins: \n draft Ship draft [m]. \n @@ -710,6 +841,9 @@ class Point: farea Floating area [m2]. KBt Transversal KB height [m]. BMt Transversal BM height [m]. + Cb Block coefficient. + Cf Floating coefficient. + Cm Main frame coefficient. @note Moment is positive when produce positive trim. """ def __init__(self, ship, draft, trim): @@ -726,13 +860,17 @@ class Point: farea = FloatingArea(ship,draft,trim) kb = KBT(ship,draft,trim) bm = BMT(ship,draft,trim) + cm = MainFrameCoeff(ship,draft) # Store final data self.draft = draft self.trim = trim self.disp = areasData[1] self.xcb = areasData[2] self.wet = wettedArea - self.farea = farea + self.farea = farea[0] self.mom = moment self.KBt = kb[1] self.BMt = bm + self.Cb = areasData[3] + self.Cf = farea[1] + self.Cm = cm