Merge branch 'sanguinariojoe-ship' of ssh://free-cad.git.sourceforge.net/gitroot/free-cad/free-cad into sanguinariojoe-ship
This commit is contained in:
commit
ca881d1455
|
@ -2,6 +2,7 @@ SET(ShipMain_SRCS
|
||||||
InitGui.py
|
InitGui.py
|
||||||
ShipGui.py
|
ShipGui.py
|
||||||
Instance.py
|
Instance.py
|
||||||
|
SimInstance.py
|
||||||
TankInstance.py
|
TankInstance.py
|
||||||
)
|
)
|
||||||
SOURCE_GROUP("" FILES ${ShipMain_SRCS})
|
SOURCE_GROUP("" FILES ${ShipMain_SRCS})
|
||||||
|
@ -36,6 +37,14 @@ SET(ShipIcons_SRCS
|
||||||
Icons/Weight.png
|
Icons/Weight.png
|
||||||
Icons/Weight.xcf
|
Icons/Weight.xcf
|
||||||
Icons/Weight.xpm
|
Icons/Weight.xpm
|
||||||
|
Icons/SimIco.xcf
|
||||||
|
Icons/Sim.xpm
|
||||||
|
Icons/SimCreateIco.png
|
||||||
|
Icons/SimCreateIco.xpm
|
||||||
|
Icons/SimRunIco.png
|
||||||
|
Icons/SimRunIco.xpm
|
||||||
|
Icons/SimStopIco.png
|
||||||
|
Icons/SimStopIco.xpm
|
||||||
Icons/Tank.png
|
Icons/Tank.png
|
||||||
Icons/Tank.xcf
|
Icons/Tank.xcf
|
||||||
Icons/Tank.xpm
|
Icons/Tank.xpm
|
||||||
|
@ -121,9 +130,24 @@ SET(ShipGZ_SRCS
|
||||||
tankGZ/TaskPanel.py
|
tankGZ/TaskPanel.py
|
||||||
tankGZ/TaskPanel.ui
|
tankGZ/TaskPanel.ui
|
||||||
)
|
)
|
||||||
SOURCE_GROUP("shipcreatetank" FILES ${ShipCreateTank_SRCS})
|
SOURCE_GROUP("shipgz" FILES ${ShipGZ_SRCS})
|
||||||
|
|
||||||
SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipExamples_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS} ${ShipWeights_SRCS} ${ShipCreateTank_SRCS} ${ShipGZ_SRCS})
|
SET(SimCreate_SRCS
|
||||||
|
simCreate/__init__.py
|
||||||
|
simCreate/TaskPanel.py
|
||||||
|
simCreate/TaskPanel.ui
|
||||||
|
)
|
||||||
|
SOURCE_GROUP("simcreate" FILES ${SimCreate_SRCS})
|
||||||
|
|
||||||
|
SET(SimRun_SRCS
|
||||||
|
simRun/__init__.py
|
||||||
|
simRun/Simulation.py
|
||||||
|
simRun/TaskPanel.py
|
||||||
|
simRun/TaskPanel.ui
|
||||||
|
)
|
||||||
|
SOURCE_GROUP("simrun" FILES ${SimRun_SRCS})
|
||||||
|
|
||||||
|
SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipExamples_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS} ${ShipWeights_SRCS} ${ShipCreateTank_SRCS} ${ShipGZ_SRCS} ${SimCreate_SRCS} ${SimRun_SRCS})
|
||||||
|
|
||||||
ADD_CUSTOM_TARGET(Ship ALL
|
ADD_CUSTOM_TARGET(Ship ALL
|
||||||
SOURCES ${all_files}
|
SOURCES ${all_files}
|
||||||
|
@ -197,6 +221,18 @@ INSTALL(
|
||||||
DESTINATION
|
DESTINATION
|
||||||
Mod/Ship/tankGZ
|
Mod/Ship/tankGZ
|
||||||
)
|
)
|
||||||
|
INSTALL(
|
||||||
|
FILES
|
||||||
|
${SimCreate_SRCS}
|
||||||
|
DESTINATION
|
||||||
|
Mod/Ship/simCreate
|
||||||
|
)
|
||||||
|
INSTALL(
|
||||||
|
FILES
|
||||||
|
${SimRun_SRCS}
|
||||||
|
DESTINATION
|
||||||
|
Mod/Ship/simRun
|
||||||
|
)
|
||||||
INSTALL(
|
INSTALL(
|
||||||
FILES
|
FILES
|
||||||
${ShipMain_SRCS}
|
${ShipMain_SRCS}
|
||||||
|
|
336
src/Mod/Ship/Icons/Sim.xpm
Normal file
336
src/Mod/Ship/Icons/Sim.xpm
Normal file
|
@ -0,0 +1,336 @@
|
||||||
|
/* XPM */
|
||||||
|
static char * Sim_xpm[] = {
|
||||||
|
"32 32 301 2",
|
||||||
|
" c None",
|
||||||
|
". c #CCCCCC",
|
||||||
|
"+ c #A9A9A9",
|
||||||
|
"@ c #989898",
|
||||||
|
"# c #A1A1A1",
|
||||||
|
"$ c #C3C3C3",
|
||||||
|
"% c #C1C0C1",
|
||||||
|
"& c #BFBFBF",
|
||||||
|
"* c #A7A7A7",
|
||||||
|
"= c #808080",
|
||||||
|
"- c #5C5C5C",
|
||||||
|
"; c #565655",
|
||||||
|
"> c #4E4E4E",
|
||||||
|
", c #676767",
|
||||||
|
"' c #898989",
|
||||||
|
") c #B6B5B6",
|
||||||
|
"! c #BABABA",
|
||||||
|
"~ c #B9B9B9",
|
||||||
|
"{ c #A5A5A5",
|
||||||
|
"] c #7E7E7E",
|
||||||
|
"^ c #595A59",
|
||||||
|
"/ c #575656",
|
||||||
|
"( c #535353",
|
||||||
|
"_ c #505050",
|
||||||
|
": c #4D4D4C",
|
||||||
|
"< c #474747",
|
||||||
|
"[ c #404040",
|
||||||
|
"} c #4D4D4D",
|
||||||
|
"| c #787878",
|
||||||
|
"1 c #B8B7B8",
|
||||||
|
"2 c #B6B6B6",
|
||||||
|
"3 c #888888",
|
||||||
|
"4 c #7C7C7C",
|
||||||
|
"5 c #575657",
|
||||||
|
"6 c #535354",
|
||||||
|
"7 c #4E4D4E",
|
||||||
|
"8 c #4A4A4A",
|
||||||
|
"9 c #444444",
|
||||||
|
"0 c #414141",
|
||||||
|
"a c #3E3E3E",
|
||||||
|
"b c #393938",
|
||||||
|
"c c #313131",
|
||||||
|
"d c #393939",
|
||||||
|
"e c #636363",
|
||||||
|
"f c #ABABAB",
|
||||||
|
"g c #B3B3B3",
|
||||||
|
"h c #848484",
|
||||||
|
"i c #787979",
|
||||||
|
"j c #545454",
|
||||||
|
"k c #515151",
|
||||||
|
"l c #4B4B4B",
|
||||||
|
"m c #484748",
|
||||||
|
"n c #3B3B3B",
|
||||||
|
"o c #383838",
|
||||||
|
"p c #353535",
|
||||||
|
"q c #323232",
|
||||||
|
"r c #2F2F2E",
|
||||||
|
"s c #2A2A2A",
|
||||||
|
"t c #222323",
|
||||||
|
"u c #252625",
|
||||||
|
"v c #AFAFAF",
|
||||||
|
"w c #767676",
|
||||||
|
"x c #484848",
|
||||||
|
"y c #454545",
|
||||||
|
"z c #424242",
|
||||||
|
"A c #3F3F3E",
|
||||||
|
"B c #3B3B3C",
|
||||||
|
"C c #393838",
|
||||||
|
"D c #2F2F2F",
|
||||||
|
"E c #2C2C2C",
|
||||||
|
"F c #292929",
|
||||||
|
"G c #262626",
|
||||||
|
"H c #222222",
|
||||||
|
"I c #1F1F20",
|
||||||
|
"J c #171716",
|
||||||
|
"K c #959595",
|
||||||
|
"L c #747474",
|
||||||
|
"M c #4E4E4F",
|
||||||
|
"N c #4C4B4C",
|
||||||
|
"O c #484849",
|
||||||
|
"P c #424243",
|
||||||
|
"Q c #282828",
|
||||||
|
"R c #525251",
|
||||||
|
"S c #373737",
|
||||||
|
"T c #353636",
|
||||||
|
"U c #333233",
|
||||||
|
"V c #30302F",
|
||||||
|
"W c #2C2D2D",
|
||||||
|
"X c #232323",
|
||||||
|
"Y c #201F20",
|
||||||
|
"Z c #1D1D1D",
|
||||||
|
"` c #151414",
|
||||||
|
" . c #717272",
|
||||||
|
".. c #4C4C4C",
|
||||||
|
"+. c #484949",
|
||||||
|
"@. c #464545",
|
||||||
|
"#. c #424343",
|
||||||
|
"$. c #3A3A3A",
|
||||||
|
"%. c #5D4A49",
|
||||||
|
"&. c #7E7E86",
|
||||||
|
"*. c #56569F",
|
||||||
|
"=. c #3E3E41",
|
||||||
|
"-. c #757575",
|
||||||
|
";. c #575757",
|
||||||
|
">. c #222221",
|
||||||
|
",. c #262627",
|
||||||
|
"'. c #242423",
|
||||||
|
"). c #212020",
|
||||||
|
"!. c #1A1A1A",
|
||||||
|
"~. c #121212",
|
||||||
|
"{. c #939493",
|
||||||
|
"]. c #6F6F6F",
|
||||||
|
"^. c #494949",
|
||||||
|
"/. c #464646",
|
||||||
|
"(. c #434343",
|
||||||
|
"_. c #554545",
|
||||||
|
":. c #686863",
|
||||||
|
"<. c #939394",
|
||||||
|
"[. c #BDBDBD",
|
||||||
|
"}. c #202021",
|
||||||
|
"|. c #1E1E1E",
|
||||||
|
"1. c #171718",
|
||||||
|
"2. c #0F0F0F",
|
||||||
|
"3. c #929292",
|
||||||
|
"4. c #6C6D6D",
|
||||||
|
"5. c #464746",
|
||||||
|
"6. c #525F73",
|
||||||
|
"7. c #444648",
|
||||||
|
"8. c #3D3D3D",
|
||||||
|
"9. c #2D2C2A",
|
||||||
|
"0. c #A1A2A2",
|
||||||
|
"a. c #AAACAC",
|
||||||
|
"b. c #A6A7A7",
|
||||||
|
"c. c #A8AAAA",
|
||||||
|
"d. c #AFB0B0",
|
||||||
|
"e. c #777676",
|
||||||
|
"f. c #9A9A9A",
|
||||||
|
"g. c #1B1B1B",
|
||||||
|
"h. c #181818",
|
||||||
|
"i. c #0C0C0C",
|
||||||
|
"j. c #909090",
|
||||||
|
"k. c #6B6A6B",
|
||||||
|
"l. c #55657E",
|
||||||
|
"m. c #6990FB",
|
||||||
|
"n. c #6483CD",
|
||||||
|
"o. c #5871B2",
|
||||||
|
"p. c #434E7E",
|
||||||
|
"q. c #A97C76",
|
||||||
|
"r. c #AB7777",
|
||||||
|
"s. c #AC7070",
|
||||||
|
"t. c #A26565",
|
||||||
|
"u. c #805C5C",
|
||||||
|
"v. c #848686",
|
||||||
|
"w. c #424342",
|
||||||
|
"x. c #151515",
|
||||||
|
"y. c #0A0909",
|
||||||
|
"z. c #8F8F8F",
|
||||||
|
"A. c #676868",
|
||||||
|
"B. c #3B3A3A",
|
||||||
|
"C. c #383738",
|
||||||
|
"D. c #353534",
|
||||||
|
"E. c #45525F",
|
||||||
|
"F. c #6367AC",
|
||||||
|
"G. c #804682",
|
||||||
|
"H. c #942A39",
|
||||||
|
"I. c #991312",
|
||||||
|
"J. c #540901",
|
||||||
|
"K. c #393742",
|
||||||
|
"L. c #1C1C1C",
|
||||||
|
"M. c #191919",
|
||||||
|
"N. c #161515",
|
||||||
|
"O. c #121313",
|
||||||
|
"P. c #070707",
|
||||||
|
"Q. c #8D8E8D",
|
||||||
|
"R. c #656566",
|
||||||
|
"S. c #3E3F3F",
|
||||||
|
"T. c #2F2E2F",
|
||||||
|
"U. c #353838",
|
||||||
|
"V. c #35496A",
|
||||||
|
"W. c #3E4D88",
|
||||||
|
"X. c #354889",
|
||||||
|
"Y. c #5573D7",
|
||||||
|
"Z. c #5D80FB",
|
||||||
|
"`. c #374899",
|
||||||
|
" + c #293338",
|
||||||
|
".+ c #101010",
|
||||||
|
"++ c #0D0D0D",
|
||||||
|
"@+ c #040404",
|
||||||
|
"#+ c #8C8C8C",
|
||||||
|
"$+ c #8B8B8B",
|
||||||
|
"%+ c #4B4A4B",
|
||||||
|
"&+ c #303030",
|
||||||
|
"*+ c #333232",
|
||||||
|
"=+ c #2F2F30",
|
||||||
|
"-+ c #232223",
|
||||||
|
";+ c #1A1919",
|
||||||
|
">+ c #2E3949",
|
||||||
|
",+ c #5C7BA3",
|
||||||
|
"'+ c #36467D",
|
||||||
|
")+ c #536F93",
|
||||||
|
"!+ c #0A0A0A",
|
||||||
|
"~+ c #010101",
|
||||||
|
"{+ c #C1C1C1",
|
||||||
|
"]+ c #B8B8B8",
|
||||||
|
"^+ c #A0A0A0",
|
||||||
|
"/+ c #3F3F3F",
|
||||||
|
"(+ c #222122",
|
||||||
|
"_+ c #202020",
|
||||||
|
":+ c #161717",
|
||||||
|
"<+ c #141414",
|
||||||
|
"[+ c #111011",
|
||||||
|
"}+ c #0D0E0E",
|
||||||
|
"|+ c #0B0B0A",
|
||||||
|
"1+ c #000000",
|
||||||
|
"2+ c #525252",
|
||||||
|
"3+ c #686868",
|
||||||
|
"4+ c #ADADAD",
|
||||||
|
"5+ c #9E9F9F",
|
||||||
|
"6+ c #6D6D6D",
|
||||||
|
"7+ c #3C3C3C",
|
||||||
|
"8+ c #131414",
|
||||||
|
"9+ c #111111",
|
||||||
|
"0+ c #0E0E0E",
|
||||||
|
"a+ c #0B0B0B",
|
||||||
|
"b+ c #080708",
|
||||||
|
"c+ c #050504",
|
||||||
|
"d+ c #4C4D4C",
|
||||||
|
"e+ c #4D4C4D",
|
||||||
|
"f+ c #494A4A",
|
||||||
|
"g+ c #454444",
|
||||||
|
"h+ c #9D9D9D",
|
||||||
|
"i+ c #9E9E9E",
|
||||||
|
"j+ c #AEAEAE",
|
||||||
|
"k+ c #BEBEBF",
|
||||||
|
"l+ c #BEBDBD",
|
||||||
|
"m+ c #979797",
|
||||||
|
"n+ c #6A6B6A",
|
||||||
|
"o+ c #3F3F40",
|
||||||
|
"p+ c #020202",
|
||||||
|
"q+ c #030303",
|
||||||
|
"r+ c #878787",
|
||||||
|
"s+ c #69696A",
|
||||||
|
"t+ c #868685",
|
||||||
|
"u+ c #646464",
|
||||||
|
"v+ c #474647",
|
||||||
|
"w+ c #656565",
|
||||||
|
"x+ c #9E9F9E",
|
||||||
|
"y+ c #A8A8A8",
|
||||||
|
"z+ c #AFAFAE",
|
||||||
|
"A+ c #A4A4A4",
|
||||||
|
"B+ c #7A7A7A",
|
||||||
|
"C+ c #969696",
|
||||||
|
"D+ c #363636",
|
||||||
|
"E+ c #777776",
|
||||||
|
"F+ c #8C8D8D",
|
||||||
|
"G+ c #7D7D7D",
|
||||||
|
"H+ c #5E5E5E",
|
||||||
|
"I+ c #4F4F50",
|
||||||
|
"J+ c #808181",
|
||||||
|
"K+ c #707070",
|
||||||
|
"L+ c #909191",
|
||||||
|
"M+ c #9C9C9C",
|
||||||
|
"N+ c #787877",
|
||||||
|
"O+ c #696969",
|
||||||
|
"P+ c #616161",
|
||||||
|
"Q+ c #6E6E6E",
|
||||||
|
"R+ c #7C7B7C",
|
||||||
|
"S+ c #777677",
|
||||||
|
"T+ c #6F6E6E",
|
||||||
|
"U+ c #595959",
|
||||||
|
"V+ c #717171",
|
||||||
|
"W+ c #8D8D8D",
|
||||||
|
"X+ c #515051",
|
||||||
|
"Y+ c #49494A",
|
||||||
|
"Z+ c #4B4A4A",
|
||||||
|
"`+ c #606060",
|
||||||
|
" @ c #6A6A6A",
|
||||||
|
".@ c #616162",
|
||||||
|
"+@ c #6C6D6C",
|
||||||
|
"@@ c #767777",
|
||||||
|
"#@ c #727272",
|
||||||
|
"$@ c #6B6B6B",
|
||||||
|
"%@ c #828283",
|
||||||
|
"&@ c #757475",
|
||||||
|
"*@ c #444545",
|
||||||
|
"=@ c #565656",
|
||||||
|
"-@ c #5A595A",
|
||||||
|
";@ c #666666",
|
||||||
|
">@ c #878687",
|
||||||
|
",@ c #8A8A8A",
|
||||||
|
"'@ c #797979",
|
||||||
|
")@ c #444344",
|
||||||
|
"!@ c #7F8080",
|
||||||
|
"~@ c #737373",
|
||||||
|
"{@ c #484747",
|
||||||
|
"]@ c #707170",
|
||||||
|
"^@ c #7F7F7F",
|
||||||
|
"/@ c #676867",
|
||||||
|
"(@ c #4D4C4C",
|
||||||
|
"_@ c #5F5F5F",
|
||||||
|
":@ c #434444",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" . + ",
|
||||||
|
" @ # $ % & * ",
|
||||||
|
" = - ; > , ' ) ! ~ { ",
|
||||||
|
" ] ^ / ( _ : < [ } | # 1 2 # 3 ",
|
||||||
|
" 4 5 6 _ 7 8 < 9 0 a b c d e ' f g + h ",
|
||||||
|
" i j k 7 l m 9 0 a n o p q r s t u < | v ",
|
||||||
|
" w k > l x y z A B C p q D E F G H I J K ",
|
||||||
|
" L M N O y P Q R S T U V W F G X Y Z ` K ",
|
||||||
|
" ...+.@.#.$.%.&.*.=.-.;.>.,.'.).Z !.~.{. ",
|
||||||
|
" ].^./.(.[ c _._ :.<.[.$ ' /.}.|.!.1.2.3. ",
|
||||||
|
" 4.5.6.7.8.9.# 0.a.b.c.d.e.f.g.g.h.` i.j. ",
|
||||||
|
" k.9 l.m.n.o.p.q.r.s.t.u.v.w.g.h.x.~.y.z. ",
|
||||||
|
" A.0 a B.C.D.E.F.G.H.I.J.K.L.M.N.O.2.P.Q. ",
|
||||||
|
" R.S.n o p q T.E U.V.W.X.Y.Z.`. +.+++@+#+ ",
|
||||||
|
" $+%+&+q *+=+E F G -+I Z ;+>+,+'+)+!+~+$+ ",
|
||||||
|
" {+]+^+w /+H (+X _+Z !.:+<+[+}+|+P.1+' ",
|
||||||
|
" k 2+_ > 3+z.4+5+6+7+x.~.8+9+0+a+b+c+1+3 ",
|
||||||
|
" %+..d+e+..f+< g+h+i+j+k+l+m+n+o+P.p+q+p+1+r+ ",
|
||||||
|
" s+t+u+< (.< v+y 9 (.w+x+y+z+y+h+A+B+C+K ].D+1+h ",
|
||||||
|
" E+i+F+f.j.G+H+9 [ (.z I+J+m+f.j.K+z 9 9 9 K+L+r+/.9 (. ",
|
||||||
|
" L M+N+O+u+P+Q+R+S+T+U+y 8 - ;...9 9 9 9 9 9 9 9 (.(.k w+ ",
|
||||||
|
" V+m+' W+r+] , X+Y+(.: r+L P+k 9 z (.9 9 9 9 (.(.Z+;.- `+ ",
|
||||||
|
" ].C+w @u+.@+@@@#@$@j %@B+&@#@L $@H+2+/.0 (.*@+.} 2+=@-@ ",
|
||||||
|
" ;@| >@,@'@u+k 8 )@..!@| ~@V+#@#@#@#@L 6+..(.9 {@.._ ( ",
|
||||||
|
" e ]@^@] /@k G+w #@#@#@#@#@V+ @$@_ 9 9 9 /.Y+(@ ",
|
||||||
|
" - R.T+L ~@#@#@#@#@]._ _@_ 9 9 9 (.9 x ",
|
||||||
|
" =@_@O+L ~@#@~@L _ 9 9 :@ ",
|
||||||
|
" ;.H+ @-._ (. ",
|
||||||
|
" ",
|
||||||
|
" "};
|
BIN
src/Mod/Ship/Icons/SimCreateIco.png
Normal file
BIN
src/Mod/Ship/Icons/SimCreateIco.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
2255
src/Mod/Ship/Icons/SimCreateIco.xpm
Normal file
2255
src/Mod/Ship/Icons/SimCreateIco.xpm
Normal file
File diff suppressed because it is too large
Load Diff
BIN
src/Mod/Ship/Icons/SimIco.xcf
Normal file
BIN
src/Mod/Ship/Icons/SimIco.xcf
Normal file
Binary file not shown.
BIN
src/Mod/Ship/Icons/SimRunIco.png
Normal file
BIN
src/Mod/Ship/Icons/SimRunIco.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
2590
src/Mod/Ship/Icons/SimRunIco.xpm
Normal file
2590
src/Mod/Ship/Icons/SimRunIco.xpm
Normal file
File diff suppressed because it is too large
Load Diff
BIN
src/Mod/Ship/Icons/SimStopIco.png
Normal file
BIN
src/Mod/Ship/Icons/SimStopIco.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
2217
src/Mod/Ship/Icons/SimStopIco.xpm
Normal file
2217
src/Mod/Ship/Icons/SimStopIco.xpm
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -35,12 +35,33 @@ class ShipWorkbench ( Workbench ):
|
||||||
list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"]
|
list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"]
|
||||||
self.appendToolbar("Ship design",list)
|
self.appendToolbar("Ship design",list)
|
||||||
list = ["Ship_Weights", "Ship_CreateTank", "Ship_GZ"]
|
list = ["Ship_Weights", "Ship_CreateTank", "Ship_GZ"]
|
||||||
self.appendToolbar("Loading",list)
|
self.appendToolbar("Weights",list)
|
||||||
|
# Simulation stuff only if pyOpenCL & numpy are present
|
||||||
|
hasOpenCL = True
|
||||||
|
hasNumpy = True
|
||||||
|
try:
|
||||||
|
import pyopencl
|
||||||
|
except ImportError:
|
||||||
|
hasOpenCL = False
|
||||||
|
msg = Translator.translate("pyOpenCL not installed, ship simulations disabled\n")
|
||||||
|
App.Console.PrintWarning(msg)
|
||||||
|
try:
|
||||||
|
import numpy
|
||||||
|
except ImportError:
|
||||||
|
hasNumpy = False
|
||||||
|
msg = Translator.translate("numpy not installed, ship simulations disabled\n")
|
||||||
|
App.Console.PrintWarning(msg)
|
||||||
|
if hasOpenCL and hasNumpy:
|
||||||
|
list = ["Ship_CreateSim", "Ship_RunSim", "Ship_StopSim"]
|
||||||
|
self.appendToolbar("Simulation",list)
|
||||||
|
|
||||||
# Menu
|
# Menu
|
||||||
list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"]
|
list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"]
|
||||||
self.appendMenu("Ship design",list)
|
self.appendMenu("Ship design",list)
|
||||||
list = ["Ship_Weights", "Ship_CreateTank", "Ship_GZ"]
|
list = ["Ship_Weights", "Ship_CreateTank", "Ship_GZ"]
|
||||||
self.appendToolbar("Loading",list)
|
self.appendMenu("Weights",list)
|
||||||
|
if hasOpenCL and hasNumpy:
|
||||||
|
list = ["Ship_CreateSim", "Ship_RunSim", "Ship_StopSim"]
|
||||||
|
self.appendMenu("Simulation",list)
|
||||||
|
|
||||||
Gui.addWorkbench(ShipWorkbench())
|
Gui.addWorkbench(ShipWorkbench())
|
||||||
|
|
|
@ -5,6 +5,7 @@ data_DATA = \
|
||||||
InitGui.py \
|
InitGui.py \
|
||||||
ShipGui.py \
|
ShipGui.py \
|
||||||
Instance.py \
|
Instance.py \
|
||||||
|
SimInstance.py \
|
||||||
TankInstance.py
|
TankInstance.py
|
||||||
|
|
||||||
nobase_data_DATA = \
|
nobase_data_DATA = \
|
||||||
|
@ -37,6 +38,14 @@ nobase_data_DATA = \
|
||||||
Icons/Weight.png \
|
Icons/Weight.png \
|
||||||
Icons/Weight.xcf \
|
Icons/Weight.xcf \
|
||||||
Icons/Weight.xpm \
|
Icons/Weight.xpm \
|
||||||
|
Icons/SimIco.xcf \
|
||||||
|
Icons/Sim.xpm \
|
||||||
|
Icons/SimCreateIco.png \
|
||||||
|
Icons/SimCreateIco.xpm \
|
||||||
|
Icons/SimRunIco.png \
|
||||||
|
Icons/SimRunIco.xpm \
|
||||||
|
Icons/SimStopIco.png \
|
||||||
|
Icons/SimStopIco.xpm \
|
||||||
Icons/Tank.png \
|
Icons/Tank.png \
|
||||||
Icons/Tank.xcf \
|
Icons/Tank.xcf \
|
||||||
Icons/Tank.xpm \
|
Icons/Tank.xpm \
|
||||||
|
@ -80,7 +89,14 @@ nobase_data_DATA = \
|
||||||
tankGZ/__init__.py \
|
tankGZ/__init__.py \
|
||||||
tankGZ/Plot.py \
|
tankGZ/Plot.py \
|
||||||
tankGZ/TaskPanel.py \
|
tankGZ/TaskPanel.py \
|
||||||
tankGZ/TaskPanel.ui
|
tankGZ/TaskPanel.ui \
|
||||||
|
simCreate/__init__.py \
|
||||||
|
simCreate/TaskPanel.py \
|
||||||
|
simCreate/TaskPanel.ui \
|
||||||
|
simRun/__init__.py \
|
||||||
|
simRun/Simulation.py \
|
||||||
|
simRun/TaskPanel.py \
|
||||||
|
simRun/TaskPanel.ui
|
||||||
|
|
||||||
CLEANFILES = $(BUILT_SOURCES)
|
CLEANFILES = $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,42 @@ class GZ:
|
||||||
ToolTip = str(Translator.translate('Transversal stability GZ curve computation'))
|
ToolTip = str(Translator.translate('Transversal stability GZ curve computation'))
|
||||||
return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip}
|
return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||||
|
|
||||||
|
class CreateSim:
|
||||||
|
def Activated(self):
|
||||||
|
import simCreate
|
||||||
|
simCreate.load()
|
||||||
|
|
||||||
|
def GetResources(self):
|
||||||
|
from shipUtils import Paths, Translator
|
||||||
|
IconPath = Paths.iconsPath() + "/SimCreateIco.png"
|
||||||
|
MenuText = str(Translator.translate('Create a new simulation'))
|
||||||
|
ToolTip = str(Translator.translate('Create a new simulation in order to process later'))
|
||||||
|
return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||||
|
|
||||||
|
class RunSim:
|
||||||
|
def Activated(self):
|
||||||
|
import simRun
|
||||||
|
simRun.load()
|
||||||
|
|
||||||
|
def GetResources(self):
|
||||||
|
from shipUtils import Paths, Translator
|
||||||
|
IconPath = Paths.iconsPath() + "/SimRunIco.png"
|
||||||
|
MenuText = str(Translator.translate('Run a simulation'))
|
||||||
|
ToolTip = str(Translator.translate('Run a simulation'))
|
||||||
|
return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||||
|
|
||||||
|
class StopSim:
|
||||||
|
def Activated(self):
|
||||||
|
import simRun
|
||||||
|
simRun.stop()
|
||||||
|
|
||||||
|
def GetResources(self):
|
||||||
|
from shipUtils import Paths, Translator
|
||||||
|
IconPath = Paths.iconsPath() + "/SimStopIco.png"
|
||||||
|
MenuText = str(Translator.translate('Stop active simulation'))
|
||||||
|
ToolTip = str(Translator.translate('Stop active simulation'))
|
||||||
|
return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||||
|
|
||||||
FreeCADGui.addCommand('Ship_LoadExample', LoadExample())
|
FreeCADGui.addCommand('Ship_LoadExample', LoadExample())
|
||||||
FreeCADGui.addCommand('Ship_CreateShip', CreateShip())
|
FreeCADGui.addCommand('Ship_CreateShip', CreateShip())
|
||||||
FreeCADGui.addCommand('Ship_OutlineDraw', OutlineDraw())
|
FreeCADGui.addCommand('Ship_OutlineDraw', OutlineDraw())
|
||||||
|
@ -128,3 +164,6 @@ FreeCADGui.addCommand('Ship_Hydrostatics', Hydrostatics())
|
||||||
FreeCADGui.addCommand('Ship_Weights', SetWeights())
|
FreeCADGui.addCommand('Ship_Weights', SetWeights())
|
||||||
FreeCADGui.addCommand('Ship_CreateTank', CreateTank())
|
FreeCADGui.addCommand('Ship_CreateTank', CreateTank())
|
||||||
FreeCADGui.addCommand('Ship_GZ', GZ())
|
FreeCADGui.addCommand('Ship_GZ', GZ())
|
||||||
|
FreeCADGui.addCommand('Ship_CreateSim', CreateSim())
|
||||||
|
FreeCADGui.addCommand('Ship_RunSim', RunSim())
|
||||||
|
FreeCADGui.addCommand('Ship_StopSim', StopSim())
|
||||||
|
|
656
src/Mod/Ship/SimInstance.py
Normal file
656
src/Mod/Ship/SimInstance.py
Normal file
|
@ -0,0 +1,656 @@
|
||||||
|
#***************************************************************************
|
||||||
|
#* *
|
||||||
|
#* 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 time
|
||||||
|
from math import *
|
||||||
|
import threading
|
||||||
|
|
||||||
|
# COIN
|
||||||
|
from pivy.coin import *
|
||||||
|
from pivy import coin
|
||||||
|
|
||||||
|
# FreeCAD
|
||||||
|
import FreeCAD,FreeCADGui
|
||||||
|
from FreeCAD import Part, Base, Vector
|
||||||
|
|
||||||
|
# Ship design module
|
||||||
|
from shipUtils import Paths, Translator, Math
|
||||||
|
|
||||||
|
class FreeSurfaceFace:
|
||||||
|
def __init__(self, pos, normal, l, b):
|
||||||
|
""" Face storage.
|
||||||
|
@param pos Face position.
|
||||||
|
@param normal Face normal.
|
||||||
|
@param l Element length (distance between elements at x direction)
|
||||||
|
@param b Element beam (distance between elements at y direction)
|
||||||
|
"""
|
||||||
|
self.pos = pos
|
||||||
|
self.normal = normal
|
||||||
|
self.area = l*b
|
||||||
|
|
||||||
|
def __init__(self, pos, normal, area):
|
||||||
|
""" Face storage.
|
||||||
|
@param pos Face position.
|
||||||
|
@param normal Face normal.
|
||||||
|
@param area Element area
|
||||||
|
"""
|
||||||
|
self.pos = pos
|
||||||
|
self.normal = normal
|
||||||
|
self.area = area
|
||||||
|
|
||||||
|
class ShipSimulation:
|
||||||
|
def __init__(self, obj, fsMeshData, waves):
|
||||||
|
""" Creates a new simulation instance on active document.
|
||||||
|
@param obj Created Part::FeaturePython object.
|
||||||
|
@param fsMeshData [L,B,N] Free surface mesh data, with lenght
|
||||||
|
(x), Beam (y) and desired number of points.
|
||||||
|
@param waves [[A,T,phi,heading],] Waves involved
|
||||||
|
"""
|
||||||
|
# Add uniqueness property to identify Tank instances
|
||||||
|
obj.addProperty("App::PropertyBool","IsShipSimulation","ShipSimulation", str(Translator.translate("True if is a valid ship simulation instance"))).IsShipSimulation=True
|
||||||
|
# Compute free surface mesh
|
||||||
|
self.createFSMesh(obj,fsMeshData)
|
||||||
|
# Store waves
|
||||||
|
obj.addProperty("App::PropertyVectorList","Waves","ShipSimulation", str(Translator.translate("Waves (Amplitude,period,phase)"))).Waves=[]
|
||||||
|
obj.addProperty("App::PropertyFloatList","Waves_Dir","ShipSimulation", str(Translator.translate("Waves direction (0 deg to stern waves)"))).Waves_Dir=[]
|
||||||
|
w = []
|
||||||
|
d = []
|
||||||
|
for i in range(0,len(waves)):
|
||||||
|
w.append(Vector(waves[i][0], waves[i][1], waves[i][2]))
|
||||||
|
d.append(waves[i][3])
|
||||||
|
obj.Waves = w
|
||||||
|
obj.Waves_Dir = d
|
||||||
|
# Add shapes
|
||||||
|
shape = self.computeShape(obj)
|
||||||
|
if not shape:
|
||||||
|
obj.IsShipSimulation=False
|
||||||
|
return
|
||||||
|
obj.Shape = shape
|
||||||
|
obj.Proxy = self
|
||||||
|
|
||||||
|
def onChanged(self, fp, prop):
|
||||||
|
""" Property changed, tank must be recomputed """
|
||||||
|
if prop == "IsShipSimulation":
|
||||||
|
FreeCAD.Console.PrintWarning("Ussually you don't want to modify manually this option.\n")
|
||||||
|
|
||||||
|
def execute(self, obj):
|
||||||
|
""" Shape recomputation called """
|
||||||
|
obj.Shape = self.computeShape(obj)
|
||||||
|
|
||||||
|
def createFSMesh(self, obj, fsMeshData):
|
||||||
|
""" Create or modify free surface mesh.
|
||||||
|
@param obj Created Part::FeaturePython object.
|
||||||
|
@param fsMeshData [L,B,N] Free surface mesh data, with lenght
|
||||||
|
(x), Beam (y) and desired number of points.
|
||||||
|
"""
|
||||||
|
# Study input object
|
||||||
|
try:
|
||||||
|
props = obj.PropertiesList
|
||||||
|
props.index("IsShipSimulation")
|
||||||
|
if not obj.IsShipSimulation:
|
||||||
|
msg = str(Translator.translate("Object is not a valid ship simulation.\n"))
|
||||||
|
FreeCAD.Console.PrintError(msg)
|
||||||
|
return
|
||||||
|
except ValueError:
|
||||||
|
msg = str(Translator.translate("Object is not a ship simulation.\n"))
|
||||||
|
FreeCAD.Console.PrintError(msg)
|
||||||
|
return
|
||||||
|
# Get areas and number of elements per direction
|
||||||
|
L = fsMeshData[0]
|
||||||
|
B = fsMeshData[1]
|
||||||
|
N = fsMeshData[2]
|
||||||
|
A = L*B
|
||||||
|
area = A/N
|
||||||
|
l = sqrt(area)
|
||||||
|
b = sqrt(area)
|
||||||
|
nx = int(round(L / l))
|
||||||
|
ny = int(round(B / b))
|
||||||
|
# Start data fields if not already exist
|
||||||
|
props = obj.PropertiesList
|
||||||
|
try:
|
||||||
|
props.index("FS_Nx")
|
||||||
|
except ValueError:
|
||||||
|
obj.addProperty("App::PropertyInteger","FS_Nx","ShipSimulation", str(Translator.translate("Free surface number of elements at x direction"))).FS_Nx=0
|
||||||
|
try:
|
||||||
|
props.index("FS_Ny")
|
||||||
|
except ValueError:
|
||||||
|
obj.addProperty("App::PropertyInteger","FS_Ny","ShipSimulation", str(Translator.translate("Free surface number of elements at y direction"))).FS_Ny=0
|
||||||
|
try:
|
||||||
|
props.index("FS_Position")
|
||||||
|
except ValueError:
|
||||||
|
obj.addProperty("App::PropertyVectorList","FS_Position","ShipSimulation", str(Translator.translate("Free surface elements position"))).FS_Position=[]
|
||||||
|
try:
|
||||||
|
props.index("FS_Area")
|
||||||
|
except ValueError:
|
||||||
|
obj.addProperty("App::PropertyFloatList","FS_Area","ShipSimulation", str(Translator.translate("Free surface elements area"))).FS_Area=[]
|
||||||
|
try:
|
||||||
|
props.index("FS_Normal")
|
||||||
|
except ValueError:
|
||||||
|
obj.addProperty("App::PropertyVectorList","FS_Normal","ShipSimulation", str(Translator.translate("Free surface elements normal"))).FS_Normal=[]
|
||||||
|
# Fill data
|
||||||
|
obj.FS_Nx = nx
|
||||||
|
obj.FS_Ny = ny
|
||||||
|
pos = []
|
||||||
|
areas = []
|
||||||
|
normal = []
|
||||||
|
for i in range(0,nx):
|
||||||
|
for j in range(0,ny):
|
||||||
|
pos.append(Vector(-0.5*L + (i+0.5)*l,-0.5*B + (j+0.5)*b,0.0))
|
||||||
|
areas.append(l*b)
|
||||||
|
normal.append(Vector(0.0,0.0,1.0))
|
||||||
|
obj.FS_Position = pos[:]
|
||||||
|
obj.FS_Area = areas[:]
|
||||||
|
obj.FS_Normal = normal[:]
|
||||||
|
|
||||||
|
def computeShape(self, obj):
|
||||||
|
""" Computes simulation involved shapes.
|
||||||
|
@param obj Created Part::FeaturePython object.
|
||||||
|
@return Shape
|
||||||
|
"""
|
||||||
|
print("[ShipSimulation] Computing mesh shape...")
|
||||||
|
nx = obj.FS_Nx
|
||||||
|
ny = obj.FS_Ny
|
||||||
|
mesh = FSMesh(obj)
|
||||||
|
planes = []
|
||||||
|
# Create planes
|
||||||
|
Percentage = 0
|
||||||
|
Count = 0
|
||||||
|
print("0%")
|
||||||
|
for i in range(1,nx-1):
|
||||||
|
for j in range(1,ny-1):
|
||||||
|
Count = Count+1
|
||||||
|
done = int(round(100 * Count / ((nx-2)*(ny-2))))
|
||||||
|
if done != Percentage:
|
||||||
|
Percentage = done
|
||||||
|
print("%i%%" % (done))
|
||||||
|
v0 = (mesh[i][j].pos + mesh[i-1][j].pos + mesh[i][j-1].pos + mesh[i-1][j-1].pos).multiply(0.25)
|
||||||
|
v1 = (mesh[i][j].pos + mesh[i+1][j].pos + mesh[i][j-1].pos + mesh[i+1][j-1].pos).multiply(0.25)
|
||||||
|
v2 = (mesh[i][j].pos + mesh[i+1][j].pos + mesh[i][j+1].pos + mesh[i+1][j+1].pos).multiply(0.25)
|
||||||
|
v3 = (mesh[i][j].pos + mesh[i-1][j].pos + mesh[i][j+1].pos + mesh[i-1][j+1].pos).multiply(0.25)
|
||||||
|
p = Part.makePolygon([v0,v1,v2,v3,v0])
|
||||||
|
planes.append(Part.makeFilledFace(p.Edges))
|
||||||
|
# Join into a compound
|
||||||
|
return Part.makeCompound(planes)
|
||||||
|
|
||||||
|
class ViewProviderShipSimulation:
|
||||||
|
def __init__(self, obj):
|
||||||
|
""" Set this object to the proxy object of the actual view provider """
|
||||||
|
obj.Proxy = self
|
||||||
|
|
||||||
|
def attach(self, obj):
|
||||||
|
""" Setup the scene sub-graph of the view provider, this method is mandatory """
|
||||||
|
return
|
||||||
|
|
||||||
|
def updateData(self, fp, prop):
|
||||||
|
""" If a property of the handled feature has changed we have the chance to handle this here """
|
||||||
|
return
|
||||||
|
|
||||||
|
def getDisplayModes(self,obj):
|
||||||
|
''' Return a list of display modes. '''
|
||||||
|
modes=[]
|
||||||
|
return modes
|
||||||
|
|
||||||
|
def getDefaultDisplayMode(self):
|
||||||
|
''' Return the name of the default display mode. It must be defined in getDisplayModes. '''
|
||||||
|
return "Flat Lines"
|
||||||
|
|
||||||
|
def setDisplayMode(self,mode):
|
||||||
|
''' Map the display mode defined in attach with those defined in getDisplayModes.
|
||||||
|
Since they have the same names nothing needs to be done. This method is optinal.
|
||||||
|
'''
|
||||||
|
return mode
|
||||||
|
|
||||||
|
def onChanged(self, vp, prop):
|
||||||
|
''' Print the name of the property that has changed '''
|
||||||
|
# FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
|
||||||
|
|
||||||
|
def __getstate__(self):
|
||||||
|
''' When saving the document this object gets stored using Python's cPickle module.
|
||||||
|
Since we have some un-pickable here -- the Coin stuff -- we must define this method
|
||||||
|
to return a tuple of all pickable objects or None.
|
||||||
|
'''
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __setstate__(self,state):
|
||||||
|
''' When restoring the pickled object from document we have the chance to set some
|
||||||
|
internals here. Since no data were pickled nothing needs to be done here.
|
||||||
|
'''
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getIcon(self):
|
||||||
|
return """
|
||||||
|
/* XPM */
|
||||||
|
static char * Sim_xpm[] = {
|
||||||
|
"32 32 301 2",
|
||||||
|
" c None",
|
||||||
|
". c #CCCCCC",
|
||||||
|
"+ c #A9A9A9",
|
||||||
|
"@ c #989898",
|
||||||
|
"# c #A1A1A1",
|
||||||
|
"$ c #C3C3C3",
|
||||||
|
"% c #C1C0C1",
|
||||||
|
"& c #BFBFBF",
|
||||||
|
"* c #A7A7A7",
|
||||||
|
"= c #808080",
|
||||||
|
"- c #5C5C5C",
|
||||||
|
"; c #565655",
|
||||||
|
"> c #4E4E4E",
|
||||||
|
", c #676767",
|
||||||
|
"' c #898989",
|
||||||
|
") c #B6B5B6",
|
||||||
|
"! c #BABABA",
|
||||||
|
"~ c #B9B9B9",
|
||||||
|
"{ c #A5A5A5",
|
||||||
|
"] c #7E7E7E",
|
||||||
|
"^ c #595A59",
|
||||||
|
"/ c #575656",
|
||||||
|
"( c #535353",
|
||||||
|
"_ c #505050",
|
||||||
|
": c #4D4D4C",
|
||||||
|
"< c #474747",
|
||||||
|
"[ c #404040",
|
||||||
|
"} c #4D4D4D",
|
||||||
|
"| c #787878",
|
||||||
|
"1 c #B8B7B8",
|
||||||
|
"2 c #B6B6B6",
|
||||||
|
"3 c #888888",
|
||||||
|
"4 c #7C7C7C",
|
||||||
|
"5 c #575657",
|
||||||
|
"6 c #535354",
|
||||||
|
"7 c #4E4D4E",
|
||||||
|
"8 c #4A4A4A",
|
||||||
|
"9 c #444444",
|
||||||
|
"0 c #414141",
|
||||||
|
"a c #3E3E3E",
|
||||||
|
"b c #393938",
|
||||||
|
"c c #313131",
|
||||||
|
"d c #393939",
|
||||||
|
"e c #636363",
|
||||||
|
"f c #ABABAB",
|
||||||
|
"g c #B3B3B3",
|
||||||
|
"h c #848484",
|
||||||
|
"i c #787979",
|
||||||
|
"j c #545454",
|
||||||
|
"k c #515151",
|
||||||
|
"l c #4B4B4B",
|
||||||
|
"m c #484748",
|
||||||
|
"n c #3B3B3B",
|
||||||
|
"o c #383838",
|
||||||
|
"p c #353535",
|
||||||
|
"q c #323232",
|
||||||
|
"r c #2F2F2E",
|
||||||
|
"s c #2A2A2A",
|
||||||
|
"t c #222323",
|
||||||
|
"u c #252625",
|
||||||
|
"v c #AFAFAF",
|
||||||
|
"w c #767676",
|
||||||
|
"x c #484848",
|
||||||
|
"y c #454545",
|
||||||
|
"z c #424242",
|
||||||
|
"A c #3F3F3E",
|
||||||
|
"B c #3B3B3C",
|
||||||
|
"C c #393838",
|
||||||
|
"D c #2F2F2F",
|
||||||
|
"E c #2C2C2C",
|
||||||
|
"F c #292929",
|
||||||
|
"G c #262626",
|
||||||
|
"H c #222222",
|
||||||
|
"I c #1F1F20",
|
||||||
|
"J c #171716",
|
||||||
|
"K c #959595",
|
||||||
|
"L c #747474",
|
||||||
|
"M c #4E4E4F",
|
||||||
|
"N c #4C4B4C",
|
||||||
|
"O c #484849",
|
||||||
|
"P c #424243",
|
||||||
|
"Q c #282828",
|
||||||
|
"R c #525251",
|
||||||
|
"S c #373737",
|
||||||
|
"T c #353636",
|
||||||
|
"U c #333233",
|
||||||
|
"V c #30302F",
|
||||||
|
"W c #2C2D2D",
|
||||||
|
"X c #232323",
|
||||||
|
"Y c #201F20",
|
||||||
|
"Z c #1D1D1D",
|
||||||
|
"` c #151414",
|
||||||
|
" . c #717272",
|
||||||
|
".. c #4C4C4C",
|
||||||
|
"+. c #484949",
|
||||||
|
"@. c #464545",
|
||||||
|
"#. c #424343",
|
||||||
|
"$. c #3A3A3A",
|
||||||
|
"%. c #5D4A49",
|
||||||
|
"&. c #7E7E86",
|
||||||
|
"*. c #56569F",
|
||||||
|
"=. c #3E3E41",
|
||||||
|
"-. c #757575",
|
||||||
|
";. c #575757",
|
||||||
|
">. c #222221",
|
||||||
|
",. c #262627",
|
||||||
|
"'. c #242423",
|
||||||
|
"). c #212020",
|
||||||
|
"!. c #1A1A1A",
|
||||||
|
"~. c #121212",
|
||||||
|
"{. c #939493",
|
||||||
|
"]. c #6F6F6F",
|
||||||
|
"^. c #494949",
|
||||||
|
"/. c #464646",
|
||||||
|
"(. c #434343",
|
||||||
|
"_. c #554545",
|
||||||
|
":. c #686863",
|
||||||
|
"<. c #939394",
|
||||||
|
"[. c #BDBDBD",
|
||||||
|
"}. c #202021",
|
||||||
|
"|. c #1E1E1E",
|
||||||
|
"1. c #171718",
|
||||||
|
"2. c #0F0F0F",
|
||||||
|
"3. c #929292",
|
||||||
|
"4. c #6C6D6D",
|
||||||
|
"5. c #464746",
|
||||||
|
"6. c #525F73",
|
||||||
|
"7. c #444648",
|
||||||
|
"8. c #3D3D3D",
|
||||||
|
"9. c #2D2C2A",
|
||||||
|
"0. c #A1A2A2",
|
||||||
|
"a. c #AAACAC",
|
||||||
|
"b. c #A6A7A7",
|
||||||
|
"c. c #A8AAAA",
|
||||||
|
"d. c #AFB0B0",
|
||||||
|
"e. c #777676",
|
||||||
|
"f. c #9A9A9A",
|
||||||
|
"g. c #1B1B1B",
|
||||||
|
"h. c #181818",
|
||||||
|
"i. c #0C0C0C",
|
||||||
|
"j. c #909090",
|
||||||
|
"k. c #6B6A6B",
|
||||||
|
"l. c #55657E",
|
||||||
|
"m. c #6990FB",
|
||||||
|
"n. c #6483CD",
|
||||||
|
"o. c #5871B2",
|
||||||
|
"p. c #434E7E",
|
||||||
|
"q. c #A97C76",
|
||||||
|
"r. c #AB7777",
|
||||||
|
"s. c #AC7070",
|
||||||
|
"t. c #A26565",
|
||||||
|
"u. c #805C5C",
|
||||||
|
"v. c #848686",
|
||||||
|
"w. c #424342",
|
||||||
|
"x. c #151515",
|
||||||
|
"y. c #0A0909",
|
||||||
|
"z. c #8F8F8F",
|
||||||
|
"A. c #676868",
|
||||||
|
"B. c #3B3A3A",
|
||||||
|
"C. c #383738",
|
||||||
|
"D. c #353534",
|
||||||
|
"E. c #45525F",
|
||||||
|
"F. c #6367AC",
|
||||||
|
"G. c #804682",
|
||||||
|
"H. c #942A39",
|
||||||
|
"I. c #991312",
|
||||||
|
"J. c #540901",
|
||||||
|
"K. c #393742",
|
||||||
|
"L. c #1C1C1C",
|
||||||
|
"M. c #191919",
|
||||||
|
"N. c #161515",
|
||||||
|
"O. c #121313",
|
||||||
|
"P. c #070707",
|
||||||
|
"Q. c #8D8E8D",
|
||||||
|
"R. c #656566",
|
||||||
|
"S. c #3E3F3F",
|
||||||
|
"T. c #2F2E2F",
|
||||||
|
"U. c #353838",
|
||||||
|
"V. c #35496A",
|
||||||
|
"W. c #3E4D88",
|
||||||
|
"X. c #354889",
|
||||||
|
"Y. c #5573D7",
|
||||||
|
"Z. c #5D80FB",
|
||||||
|
"`. c #374899",
|
||||||
|
" + c #293338",
|
||||||
|
".+ c #101010",
|
||||||
|
"++ c #0D0D0D",
|
||||||
|
"@+ c #040404",
|
||||||
|
"#+ c #8C8C8C",
|
||||||
|
"$+ c #8B8B8B",
|
||||||
|
"%+ c #4B4A4B",
|
||||||
|
"&+ c #303030",
|
||||||
|
"*+ c #333232",
|
||||||
|
"=+ c #2F2F30",
|
||||||
|
"-+ c #232223",
|
||||||
|
";+ c #1A1919",
|
||||||
|
">+ c #2E3949",
|
||||||
|
",+ c #5C7BA3",
|
||||||
|
"'+ c #36467D",
|
||||||
|
")+ c #536F93",
|
||||||
|
"!+ c #0A0A0A",
|
||||||
|
"~+ c #010101",
|
||||||
|
"{+ c #C1C1C1",
|
||||||
|
"]+ c #B8B8B8",
|
||||||
|
"^+ c #A0A0A0",
|
||||||
|
"/+ c #3F3F3F",
|
||||||
|
"(+ c #222122",
|
||||||
|
"_+ c #202020",
|
||||||
|
":+ c #161717",
|
||||||
|
"<+ c #141414",
|
||||||
|
"[+ c #111011",
|
||||||
|
"}+ c #0D0E0E",
|
||||||
|
"|+ c #0B0B0A",
|
||||||
|
"1+ c #000000",
|
||||||
|
"2+ c #525252",
|
||||||
|
"3+ c #686868",
|
||||||
|
"4+ c #ADADAD",
|
||||||
|
"5+ c #9E9F9F",
|
||||||
|
"6+ c #6D6D6D",
|
||||||
|
"7+ c #3C3C3C",
|
||||||
|
"8+ c #131414",
|
||||||
|
"9+ c #111111",
|
||||||
|
"0+ c #0E0E0E",
|
||||||
|
"a+ c #0B0B0B",
|
||||||
|
"b+ c #080708",
|
||||||
|
"c+ c #050504",
|
||||||
|
"d+ c #4C4D4C",
|
||||||
|
"e+ c #4D4C4D",
|
||||||
|
"f+ c #494A4A",
|
||||||
|
"g+ c #454444",
|
||||||
|
"h+ c #9D9D9D",
|
||||||
|
"i+ c #9E9E9E",
|
||||||
|
"j+ c #AEAEAE",
|
||||||
|
"k+ c #BEBEBF",
|
||||||
|
"l+ c #BEBDBD",
|
||||||
|
"m+ c #979797",
|
||||||
|
"n+ c #6A6B6A",
|
||||||
|
"o+ c #3F3F40",
|
||||||
|
"p+ c #020202",
|
||||||
|
"q+ c #030303",
|
||||||
|
"r+ c #878787",
|
||||||
|
"s+ c #69696A",
|
||||||
|
"t+ c #868685",
|
||||||
|
"u+ c #646464",
|
||||||
|
"v+ c #474647",
|
||||||
|
"w+ c #656565",
|
||||||
|
"x+ c #9E9F9E",
|
||||||
|
"y+ c #A8A8A8",
|
||||||
|
"z+ c #AFAFAE",
|
||||||
|
"A+ c #A4A4A4",
|
||||||
|
"B+ c #7A7A7A",
|
||||||
|
"C+ c #969696",
|
||||||
|
"D+ c #363636",
|
||||||
|
"E+ c #777776",
|
||||||
|
"F+ c #8C8D8D",
|
||||||
|
"G+ c #7D7D7D",
|
||||||
|
"H+ c #5E5E5E",
|
||||||
|
"I+ c #4F4F50",
|
||||||
|
"J+ c #808181",
|
||||||
|
"K+ c #707070",
|
||||||
|
"L+ c #909191",
|
||||||
|
"M+ c #9C9C9C",
|
||||||
|
"N+ c #787877",
|
||||||
|
"O+ c #696969",
|
||||||
|
"P+ c #616161",
|
||||||
|
"Q+ c #6E6E6E",
|
||||||
|
"R+ c #7C7B7C",
|
||||||
|
"S+ c #777677",
|
||||||
|
"T+ c #6F6E6E",
|
||||||
|
"U+ c #595959",
|
||||||
|
"V+ c #717171",
|
||||||
|
"W+ c #8D8D8D",
|
||||||
|
"X+ c #515051",
|
||||||
|
"Y+ c #49494A",
|
||||||
|
"Z+ c #4B4A4A",
|
||||||
|
"`+ c #606060",
|
||||||
|
" @ c #6A6A6A",
|
||||||
|
".@ c #616162",
|
||||||
|
"+@ c #6C6D6C",
|
||||||
|
"@@ c #767777",
|
||||||
|
"#@ c #727272",
|
||||||
|
"$@ c #6B6B6B",
|
||||||
|
"%@ c #828283",
|
||||||
|
"&@ c #757475",
|
||||||
|
"*@ c #444545",
|
||||||
|
"=@ c #565656",
|
||||||
|
"-@ c #5A595A",
|
||||||
|
";@ c #666666",
|
||||||
|
">@ c #878687",
|
||||||
|
",@ c #8A8A8A",
|
||||||
|
"'@ c #797979",
|
||||||
|
")@ c #444344",
|
||||||
|
"!@ c #7F8080",
|
||||||
|
"~@ c #737373",
|
||||||
|
"{@ c #484747",
|
||||||
|
"]@ c #707170",
|
||||||
|
"^@ c #7F7F7F",
|
||||||
|
"/@ c #676867",
|
||||||
|
"(@ c #4D4C4C",
|
||||||
|
"_@ c #5F5F5F",
|
||||||
|
":@ c #434444",
|
||||||
|
" ",
|
||||||
|
" ",
|
||||||
|
" . + ",
|
||||||
|
" @ # $ % & * ",
|
||||||
|
" = - ; > , ' ) ! ~ { ",
|
||||||
|
" ] ^ / ( _ : < [ } | # 1 2 # 3 ",
|
||||||
|
" 4 5 6 _ 7 8 < 9 0 a b c d e ' f g + h ",
|
||||||
|
" i j k 7 l m 9 0 a n o p q r s t u < | v ",
|
||||||
|
" w k > l x y z A B C p q D E F G H I J K ",
|
||||||
|
" L M N O y P Q R S T U V W F G X Y Z ` K ",
|
||||||
|
" ...+.@.#.$.%.&.*.=.-.;.>.,.'.).Z !.~.{. ",
|
||||||
|
" ].^./.(.[ c _._ :.<.[.$ ' /.}.|.!.1.2.3. ",
|
||||||
|
" 4.5.6.7.8.9.# 0.a.b.c.d.e.f.g.g.h.` i.j. ",
|
||||||
|
" k.9 l.m.n.o.p.q.r.s.t.u.v.w.g.h.x.~.y.z. ",
|
||||||
|
" A.0 a B.C.D.E.F.G.H.I.J.K.L.M.N.O.2.P.Q. ",
|
||||||
|
" R.S.n o p q T.E U.V.W.X.Y.Z.`. +.+++@+#+ ",
|
||||||
|
" $+%+&+q *+=+E F G -+I Z ;+>+,+'+)+!+~+$+ ",
|
||||||
|
" {+]+^+w /+H (+X _+Z !.:+<+[+}+|+P.1+' ",
|
||||||
|
" k 2+_ > 3+z.4+5+6+7+x.~.8+9+0+a+b+c+1+3 ",
|
||||||
|
" %+..d+e+..f+< g+h+i+j+k+l+m+n+o+P.p+q+p+1+r+ ",
|
||||||
|
" s+t+u+< (.< v+y 9 (.w+x+y+z+y+h+A+B+C+K ].D+1+h ",
|
||||||
|
" E+i+F+f.j.G+H+9 [ (.z I+J+m+f.j.K+z 9 9 9 K+L+r+/.9 (. ",
|
||||||
|
" L M+N+O+u+P+Q+R+S+T+U+y 8 - ;...9 9 9 9 9 9 9 9 (.(.k w+ ",
|
||||||
|
" V+m+' W+r+] , X+Y+(.: r+L P+k 9 z (.9 9 9 9 (.(.Z+;.- `+ ",
|
||||||
|
" ].C+w @u+.@+@@@#@$@j %@B+&@#@L $@H+2+/.0 (.*@+.} 2+=@-@ ",
|
||||||
|
" ;@| >@,@'@u+k 8 )@..!@| ~@V+#@#@#@#@L 6+..(.9 {@.._ ( ",
|
||||||
|
" e ]@^@] /@k G+w #@#@#@#@#@V+ @$@_ 9 9 9 /.Y+(@ ",
|
||||||
|
" - R.T+L ~@#@#@#@#@]._ _@_ 9 9 9 (.9 x ",
|
||||||
|
" =@_@O+L ~@#@~@L _ 9 9 :@ ",
|
||||||
|
" ;.H+ @-._ (. ",
|
||||||
|
" ",
|
||||||
|
" "};
|
||||||
|
"""
|
||||||
|
|
||||||
|
def FSMesh(obj, recompute=False):
|
||||||
|
""" Get free surface mesh in matrix mode.
|
||||||
|
@param obj Created Part::FeaturePython object.
|
||||||
|
@param recompute True if mesh must be recomputed, False otherwise.
|
||||||
|
@return Faces matrix
|
||||||
|
"""
|
||||||
|
nx = obj.FS_Nx
|
||||||
|
ny = obj.FS_Ny
|
||||||
|
if not recompute:
|
||||||
|
faces = []
|
||||||
|
for i in range(0,nx):
|
||||||
|
faces.append([])
|
||||||
|
for j in range(0,ny):
|
||||||
|
faces[i].append(FreeSurfaceFace(obj.FS_Position[j + i*ny],
|
||||||
|
obj.FS_Normal[j + i*ny],
|
||||||
|
obj.FS_Area[j + i*ny]))
|
||||||
|
return faces
|
||||||
|
# Transform positions into a mesh
|
||||||
|
pos = []
|
||||||
|
for i in range(0,nx):
|
||||||
|
pos.append([])
|
||||||
|
for j in range(0,ny):
|
||||||
|
pos[i].append(obj.FS_Position[j + i*ny])
|
||||||
|
# Recompute normals and dimensions
|
||||||
|
normal = []
|
||||||
|
l = []
|
||||||
|
b = []
|
||||||
|
for i in range(0,nx):
|
||||||
|
normal.append([])
|
||||||
|
l.append([])
|
||||||
|
b.append([])
|
||||||
|
for j in range(0,ny):
|
||||||
|
i0 = i-1
|
||||||
|
i1 = i+1
|
||||||
|
fi = 1.0
|
||||||
|
j0 = j-1
|
||||||
|
j1 = j+1
|
||||||
|
fj = 1.0
|
||||||
|
if i == 0:
|
||||||
|
i0 = i
|
||||||
|
i1 = i+1
|
||||||
|
fi = 2.0
|
||||||
|
if i == nx-1:
|
||||||
|
i0 = i-1
|
||||||
|
i1 = i
|
||||||
|
fi = 2.0
|
||||||
|
if j == 0:
|
||||||
|
j0 = j
|
||||||
|
j1 = j+1
|
||||||
|
fj = 2.0
|
||||||
|
if j == ny-1:
|
||||||
|
j0 = j-1
|
||||||
|
j1 = j
|
||||||
|
fj = 2.0
|
||||||
|
l[i].append(fi*(obj.FS_Position[j + i1*ny].x - obj.FS_Position[j + i0*ny].x))
|
||||||
|
b[i].append(fj*(obj.FS_Position[j1 + i*ny].y - obj.FS_Position[j0 + i*ny].y))
|
||||||
|
xvec = Vector(obj.FS_Position[j + i1*ny].x - obj.FS_Position[j + i0*ny].x,
|
||||||
|
obj.FS_Position[j + i1*ny].y - obj.FS_Position[j + i0*ny].y,
|
||||||
|
obj.FS_Position[j + i1*ny].z - obj.FS_Position[j + i0*ny].z)
|
||||||
|
yvec = Vector(obj.FS_Position[j1 + i*ny].x - obj.FS_Position[j0 + i*ny].x,
|
||||||
|
obj.FS_Position[j1 + i*ny].y - obj.FS_Position[j0 + i*ny].y,
|
||||||
|
obj.FS_Position[j1 + i*ny].z - obj.FS_Position[j0 + i*ny].z)
|
||||||
|
n = Vector(xvec.cross(yvec)) # Z positive
|
||||||
|
normal[i].append(n.normalize())
|
||||||
|
# Create faces
|
||||||
|
faces = []
|
||||||
|
for i in range(0,nx):
|
||||||
|
faces.append([])
|
||||||
|
for j in range(0,ny):
|
||||||
|
faces[i].append(FreeSurfaceFace(pos[i][j], normal[i][j], l[i][j], b[i][j]))
|
||||||
|
# Reconstruct mesh data
|
||||||
|
for i in range(0,nx):
|
||||||
|
for j in range(0,ny):
|
||||||
|
obj.FS_Position[j + i*ny] = faces[i][j].pos
|
||||||
|
obj.FS_Normal[j + i*ny] = faces[i][j].normal
|
||||||
|
obj.FS_Area[j + i*ny] = faces[i][j].area
|
||||||
|
return faces
|
|
@ -31,7 +31,6 @@ from PyQt4 import QtGui,QtCore
|
||||||
import Plot
|
import Plot
|
||||||
import Instance
|
import Instance
|
||||||
from shipUtils import Paths, Translator
|
from shipUtils import Paths, Translator
|
||||||
from surfUtils import Geometry
|
|
||||||
import Tools
|
import Tools
|
||||||
|
|
||||||
class TaskPanel:
|
class TaskPanel:
|
||||||
|
@ -45,7 +44,7 @@ class TaskPanel:
|
||||||
self.save()
|
self.save()
|
||||||
draft = self.form.minDraft.value()
|
draft = self.form.minDraft.value()
|
||||||
drafts = [draft]
|
drafts = [draft]
|
||||||
dDraft = (self.form.maxDraft.value() - self.form.minDraft.value())/self.form.nDraft.value()
|
dDraft = (self.form.maxDraft.value() - self.form.minDraft.value())/(self.form.nDraft.value()-1)
|
||||||
for i in range(1,self.form.nDraft.value()):
|
for i in range(1,self.form.nDraft.value()):
|
||||||
draft = draft + dDraft
|
draft = draft + dDraft
|
||||||
drafts.append(draft)
|
drafts.append(draft)
|
||||||
|
@ -108,7 +107,7 @@ class TaskPanel:
|
||||||
""" Set initial values for fields
|
""" Set initial values for fields
|
||||||
"""
|
"""
|
||||||
# Get objects
|
# Get objects
|
||||||
selObjs = Geometry.getSelectedObjs()
|
selObjs = Gui.Selection.getSelection()
|
||||||
if not selObjs:
|
if not selObjs:
|
||||||
msg = Translator.translate("Ship instance must be selected (no object selected)\n")
|
msg = Translator.translate("Ship instance must be selected (no object selected)\n")
|
||||||
App.Console.PrintError(msg)
|
App.Console.PrintError(msg)
|
||||||
|
|
|
@ -279,9 +279,9 @@ def FloatingArea(ship, draft, trim):
|
||||||
# Valid face, compute area
|
# Valid face, compute area
|
||||||
area = area + f.Area
|
area = area + f.Area
|
||||||
maxX = max(maxX, faceBounds.XMax)
|
maxX = max(maxX, faceBounds.XMax)
|
||||||
minX = max(minX, faceBounds.XMin)
|
minX = min(minX, faceBounds.XMin)
|
||||||
maxY = max(maxY, faceBounds.YMax)
|
maxY = max(maxY, faceBounds.YMax)
|
||||||
minY = max(minY, faceBounds.YMin)
|
minY = min(minY, faceBounds.YMin)
|
||||||
# Destroy last object generated
|
# Destroy last object generated
|
||||||
App.ActiveDocument.removeObject(App.ActiveDocument.Objects[-1].Name)
|
App.ActiveDocument.removeObject(App.ActiveDocument.Objects[-1].Name)
|
||||||
dx = maxX - minX
|
dx = maxX - minX
|
||||||
|
@ -416,7 +416,7 @@ class Point:
|
||||||
self.wet = wet
|
self.wet = wet
|
||||||
self.farea = farea[0]
|
self.farea = farea[0]
|
||||||
self.mom = mom
|
self.mom = mom
|
||||||
self.KBt = dispData[1].y
|
self.KBt = dispData[1].z
|
||||||
self.BMt = bm
|
self.BMt = bm
|
||||||
self.Cb = dispData[2]
|
self.Cb = dispData[2]
|
||||||
self.Cf = farea[1]
|
self.Cf = farea[1]
|
||||||
|
|
174
src/Mod/Ship/simCreate/TaskPanel.py
Normal file
174
src/Mod/Ship/simCreate/TaskPanel.py
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
#***************************************************************************
|
||||||
|
#* *
|
||||||
|
#* 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 SimInstance
|
||||||
|
from shipUtils import Paths, Translator
|
||||||
|
|
||||||
|
class TaskPanel:
|
||||||
|
def __init__(self):
|
||||||
|
self.ui = Paths.modulePath() + "/simCreate/TaskPanel.ui"
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
form = self.form
|
||||||
|
# Read waves data
|
||||||
|
w = []
|
||||||
|
for i in range(0,form.waves.rowCount() - 1):
|
||||||
|
item = form.waves.item(i,0)
|
||||||
|
A = item.text().toFloat()[0]
|
||||||
|
item = form.waves.item(i,1)
|
||||||
|
T = item.text().toFloat()[0]
|
||||||
|
item = form.waves.item(i,2)
|
||||||
|
phi = item.text().toFloat()[0]
|
||||||
|
item = form.waves.item(i,3)
|
||||||
|
head = item.text().toFloat()[0]
|
||||||
|
w.append([A,T,phi,head])
|
||||||
|
obj = App.ActiveDocument.addObject("Part::FeaturePython","ShipSimulation")
|
||||||
|
sim = SimInstance.ShipSimulation(obj,
|
||||||
|
[form.length.value(), form.beam.value(), form.n.value()],
|
||||||
|
w)
|
||||||
|
SimInstance.ViewProviderShipSimulation(obj.ViewObject)
|
||||||
|
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.length = form.findChild(QtGui.QDoubleSpinBox, "Length")
|
||||||
|
form.beam = form.findChild(QtGui.QDoubleSpinBox, "Beam")
|
||||||
|
form.n = form.findChild(QtGui.QSpinBox, "N")
|
||||||
|
form.waves = form.findChild(QtGui.QTableWidget, "Waves")
|
||||||
|
self.form = form
|
||||||
|
# Initial values
|
||||||
|
if self.initValues():
|
||||||
|
return True
|
||||||
|
self.retranslateUi()
|
||||||
|
# Connect Signals and Slots
|
||||||
|
QtCore.QObject.connect(form.length, QtCore.SIGNAL("valueChanged(double)"), self.onFS)
|
||||||
|
QtCore.QObject.connect(form.beam, QtCore.SIGNAL("valueChanged(double)"), self.onFS)
|
||||||
|
QtCore.QObject.connect(form.n, QtCore.SIGNAL("valueChanged(int)"), self.onFS)
|
||||||
|
QtCore.QObject.connect(form.waves,QtCore.SIGNAL("cellChanged(int,int)"),self.onWaves);
|
||||||
|
|
||||||
|
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
|
||||||
|
"""
|
||||||
|
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("Create a new ship simulation"))
|
||||||
|
self.form.findChild(QtGui.QGroupBox, "FSDataBox").setTitle(Translator.translate("Free surface"))
|
||||||
|
self.form.findChild(QtGui.QLabel, "LengthLabel").setText(Translator.translate("Length"))
|
||||||
|
self.form.findChild(QtGui.QLabel, "BeamLabel").setText(Translator.translate("Beam"))
|
||||||
|
self.form.findChild(QtGui.QLabel, "NLabel").setText(Translator.translate("Number of points"))
|
||||||
|
self.form.findChild(QtGui.QGroupBox, "WavesDataBox").setTitle(Translator.translate("Waves"))
|
||||||
|
labels = []
|
||||||
|
labels.append(Translator.translate("Amplitude") + " [m]")
|
||||||
|
labels.append(Translator.translate("Period") + " [s]")
|
||||||
|
labels.append(Translator.translate("Phase") + " [rad]")
|
||||||
|
labels.append(Translator.translate("Heading") + " [deg]")
|
||||||
|
self.form.waves.setHorizontalHeaderLabels(labels)
|
||||||
|
|
||||||
|
def onFS(self, value):
|
||||||
|
""" Method called when free surface data is changed.
|
||||||
|
@param value Changed value.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def onWaves(self, row, column):
|
||||||
|
""" Method called when waves data is changed.
|
||||||
|
@param row Affected row.
|
||||||
|
@param col Affected column.
|
||||||
|
"""
|
||||||
|
item = self.form.waves.item(row,column)
|
||||||
|
# Row deletion
|
||||||
|
if column == 0:
|
||||||
|
if not item.text():
|
||||||
|
self.form.waves.removeRow(row)
|
||||||
|
# Ensure that exist one empty item at the end
|
||||||
|
nRow = self.form.waves.rowCount()
|
||||||
|
last = self.form.waves.item(nRow-1,0)
|
||||||
|
if last:
|
||||||
|
if(last.text() != ''):
|
||||||
|
self.form.waves.setRowCount(nRow+1)
|
||||||
|
# Fields must be numbers
|
||||||
|
for i in range(0,self.form.waves.rowCount()-1): # Avoid last row
|
||||||
|
for j in range(0,self.form.waves.columnCount()): # Avoid name column
|
||||||
|
item = self.form.waves.item(i,j)
|
||||||
|
if not item:
|
||||||
|
item = QtGui.QTableWidgetItem('0.0')
|
||||||
|
self.form.waves.setItem(i,j,item)
|
||||||
|
continue
|
||||||
|
(number,flag) = item.text().toFloat()
|
||||||
|
if not flag:
|
||||||
|
item.setText('0.0')
|
||||||
|
|
||||||
|
def createTask():
|
||||||
|
panel = TaskPanel()
|
||||||
|
Gui.Control.showDialog(panel)
|
||||||
|
if panel.setupUi():
|
||||||
|
Gui.Control.closeDialog(panel)
|
||||||
|
return None
|
||||||
|
return panel
|
269
src/Mod/Ship/simCreate/TaskPanel.ui
Normal file
269
src/Mod/Ship/simCreate/TaskPanel.ui
Normal file
|
@ -0,0 +1,269 @@
|
||||||
|
<?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>269</width>
|
||||||
|
<height>384</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>1</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>384</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Create new simulation</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinimumSize</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="FSDataBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>1</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>128</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Free surface</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinimumSize</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="LengthLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Length</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDoubleSpinBox" name="Length">
|
||||||
|
<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>100.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinimumSize</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="BeamLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Beam</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDoubleSpinBox" name="Beam">
|
||||||
|
<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>100.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetMinimumSize</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="NLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Number of points</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="N">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>1000000000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1000</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="WavesDataBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>2</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="baseSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Waves</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3" stretch="0">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetDefaultConstraint</enum>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QTableWidget" name="Waves">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="alternatingRowColors">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="rowCount">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<attribute name="horizontalHeaderVisible">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<row/>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Amplitude [m]</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Period [s]</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Phase [rad]</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
<column>
|
||||||
|
<property name="text">
|
||||||
|
<string>Heading [deg]</string>
|
||||||
|
</property>
|
||||||
|
</column>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
36
src/Mod/Ship/simCreate/__init__.py
Normal file
36
src/Mod/Ship/simCreate/__init__.py
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#***************************************************************************
|
||||||
|
#* *
|
||||||
|
#* 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()
|
96
src/Mod/Ship/simRun/Simulation.py
Normal file
96
src/Mod/Ship/simRun/Simulation.py
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#***************************************************************************
|
||||||
|
#* *
|
||||||
|
#* 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 time
|
||||||
|
from math import *
|
||||||
|
import threading
|
||||||
|
|
||||||
|
# pyOpenCL
|
||||||
|
import pyopencl as cl
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
# FreeCAD
|
||||||
|
import FreeCAD,FreeCADGui
|
||||||
|
from FreeCAD import Part, Base, Vector
|
||||||
|
|
||||||
|
# Ship design module
|
||||||
|
from shipUtils import Paths, Translator, Math
|
||||||
|
|
||||||
|
class Singleton(type):
|
||||||
|
def __init__(cls, name, bases, dct):
|
||||||
|
cls.__instance = None
|
||||||
|
type.__init__(cls, name, bases, dct)
|
||||||
|
|
||||||
|
def __call__(cls, *args, **kw):
|
||||||
|
if cls.__instance is None:
|
||||||
|
cls.__instance = type.__call__(cls, *args,**kw)
|
||||||
|
return cls.__instance
|
||||||
|
|
||||||
|
class FreeCADShipSimulation(threading.Thread):
|
||||||
|
__metaclass__ = Singleton
|
||||||
|
def __init__ (self, device, endTime, output, FSmesh, waves):
|
||||||
|
""" Thread constructor.
|
||||||
|
@param device Device to use.
|
||||||
|
@param endTime Maximum simulation time.
|
||||||
|
@param output [Rate,Type] Output rate, Type=0 if FPS, 1 if IPF.
|
||||||
|
@param FSmesh Free surface mesh faces.
|
||||||
|
@param waves Waves parameters (A,T,phi,heading)
|
||||||
|
"""
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
# Setup as stopped
|
||||||
|
self.active = False
|
||||||
|
# Build OpenCL context and command queue
|
||||||
|
self.device = device
|
||||||
|
self.context = cl.Context(devices=[self.device])
|
||||||
|
self.queue = cl.CommandQueue(self.context)
|
||||||
|
# Storage data
|
||||||
|
self.endTime = endTime
|
||||||
|
self.output = output
|
||||||
|
self.FSmesh = FSmesh
|
||||||
|
self.waves = waves
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
""" Runs the simulation.
|
||||||
|
"""
|
||||||
|
self.active = True
|
||||||
|
# Perform work here
|
||||||
|
while self.active:
|
||||||
|
print("Im thread, Im running...")
|
||||||
|
time.sleep(1)
|
||||||
|
# ...
|
||||||
|
print("Im thread, step done!")
|
||||||
|
# Set thread as stopped (and prepare it to restarting)
|
||||||
|
self.active = False
|
||||||
|
threading.Event().set()
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
""" Call to stop execution.
|
||||||
|
"""
|
||||||
|
self.active = False
|
||||||
|
|
||||||
|
def isRunning(self):
|
||||||
|
""" Report thread state
|
||||||
|
@return True if thread is running, False otherwise.
|
||||||
|
"""
|
||||||
|
return self.active
|
203
src/Mod/Ship/simRun/TaskPanel.py
Normal file
203
src/Mod/Ship/simRun/TaskPanel.py
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
#***************************************************************************
|
||||||
|
#* *
|
||||||
|
#* 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
|
||||||
|
# pyOpenCL
|
||||||
|
import pyopencl as cl
|
||||||
|
# Module
|
||||||
|
import SimInstance
|
||||||
|
from shipUtils import Paths, Translator
|
||||||
|
from Simulation import FreeCADShipSimulation as Sim
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
class TaskPanel:
|
||||||
|
def __init__(self):
|
||||||
|
self.ui = Paths.modulePath() + "/simRun/TaskPanel.ui"
|
||||||
|
self.sim = False
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
msg = Translator.translate("Building data...\n")
|
||||||
|
App.Console.PrintMessage(msg)
|
||||||
|
# Get GUI data
|
||||||
|
endTime = self.form.time.value()
|
||||||
|
output = []
|
||||||
|
output.append(self.form.output.value())
|
||||||
|
output.append(self.form.outputType.currentIndex())
|
||||||
|
devId = self.form.device.currentIndex()
|
||||||
|
# Get OpenCL device
|
||||||
|
count = 0
|
||||||
|
platforms = cl.get_platforms()
|
||||||
|
for p in platforms:
|
||||||
|
devs = p.get_devices()
|
||||||
|
for d in devs:
|
||||||
|
if count == devId:
|
||||||
|
device = d
|
||||||
|
count = count + 1
|
||||||
|
# Get free surfaces data
|
||||||
|
FSMesh = SimInstance.FSMesh(self.sim)
|
||||||
|
wData = self.sim.Waves
|
||||||
|
wDir = self.sim.Waves_Dir
|
||||||
|
waves = []
|
||||||
|
for i in range(0,len(wData)):
|
||||||
|
waves.append([wData[i].x, wData[i].y, wData[i].z, wDir[i]])
|
||||||
|
msg = Translator.translate("Launching simulation...\n")
|
||||||
|
App.Console.PrintMessage(msg)
|
||||||
|
# Build simulation thread
|
||||||
|
simulator = Sim(device, endTime, output, FSMesh, waves)
|
||||||
|
simulator.start()
|
||||||
|
msg = Translator.translate("Done!\n")
|
||||||
|
App.Console.PrintMessage(msg)
|
||||||
|
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.time = form.findChild(QtGui.QDoubleSpinBox, "SimTime")
|
||||||
|
form.output = form.findChild(QtGui.QDoubleSpinBox, "Output")
|
||||||
|
form.outputType = form.findChild(QtGui.QComboBox, "OutputType")
|
||||||
|
form.device = form.findChild(QtGui.QComboBox, "Device")
|
||||||
|
self.form = form
|
||||||
|
# Initial values
|
||||||
|
if self.initValues():
|
||||||
|
return True
|
||||||
|
self.retranslateUi()
|
||||||
|
# Connect Signals and Slots
|
||||||
|
# QtCore.QObject.connect(form.time, 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 = Gui.Selection.getSelection()
|
||||||
|
if not selObjs:
|
||||||
|
msg = Translator.translate("Ship simulation 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("IsShipSimulation")
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
if obj.IsShipSimulation:
|
||||||
|
# Test if another ship already selected
|
||||||
|
if self.sim:
|
||||||
|
msg = Translator.translate("More than one ship simulation selected (extra simulations will be neglected)\n")
|
||||||
|
App.Console.PrintWarning(msg)
|
||||||
|
break
|
||||||
|
self.sim = obj
|
||||||
|
# Test if any valid ship was selected
|
||||||
|
if not self.sim:
|
||||||
|
msg = Translator.translate("Ship simulation instance must be selected (no valid simulation found at selected objects)\n")
|
||||||
|
App.Console.PrintError(msg)
|
||||||
|
return True
|
||||||
|
# Get the list of devices
|
||||||
|
devices = []
|
||||||
|
platforms = cl.get_platforms()
|
||||||
|
for p in platforms:
|
||||||
|
devs = p.get_devices()
|
||||||
|
for d in devs:
|
||||||
|
devices.append([p,d])
|
||||||
|
dname = d.get_info(cl.device_info.NAME)
|
||||||
|
pname = p.get_info(cl.platform_info.NAME)
|
||||||
|
self.form.device.addItem(dname + " (" + pname + ")")
|
||||||
|
if not len(devices):
|
||||||
|
msg = Translator.translate("This tool requires an active OpenCL context to work\n")
|
||||||
|
App.Console.PrintError(msg)
|
||||||
|
return True
|
||||||
|
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("Run the simulation"))
|
||||||
|
self.form.findChild(QtGui.QLabel, "SimTimeLabel").setText(Translator.translate("Simulation time"))
|
||||||
|
self.form.findChild(QtGui.QLabel, "OutputLabel").setText(Translator.translate("Output"))
|
||||||
|
self.form.findChild(QtGui.QLabel, "DeviceLabel").setText(Translator.translate("OpenCL device"))
|
||||||
|
|
||||||
|
def createTask():
|
||||||
|
panel = TaskPanel()
|
||||||
|
Gui.Control.showDialog(panel)
|
||||||
|
if panel.setupUi():
|
||||||
|
Gui.Control.closeDialog(panel)
|
||||||
|
return None
|
||||||
|
return panel
|
||||||
|
|
||||||
|
def stopSimulation():
|
||||||
|
try:
|
||||||
|
simulator = Sim()
|
||||||
|
if not simulator.isRunning():
|
||||||
|
msg = Translator.translate("Simulation already stopped\n")
|
||||||
|
App.Console.PrintWarning(msg)
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
msg = Translator.translate("Any active simulation to stop!\n")
|
||||||
|
App.Console.PrintError(msg)
|
||||||
|
return
|
||||||
|
simulator.stop()
|
||||||
|
msg = Translator.translate("Simulation will stop at the end of actual iteration\n")
|
||||||
|
App.Console.PrintMessage(msg)
|
131
src/Mod/Ship/simRun/TaskPanel.ui
Normal file
131
src/Mod/Ship/simRun/TaskPanel.ui
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
<?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>300</width>
|
||||||
|
<height>102</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>1</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>100</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>300</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Create new simulation</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="SimTimeLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Simulation time</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="SimTime">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>10000000.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>10.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>3600.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QLabel" name="SimTimeUnitsLabel">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>s</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="OutputLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Output</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="Output">
|
||||||
|
<property name="maximum">
|
||||||
|
<double>10000.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QComboBox" name="OutputType">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>56</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string comment="FPS = Frames per second, IPF = Iterations per frame"/>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>FPS</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>IPF</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="DeviceLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>OpenCL device</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1" colspan="2">
|
||||||
|
<widget class="QComboBox" name="Device"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
40
src/Mod/Ship/simRun/__init__.py
Normal file
40
src/Mod/Ship/simRun/__init__.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#***************************************************************************
|
||||||
|
#* *
|
||||||
|
#* 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()
|
||||||
|
|
||||||
|
def stop():
|
||||||
|
""" Stops the simulation """
|
||||||
|
TaskPanel.stopSimulation()
|
Loading…
Reference in New Issue
Block a user