Cleared unused tools

This commit is contained in:
Jose Luis Cercos-Pita 2014-05-03 14:35:10 +02:00 committed by wmayer
parent 12198fcf52
commit 6094db62f2
23 changed files with 6 additions and 4245 deletions

View File

@ -64,30 +64,7 @@ SET(ShipUtils_SRCS
)
SOURCE_GROUP("shiputils" FILES ${ShipUtils_SRCS})
SET(ShipWeights_SRCS
tankWeights/__init__.py
tankWeights/Preview.py
tankWeights/TaskPanel.py
tankWeights/TaskPanel.ui
)
SOURCE_GROUP("shipweights" FILES ${ShipWeights_SRCS})
SET(ShipCreateTank_SRCS
tankCreateTank/__init__.py
tankCreateTank/TaskPanel.py
tankCreateTank/TaskPanel.ui
)
SOURCE_GROUP("shipcreatetank" FILES ${ShipCreateTank_SRCS})
SET(ShipGZ_SRCS
tankGZ/__init__.py
tankGZ/PlotAux.py
tankGZ/TaskPanel.py
tankGZ/TaskPanel.ui
)
SOURCE_GROUP("shipgz" FILES ${ShipGZ_SRCS})
SET(all_files ${ShipMain_SRCS} ${ShipExamples_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS} ${ShipWeights_SRCS} ${ShipCreateTank_SRCS} ${ShipGZ_SRCS})
SET(all_files ${ShipMain_SRCS} ${ShipExamples_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS})
ADD_CUSTOM_TARGET(Ship ALL
SOURCES ${all_files}
@ -137,24 +114,6 @@ INSTALL(
DESTINATION
Mod/Ship/shipUtils
)
INSTALL(
FILES
${ShipWeights_SRCS}
DESTINATION
Mod/Ship/tankWeights
)
INSTALL(
FILES
${ShipCreateTank_SRCS}
DESTINATION
Mod/Ship/tankCreateTank
)
INSTALL(
FILES
${ShipGZ_SRCS}
DESTINATION
Mod/Ship/tankGZ
)
INSTALL(
FILES
${ShipMain_SRCS}

View File

@ -37,18 +37,7 @@ nobase_data_DATA = \
shipHydrostatics/Tools.py \
shipUtils/__init__.py \
shipUtils/Math.py \
shipUtils/Paths.py \
tankWeights/__init__.py \
tankWeights/Preview.py \
tankWeights/TaskPanel.py \
tankWeights/TaskPanel.ui \
tankCreateTank/__init__.py \
tankCreateTank/TaskPanel.py \
tankCreateTank/TaskPanel.ui \
tankGZ/__init__.py \
tankGZ/PlotAux.py \
tankGZ/TaskPanel.py \
tankGZ/TaskPanel.ui
shipUtils/Paths.py
CLEANFILES = $(BUILT_SOURCES)

View File

@ -119,62 +119,8 @@ class Hydrostatics:
'ToolTip': ToolTip}
class SetWeights:
def Activated(self):
import tankWeights
tankWeights.load()
def GetResources(self):
MenuText = QtCore.QT_TRANSLATE_NOOP(
'Ship_Weights',
'Set ship weights')
ToolTip = QtCore.QT_TRANSLATE_NOOP(
'Ship_Weights',
'Set the ship weights (tanks must be added later)')
return {'Pixmap': 'Weight',
'MenuText': MenuText,
'ToolTip': ToolTip}
class CreateTank:
def Activated(self):
import tankCreateTank
tankCreateTank.load()
def GetResources(self):
MenuText = QtCore.QT_TRANSLATE_NOOP(
'Ship_CreateTank',
'Create a new tank')
ToolTip = QtCore.QT_TRANSLATE_NOOP(
'Ship_CreateTank',
'Create a new ship tank')
return {'Pixmap': 'Tank',
'MenuText': MenuText,
'ToolTip': ToolTip}
class GZ:
def Activated(self):
import tankGZ
tankGZ.load()
def GetResources(self):
MenuText = QtCore.QT_TRANSLATE_NOOP(
'Ship_GZ',
'GZ curve')
ToolTip = QtCore.QT_TRANSLATE_NOOP(
'Ship_GZ',
'Transversal stability GZ curve computation')
return {'Pixmap': 'HydrostaticsIco',
'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())
FreeCADGui.addCommand('Ship_Weights', SetWeights())
FreeCADGui.addCommand('Ship_CreateTank', CreateTank())
FreeCADGui.addCommand('Ship_GZ', GZ())

File diff suppressed because one or more lines are too long

View File

@ -7,8 +7,6 @@
<file>icons/Ship_Logo.svg</file>
<file>icons/Ship_Module.svg</file>
<file>icons/Ship_OutlineDraw.svg</file>
<file>icons/Tank.png</file>
<file>icons/Weight.png</file>
<file>translations/Ship.qm</file>
<file>translations/Ship_af.qm</file>
<file>translations/Ship_cs.qm</file>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -1,721 +0,0 @@
/* XPM */
static char * Weight_xpm[] = {
"128 128 590 2",
" c None",
". c #5F5F5F",
"+ c #606060",
"@ c #60605F",
"# c #5F6060",
"$ c #616160",
"% c #606161",
"& c #616161",
"* c #626262",
"= c #626261",
"- c #616162",
"; c #616261",
"> c #767576",
", c #90908F",
"' c #A1A2A2",
") c #ACACAC",
"! c #A1A1A1",
"~ c #8F8E8F",
"{ c #777776",
"] c #636363",
"^ c #636364",
"/ c #636263",
"( c #636362",
"_ c #767676",
": c #9D9D9D",
"< c #B0B0B1",
"[ c #B1B1B0",
"} c #B0B0B0",
"| c #AFAFAF",
"1 c #9C9C9C",
"2 c #767777",
"3 c #656565",
"4 c #646463",
"5 c #868787",
"6 c #AFAFB0",
"7 c #AEAEAE",
"8 c #ADAEAE",
"9 c #ADADAE",
"0 c #868687",
"a c #666667",
"b c #676766",
"c c #656665",
"d c #7B7B7C",
"e c #AFAEAE",
"f c #ACADAC",
"g c #ACACAB",
"h c #7C7C7C",
"i c #686867",
"j c #686868",
"k c #666767",
"l c #A0A0A0",
"m c #ADADAD",
"n c #ADADAC",
"o c #ABAAAA",
"p c #ABABAA",
"q c #9E9E9E",
"r c #6A6969",
"s c #696969",
"t c #676768",
"u c #676868",
"v c #7F7F7F",
"w c #ABABAC",
"x c #A9A9A9",
"y c #A8A8A9",
"z c #80807F",
"A c #6B6B6B",
"B c #6B6C6B",
"C c #696A69",
"D c #939394",
"E c #AAAAAA",
"F c #A7A8A8",
"G c #A8A7A8",
"H c #929292",
"I c #6D6C6D",
"J c #6D6D6D",
"K c #6A6A6A",
"L c #A6A6A6",
"M c #9D9E9E",
"N c #6D6E6E",
"O c #6E6E6D",
"P c #6C6C6C",
"Q c #A0A09F",
"R c #A8A7A7",
"S c #A4A4A5",
"T c #706F6F",
"U c #706F70",
"V c #6D6E6D",
"W c #A6A5A6",
"X c #A3A3A3",
"Y c #919191",
"Z c #717070",
"` c #707171",
" . c #6F6F6F",
".. c #6F6F6E",
"+. c #818281",
"@. c #A4A4A4",
"#. c #A2A2A2",
"$. c #A2A2A1",
"%. c #727272",
"&. c #707071",
"*. c #717071",
"=. c #9A9A9A",
"-. c #A2A2A3",
";. c #A0A1A0",
">. c #989897",
",. c #737473",
"'. c #737474",
"). c #727172",
"!. c #808080",
"~. c #9F9F9F",
"{. c #9E9F9F",
"]. c #808181",
"^. c #747574",
"/. c #757575",
"(. c #737373",
"_. c #737374",
":. c #888888",
"<. c #A09FA0",
"[. c #9F9FA0",
"}. c #A09F9F",
"|. c #878888",
"1. c #767675",
"2. c #949494",
"3. c #9D9D9E",
"4. c #9D9C9C",
"5. c #9C9C9D",
"6. c #787778",
"7. c #777778",
"8. c #777777",
"9. c #8C8C8C",
"0. c #999A99",
"a. c #818181",
"b. c #797878",
"c. c #797879",
"d. c #605F60",
"e. c #605F5F",
"f. c #606160",
"g. c #616061",
"h. c #626162",
"i. c #616262",
"j. c #636262",
"k. c #626363",
"l. c #636463",
"m. c #646464",
"n. c #646564",
"o. c #646465",
"p. c #656564",
"q. c #656666",
"r. c #666666",
"s. c #666565",
"t. c #676666",
"u. c #676767",
"v. c #686768",
"w. c #686767",
"x. c #696869",
"y. c #5F5F60",
"z. c #616060",
"A. c #626161",
"B. c #626263",
"C. c #636464",
"D. c #656464",
"E. c #656566",
"F. c #696868",
"G. c #6A6A69",
"H. c #69696A",
"I. c #B3B3B3",
"J. c #B3B2B2",
"K. c #B2B2B2",
"L. c #B2B2B1",
"M. c #B2B1B1",
"N. c #B1B1B1",
"O. c #B0B1B1",
"P. c #AFB0AF",
"Q. c #AEAFAF",
"R. c #ACADAD",
"S. c #ABABAB",
"T. c #AAABAA",
"U. c #AAA9AA",
"V. c #6B6B6A",
"W. c #6B6C6C",
"X. c #6C6B6C",
"Y. c #B2B3B3",
"Z. c #B2B3B2",
"`. c #B2B1B2",
" + c #B1B2B1",
".+ c #B1B1B2",
"++ c #B1B0B0",
"@+ c #B0AFB0",
"#+ c #AFAEAF",
"$+ c #AEADAE",
"%+ c #ADACAC",
"&+ c #ACACAD",
"*+ c #ABACAC",
"=+ c #ACABAB",
"-+ c #AAAAAB",
";+ c #A9A9AA",
">+ c #A8A8A8",
",+ c #6D6C6C",
"'+ c #6C6D6D",
")+ c #B1B2B2",
"!+ c #B0B1B0",
"~+ c #AFB0B0",
"{+ c #AEAFAE",
"]+ c #AFAFAE",
"^+ c #AEADAD",
"/+ c #ACABAC",
"(+ c #A9AAAA",
"_+ c #A9A8A9",
":+ c #A7A7A7",
"<+ c #A6A7A6",
"[+ c #6E6E6E",
"}+ c #B1B0B1",
"|+ c #ADAEAD",
"1+ c #ADACAD",
"2+ c #A9A8A8",
"3+ c #A7A8A7",
"4+ c #A7A6A7",
"5+ c #A5A5A6",
"6+ c #A6A6A5",
"7+ c #A6A5A5",
"8+ c #A5A5A5",
"9+ c #6F6F70",
"0+ c #5F605F",
"a+ c #B3B2B3",
"b+ c #AAABAB",
"c+ c #A9AAA9",
"d+ c #A4A5A5",
"e+ c #A3A4A4",
"f+ c #A4A3A3",
"g+ c #A3A3A4",
"h+ c #B0AFAF",
"i+ c #AEAEAF",
"j+ c #A8A9A8",
"k+ c #A7A7A8",
"l+ c #A7A7A6",
"m+ c #A7A6A6",
"n+ c #A5A4A4",
"o+ c #A4A3A4",
"p+ c #A3A4A3",
"q+ c #A3A3A2",
"r+ c #B2B2B3",
"s+ c #AAAAA9",
"t+ c #A6A6A7",
"u+ c #A5A6A6",
"v+ c #A5A6A5",
"w+ c #A4A5A4",
"x+ c #A4A4A3",
"y+ c #A1A2A1",
"z+ c #A1A1A0",
"A+ c #737273",
"B+ c #747374",
"C+ c #AEAEAD",
"D+ c #A6A7A7",
"E+ c #A2A3A2",
"F+ c #A2A1A2",
"G+ c #A0A1A1",
"H+ c #A1A0A1",
"I+ c #A0A0A1",
"J+ c #747474",
"K+ c #B0B0AF",
"L+ c #ABACAB",
"M+ c #ABAAAB",
"N+ c #A5A4A5",
"O+ c #A3A2A3",
"P+ c #A2A1A1",
"Q+ c #9FA09F",
"R+ c #9E9F9E",
"S+ c #757676",
"T+ c #AAA9A9",
"U+ c #A5A5A4",
"V+ c #A2A3A3",
"W+ c #A1A1A2",
"X+ c #9F9E9E",
"Y+ c #9E9D9D",
"Z+ c #9C9D9D",
"`+ c #9D9D9C",
" @ c #777877",
".@ c #A8A8A7",
"+@ c #9FA0A0",
"@@ c #9F9E9F",
"#@ c #9D9E9D",
"$@ c #9C9D9C",
"%@ c #9B9C9C",
"&@ c #787879",
"*@ c #676867",
"=@ c #A9A9A8",
"-@ c #9E9E9D",
";@ c #9C9C9B",
">@ c #9B9B9B",
",@ c #9B9B9A",
"'@ c #9A9B9B",
")@ c #797A79",
"!@ c #797A7A",
"~@ c #7A797A",
"{@ c #686969",
"]@ c #9D9C9D",
"^@ c #9A9B9A",
"/@ c #999A9A",
"(@ c #999999",
"_@ c #999899",
":@ c #7A7B7B",
"<@ c #7B7B7B",
"[@ c #A3A2A2",
"}@ c #A1A0A0",
"|@ c #9E9E9F",
"1@ c #9C9B9C",
"2@ c #9C9B9B",
"3@ c #9A9A99",
"4@ c #9A999A",
"5@ c #989998",
"6@ c #989898",
"7@ c #979898",
"8@ c #989797",
"9@ c #979797",
"0@ c #7C7C7D",
"a@ c #6B6A6A",
"b@ c #6B6A6B",
"c@ c #000000",
"d@ c #9F9F9E",
"e@ c #9B9A9A",
"f@ c #9A9999",
"g@ c #989899",
"h@ c #969796",
"i@ c #969696",
"j@ c #7D7E7D",
"k@ c #7E7E7E",
"l@ c #9B9B9C",
"m@ c #999898",
"n@ c #979897",
"o@ c #969697",
"p@ c #969595",
"q@ c #959596",
"r@ c #959595",
"s@ c #959594",
"t@ c #959495",
"u@ c #7E7F7F",
"v@ c #6C6D6C",
"w@ c #9E9D9E",
"x@ c #979798",
"y@ c #969596",
"z@ c #969695",
"A@ c #949594",
"B@ c #939494",
"C@ c #949493",
"D@ c #939493",
"E@ c #807F80",
"F@ c #9B9C9B",
"G@ c #969797",
"H@ c #959696",
"I@ c #959494",
"J@ c #949394",
"K@ c #939393",
"L@ c #939293",
"M@ c #929392",
"N@ c #939292",
"O@ c #818282",
"P@ c #6E6F6F",
"Q@ c #989999",
"R@ c #979696",
"S@ c #939392",
"T@ c #929393",
"U@ c #919291",
"V@ c #919190",
"W@ c #828283",
"X@ c #828382",
"Y@ c #707070",
"Z@ c #9B9A9B",
"`@ c #9A9A9B",
" # c #949595",
".# c #929291",
"+# c #929191",
"@# c #919091",
"## c #909090",
"$# c #908F90",
"%# c #8F8F90",
"&# c #848383",
"*# c #838384",
"=# c #848484",
"-# c #717171",
";# c #999998",
"># c #979697",
",# c #909190",
"'# c #919090",
")# c #8F8F8F",
"!# c #8E8E8E",
"~# c #8E8F8E",
"{# c #858484",
"]# c #858585",
"^# c #727372",
"/# c #99999A",
"(# c #959695",
"_# c #949495",
":# c #949393",
"<# c #919292",
"[# c #908F8F",
"}# c #8F8F8E",
"|# c #8F8E8E",
"1# c #8E8F8F",
"2# c #8E8D8E",
"3# c #8E8D8D",
"4# c #8D8E8D",
"5# c #8D8C8D",
"6# c #8D8D8D",
"7# c #868686",
"8# c #747473",
"9# c #929192",
"0# c #909091",
"a# c #8D8E8E",
"b# c #8D8D8E",
"c# c #8C8D8D",
"d# c #8B8C8B",
"e# c #878787",
"f# c #878887",
"g# c #747475",
"h# c #747575",
"i# c #979796",
"j# c #8E8E8F",
"k# c #8E8E8D",
"l# c #8D8D8C",
"m# c #8B8C8C",
"n# c #8B8B8B",
"o# c #8A8B8B",
"p# c #8B8A8A",
"q# c #8A8A8A",
"r# c #888988",
"s# c #898989",
"t# c #8F9090",
"u# c #8D8C8C",
"v# c #8C8B8C",
"w# c #8B8B8A",
"x# c #8C8C8B",
"y# c #8A8A8B",
"z# c #89898A",
"A# c #898A89",
"B# c #8A8989",
"C# c #888788",
"D# c #8C8B8B",
"E# c #777878",
"F# c #8B8A8B",
"G# c #8A8B8A",
"H# c #8A898A",
"I# c #8A8A89",
"J# c #888989",
"K# c #898888",
"L# c #888887",
"M# c #868786",
"N# c #797978",
"O# c #797979",
"P# c #929293",
"Q# c #878788",
"R# c #878687",
"S# c #868586",
"T# c #858485",
"U# c #7A7A7A",
"V# c #898A8A",
"W# c #898889",
"X# c #888889",
"Y# c #888787",
"Z# c #878786",
"`# c #868685",
" $ c #858685",
".$ c #838483",
"+$ c #8F908F",
"@$ c #7B7C7C",
"#$ c #8C8C8D",
"$$ c #898988",
"%$ c #878686",
"&$ c #868585",
"*$ c #848585",
"=$ c #858584",
"-$ c #838383",
";$ c #828282",
">$ c #838282",
",$ c #7D7C7C",
"'$ c #858586",
")$ c #838484",
"!$ c #838382",
"~$ c #818182",
"{$ c #828181",
"]$ c #808180",
"^$ c #919192",
"/$ c #7E7D7D",
"($ c #8C8D8C",
"_$ c #838283",
":$ c #828383",
"<$ c #828281",
"[$ c #818180",
"}$ c #7F807F",
"|$ c #7E7E7F",
"1$ c #7E7F7E",
"2$ c #7F7E7F",
"3$ c #858686",
"4$ c #848384",
"5$ c #818081",
"6$ c #818080",
"7$ c #807F7F",
"8$ c #7F7F7E",
"9$ c #7F7F80",
"0$ c #909191",
"a$ c #8B8B8C",
"b$ c #848584",
"c$ c #848483",
"d$ c #7E7E7D",
"e$ c #7E7D7E",
"f$ c #7D7D7D",
"g$ c #828182",
"h$ c #7F8080",
"i$ c #7D7C7D",
"j$ c #7C7D7D",
"k$ c #7C7D7C",
"l$ c #7C7C7B",
"m$ c #7B7C7B",
"n$ c #7D7E7E",
"o$ c #7D7D7E",
"p$ c #7D7D7C",
"q$ c #7C7B7C",
"r$ c #7B7B7A",
"s$ c #7A7B7A",
"t$ c #7A7A7B",
"u$ c #7A7A79",
"v$ c #787979",
"w$ c #848485",
"x$ c #7F7E7E",
"y$ c #7C7B7B",
"z$ c #7A7979",
"A$ c #787878",
"B$ c #787777",
"C$ c #787877",
"D$ c #808081",
"E$ c #787978",
"F$ c #777677",
"G$ c #767776",
"H$ c #7B7A7A",
"I$ c #767677",
"J$ c #757576",
"K$ c #757475",
"L$ c #747373",
"M$ c #727373",
"N$ c #737372",
"O$ c #737272",
"P$ c #7B7A7B",
"Q$ c #757675",
"R$ c #757574",
"S$ c #717272",
"T$ c #717172",
"U$ c #777676",
"V$ c #70706F",
"W$ c #79797A",
"X$ c #757474",
"Y$ c #727271",
"Z$ c #727171",
"`$ c #6F6E6F",
" % c #767575",
".% c #6F6E6E",
"+% c #6E6F6E",
"@% c #6E6D6D",
"#% c #6D6D6E",
"$% c #6D6D6C",
"%% c #717271",
"&% c #6C6C6D",
"*% c #6B6B6C",
"=% c #717170",
"-% c #6F706F",
";% c #6E6D6E",
">% c #6C6C6B",
",% c #6A6B6B",
"'% c #6A6B6A",
")% c #707170",
"!% c #6F7070",
"~% c #6A6A6B",
"{% c #6E6E6F",
"]% c #696A6A",
"^% c #696968",
"/% c #686968",
"(% c #666766",
"_% c #6C6B6B",
":% c #676667",
"<% c #6A696A",
"[% c #656465",
"}% c #666566",
"|% c #666665",
"1% c #646565",
"2% c #646364",
"3% c #646363",
"4% c #989798",
"5% c #686869",
"6% c #626362",
"7% c #606061",
"8% c #B3B3B2",
"9% c #A8A9A9",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" . . + @ + # + ",
" + + $ + % & & & * * = ",
" - - ; > , ' ) ! ~ { ] ] ^ ",
" / ( _ : < [ < } } | | 1 2 3 3 ",
" 4 4 5 } 6 | | 7 7 8 9 0 a b ",
" 3 c d e 7 7 f ) g h i j ",
" k k l m n o p q r s ",
" t u v ) w x y z A B ",
" C s D o E F G H I J ",
" K A l x L M N O ",
" P P Q R S 1 T U ",
" V V H L W X X Y Z ` ",
" ...+.@.S #.$.+.%.%. ",
" &.*.=.-.X ;.l >.,.'. ",
" ).%.!.! ! ! ~.~.{.].^./. ",
" (._.:.<.[.}.~. q q q M |.1._ ",
" /./.v 2.q M 3.: : 4.5.H !.6.7. ",
" 2 { 8.!.9.2.0.2.9.a.b.b.c. ",
" . . . . . . . . . . . . . . . . . . . . . . . . . . d.. e.@ f.f.g.& & h.& = i.j.j.j.k.] ] l.4 m.n.o.p.3 3 q.r.s.r.r.t.t.u.u.j v.w.j j x. ",
" . . . . . . . . . . . . . . . . . . . . . . . @ d.y.+ z.z.f.$ & A.A.= * * j.B.] ] C.m.4 m.m.D.p.p.3 E.E.r.r.t.r.u.u.u.u t i j j x.F.s s G.H.K K ",
" . . . . I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.J.K.K.K.L.M.N.O.} } } } } P.| | Q.7 7 8 m m 9 m f R.) ) ) S.S.S.S.T.E E U.E x V.A W.X. ",
" . . . I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.Y.Z.K.`. +M..+N.++N.++} @+| | | | e #+7 $+$+m m %+&+) ) ) *+=+g S.o E -+;+E ;+x x x >+>+>+F G ,+'+J ",
" . . I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.J.I.K.K.K.K.)+M.[ ++!+} ~+} ~+| | {+]+{+$+7 $+^+m n n %+) /+w S.S.S.o E E E U.(+x x x _+>+>+>+:+R :+:+<+:+L O [+ ",
" . . . I.I.I.I.I.I.I.I.I.I.I.I.I.I.J.Z.K.K..+`.N.N.}+++} ~+} 6 | | | e 7 7 7 m |+m &+1+f ) *+*+w S.T.-+o E E E (+x x 2+2+>+>+3+F R :+4+L L L 5+6+7+8+@. .9+T ",
" 0+@ I.I.I.I.I.I.I.I.I.Y.a+Z.K.K.L.N.N.[ !+} } } ~+} 6 | {+7 7 7 $+m ^+m ) ) 1+) g /+S.S.S.b+E E E (+c+x x y >+>+>+F F :+:+:+L L L W W 5+8+S d+@.@.e+f+g+Z &. ",
" & $ I.I.I.I.I.I.J.K.K. +L.N.N.!+} } h+| | 6 | | {+i+7 7 8 m R.R.) ) ) ) *+w S.b+b+E E E (+x x _+j+y >+G G 3+k+:+l+m+m+L 7+5+5+d+8+n+@.o+o+p+X q+X #.#.#.).%. ",
" & * * r+K.L.)+.+N.N.++N.!+} } h+@+| | | 7 7 7 9 m m 1+&+&+f ) ) w S.S.o E T.s+s+x (+x 2+j+y >+F k+:+:+4+t+t+L u+u+v+v+8+8+w+@.x+o+@.X X q+-.-.#.' y+! ! z+A+(.B+ ",
" ] / +.+N.N.} !+} @+@+P.| | ]+i+7 |+C+m m m &+f f g *+=+S.S.S.o E E U.s+(+x x j+2+>+F k+k+:+D+m+L L 6+8+7+8+8+8+n+@.@.o+x+f+X -.E+#.' F+' ! ! ;.G+H+I+}.}.<.J+/. ",
" 4 m.m.!+K+@+~+h+| #+7 {+7 C+^+8 m m &+&+) g L+S.S.S.p M+E U.s+x x x x 2+2+>+R F k+:+<+l+L L L W 8+v+N+w+@.S x+x+X X q+X O+E+F+P+F+! ! H+I+;.Q l Q+~.~.{.~.R+q S+_ _ ",
" 3 3 h+| | {+e 7 ^+^+^+m m ) ) ) ) =+w S.S.b+-+T.U.c+T+;+x x 2+2+>+>+R :+:+D+L L L L 6+7+8+N+U+w+@.e+x+o+p+V+X #.E+' y+W+! H+l l l l [.[.~.{.~.q X+q 3.Y+: : Z+`+8. @ ",
" r.r.7 m 7 ^+m n R.) ) L+*+=+L+S.-+b+E E (+T+x x x >+j+>+.@G :+l+:+D+L L u+7+5+8+N+8+@.@.f+X f+f+q+X #.#.y+' $.! ! ;.I+l Q +@Q+}.@@~.q q q #@3.: : : $@$@1 1 %@%@&@c. ",
" u.w.*@m &+&+) /+w S.S.S.S.o o E x c+T+x y =@>+>+R G :+:+:+m+:+6+7+6+8+8+8+n+S @.e+@.x+X q+#.#.E+#.y+! ! ! z+I+l l +@l }.~.~.R+R+q -@#@: : `+5.1 1 ;@>@>@>@>@,@'@=.)@!@~@ ",
" j {@g S.S.S.S.E p E c+T+U.x x 2+_+>+>+F R R t+:+m+L L 5+v+8+8+8+N+w+@.@.f+p+f+X X #.#.#.! ! ! ! I+z+l l [.~.~.~.{.X+q q M M : : ]@5.1 1 %@;@>@>@>@>@^@=./@(@(@0.(@_@:@<@ ",
" H.s r M+T.E E T+;+x =@x y >+>+G F :+:+D+L L L L 7+8+8+n+U+@.@.p+p+X X O+V+#.[@#.$.P+! ! }@G+l <.Q [.[.~.@@|@q q M #@: : : 4.1 1 1@2@>@>@>@=.=.=.3@4@3@(@(@_@5@6@7@8@9@h h 0@ ",
" a@b@T+;+x =@y >+>+>+3+G :+:+l+c@c@c@c@c@c@d+8+N+@.@.@.X o+X X q+#.#.P+P+W+! ! G+H+l +@+@<.~.~.d@R+q q 3.M 3.: ]@Z+5.1@2@1 >@>@=.=.e@=.=.f@(@(@(@g@6@6@6@6@9@8@h@9@i@i@i@j@k@ ",
" P W.j+>+G R 3+:+:+t+:+L L 7+7+c@c@c@c@c@c@@.@.X X O+X #.' #.F+P+! G+H+l l l ~.Q ~.~.X+q R+-@M M #@Z+]@4.1 1 ;@2@l@>@e@^@^@=.4@=.0.(@(@5@m@6@>.8@n@9@9@i@o@i@p@q@p@r@s@t@v u@ ",
" J J v@:+:+:+l+L 5+6+5+8+d+d+@.@.c@c@c@c@c@c@#.#.#.#.' P+! ! ! I+l Q ~.~.~.d@q X+q q w@3.: : 5.1 4.1 %@2@>@>@>@e@=.=.3@4@0._@_@5@5@6@6@x@9@8@9@9@i@i@i@y@z@r@r@t@A@2.B@C@D@!.E@!. ",
" O [+L L v+8+8+8+8+S @.e+x+x+X X c@c@c@c@c@c@! H+! }@}@l l l [.~.{.d@q q M w@Y+: : ]@1 $@1 1 %@F@>@'@'@=.=.4@=.(@(@g@(@6@6@7@9@n@9@9@o@G@i@z@H@y@r@r@I@r@2.2.2.J@K@K@L@M@N@H a.O@ ",
" P@T N+w+n+@.@.g+X X V+O+V+[@#.y+c@c@c@c@c@c@l Q Q+~.~.~.{.{.q q q : : `+: `+1 ;@2@F@l@>@,@^@=.=./@/@(@Q@Q@m@5@6@x@x@x@9@9@i@R@i@z@r@q@r@r@t@A@A@D 2.K@D@K@S@T@H H U@H Y Y V@W@X@ ",
" Y@Y@Y@p+g+X [@X #.-.#.F+W+! ! ! ! c@c@c@c@c@c@|@q q q M 3.: : ]@]@5.1 1 1 >@>@^@Z@=.`@=.f@f@(@Q@m@6@Q@6@x@9@8@9@9@o@R@i@i@y@q@r@ #I@I@2.J@B@K@K@S@N@M@H .#+#.#Y Y V@@#####$#%#&#*#=# ",
" -#-#-.O+#.' ! P+W+z+}@I+}@l l Q [.c@c@c@c@c@c@Y+: ]@Z+: 1 1 %@>@>@>@>@'@=.=./@3@(@(@;#6@6@6@6@7@9@n@>#9@i@R@i@i@q@r@r@ #s@2.2.J@D D@K@S@K@H N@H +#Y Y Y ,#'#####, $#)#)#)#!#~#!#{#]# ",
" %.^#! ! ! }@z+}@l +@+@~.~.X+{.R+q c@c@c@c@c@c@1 1 ;@;@F@>@=.e@'@=./#3@f@(@Q@_@5@m@>.>.n@9@G@R@>#o@i@(#z@H@r@t@2._#2.:#B@D K@N@T@H H .#<#Y Y Y Y ######$#[#)#}#|#1#|#!#2#3#4#5#6#7#7# ",
" (.(.8#l l l ~.[.d@~.q X+q Y+#@3.: Z+c@c@c@c@c@c@>@>@^@`@=.=./@c@c@c@c@c@c@6@>.8@9@9@h@9@i@i@c@c@c@c@c@c@2.2.2.c@c@c@c@c@c@H U@9#U@Y Y Y 0#####%#)#)#)#)#!#}#a#b#b#6#c#5#c#9.9.9.d#e#f#e# ",
" g#h#~.|@@@|@q -@q #@: : : 4.$@F@%@%@c@c@c@c@c@c@4@4@(@(@Q@Q@c@c@c@c@c@c@i#i#o@i@z@i@H@r@c@c@c@c@c@c@c@c@c@N@M@c@c@c@c@c@c@Y '#'#####%#%#)#)#j#!#!#!#k#!#6#6#5#9.l#9.9.m#d#n#o#o#p#q#r#s# ",
" S+/.S+q q 3.: ]@$@`+4.1 %@l@>@Z@,@e@=.c@c@c@c@c@c@(@m@6@>.8@n@c@c@c@c@c@i@y@q@r@r@s@s@2.c@c@c@c@c@c@c@c@c@c@c@U@c@c@c@c@c@c@t#, )#1#}#|#!#!#2#4#6#6#c#u#9.9.v#n#n#n#w#q#q#q#q#q#s#s#s#q#q#p# ",
" 2 8.`+`+1 1 %@1 F@2@>@>@^@=./@3@4@/@(@c@c@c@c@c@c@9@9@9@>#h@c@c@c@c@c@r@r@t@I@2.B@D@K@K@c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@|#!#!#6#b#6#5#l#9.9.9.x#9.n#n#n#o#y#q#z#A#B#s#s#r#:.:.f#C#f#d#D# ",
" 7.E#%@l@>@>@`@'@e@3@=.4@(@(@5@5@6@6@6@c@c@c@c@c@c@i@i@r@r@c@c@c@c@c@c@K@K@D@K@S@S@L@H c@c@c@c@c@c@c@##$#$#$#c@c@c@c@c@c@c@c@6#6#9.5#9.9.d#D#n#n#F#q#G#q#H#I#A#s#J#K#K#:.C#C#L#e#e#M#7#7#9.9. ",
" N#c.O#e@=.=.=.(@0.(@(@_@5@>.6@7@9@9@9@G@c@c@c@c@c@c@s@r@r@c@c@c@c@c@c@S@S@P#H U@Y Y Y Y c@c@c@c@c@c@)#~ 1#~#!#2#c@c@c@c@c@c@c@x#n#9.n#n#w#G#q#I#H#B#A#s#r#s#:.:.:.Q#L#e#R#R#7#7#S#7#]#]#T#a#!#~# ",
" ~@U#f@f@(@Q@m@g@7@>.x@n@9@i@9@i@H@y@r@y@c@c@c@c@c@c@2.D c@c@c@c@c@c@H U@Y Y V@,#,###, c@c@c@c@c@c@c@a#a#k#6#5#6#c@c@c@c@c@c@c@o#y#q#q#I#s#V#W#s#X#:.:.Y#:.C#e#Z#7#7#`#7# $]#]#T#]#{#=#=#=#.$)#+$ ",
" <@@$6@8@9@x@9@9@o@o@i@i@y@H@r@r@ #I@A@2.c@c@c@c@c@c@M@c@c@c@c@c@c@Y 0#####$#)#)#)#1#~#c@c@c@c@c@c@u#6##$9.9.D#D#d#c@c@c@c@c@c@A#s#$$J#X#r#:.:.f#e#e#%$R#7#7#&$]#`#*$=$=$=#=#=#*#-$-$-$;$W@>$,#Y ",
" h h ,$9@i@i@i@i@y@H@r@r@r@r@_#2.J@:#K@K@N@c@c@c@c@c@c@c@c@c@c@c@c@##$#%#)#1#|#~#!#a#a#6#c@c@c@c@c@c@D#9.n#o#p#q#q#B#c@c@c@c@c@c@:.|.:.L#e#5 Z#R#7#7#'$ $]#]#{#=#=#=#=#)$&#-$-$W@!$X@;$~${$a.]$H H ^$ ",
" j@/$H@y@p@r@r@t@2.2.2.2.J@:#K@K@P#M@H H +#c@c@c@c@c@c@c@c@c@c@c@c@c@!#2#k#b#3#5#c##$($9.c@c@c@c@c@c@o#q#V#z#B#s#s#W#c@c@c@c@c@c@e#e#0 7#`#`#S#]#]#=$T#=#=#)$*#-$-$_$:$;$;$<$O@{$a.]$[$!.!.!.v }$K@:# ",
" |$1$2$s@2.2.C@:#D@K@K@K@H M@H H U@Y Y Y 0###c@c@c@c@c@c@c@c@c@c@c@c@c@c#5##$9.9.m#D#v#n#o#c@c@c@c@c@c@s#J#$$:.:.:.L#Y#c@c@c@c@c@c@`#3$]#]#]#*$]#=#*#4$)$-$!$X@!$;$;$~$a.a.].5$5$6$!.}$7$v 8$v u@2$2.2.r@ ",
" 9$}$:#B@K@K@L@H N@<#H <#<#@#0$0$######, +$)#c@c@c@c@c@c@c@c@c@c@c@c@c@c@a$D#y#p#q#q#q#q#s#c@c@c@c@c@c@C#e#:.e#e#5 %$7#c@c@c@c@c@c@b$=#c$=#-$-$-$W@;$;$;$;$+.a.a.a.[$[$!.!.!.}$v u@2$k@k@k@d$e$f$,$f$r@z@ ",
" a.].L@T@H U@+#U@Y Y Y ######, +$)#)#j#!#!#k#c@c@c@c@c@c@c@c@a$c@c@c@c@c@p#q#I#B#s#s#K#s#K#c@c@c@c@c@c@%$%$7#7#'$'$]#{#c@c@c@c@c@c@-$-$:$!$X@g$~$O@+.a.a.[$!.!.}$E@h$v 2$2$|$k@k@f$/$f$i$j$k$h l$@$m$9@9@ ",
" g$~$<$+#Y @#'#V@t#[#[#%#)#1#|#j#!#k#b#6#4#l#l#c@c@c@c@c@c@n#w#y#c@c@c@c@c@c@W#J#:.:.:.|.e#e#c@c@c@c@c@c@3$]#*$=$=$=#4$*#c@c@c@c@c@c@<$a.+.a.a.[$].!.z E@z v v v |$1$k@n$k@f$o$f$j$p$0@h q$<@<@r$r$s$s$6@6@5@ ",
" >$-$,###+$[#[#)#}#}#!#!#b#b#6#6#6#6##$u#9.x#d#c@c@c@c@c@c@I#B#s#s#c@c@c@c@c@c@Q#5 Z#M#7#7#7#c@c@c@c@c@c@=#c$c$-$-$-$>$X@c@c@c@c@c@c@a.[$!.!.7$h$v 8$8$8$1$k@n$j@/$f$f$j$0@h q$<@l$<@<@t$U#U#~@u$O#O#O#v$f@/@ ",
" c$)$=#)#)#!#~#!#3#a#4#6#5#9.#$9.v#m#n#n#n#w#G#q#c@c@c@c@c@c@$$K#:.C#c@c@c@c@c@c@7#7# $ $]#T#w$c@c@c@c@c@c@c@!$X@;$;$a.<$c@c@c@c@c@c@c@v v v k@x$k@k@k@o$o$f$k$f$i$h l$q$y$<@<@<@t$U#U#u$O#z$c.&@b.A$E#B$C$,@^@,@ ",
" ]#]#!#6#k#3#6#6#l#($9.9.m#n#n#n#F#y#q#I#V#z#s#s#c@c@c@c@c@c@e#e#M#M#7#c@c@c@c@c@c@b$=#=#)$.$-$-$c@c@c@c@c@c@g${$a.!.a.D$c@c@c@c@c@c@c@x$k@d$/$f$f$j$p$h h h c@c@c@c@c@c@U#U#z$~@O#b.E$c.A$A$C$7.8.8.F$G$_ _ 1 1 ",
" 7#7##$9.c#9.x#n#n#n#n#n#p#q#I#H#s#s#s#s#J#:.:.L#c@c@c@c@c@c@3$ $&$]#]#c@c@c@c@c@c@-$-$>$>$;$;$O@c@c@c@c@c@c@c@!.E@9$v c@c@c@c@c@c@c@c@f$f$0@0@h <@l$y$<@t$H$c@c@c@c@c@c@c.O#c.&@A$A$8.B$8.{ I$_ > S+/.J$/.h#: #@ ",
" e#e#Y#v#n#n#o#p#q#q#q#A#z#s#J#K#X#:.:.Q#e#e#e#Z#0 c@c@c@c@c@c@b$*$b$=#=#)$c@c@c@c@c@c@O@;$a.a.]$].6$c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@d <@<@r$:@<@H$U#u$u$U#c@c@c@c@c@c@7.7.8.I$2 I$_ S+S+S+/.g#/./.^.J+'.8#q @@{. ",
" :.:.F#p#q#q#q#A#s#J#s#X#:.:.|.L#Y#5 %$7#7#7# $`#]#c@c@c@c@c@c@c$-$-$-$>$;$;$c@c@c@c@c@c@!.!.!.}$v v c@c@c@c@c@c@c@c@c@c@c@h c@c@c@c@c@c@r$U#U#~@u$O#O#N#E$A$A$c@c@c@c@c@c@2 _ _ 1.J$J$/.K$h#J+J+L$'.(.M$N$%.O$%.l +@ ",
" z#V#z#$$W#X#r#:.:.Q#e#Q#R#Z#%$7#S#'$]#]#]#]#=#{#=#c@c@c@c@c@c@W@;$;$+.a.a.5$c@c@c@c@c@c@v u@1$1$k@k@d$c@c@c@c@c@c@c@c@c@<@P$c@c@c@c@c@c@z$O#v$b.A$A$A$B$B$8.8.c@c@c@c@c@c@Q$K$J+R$J+J+B+L$'.(.(.%.O$%.S$T$-#-#` H+! ",
" p#F#w#:.:.:.Y#e#Z#Z#7#7#7#`#&$]#]#T#b$=#=#c$-$*#-$!$c@c@c@c@c@c@a.].]$]$!.E@}$9$c@c@c@c@c@c@e$f$f$f$f$i$h h c@c@c@c@c@s$U#U#u$c@c@c@c@c@c@A$ @6. @8.{ 2 U$_ _ _ c@c@c@c@c@c@B+J+_.(.A+A+^#%.%.%.%.S$` *.-#Y@Y@U V$#.q+E+ ",
" v#9.e#5 e#7#7#S#3$]#]#]#*$=$b$4$&#-$-$-$:$_$;$;$<$<${$a.].]$!.!.!.z v 8$v 8$x$k@k@d$j@f$f$p$f$h l$m$d <@<@:@U#t$u$W$O#O#O#v$v$c@c@c@c@c@c@{ { G$_ _ _ /./.h#X$^.^.8#(.,.(.(.A+%.%.Y$Z$S$-#-#*.Z Y@Y@U U . .`$`$[+[+e+o+ ",
" c#5#6#7#`#]#]#=$=$w$=#c$=#-$4$-$_$X@;$;${$a.{$a.a.a.6$!.h$7$}$2$2$k@k@k@n$/$f$f$f$k$k$h h q$m$<@P$r$U#U#U#U#u$O#O#c.E$A$E#7. @7.c@c@c@c@c@c@J$ %/./.X$J+J+_.B+(.(.A+M$^#%.%.S$S$-#-#*.&.Z Y@U . ....%+%[+[+@%#%#%J $%U+8+8+ ",
" 2#!#*$b$w$=#.$-$-$-$W@-$;$;$;${${$a.a.!.!.!.h$h$9$v v 2$2$1$e$k@k@j@p$h ,$h h l$h <@<@<@U#s$U#U#W$W$O#c@c@c@c@c@c@8.E#8.2 8._ c@c@c@c@c@c@R$g#J+_.8#,.(.A+M$%.A+%%S$-#-#-#` Y@Y@Y@V$ .9+ .[+`$.%[+[+N J J I &%,+P P P *%<+<+ ",
" ~ )#-$-$-$:$_$>$;$g$g$+.a.a.6$5$!.!.E@7$v v |$|$k@k@k@f$/$f$k$h k$h @$l$<@<@:@<@r$U#~@u$z$)@O#b.A$E$C$c@c@c@c@c@c@c@S+1.S+Q$c@c@c@c@c@c@c@L$(.(.N$%.%.%.Z$).-#-#=%*.Y@Y@U -% . . .[++%O V ;%J J J v@P W.>%A A A ,%'%V.K :+3+ ",
" )###,#;$;$g$a.+.a.a.[$a.!.h$9$E@v 8$v x$x$n$e$/$f$f$i$0@k$h q$q$d <@H$t$U#U#~@U#!@O#v$&@A$b.7.6.7.8.8.F$8.c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@O$%.S$Y$-#-#=%` )%Y@!%9+T T ..%P@[+N ;%O J J '+$%I P P B A A a@b@~%K r s s s F.2+=@_+ ",
" Y Y a.a.a.5$!.]$E@z z v u@u@k@x$k@e$f$f$j$f$h 0@h h d <@<@<@H$U#U#U#u$O#O#N#A$E$A$A$C$A$8.8.U$_ _ > > _ /./.c@c@c@c@c@c@c@c@c@c@c@c@c@c@c@-#Z )%&.Y@Y@T !% . .{%+%[+[+N V @%I $%,+&%P W.P A A A ,%K K G.]%s s s x.j j j u w.E E ",
" S@M@!.E@}$v v v 8$1$k@k@k@e$f$f$j$h k$h y$q$<@<@U#r$U#U#u$U#O#v$E$N#b.A$B$ @8.8.{ I$U$2 > %S+Q$h#/.g#J+,.J+,.c@c@c@c@c@c@c@c@c@c@c@c@` Y@!%!%T . .`$[+[+N O J J J $%I P P P P A A A ,%'%K s H.H.s ^%/%^%j t u t u.u.(%b a S.L+ ",
" D K@C@v u@k@k@k@j@f$/$f$f$h h h d d <@<@P$:@H$u$U#!@z$O#&@O#c.A$E#6.8.8.F$F$G$_ _ %> /.X$/.^.J+J+_.J+(.(.(.A+^#%.Y$c@c@c@c@c@c@c@c@T . .P@P@{%[+O N N J J $%P ,+B _%*%_%,%b@,%K K K H.s s s j j j i *@u.u.k :%(%a r.3 c s.3 ) R.1+ ",
" 2.s@k@e$j@j@p$f$p$h h q$<@<@<@s$t$t$U#U#W$O#O#c.A$A$A$A$ @7.8.{ { I$_ Q$J$> /./.g#J+J+J+J+8#(.(.M$A+%.%.S$T$-#-#*.)%Y@Y@U Y@-% .+%{%+%[+[+;%@%J $%&%P P X.X._%A A A V.,%K <%C C s /%s ^%u j u.u.u.u.a :%r.r.E.3 3 p.p.[%m.m.m.] 9 ^+ ",
" z@i@H@,$j$h @$m$d <@<@P$U#U#)@U#u$O#E$b.b.A$A$6.C$7.8.G$I$_ _ _ S+Q$/.K$R$^.J+'.(._.(.(.(.O$O$%.%.-#-#-#-#-#)%V$Y@T -% . . .{%[+N N J J J v@,+P _%>%X.B A '%A K G.G.<%r s /%{@j j j v.*@u.t.t.r.r.}%E.|%3 1%o.p.m.2%m.] 3%] / j.j.#+| | ",
" 9@9@h l$<@<@t$H$U#u$W$O#O#O#O#A$b.A$E# @8.8.8.I$_ _ /.S+1./.R$/.J+J+L$8#(.(.(.^#A+%.S$Z$%%-#*.-#)%=%Y@T V$-% ...`$+%[+O J J J '+&%J P P X._%A A V.A K K ]%C r ^%{@^%j j v.*@w.u.u.:%t.r.r.c q.3 1%1%3 m.4 ] 4 ] ] / * * * A.& & f.& < ++ ",
" 4%6@H$U#!@z$W$O#O#b.c.A$A$C$7.7.8.I$U$G$_ /.1.1././.R$^.J+_._.'.(.(.^#A+%.%.Z$T$-#-#=%)%Y@Y@T T . .`$`$+%[+[+O @%J ,+&%P P P W._%A A A K K K K G.s ^%F.s j u u j u u.k b r.|%s.s.3 3 [%p.[%m.m.] ^ ] ] k.( * = * - & $ % z.+ + # + .+.+ ",
" _@(@(@O#E$E$A$A$6.8.C$8.8.8._ _ _ S+S+/././.X$X$J+J+(.L$(.(.N$M$%.%.%%%%-#-#Y@)%Z 9+Y@ . . .`$+%[+O N O #%J J v@$%P P A *%A V.,%~%a@K K s s ^%^%5%/%i u.*@u.u.b r.r.r.|%3 s.3 3 1%m.m.m.] m.] 6%] * * i.- - - & + 7%+ + + y.. . . . . a+I.I. ",
" =.=.A$A$B$8. @I$F$G$G$_ S+ %/./.^.J+^.8#J+B+(.(.O$A+%.%.Y$%.T$-#-#=%Y@Y@!%-%U . ...[++%[+O @%J J '+P v@P W.B _%A A ,%,%K K <%s s {@{@^%j v.i t u.u.t.a r.r.r.E.E.3 o.D.m.m.C.l.3%] ( / j.* = A.& & g.g.z.+ d.y.. . . . . . . . . . . . I.I. ",
" >@>@>@8.8._ G$> > _ S+R$g#^.J+J+8#_.(.(.N$^#O$%.T$-#-#-#-#=%Y@Y@Y@!%9+ .[+P@..[+[+O J J J ,+$%P P B W.*%A ~%K K K <%s <%s F.5%/%j u v.u.w.u.k t.r.r.3 }%3 [%D.1%m.m.4 C.2%] ] ( 6%* A.- & & & + + + d.0+y.. . . . . . . . . . . . . . . . I.I.I. ",
" 1 1 _ J$/.J$/.R$J+R$J+8#_.(.(.M$O$O$%.Y$S$T$=%-#Z &.Y@Y@ .T ...`$[+[+N [+N J I '+v@P P W._%A A ,%A K ]%K C s s s s /%j v.w.j u.u.k :%r.|%r.q.3 3 3 n.m.m.2%C.] ] / B.* * * A.h.& z.+ + + 0++ 0+0+. . . . . . . . . . . . . . . . . . . . . I.I. ",
" : 3.R$K$J+J+(.L$(.A+N$N$%.%.Y$-#T$-#&.&.` Y@-%V$ . ...+%{%[+N [+J J ,+&%P P P P A A A A K K K K G.s s x.F.5%j j w.u.u.a u.r.r.r.3 q.c 1%1%o.m.m.2%C.] ] ] k.6%* = & ; & $ f.f.d.@ d.. . . . . . . . . . . . . . . . . . . . . . . . . . . . I.I. ",
" |@d@8#(.(.A+^#%.Y$-#-#-#-#*.&.Y@Y@Y@9+9+ .+%+%[+[+[+[+#%J J v@P P W.*%_%A A a@'%K K H.C <%x.F.5%j j i i *@u.:%b r.r.r.}%3 3 3 [%o.o.2%m.^ ^ ] / 6%j.= h.= h.& & f.+ + + y.y.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I.I. ",
" Q+[.l %.Y$Y$-#-#-#&.Z !%V$9+ . . . ..%[+V [+J J J v@J P P X._%A A a@V.~%]%K r s s s {@j j j i u.u.u.k (%r.}%|%c 3 1%p.3 m.^ C.] ] ] * * j.h.- ; & % 7%f.+ + + e.e.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I.I.I. ",
" ! ! -#)%Y@V$V$9+ . ...{%[+O [+@%J J '+I $%P P P A B A ~%b@V.<%r C s s s /%j j *@w.i u.u.k r.r.r.3 3 3 3 D.m.m.] 3%] ] 6%k.* * * = h.& & g.f.+ + y.# d.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I.I. ",
" #.#.E+U ..%[+{%[+V @%[+J J v@v@P B W.*%A V.a@'%K r <%C H.s /%j j j i *@u.u.k b t.r.q.|%|%3 3 n.1%4 m.3%] ] j.B.j.* * * & & & g.+ f.+ . # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I.I.I. ",
" f+x+@.@.N+d+N+8+u+5+u+L L l+l+<+:+:+F >+>+>+2+2+x x c+(+E E T.E b+S.g S.g ) ) f n m m m 8 $+^+7 i+e 7 | | ~+K+K+++}+[ }+N.N.K.`.K.Z.K.8%I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I. ",
" 8+8+5+L L L <+D+:+4+F .@:+>+>+>+9%x x T+U.E U.E b+b+S.S.g w ) ) f R.n m m m ^+7 8 7 7 ]+Q.| | P.h+} < N.}+N.N.)+ +)+K.Z.Y.8%I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I.I. ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" "};

View File

@ -1,176 +0,0 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* 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
import Part
# Qt library
from PyQt4 import QtGui,QtCore
# Module
from TankInstance import *
from shipUtils import Paths
class TaskPanel:
def __init__(self):
self.ui = Paths.modulePath() + "/tankCreateTank/TaskPanel.ui"
def accept(self):
# Create new ship instance
obj = App.ActiveDocument.addObject("Part::FeaturePython","Tank")
ShipTank(obj, self.solid, self.form.level.value(), self.form.dens.value())
if not obj.IsShipTank:
msg = QtGui.QApplication.translate("ship_console", "Tank has not been created",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintError(msg + '\n')
ViewProviderShipTank(obj.ViewObject)
App.ActiveDocument.recompute()
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.level = form.findChild(QtGui.QDoubleSpinBox, "Level")
form.dens = form.findChild(QtGui.QDoubleSpinBox, "Density")
self.form = form
# Initial values
if self.initValues():
return True
self.retranslateUi()
# Connect Signals and Slots
QtCore.QObject.connect(form.level, QtCore.SIGNAL("valueChanged(double)"), self.onLevel)
QtCore.QObject.connect(form.dens , QtCore.SIGNAL("valueChanged(double)"), self.onDens)
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):
""" Get selected geometry.
@return False if sucessfully find valid geometry.
"""
self.solid = None
solids = []
selObjs = Gui.Selection.getSelection()
if not selObjs:
msg = QtGui.QApplication.translate("ship_console",
"Tank objects can only be created on top of structure geometry (no object selected)",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintError(msg + '\n')
msg = QtGui.QApplication.translate("ship_console",
"Please create a tank geometry before using this tool",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintError(msg + '\n')
return True
for i in range(0, len(selObjs)):
solid = selObjs[i]
if solid.isDerivedFrom('Part::Feature'):
# Get shape
shape = solid.Shape
if not shape:
continue
solid = shape
if not solid.isDerivedFrom('Part::TopoShape'):
return None
# Get shells
shells = solid.Shells
if not shells:
continue
# Build solids
for s in shells:
solids.append(Part.Solid(s))
if not solids:
msg = QtGui.QApplication.translate("ship_console",
"Tank objects can only be created on top of structure geometry (no solids can't be computed)",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintError(msg + '\n')
msg = QtGui.QApplication.translate("ship_console",
"Please create a tank geometry before using this tool",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintError(msg + '\n')
return True
self.solid = Part.CompSolid(solids)
return False
def retranslateUi(self):
""" Set user interface locale strings.
"""
self.form.setWindowTitle(QtGui.QApplication.translate("shiptank_create","Create a new tank",
None,QtGui.QApplication.UnicodeUTF8))
name = QtGui.QApplication.translate("shiptank_create","Filling level", None,QtGui.QApplication.UnicodeUTF8) + " (%)"
self.form.findChild(QtGui.QLabel, "LevelLabel").setText(name)
name = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">\n<html><body>'
name = name + QtGui.QApplication.translate("shiptank_create","Fluid density", None,QtGui.QApplication.UnicodeUTF8)
name = name + '(kg/m<span style=" vertical-align:super;">3</span>)</body></html>'
self.form.findChild(QtGui.QLabel, "DensityLabel").setText(name)
def onLevel(self, value):
""" Method called when tank filling level has been modified.
@param value Changed value.
"""
pass
def onDens(self, value):
""" Method called when fluid density has been modified.
@param value Changed value.
"""
pass
def createTask():
panel = TaskPanel()
Gui.Control.showDialog(panel)
if panel.setupUi():
Gui.Control.closeDialog(panel)
return None
return panel

View File

@ -1,131 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskPanel</class>
<widget class="QWidget" name="TaskPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>260</width>
<height>180</height>
</rect>
</property>
<property name="windowTitle">
<string>Create new ship tank</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="ShipDataBox">
<property name="minimumSize">
<size>
<width>240</width>
<height>160</height>
</size>
</property>
<property name="title">
<string>Fluid</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0">
<property name="spacing">
<number>6</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="LevelLabel">
<property name="text">
<string>Filling level (%)</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="Level">
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="DensityLabel">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Density (kg/m&lt;span style=&quot; vertical-align:super;&quot;&gt;3&lt;/span&gt;)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="Density">
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>1000000.000000000000000</double>
</property>
<property name="singleStep">
<double>10.000000000000000</double>
</property>
<property name="value">
<double>998.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,36 +0,0 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* 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()

View File

@ -1,154 +0,0 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* 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
# Qt library
from PyQt4 import QtGui,QtCore
# FreeCAD modules
import FreeCAD,FreeCADGui
from FreeCAD import Base
import Part, Image, ImageGui
# FreeCADShip modules
from shipUtils import Paths
header = """ #################################################################
##### #### ### #### ##### # # ### ####
# # # # # # # # # # # #
# ## #### #### # # # # # # # # # # #
#### # # # # # # # ##### # # ## ## ##### # ####
# # #### #### # # # # # # # # # #
# # # # # # # # # # # # # #
# # #### #### ### # # #### ##### # # ### #
#################################################################
"""
class Plot(object):
def __init__(self, x, y, disp, draft, trim):
""" Constructor. performs plot and show it (Using pyxplot).
@param x Roll angles [deg].
@param y GZ value [m].
@param disp Ship displacement [tons].
@param draft Ship draft [m].
@param trim Ship trim angle [deg].
"""
# Try to plot
self.plot(x,y,disp,draft,trim)
# Save data
if self.createDirectory():
return
if self.saveData(x,y):
return
def plot(self, x, y, disp, draft, trim):
""" Perform GZ stability plot.
@param x X coordinates.
@param y Transversal areas.
@param disp Ship displacement [tons].
@param draft Ship draft [m].
@param trim Ship trim angle [deg].
@return True if error happens.
"""
# Create plot
try:
import Plot
plt = Plot.figure('GZ')
except ImportError:
msg = QtGui.QApplication.translate("ship_console", "Plot module is disabled, can't perform plot",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintWarning(msg + '\n')
return True
# Plot areas curve
gz = Plot.plot(x,y,r'GZ')
gz.line.set_linestyle('-')
gz.line.set_linewidth(3.0)
gz.line.set_color((0.0, 0.0, 0.0))
# Add some additional data
ax = Plot.axes()
addInfo = r"""$\bigtriangleup = %g \; \mathrm{tons}$
$T = %g \; \mathrm{m}$
$Trim = %g^\circ$""" % (disp, draft, trim)
ax.text(x[-1] - 0.001*(x[-1] - x[0]), max(y) - 0.01*(max(y)-min(y)), addInfo,
verticalalignment='top',horizontalalignment='right', fontsize=20)
# Write axes titles
Plot.xlabel(r'$x \; \mathrm{m}$')
Plot.ylabel(r'$GZ \; \mathrm{m}$')
ax.xaxis.label.set_fontsize(20)
ax.yaxis.label.set_fontsize(20)
# Show grid
Plot.grid(True)
# End
plt.update()
return False
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 = QtGui.QApplication.translate("ship_console", "Can't create folder",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintError(msg + ':\n\t' + "\'"+ self.path + "\'\n")
return True
return False
def saveData(self,x,y):
""" Write data file.
@param x Roll angles.
@param y GZ value.
@return True if error happens.
"""
# Open the file
filename = self.path + 'gz.dat'
try:
Output = open(filename, "w")
except IOError:
msg = QtGui.QApplication.translate("ship_console", "Can't write to file",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintError(msg + ':\n\t' + "\'"+ filename + "\'\n")
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 GZ stability parameter, filled with following columns:\n")
Output.write(" # 1: Roll angles [deg]\n")
Output.write(" # 2: GZ [m]\n")
Output.write(" #\n")
Output.write(" #################################################################\n")
# Print data
for i in range(0, len(x)):
string = "%f %f\n" % (x[i], y[i])
Output.write(string)
# Close file
Output.close()
self.dataFile = filename
msg = QtGui.QApplication.translate("ship_console", "Data saved",
None,QtGui.QApplication.UnicodeUTF8)
FreeCAD.Console.PrintMessage(msg + ':\n\t' + "\'"+ self.dataFile + "\'\n")
return False

View File

@ -1,419 +0,0 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* 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 PlotAux
from Instance import *
from TankInstance import *
from shipUtils import Paths
from shipHydrostatics import Tools as Hydrostatics
class TaskPanel:
def __init__(self):
self.ui = Paths.modulePath() + "/tankGZ/TaskPanel.ui"
self.ship = None
self.tanks = {}
self.running = False
def accept(self):
if not self.ship:
return False
if self.running:
return
# Get general data
disp = self.computeDisplacement()
draft = self.computeDraft(disp[0], self.form.trim.value())
trim = self.form.trim.value()
# Get roll angles
roll0 = self.form.roll0.value()
roll1 = self.form.roll1.value()
nRoll = self.form.nRoll.value()
dRoll = (roll1 - roll0) / (nRoll - 1)
roll = []
GZ = []
msg = QtGui.QApplication.translate("ship_console","Computing GZ",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintMessage(msg + "...\n")
loop=QtCore.QEventLoop()
timer=QtCore.QTimer()
timer.setSingleShot(True)
QtCore.QObject.connect(timer,QtCore.SIGNAL("timeout()"),loop,QtCore.SLOT("quit()"))
self.running = True
for i in range(0, nRoll):
App.Console.PrintMessage("\t%d/%d\n" % (i+1,nRoll))
roll.append(i*dRoll)
GZ.append(self.computeGZ(draft[0], trim, roll[-1]))
timer.start(0.0)
loop.exec_()
if(not self.running):
break
PlotAux.Plot(roll, GZ, disp[0]/1000.0, draft[0], trim)
return True
def reject(self):
if not self.ship:
return False
if self.running:
self.running = False
return
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.tanks = form.findChild(QtGui.QListWidget, "Tanks")
form.disp = form.findChild(QtGui.QLabel, "DisplacementLabel")
form.draft = form.findChild(QtGui.QLabel, "DraftLabel")
form.update = form.findChild(QtGui.QPushButton, "UpdateData")
form.trim = form.findChild(QtGui.QDoubleSpinBox, "Trim")
form.autoTrim = form.findChild(QtGui.QPushButton, "TrimAutoCompute")
form.roll0 = form.findChild(QtGui.QDoubleSpinBox, "StartAngle")
form.roll1 = form.findChild(QtGui.QDoubleSpinBox, "EndAngle")
form.nRoll = form.findChild(QtGui.QSpinBox, "NAngle")
self.form = form
# Initial values
if self.initValues():
return True
self.retranslateUi()
# Connect Signals and Slots
QtCore.QObject.connect(form.tanks,QtCore.SIGNAL("itemSelectionChanged()"),self.onTanksSelection)
QtCore.QObject.connect(form.update,QtCore.SIGNAL("pressed()"),self.onUpdate)
QtCore.QObject.connect(form.trim,QtCore.SIGNAL("valueChanged(double)"),self.onTrim)
QtCore.QObject.connect(form.autoTrim,QtCore.SIGNAL("pressed()"),self.onAutoTrim)
QtCore.QObject.connect(form.roll0,QtCore.SIGNAL("valueChanged(double)"),self.onRoll)
QtCore.QObject.connect(form.roll1,QtCore.SIGNAL("valueChanged(double)"),self.onRoll)
QtCore.QObject.connect(form.nRoll,QtCore.SIGNAL("valueChanged(int)"),self.onRoll)
return False
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):
""" Get selected geometry.
@return False if sucessfully values initialized.
"""
# Get selected objects
selObjs = FreeCADGui.Selection.getSelection()
if not selObjs:
msg = QtGui.QApplication.translate("ship_console","Ship instance must be selected (no object selected)",
None,QtGui.QApplication.UnicodeUTF8)
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 = QtGui.QApplication.translate("ship_console",
"More than one ship selected (extra ships will be neglected)",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintWarning(msg + '\n')
break
self.ship = obj
# Test if any valid ship was selected
if not self.ship:
msg = QtGui.QApplication.translate("ship_console",
"Ship instance must be selected (no valid ship found at selected objects)",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintError(msg + '\n')
return True
props = self.ship.PropertiesList
try:
props.index("WeightNames")
except:
msg = QtGui.QApplication.translate("ship_console",
"Ship weights has not been set. You need to set weights before use this tool",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintError(msg + '\n')
return True
# Setup available tanks list
objs = App.ActiveDocument.Objects
iconPath = Paths.iconsPath() + "/Tank.xpm"
icon = QtGui.QIcon(QtGui.QPixmap(iconPath))
for obj in objs:
# Try to get valid tank property
props = obj.PropertiesList
try:
props.index("IsShipTank")
except ValueError:
continue
if not obj.IsShipTank:
continue
# Add tank to list
name = obj.Name
label = obj.Label
tag = label + ' (' + name + ')'
self.tanks[tag] = name
# self.tanks.append([name, tag])
item = QtGui.QListWidgetItem(tag)
item.setIcon(icon)
self.form.tanks.addItem(item)
return False
def retranslateUi(self):
""" Set user interface locale strings.
"""
self.form.findChild(QtGui.QLabel, "DraftLabel").setText(QtGui.QApplication.translate("shiptank_gz","Draft",
None,QtGui.QApplication.UnicodeUTF8))
self.form.setWindowTitle(QtGui.QApplication.translate("shiptank_gz","GZ curve computation",
None,QtGui.QApplication.UnicodeUTF8))
self.form.findChild(QtGui.QGroupBox, "LoadConditionGroup").setTitle(QtGui.QApplication.translate("shiptank_gz",
"Loading condition",
None,QtGui.QApplication.UnicodeUTF8))
self.form.findChild(QtGui.QGroupBox, "AnglesGroup").setTitle(QtGui.QApplication.translate("shiptank_gz","Roll angles",
None,QtGui.QApplication.UnicodeUTF8))
self.form.findChild(QtGui.QLabel, "TrimLabel").setText(QtGui.QApplication.translate("shiptank_gz","Trim",
None,QtGui.QApplication.UnicodeUTF8) + " [deg]")
self.form.findChild(QtGui.QLabel, "StartAngleLabel").setText(QtGui.QApplication.translate("shiptank_gz","Start",
None,QtGui.QApplication.UnicodeUTF8) + " [deg]")
self.form.findChild(QtGui.QLabel, "EndAngleLabel").setText(QtGui.QApplication.translate("shiptank_gz","End",
None,QtGui.QApplication.UnicodeUTF8) + " [deg]")
self.form.findChild(QtGui.QLabel, "NAngleLabel").setText(QtGui.QApplication.translate("shiptank_gz","Number of points",
None,QtGui.QApplication.UnicodeUTF8))
self.form.disp.setText(QtGui.QApplication.translate("shiptank_gz","Displacement",
None,QtGui.QApplication.UnicodeUTF8) + ' = ' + \
QtGui.QApplication.translate("shiptank_gz","Press update to compute",
None,QtGui.QApplication.UnicodeUTF8))
self.form.draft.setText(QtGui.QApplication.translate("shiptank_gz","Draft",
None,QtGui.QApplication.UnicodeUTF8) + ' = ' + \
QtGui.QApplication.translate("shiptank_gz","Press update to compute",
None,QtGui.QApplication.UnicodeUTF8))
self.form.update.setText(QtGui.QApplication.translate("shiptank_gz","Update displacement and draft",
None,QtGui.QApplication.UnicodeUTF8))
def onTanksSelection(self):
""" Called when tanks are selected or deselected.
"""
pass
def onUpdate(self):
""" Called when update displacement and draft is requested.
"""
# Set displacement label
disp = self.computeDisplacement()
self.form.disp.setText(QtGui.QApplication.translate("shiptank_gz","Displacement",
None,QtGui.QApplication.UnicodeUTF8) + ' = %g [kg]' % (disp[0]))
# Set draft label
draft = self.computeDraft(disp[0], self.form.trim.value())
self.form.draft.setText(QtGui.QApplication.translate("shiptank_gz","Draft",
None,QtGui.QApplication.UnicodeUTF8) + ' = %g [m]' % (draft[0]))
def onTrim(self, trim):
""" Called when trim angle value is changed.
@param trim Selected trim angle.
"""
self.onTanksSelection()
def onAutoTrim(self):
""" Called when trim angle must be auto computed.
"""
# Start at null trim angle
trim = 0.0
# Get center of gravity
disp = self.computeDisplacement(trim)
G = [disp[1], disp[2], disp[3]]
disp = disp[0]
# Get bouyancy center
draft = self.computeDraft(disp)
B = [draft[1].x, draft[1].y, draft[1].z]
draft = draft[0]
# Get stability initial condition
BG = [G[0]-B[0], G[1]-B[1], G[2]-B[2]]
x = BG[0]*math.cos(math.radians(trim)) - BG[2]*math.sin(math.radians(trim))
y = BG[1]
z = BG[0]*math.sin(math.radians(trim)) + BG[2]*math.cos(math.radians(trim))
var = math.degrees(math.atan2(x,z))
# Iterate looking stability point
dVar = math.copysign(0.01, var)
while True:
if (dVar*var < 0.0) or (abs(var) < 0.1):
break
trim = trim - math.copysign(max(dVar, abs(var)/200.0), var)
# Get center of gravity
disp = self.computeDisplacement(trim)
G = [disp[1], disp[2], disp[3]]
disp = disp[0]
# Get bouyancy center
draft = self.computeDraft(disp, trim)
B = [draft[1].x, draft[1].y, draft[1].z]
draft = draft[0]
# Get stability initial condition
BG = [G[0]-B[0], G[1]-B[1], G[2]-B[2]]
x = BG[0]*math.cos(math.radians(trim)) - BG[2]*math.sin(math.radians(trim))
y = BG[1]
z = BG[0]*math.sin(math.radians(trim)) + BG[2]*math.cos(math.radians(trim))
var = math.degrees(math.atan2(x,z))
self.form.trim.setValue(trim)
def onRoll(self, value):
""" Called when roll angles options are modified.
@param value Dummy changed value.
"""
roll0 = self.form.roll0.value()
self.form.roll1.setMinimum(roll0)
roll1 = self.form.roll1.value()
self.form.roll0.setMaximum(roll1)
def getTanks(self):
""" Get the selected tanks objects list.
@return Selected tanks list.
"""
items = self.form.tanks.selectedItems()
tanks = []
for item in items:
tag = str(item.text())
name = self.tanks[tag]
t = App.ActiveDocument.getObject(name)
if not t:
continue
tanks.append(t)
return tanks
def computeDisplacement(self, trim=0.0, roll=0.0):
""" Computes ship displacement.
@param trim Trim angle [degrees].
@return Ship displacement and center of gravity. None if errors
detected.
@note Returned center of gravity is refered to ship attached
axis coordinates.
"""
if not self.ship:
return None
# Get ship structure weights
W = [0.0, 0.0, 0.0, 0.0]
sWeights = weights(self.ship)
for w in sWeights:
W[0] = W[0] + w[1]
W[1] = W[1] + w[1]*w[2][0]
W[2] = W[2] + w[1]*w[2][1]
W[3] = W[3] + w[1]*w[2][2]
# Get selected tanks weights
tanks = self.getTanks()
for t in tanks:
w = tankWeight(t, App.Base.Vector(roll,-trim,0.0))
# Unrotate center of gravity
x = w[1]*math.cos(math.radians(-trim)) - w[3]*math.sin(math.radians(-trim))
y = w[2]
z = w[1]*math.sin(math.radians(-trim)) + w[3]*math.cos(math.radians(-trim))
w[1] = x
w[2] = y*math.cos(math.radians(-roll)) - z*math.sin(math.radians(-roll))
w[3] = y*math.sin(math.radians(-roll)) + z*math.cos(math.radians(-roll))
W[0] = W[0] + w[0]
W[1] = W[1] + w[0]*w[1]
W[2] = W[2] + w[0]*w[2]
W[3] = W[3] + w[0]*w[3]
return [W[0], W[1]/W[0], W[2]/W[0], W[3]/W[0]]
def computeDraft(self, disp, trim=0.0):
""" Computes ship draft.
@param disp Ship displacement.
@param trim Trim angle [degrees].
@return Ship draft, and bouyance center position. None if errors detected.
"""
if not self.ship:
return None
# Initial condition
dens = 1025
bbox = self.ship.Shape.BoundBox
draft = bbox.ZMin
dx = bbox.XMax - bbox.XMin
dy = bbox.YMax - bbox.YMin
w = 0.0
xcb = 0.0
while(abs(disp - w)/disp > 0.01):
draft = draft + (disp - w) / (dens*dx*dy)
ww = Hydrostatics.displacement(self.ship, draft, 0.0, trim, 0.0)
w = 1000.0*ww[0]
B = ww[1]
return [draft,B]
def computeGZ(self, draft, trim, roll):
""" Compute GZ value.
@param draft Ship draft.
@param trim Ship trim angle [degrees].
@param roll Ship roll angle [degrees].
@return GZ value [m].
"""
# Get center of gravity (x coordinate not relevant)
disp = self.computeDisplacement(trim, roll)
G = [disp[2], disp[3]]
disp = disp[0]
# Get bouyancy center (x coordinate not relevant)
disp = Hydrostatics.displacement(self.ship, draft, roll, trim, 0.0)
B = [disp[1].y, disp[1].z]
# GZ computation
BG = [G[0] - B[0], G[1] - B[1]]
y = BG[0]*math.cos(math.radians(roll)) - BG[1]*math.sin(math.radians(roll))
z = BG[0]*math.sin(math.radians(roll)) + BG[1]*math.cos(math.radians(roll))
return y
def createTask():
panel = TaskPanel()
Gui.Control.showDialog(panel)
if panel.setupUi():
Gui.Control.closeDialog(panel)
return None
return panel

View File

@ -1,208 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskPanel</class>
<widget class="QWidget" name="TaskPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>256</width>
<height>408</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>256</width>
<height>408</height>
</size>
</property>
<property name="windowTitle">
<string>GZ curve computation</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="LoadConditionGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>6</verstretch>
</sizepolicy>
</property>
<property name="sizeIncrement">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Loading condition</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QListWidget" name="Tanks">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="DisplacementLabel">
<property name="text">
<string>Displacement = 0 [kg]</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="DraftLabel">
<property name="text">
<string>Draft = 0 [m]</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="UpdateData">
<property name="text">
<string>Update displacement and draft</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="TrimLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Trim [deg]</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="Trim">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>3</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<double>-45.000000000000000</double>
</property>
<property name="maximum">
<double>45.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="TrimAutoCompute">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Auto</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="AnglesGroup">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>3</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Roll angles</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="StartAngleLabel">
<property name="text">
<string>Start [deg]</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="EndAngleLabel">
<property name="text">
<string>End [deg]</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="NAngleLabel">
<property name="text">
<string>Number of points</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="StartAngle">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>90.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="EndAngle">
<property name="maximum">
<double>180.000000000000000</double>
</property>
<property name="value">
<double>45.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="NAngle">
<property name="minimum">
<number>2</number>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="value">
<number>46</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,36 +0,0 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* 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()

View File

@ -1,106 +0,0 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* 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,FreeCADGui
from FreeCAD import Base
import Part
# FreeCADShip modules
from shipUtils import Paths
class Preview(object):
def __init__(self):
""" Constructor.
"""
self.objects = []
def reinit(self):
""" Reinitializate drawer.
"""
self.clean()
def update(self, names, pos):
""" Update the 3D view printing annotations.
@param names Weight names.
@param pos Weight positions (FreeCAD::Base::Vector).
"""
# Destroy all previous entities
self.clean()
for i in range(0, len(names)):
# Draw gravity line
line = Part.makeLine((pos[i].x,pos[i].y,pos[i].z),(pos[i].x,pos[i].y,pos[i].z - 9.81))
Part.show(line)
objs = FreeCAD.ActiveDocument.Objects
self.objects.append(objs[-1])
objs[-1].Label = names[i] + 'Line'
# Draw circles
circle = Part.makeCircle(0.5, pos[i], Base.Vector(1.0,0.0,0.0))
Part.show(circle)
objs = FreeCAD.ActiveDocument.Objects
self.objects.append(objs[-1])
objs[-1].Label = names[i] + 'CircleX'
circle = Part.makeCircle(0.5, pos[i], Base.Vector(0.0,1.0,0.0))
Part.show(circle)
objs = FreeCAD.ActiveDocument.Objects
self.objects.append(objs[-1])
objs[-1].Label = names[i] + 'CircleY'
circle = Part.makeCircle(0.5, pos[i], Base.Vector(0.0,0.0,1.0))
Part.show(circle)
objs = FreeCAD.ActiveDocument.Objects
self.objects.append(objs[-1])
objs[-1].Label = names[i] + 'CircleZ'
# Draw annotation
self.objects.append(DrawText(names[i] + 'Text', names[i], Base.Vector(pos[i].x+1.0,pos[i].y,pos[i].z)))
def clean(self):
""" Erase all annotations from screen.
"""
for i in range(0,len(self.objects)):
if not FreeCAD.ActiveDocument.getObject(self.objects[i].Name):
continue
FreeCAD.ActiveDocument.removeObject(self.objects[i].Name)
self.objects = []
def DrawText(name, string, position, displayMode="Screen", angle=0.0, justification="Left", colour=(0.00,0.00,0.00), size=12):
""" Draws a text in a desired position.
@param name Name of the object
@param string Text to draw (recommended format u'')
@param position Point to draw the text
@param angle Counter clockwise rotation of text
@param justification Alignement of the text ("Left", "Right" or "Center")
@param colour Colour of the text
@param size Font size
@return FreeCAD annotation object
"""
# Create the object
text = FreeCAD.ActiveDocument.addObject("App::Annotation",name)
# Set the text
text.LabelText = [string, u'']
# Set the options
text.Position = position
FreeCADGui.ActiveDocument.getObject(text.Name).Rotation = angle
FreeCADGui.ActiveDocument.getObject(text.Name).Justification = justification
FreeCADGui.ActiveDocument.getObject(text.Name).FontSize = size
FreeCADGui.ActiveDocument.getObject(text.Name).TextColor = colour
FreeCADGui.ActiveDocument.getObject(text.Name).DisplayMode = displayMode
return FreeCAD.ActiveDocument.getObject(text.Name)

View File

@ -1,252 +0,0 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* 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
import Preview
from Instance import *
from shipUtils import Paths
class TaskPanel:
def __init__(self):
self.ui = Paths.modulePath() + "/tankWeights/TaskPanel.ui"
self.ship = None
self.preview = Preview.Preview()
def accept(self):
self.preview.clean()
if not self.ship:
return False
# Setup lists
name = []
mass = []
pos = []
for i in range(0,self.form.weights.rowCount() - 1):
item = self.form.weights.item(i,0)
name.append(item.text().__str__())
item = self.form.weights.item(i,1)
mass.append(item.text().toFloat()[0])
vec = []
item = self.form.weights.item(i,2)
vec.append(item.text().toFloat()[0])
item = self.form.weights.item(i,3)
vec.append(item.text().toFloat()[0])
item = self.form.weights.item(i,4)
vec.append(item.text().toFloat()[0])
pos.append(App.Base.Vector(vec[0],vec[1],vec[2]))
# Send to ship
self.ship.WeightNames = name[:]
self.ship.WeightMass = mass[:]
self.ship.WeightPos = pos[:]
return True
def reject(self):
self.preview.clean()
if not self.ship:
return False
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.weights = form.findChild(QtGui.QTableWidget, "Weights")
self.form = form
# Initial values
if self.initValues():
return True
self.retranslateUi()
# Connect Signals and Slots
QtCore.QObject.connect(form.weights,QtCore.SIGNAL("cellChanged(int,int)"),self.onTableItem);
# Update screen
name = []
pos = []
for i in range(0,self.form.weights.rowCount() - 1):
item = self.form.weights.item(i,0)
name.append(item.text().__str__())
vec = []
item = self.form.weights.item(i,2)
vec.append(item.text().toFloat()[0])
item = self.form.weights.item(i,3)
vec.append(item.text().toFloat()[0])
item = self.form.weights.item(i,4)
vec.append(item.text().toFloat()[0])
pos.append(App.Base.Vector(vec[0],vec[1],vec[2]))
self.preview.update(name, pos)
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):
""" Get selected geometry.
@return False if sucessfully values initialized.
"""
# Get selected objects
selObjs = FreeCADGui.Selection.getSelection()
if not selObjs:
msg = QtGui.QApplication.translate("ship_console", "Ship instance must be selected (no object selected)",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintError(msg + '\n')
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 = QtGui.QApplication.translate("ship_console",
"More than one ship selected (extra ships will be neglected)",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintWarning(msg + '\n')
break
self.ship = obj
# Test if any valid ship was selected
if not self.ship:
msg = QtGui.QApplication.translate("ship_console",
"Ship instance must be selected (no valid ship found at selected objects)",
None,QtGui.QApplication.UnicodeUTF8)
App.Console.PrintError(msg + '\n')
return True
# Get weights
w = weights(self.ship)
# Set the items
self.form.weights.setRowCount(len(w)+1)
for i in range(0,len(w)):
item = QtGui.QTableWidgetItem(w[i][0])
self.form.weights.setItem(i,0,item)
string = '%g' % (w[i][1])
item = QtGui.QTableWidgetItem(string)
self.form.weights.setItem(i,1,item)
string = '%g' % (w[i][2].x)
item = QtGui.QTableWidgetItem(string)
self.form.weights.setItem(i,2,item)
string = '%g' % (w[i][2].y)
item = QtGui.QTableWidgetItem(string)
self.form.weights.setItem(i,3,item)
string = '%g' % (w[i][2].z)
item = QtGui.QTableWidgetItem(string)
self.form.weights.setItem(i,4,item)
return False
def retranslateUi(self):
""" Set user interface locale strings.
"""
self.form.setWindowTitle(QtGui.QApplication.translate("shiptank_weights","Set weights",
None,QtGui.QApplication.UnicodeUTF8))
labels = []
labels.append(QtGui.QApplication.translate("shiptank_weights","Name",
None,QtGui.QApplication.UnicodeUTF8))
labels.append(QtGui.QApplication.translate("shiptank_weights","Mass",
None,QtGui.QApplication.UnicodeUTF8) + " [kg]")
labels.append(QtCore.QString("g.x [m]"))
labels.append(QtCore.QString("g.y [m]"))
labels.append(QtCore.QString("g.z [m]"))
self.form.weights.setHorizontalHeaderLabels(labels)
def onTableItem(self, row, column):
""" Function called when an item of table is changed.
@param row Changed item row
@param column Changed item column
"""
item = self.form.weights.item(row,column)
# Row deletion
if column == 0:
if not item.text():
self.form.weights.removeRow(row)
# Ensure that exist one empty item at the end
nRow = self.form.weights.rowCount()
last = self.form.weights.item(nRow-1,0)
if last:
if(last.text() != ''):
self.form.weights.setRowCount(nRow+1)
# Fields must be numbers
for i in range(0,self.form.weights.rowCount()-1): # Avoid last row
for j in range(1,self.form.weights.columnCount()): # Avoid name column
item = self.form.weights.item(i,j)
if not item:
item = QtGui.QTableWidgetItem('0.0')
self.form.weights.setItem(i,j,item)
continue
(number,flag) = item.text().toFloat()
if not flag:
item.setText('0.0')
# Update screen annotations
name = []
pos = []
for i in range(0,self.form.weights.rowCount() - 1):
item = self.form.weights.item(i,0)
name.append(item.text().__str__())
vec = []
item = self.form.weights.item(i,2)
vec.append(item.text().toFloat()[0])
item = self.form.weights.item(i,3)
vec.append(item.text().toFloat()[0])
item = self.form.weights.item(i,4)
vec.append(item.text().toFloat()[0])
pos.append(App.Base.Vector(vec[0],vec[1],vec[2]))
self.preview.update(name, pos)
def createTask():
panel = TaskPanel()
Gui.Control.showDialog(panel)
if panel.setupUi():
Gui.Control.closeDialog(panel)
return None
return panel

View File

@ -1,97 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskPanel</class>
<widget class="QWidget" name="TaskPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>260</width>
<height>256</height>
</rect>
</property>
<property name="windowTitle">
<string>Set weights</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTableWidget" name="Weights">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="rowCount">
<number>1</number>
</property>
<property name="columnCount">
<number>5</number>
</property>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>20</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<row/>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Mass [kg]</string>
</property>
</column>
<column>
<property name="text">
<string>g.x [m]</string>
</property>
</column>
<column>
<property name="text">
<string>g.y [m]</string>
</property>
</column>
<column>
<property name="text">
<string>g.z [m]</string>
</property>
</column>
<item row="0" column="0">
<property name="text">
<string>Lightweight</string>
</property>
</item>
<item row="0" column="1">
<property name="text">
<string>0.0</string>
</property>
</item>
<item row="0" column="2">
<property name="text">
<string>0.0</string>
</property>
</item>
<item row="0" column="3">
<property name="text">
<string>0.0</string>
</property>
</item>
<item row="0" column="4">
<property name="text">
<string>0.0</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,36 +0,0 @@
#***************************************************************************
#* *
#* Copyright (c) 2011, 2012 *
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
#* *
#* 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()

View File

@ -94,28 +94,5 @@
<File Id="shipUtils03" Name="Paths.py" />
</Component>
</Directory>
<Directory Id="ModtankCreateTank" Name="tankCreateTank" FileSource="../../Mod/Ship/tankCreateTank" >
<Component Id="CompModtankCreateTank" Guid="1cc53994-9e82-4731-bd37-2705a31388c6" Win64='$(var.Win_64)' KeyPath="yes">
<File Id="tankCreateTank01" Name="__init__.py" />
<File Id="tankCreateTank02" Name="TaskPanel.py" />
<File Id="tankCreateTank03" Name="TaskPanel.ui" />
</Component>
</Directory>
<Directory Id="ModtankGZ" Name="tankGZ" FileSource="../../Mod/Ship/tankGZ" >
<Component Id="CompModtankGZ" Guid="ef798f90-0c85-4c5e-a637-22b97bf05303" Win64='$(var.Win_64)' KeyPath="yes">
<File Id="tankGZ01" Name="__init__.py" />
<File Id="tankGZ02" Name="PlotAux.py" />
<File Id="tankGZ03" Name="TaskPanel.py" />
<File Id="tankGZ04" Name="TaskPanel.ui" />
</Component>
</Directory>
<Directory Id="ModtankWeights" Name="tankWeights" FileSource="../../Mod/Ship/tankWeights" >
<Component Id="CompModtankWeights" Guid="77f12d48-58b0-4c95-8bee-7c4f709379d8" Win64='$(var.Win_64)' KeyPath="yes">
<File Id="tankWeights01" Name="__init__.py" />
<File Id="tankWeights03" Name="Preview.py" />
<File Id="tankWeights04" Name="TaskPanel.py" />
<File Id="tankWeights05" Name="TaskPanel.ui" />
</Component>
</Directory>
</Directory>
</Include>