Started ship simulations workbench

This commit is contained in:
Jose Luis Cercós pita
2012-06-29 13:22:14 +02:00
committed by Yorik van Havre
parent 88ea348623
commit 80c9086fc3
13 changed files with 3610 additions and 4 deletions

View File

@@ -2,6 +2,7 @@ SET(ShipMain_SRCS
InitGui.py
ShipGui.py
Instance.py
SimInstance.py
TankInstance.py
)
SOURCE_GROUP("" FILES ${ShipMain_SRCS})
@@ -36,6 +37,11 @@ SET(ShipIcons_SRCS
Icons/Weight.png
Icons/Weight.xcf
Icons/Weight.xpm
Icons/SimIco.xcf
Icons/Sim.xpm
Icons/SimCreateIco.png
Icons/SimCreateIco.xcf
Icons/SimCreateIco.xpm
Icons/Tank.png
Icons/Tank.xcf
Icons/Tank.xpm
@@ -121,9 +127,16 @@ SET(ShipGZ_SRCS
tankGZ/TaskPanel.py
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(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})
ADD_CUSTOM_TARGET(Ship ALL
SOURCES ${all_files}
@@ -197,6 +210,12 @@ INSTALL(
DESTINATION
Mod/Ship/tankGZ
)
INSTALL(
FILES
${SimCreate_SRCS}
DESTINATION
Mod/Ship/simCreate
)
INSTALL(
FILES
${ShipMain_SRCS}

336
src/Mod/Ship/Icons/Sim.xpm Normal file
View 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+ @-._ (. ",
" ",
" "};

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -35,12 +35,16 @@ class ShipWorkbench ( Workbench ):
list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"]
self.appendToolbar("Ship design",list)
list = ["Ship_Weights", "Ship_CreateTank", "Ship_GZ"]
self.appendToolbar("Loading",list)
self.appendToolbar("Weights",list)
list = ["Ship_CreateSim"]
self.appendToolbar("Simulation",list)
# Menu
list = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"]
self.appendMenu("Ship design",list)
list = ["Ship_Weights", "Ship_CreateTank", "Ship_GZ"]
self.appendToolbar("Loading",list)
self.appendToolbar("Weights",list)
list = ["Ship_CreateSim"]
self.appendToolbar("Simulation",list)
Gui.addWorkbench(ShipWorkbench())

View File

@@ -5,6 +5,7 @@ data_DATA = \
InitGui.py \
ShipGui.py \
Instance.py \
SimInstance.py \
TankInstance.py
nobase_data_DATA = \
@@ -37,6 +38,11 @@ nobase_data_DATA = \
Icons/Weight.png \
Icons/Weight.xcf \
Icons/Weight.xpm \
Icons/SimIco.xcf \
Icons/Sim.xpm \
Icons/SimCreateIco.png \
Icons/SimCreateIco.xcf \
Icons/SimCreateIco.xpm \
Icons/Tank.png \
Icons/Tank.xcf \
Icons/Tank.xpm \
@@ -81,6 +87,9 @@ nobase_data_DATA = \
tankGZ/Plot.py \
tankGZ/TaskPanel.py \
tankGZ/TaskPanel.ui
simCreate/__init__.py \
simCreate/TaskPanel.py \
simCreate/TaskPanel.ui
CLEANFILES = $(BUILT_SOURCES)

View File

@@ -120,6 +120,18 @@ class GZ:
ToolTip = str(Translator.translate('Transversal stability GZ curve computation'))
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}
FreeCADGui.addCommand('Ship_LoadExample', LoadExample())
FreeCADGui.addCommand('Ship_CreateShip', CreateShip())
FreeCADGui.addCommand('Ship_OutlineDraw', OutlineDraw())
@@ -128,3 +140,4 @@ FreeCADGui.addCommand('Ship_Hydrostatics', Hydrostatics())
FreeCADGui.addCommand('Ship_Weights', SetWeights())
FreeCADGui.addCommand('Ship_CreateTank', CreateTank())
FreeCADGui.addCommand('Ship_GZ', GZ())
FreeCADGui.addCommand('Ship_CreateSim', CreateSim())

617
src/Mod/Ship/SimInstance.py Normal file
View File

@@ -0,0 +1,617 @@
#***************************************************************************
#* *
#* 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 *
# 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 Element length (distance between elements at x direction)
@param Element beam (distance between elements at y direction)
"""
self.pos = pos
self.normal = normal
self.area = l*b
class ShipSimulation:
def __init__(self, obj, fsMeshData):
""" 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.
"""
# 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)
# 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))
print(l,b,nx,ny)
# 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 FSMesh(self, obj):
""" Get free surface mesh in matrix mode.
@param obj Created Part::FeaturePython object.
@return Faces matrix
@note areas and normals will recomputed.
"""
nx = obj.FS_Nx
ny = obj.FS_Ny
# 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
def computeShape(self, obj):
""" Computes simulation involved shapes.
@param obj Created Part::FeaturePython object.
@return Shape
"""
nx = obj.FS_Nx
ny = obj.FS_Ny
mesh = self.FSMesh(obj)
planes = []
# Create planes
for i in range(1,nx-1):
for j in range(1,ny-1):
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+ @-._ (. ",
" ",
" "};
"""

View File

@@ -0,0 +1,125 @@
#***************************************************************************
#* *
#* 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
obj = App.ActiveDocument.addObject("Part::FeaturePython","ShipSimulation")
sim = SimInstance.ShipSimulation(obj,
[form.length.value(), form.beam.value(), form.n.value()])
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")
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)
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"))
def onFS(self, value):
""" Method called when ship data is changed.
Annotations must be showed.
@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

@@ -0,0 +1,182 @@
<?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="minimumSize">
<size>
<width>0</width>
<height>180</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">
<item>
<widget class="QGroupBox" name="FSDataBox">
<property name="minimumSize">
<size>
<width>240</width>
<height>160</height>
</size>
</property>
<property name="title">
<string>Free surface</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<widget class="QWidget" name="verticalLayoutWidget_2">
<property name="geometry">
<rect>
<x>0</x>
<y>20</y>
<width>241</width>
<height>141</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,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="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="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="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>10000</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View 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()