Regenerated the branch
This commit is contained in:
@@ -8,11 +8,6 @@ SET(ShipMain_SRCS
|
||||
)
|
||||
SOURCE_GROUP("" FILES ${ShipMain_SRCS})
|
||||
|
||||
SET(ShipIcons_SRCS
|
||||
resources/icons/Ico.xpm
|
||||
)
|
||||
SOURCE_GROUP("shipicons" FILES ${ShipIcons_SRCS})
|
||||
|
||||
SET(ShipExamples_SRCS
|
||||
resources/examples/s60.fcstd
|
||||
resources/examples/s60_katamaran.fcstd
|
||||
@@ -137,7 +132,7 @@ SET(SimPost_SRCS
|
||||
)
|
||||
SOURCE_GROUP("simpost" FILES ${SimPost_SRCS})
|
||||
|
||||
SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipExamples_SRCS} ${ShipOpenCL_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS} ${ShipWeights_SRCS} ${ShipCreateTank_SRCS} ${ShipGZ_SRCS} ${SimCreate_SRCS} ${SimRun_SRCS} ${SimPost_SRCS})
|
||||
SET(all_files ${ShipMain_SRCS} ${ShipExamples_SRCS} ${ShipOpenCL_SRCS} ${ShipLoadExample_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipHydrostatics_SRCS} ${ShipUtils_SRCS} ${ShipWeights_SRCS} ${ShipCreateTank_SRCS} ${ShipGZ_SRCS} ${SimCreate_SRCS} ${SimRun_SRCS} ${SimPost_SRCS})
|
||||
|
||||
ADD_CUSTOM_TARGET(Ship ALL
|
||||
SOURCES ${all_files}
|
||||
@@ -145,12 +140,6 @@ ADD_CUSTOM_TARGET(Ship ALL
|
||||
|
||||
fc_copy_sources(Mod/Ship "${CMAKE_BINARY_DIR}/Mod/Ship" ${all_files})
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${ShipIcons_SRCS}
|
||||
DESTINATION
|
||||
Mod/Ship/resources/icons
|
||||
)
|
||||
INSTALL(
|
||||
FILES
|
||||
${ShipExamples_SRCS}
|
||||
|
||||
@@ -1,74 +1,111 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
class ShipWorkbench ( Workbench ):
|
||||
""" @brief Workbench of Ship design module. Here toolbars & icons are append. """
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from shipUtils import Paths
|
||||
import ShipGui
|
||||
|
||||
Icon = "Ico"
|
||||
MenuText = str(QtCore.QT_TRANSLATE_NOOP("Ship", "Ship"))
|
||||
ToolTip = str(QtCore.QT_TRANSLATE_NOOP("Ship", "Ship module provides some of the commonly used tool to design ship forms"))
|
||||
class ShipWorkbench(Workbench):
|
||||
"""Ships design workbench."""
|
||||
from shipUtils import Paths
|
||||
import ShipGui
|
||||
|
||||
def Initialize(self):
|
||||
from PyQt4 import QtCore, QtGui
|
||||
Icon = "Ship_Module.svg"
|
||||
MenuText = "Ship"
|
||||
ToolTip = ("Ship module provides some of the commonly used tool to design"
|
||||
" ship forms")
|
||||
|
||||
def Initialize(self):
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
try:
|
||||
import Plot
|
||||
except ImportError:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Plot module is disabled, tools cannot graph output curves",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + '\n')
|
||||
# ToolBar
|
||||
shiplist = ["Ship_LoadExample",
|
||||
"Ship_CreateShip",
|
||||
"Ship_OutlineDraw",
|
||||
"Ship_AreasCurve",
|
||||
"Ship_Hydrostatics"]
|
||||
weightslist = ["Ship_Weights",
|
||||
"Ship_CreateTank",
|
||||
"Ship_GZ"]
|
||||
self.appendToolbar(
|
||||
str(QtCore.QT_TRANSLATE_NOOP("Ship", "Ship design")),
|
||||
shiplist)
|
||||
self.appendToolbar(
|
||||
str(QtCore.QT_TRANSLATE_NOOP("Ship", "Weights")),
|
||||
weightslist)
|
||||
self.appendMenu(
|
||||
str(QtCore.QT_TRANSLATE_NOOP("Ship", "Ship design")),
|
||||
shiplist)
|
||||
self.appendMenu(
|
||||
str(QtCore.QT_TRANSLATE_NOOP("Ship", "Weights")),
|
||||
weightslist)
|
||||
|
||||
# Simulation tools will be added only if pyOpenCL & numpy are present
|
||||
# Simulations are in development, so keep it disabled except for
|
||||
# development purposes
|
||||
hasSim = False
|
||||
if hasSim:
|
||||
hasOpenCL = True
|
||||
hasNumpy = True
|
||||
try:
|
||||
import pyopencl
|
||||
except ImportError:
|
||||
hasOpenCL = False
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"pyOpenCL not installed, simulation tools will disabled"
|
||||
" therefore",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + '\n')
|
||||
try:
|
||||
import numpy
|
||||
except ImportError:
|
||||
hasNumpy = False
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"numpy not installed, simulation tools will disabled"
|
||||
" therefore",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + '\n')
|
||||
if hasOpenCL and hasNumpy:
|
||||
simlist = ["Ship_CreateSim",
|
||||
"Ship_RunSim",
|
||||
"Ship_StopSim",
|
||||
"Ship_TrackSim"]
|
||||
self.appendToolbar(
|
||||
str(QtCore.QT_TRANSLATE_NOOP("Ship", "Simulation")),
|
||||
simlist)
|
||||
self.appendMenu(
|
||||
str(QtCore.QT_TRANSLATE_NOOP("Ship", "Simulation")),
|
||||
simlist)
|
||||
|
||||
# Print a warning if Plot module can't be used
|
||||
try:
|
||||
import Plot
|
||||
except ImportError:
|
||||
msg = QtGui.QApplication.translate("ship_console", "Plot module is disabled, tools can't graph output curves",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + '\n')
|
||||
# ToolBar
|
||||
shiplist = ["Ship_LoadExample", "Ship_CreateShip", "Ship_OutlineDraw", "Ship_AreasCurve", "Ship_Hydrostatics"]
|
||||
weightslist = ["Ship_Weights", "Ship_CreateTank", "Ship_GZ"]
|
||||
self.appendToolbar(str(QtCore.QT_TRANSLATE_NOOP("Ship", "Ship design")),shiplist)
|
||||
self.appendToolbar(str(QtCore.QT_TRANSLATE_NOOP("Ship", "Weights")),weightslist)
|
||||
self.appendMenu(str(QtCore.QT_TRANSLATE_NOOP("Ship", "Ship design")),shiplist)
|
||||
self.appendMenu(str(QtCore.QT_TRANSLATE_NOOP("Ship", "Weights")),weightslist)
|
||||
# Simulation stuff only if pyOpenCL & numpy are present
|
||||
hasOpenCL = True
|
||||
hasNumpy = True
|
||||
hasSim = False # In development, activate it only for development purposes
|
||||
try:
|
||||
import pyopencl
|
||||
except ImportError:
|
||||
hasOpenCL = False
|
||||
msg = QtGui.QApplication.translate("ship_console", "pyOpenCL not installed, simulations stuff will disabled therefore",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + '\n')
|
||||
try:
|
||||
import numpy
|
||||
except ImportError:
|
||||
hasNumpy = False
|
||||
msg = QtGui.QApplication.translate("ship_console", "numpy not installed, simulations stuff will disabled therefore",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + '\n')
|
||||
if hasOpenCL and hasNumpy and hasSim:
|
||||
simlist = ["Ship_CreateSim", "Ship_RunSim", "Ship_StopSim", "Ship_TrackSim"]
|
||||
self.appendToolbar(str(QtCore.QT_TRANSLATE_NOOP("Ship", "Simulation")),simlist)
|
||||
self.appendMenu(str(QtCore.QT_TRANSLATE_NOOP("Ship", "Simulation")),simlist)
|
||||
|
||||
Gui.addWorkbench(ShipWorkbench())
|
||||
|
||||
@@ -1,599 +1,264 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
import time
|
||||
from math import *
|
||||
|
||||
# Qt library
|
||||
from PyQt4 import QtGui,QtCore
|
||||
|
||||
# COIN
|
||||
from PySide import QtGui, QtCore
|
||||
from pivy.coin import *
|
||||
from pivy import coin
|
||||
|
||||
# FreeCAD
|
||||
import FreeCAD,FreeCADGui
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from FreeCAD import Base, Vector
|
||||
import Part
|
||||
|
||||
# Ship design module
|
||||
from shipUtils import Paths, Math
|
||||
|
||||
|
||||
class Ship:
|
||||
def __init__(self, obj, solids):
|
||||
""" Creates a new ship on active document.
|
||||
@param obj Part::FeaturePython created object.
|
||||
@param faces Ship solids components.
|
||||
"""
|
||||
# Add uniqueness property to identify Ship instances
|
||||
tooltip = str(QtGui.QApplication.translate("Ship","True if is a valid ship instance",None,QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyBool","IsShip","Ship", tooltip).IsShip=True
|
||||
# Add main dimensions
|
||||
tooltip = str(QtGui.QApplication.translate("Ship","True if is a valid ship instance",None,QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyLength","Length","Ship", tooltip).Length=0.0
|
||||
tooltip = str(QtGui.QApplication.translate("Ship","True if is a valid ship instance",None,QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyLength","Beam","Ship", tooltip).Beam=0.0
|
||||
tooltip = str(QtGui.QApplication.translate("Ship","True if is a valid ship instance",None,QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyLength","Draft","Ship", tooltip).Draft=0.0
|
||||
# Add shapes
|
||||
obj.Shape = Part.makeCompound(solids)
|
||||
tooltip = str(QtGui.QApplication.translate("Ship","True if is a valid ship instance",None,QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("Part::PropertyPartShape","ExternalFaces","Ship", tooltip)
|
||||
obj.Proxy = self
|
||||
def __init__(self, obj, solids):
|
||||
""" Transform a generic object to a ship instance.
|
||||
|
||||
def onChanged(self, fp, prop):
|
||||
""" Called when a ship property is modified
|
||||
@param fp Part::FeaturePython object.
|
||||
@param prop Property changed.
|
||||
"""
|
||||
if prop == "Length" or prop == "Beam" or prop == "Draft":
|
||||
pass
|
||||
Keyword arguments:
|
||||
obj -- Part::FeaturePython created object which should be transformed
|
||||
in a ship instance.
|
||||
solids -- Set of solids which will compound the ship hull.
|
||||
"""
|
||||
# Add an unique property to identify the Ship instances
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"Ship",
|
||||
"True if it is a valid ship instance, False otherwise",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyBool",
|
||||
"IsShip",
|
||||
"Ship",
|
||||
tooltip).IsShip = True
|
||||
# Add the main dimensions
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"Ship",
|
||||
"Ship length [m]",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyLength",
|
||||
"Length",
|
||||
"Ship",
|
||||
tooltip).Length = 0.0
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"Ship",
|
||||
"Ship breadth [m]",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyLength",
|
||||
"Breadth",
|
||||
"Ship",
|
||||
tooltip).Breadth = 0.0
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"Ship",
|
||||
"Ship draft [m]",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyLength",
|
||||
"Draft",
|
||||
"Ship",
|
||||
tooltip).Draft = 0.0
|
||||
# Add the subshapes
|
||||
obj.Shape = Part.makeCompound(solids)
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"Ship",
|
||||
"Set of external faces of the ship hull",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("Part::PropertyPartShape",
|
||||
"ExternalFaces",
|
||||
"Ship",
|
||||
tooltip)
|
||||
obj.Proxy = self
|
||||
|
||||
def onChanged(self, fp, prop):
|
||||
"""Detects the ship data changes.
|
||||
|
||||
Keyword arguments:
|
||||
fp -- Part::FeaturePython object affected.
|
||||
prop -- Modified property name.
|
||||
"""
|
||||
if prop == "Length" or prop == "Breadth" or prop == "Draft":
|
||||
pass
|
||||
|
||||
def execute(self, fp):
|
||||
"""Detects the entity recomputations.
|
||||
|
||||
Keyword arguments:
|
||||
fp -- Part::FeaturePython object affected.
|
||||
"""
|
||||
fp.Shape = Part.makeCompound(fp.Shape.Solids)
|
||||
|
||||
def execute(self, fp):
|
||||
""" Called when a recomputation is needed.
|
||||
@param fp Part::FeaturePython object.
|
||||
"""
|
||||
fp.Shape = Part.makeCompound(fp.Shape.Solids)
|
||||
|
||||
class ViewProviderShip:
|
||||
def __init__(self, obj):
|
||||
"Set this object to the proxy object of the actual view provider"
|
||||
obj.Proxy = self
|
||||
def __init__(self, obj):
|
||||
"""Add this view provider to the selected object.
|
||||
|
||||
def attach(self, obj):
|
||||
''' Setup the scene sub-graph of the view provider, this method is mandatory '''
|
||||
return
|
||||
Keyword arguments:
|
||||
obj -- Object which must be modified.
|
||||
"""
|
||||
obj.Proxy = self
|
||||
|
||||
def updateData(self, fp, prop):
|
||||
''' If a property of the handled feature has changed we have the chance to handle this here '''
|
||||
return
|
||||
def attach(self, obj):
|
||||
"""Setup the scene sub-graph of the view provider, this method is
|
||||
mandatory.
|
||||
"""
|
||||
return
|
||||
|
||||
def getDisplayModes(self,obj):
|
||||
''' Return a list of display modes. '''
|
||||
modes=[]
|
||||
return modes
|
||||
def updateData(self, fp, prop):
|
||||
"""If a property of the handled feature has changed we have the chance
|
||||
to handle this here.
|
||||
|
||||
def getDefaultDisplayMode(self):
|
||||
''' Return the name of the default display mode. It must be defined in getDisplayModes. '''
|
||||
return "Shaded"
|
||||
Keyword arguments:
|
||||
fp -- Part::FeaturePython object affected.
|
||||
prop -- Modified property name.
|
||||
"""
|
||||
return
|
||||
|
||||
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 getDisplayModes(self, obj):
|
||||
"""Return a list of display modes.
|
||||
|
||||
def onChanged(self, vp, prop):
|
||||
''' Print the name of the property that has changed '''
|
||||
# FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n")
|
||||
Keyword arguments:
|
||||
obj -- Object associated with the view provider.
|
||||
"""
|
||||
modes = []
|
||||
return modes
|
||||
|
||||
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 getDefaultDisplayMode(self):
|
||||
"""Return the name of the default display mode. It must be defined in
|
||||
getDisplayModes."""
|
||||
return "Shaded"
|
||||
|
||||
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 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.
|
||||
|
||||
Keyword arguments:
|
||||
mode -- Mode to be activated.
|
||||
"""
|
||||
return mode
|
||||
|
||||
def onChanged(self, vp, prop):
|
||||
"""Detects the ship view provider data changes.
|
||||
|
||||
Keyword arguments:
|
||||
vp -- View provider object affected.
|
||||
prop -- Modified property name.
|
||||
"""
|
||||
pass
|
||||
|
||||
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):
|
||||
"""Returns the icon for this kind of objects."""
|
||||
return ":/icons/Ship_Instance.svg"
|
||||
|
||||
def getIcon(self):
|
||||
return """
|
||||
/* XPM */
|
||||
static char * Ship_xpm[] = {
|
||||
"32 32 396 2",
|
||||
" c None",
|
||||
". c #2C2C2C",
|
||||
"+ c #3A3A3A",
|
||||
"@ c #585857",
|
||||
"# c #161616",
|
||||
"$ c #000000",
|
||||
"% c #363636",
|
||||
"& c #333333",
|
||||
"* c #B3B3B3",
|
||||
"= c #B4B4B4",
|
||||
"- c #949494",
|
||||
"; c #565653",
|
||||
"> c #141414",
|
||||
", c #080807",
|
||||
"' c #585858",
|
||||
") c #878787",
|
||||
"! c #9F9E9F",
|
||||
"~ c #9F9F9E",
|
||||
"{ c #8F8F90",
|
||||
"] c #6B6B6B",
|
||||
"^ c #101010",
|
||||
"/ c #737373",
|
||||
"( c #4C4C4C",
|
||||
"_ c #B1B1B7",
|
||||
": c #9090C0",
|
||||
"< c #A7A7B2",
|
||||
"[ c #87878E",
|
||||
"} c #4F4F52",
|
||||
"| c #191919",
|
||||
"1 c #656565",
|
||||
"2 c #D1D1D2",
|
||||
"3 c #D1D1D1",
|
||||
"4 c #CECECE",
|
||||
"5 c #CDCCCC",
|
||||
"6 c #CCCCCC",
|
||||
"7 c #CCCCCB",
|
||||
"8 c #CDCECD",
|
||||
"9 c #BDBDBD",
|
||||
"0 c #424242",
|
||||
"a c #373737",
|
||||
"b c #0A0A0A",
|
||||
"c c #241414",
|
||||
"d c #0E0C0C",
|
||||
"e c #929393",
|
||||
"f c #383738",
|
||||
"g c #9B9B9A",
|
||||
"h c #A0A0AF",
|
||||
"i c #2929E4",
|
||||
"j c #2525E5",
|
||||
"k c #3F3FD7",
|
||||
"l c #5B5BC8",
|
||||
"m c #535368",
|
||||
"n c #686866",
|
||||
"o c #C8C8C8",
|
||||
"p c #C8C8C7",
|
||||
"q c #C7C6C7",
|
||||
"r c #C6C6C6",
|
||||
"s c #C5C5C5",
|
||||
"t c #C4C5C5",
|
||||
"u c #C3C4C3",
|
||||
"v c #C3C3C2",
|
||||
"w c #BCBCBC",
|
||||
"x c #595959",
|
||||
"y c #A6A6A6",
|
||||
"z c #969696",
|
||||
"A c #0B0B0B",
|
||||
"B c #0D0707",
|
||||
"C c #894646",
|
||||
"D c #1C1A1A",
|
||||
"E c #525252",
|
||||
"F c #6C6D6C",
|
||||
"G c #A3A3A2",
|
||||
"H c #A3A296",
|
||||
"I c #8E8F98",
|
||||
"J c #6F6EA5",
|
||||
"K c #5354AF",
|
||||
"L c #373753",
|
||||
"M c #8D8D8B",
|
||||
"N c #C5C5C4",
|
||||
"O c #C2C2C2",
|
||||
"P c #C1C1C1",
|
||||
"Q c #C0C0C0",
|
||||
"R c #C0BFBF",
|
||||
"S c #BFBFBF",
|
||||
"T c #BEBEBE",
|
||||
"U c #B1B2B2",
|
||||
"V c #404040",
|
||||
"W c #ABAAAA",
|
||||
"X c #797979",
|
||||
"Y c #2A1212",
|
||||
"Z c #662828",
|
||||
"` c #3D403F",
|
||||
" . c #B5B5B5",
|
||||
".. c #6B6A6B",
|
||||
"+. c #4A4A4A",
|
||||
"@. c #9A9A9A",
|
||||
"#. c #909090",
|
||||
"$. c #8B8B8A",
|
||||
"%. c #898A86",
|
||||
"&. c #84837F",
|
||||
"*. c #3D3D3C",
|
||||
"=. c #9E9E9E",
|
||||
"-. c #BFBFBE",
|
||||
";. c #BDBEBD",
|
||||
">. c #BBBBBB",
|
||||
",. c #BABABA",
|
||||
"'. c #B9B9B9",
|
||||
"). c #B8B8B8",
|
||||
"!. c #999999",
|
||||
"~. c #BABAB9",
|
||||
"{. c #ABABAB",
|
||||
"]. c #292929",
|
||||
"^. c #381212",
|
||||
"/. c #4C1514",
|
||||
"(. c #535656",
|
||||
"_. c #717171",
|
||||
":. c #919090",
|
||||
"<. c #818181",
|
||||
"[. c #4E4E4E",
|
||||
"}. c #4B4B4B",
|
||||
"|. c #B1B1B1",
|
||||
"1. c #B8B7B8",
|
||||
"2. c #B6B6B6",
|
||||
"3. c #B6B5B5",
|
||||
"4. c #B4B5B4",
|
||||
"5. c #B2B3B2",
|
||||
"6. c #5C5D5C",
|
||||
"7. c #AFAFAF",
|
||||
"8. c #ADACAC",
|
||||
"9. c #5B5B5B",
|
||||
"0. c #410C0C",
|
||||
"a. c #3E0707",
|
||||
"b. c #525555",
|
||||
"c. c #9C9C9C",
|
||||
"d. c #2D2D2D",
|
||||
"e. c #757575",
|
||||
"f. c #474747",
|
||||
"g. c #484848",
|
||||
"h. c #9F9F9F",
|
||||
"i. c #B3B3B4",
|
||||
"j. c #B2B2B2",
|
||||
"k. c #B0B0B0",
|
||||
"l. c #ADAEAD",
|
||||
"m. c #ADADAD",
|
||||
"n. c #B0B1B0",
|
||||
"o. c #1E1E1E",
|
||||
"p. c #ACABAC",
|
||||
"q. c #AAA9A9",
|
||||
"r. c #A8A8A8",
|
||||
"s. c #5D5D5D",
|
||||
"t. c #290202",
|
||||
"u. c #281010",
|
||||
"v. c #272828",
|
||||
"w. c #767777",
|
||||
"x. c #505050",
|
||||
"y. c #1F1F1F",
|
||||
"z. c #5E5E5D",
|
||||
"A. c #A4A5A5",
|
||||
"B. c #B1B2B1",
|
||||
"C. c #AEAEAE",
|
||||
"D. c #AEADAD",
|
||||
"E. c #ABACAC",
|
||||
"F. c #AAAAAA",
|
||||
"G. c #A9A8A8",
|
||||
"H. c #ABABAC",
|
||||
"I. c #7B7B7B",
|
||||
"J. c #2B2B2B",
|
||||
"K. c #A4A4A4",
|
||||
"L. c #A6A5A6",
|
||||
"M. c #888888",
|
||||
"N. c #0E0E0E",
|
||||
"O. c #101312",
|
||||
"P. c #7E8080",
|
||||
"Q. c #5E5E5E",
|
||||
"R. c #242424",
|
||||
"S. c #555555",
|
||||
"T. c #7F7F7F",
|
||||
"U. c #A4A3A4",
|
||||
"V. c #B3B3B2",
|
||||
"W. c #ACACAC",
|
||||
"X. c #A9A9A9",
|
||||
"Y. c #A8A7A7",
|
||||
"Z. c #A7A6A7",
|
||||
"`. c #A7A7A7",
|
||||
" + c #A8A8A7",
|
||||
".+ c #A5A5A5",
|
||||
"++ c #A2A2A2",
|
||||
"@+ c #222122",
|
||||
"#+ c #7E7E7E",
|
||||
"$+ c #A3A3A3",
|
||||
"%+ c #9B9B9B",
|
||||
"&+ c #050505",
|
||||
"*+ c #6E6E6E",
|
||||
"=+ c #A7A7A6",
|
||||
"-+ c #989898",
|
||||
";+ c #A5A4A4",
|
||||
">+ c #A7A7A8",
|
||||
",+ c #A5A6A7",
|
||||
"'+ c #979A99",
|
||||
")+ c #818383",
|
||||
"!+ c #757878",
|
||||
"~+ c #757979",
|
||||
"{+ c #878A8A",
|
||||
"]+ c #A3A5A5",
|
||||
"^+ c #828282",
|
||||
"/+ c #A0A0A0",
|
||||
"(+ c #232323",
|
||||
"_+ c #939393",
|
||||
":+ c #A5A6A5",
|
||||
"<+ c #A2A3A2",
|
||||
"[+ c #A2A1A1",
|
||||
"}+ c #A1A0A1",
|
||||
"|+ c #939292",
|
||||
"1+ c #636262",
|
||||
"2+ c #554D4D",
|
||||
"3+ c #634C4C",
|
||||
"4+ c #755555",
|
||||
"5+ c #936464",
|
||||
"6+ c #9F6868",
|
||||
"7+ c #9B6060",
|
||||
"8+ c #804A4A",
|
||||
"9+ c #5C3737",
|
||||
"0+ c #1D1616",
|
||||
"a+ c #A1A1A1",
|
||||
"b+ c #010101",
|
||||
"c+ c #151516",
|
||||
"d+ c #707070",
|
||||
"e+ c #9D9E9E",
|
||||
"f+ c #8C8D8D",
|
||||
"g+ c #8B8888",
|
||||
"h+ c #726A6A",
|
||||
"i+ c #6D5959",
|
||||
"j+ c #866261",
|
||||
"k+ c #C18B8B",
|
||||
"l+ c #D79696",
|
||||
"m+ c #D18C8C",
|
||||
"n+ c #CB8180",
|
||||
"o+ c #C57575",
|
||||
"p+ c #BF6B6A",
|
||||
"q+ c #BB6161",
|
||||
"r+ c #B95958",
|
||||
"s+ c #9C4544",
|
||||
"t+ c #2E1212",
|
||||
"u+ c #6F6C6C",
|
||||
"v+ c #A0A1A1",
|
||||
"w+ c #575757",
|
||||
"x+ c #0C0C0C",
|
||||
"y+ c #9C9D9D",
|
||||
"z+ c #7A7272",
|
||||
"A+ c #876F6F",
|
||||
"B+ c #977070",
|
||||
"C+ c #C28C8C",
|
||||
"D+ c #D59595",
|
||||
"E+ c #D08A8A",
|
||||
"F+ c #C67D7D",
|
||||
"G+ c #C07272",
|
||||
"H+ c #BC6969",
|
||||
"I+ c #B85F5F",
|
||||
"J+ c #B35656",
|
||||
"K+ c #B04C4C",
|
||||
"L+ c #AB4243",
|
||||
"M+ c #A63939",
|
||||
"N+ c #591B1B",
|
||||
"O+ c #6A2121",
|
||||
"P+ c #542323",
|
||||
"Q+ c #585A5A",
|
||||
"R+ c #191515",
|
||||
"S+ c #706262",
|
||||
"T+ c #A58080",
|
||||
"U+ c #B58383",
|
||||
"V+ c #CE8F8F",
|
||||
"W+ c #CD8989",
|
||||
"X+ c #C17372",
|
||||
"Y+ c #B45656",
|
||||
"Z+ c #AF4C4C",
|
||||
"`+ c #AB4242",
|
||||
" @ c #A73A39",
|
||||
".@ c #A3302F",
|
||||
"+@ c #9F2626",
|
||||
"@@ c #8E1A1A",
|
||||
"#@ c #2C0808",
|
||||
"$@ c #91191A",
|
||||
"%@ c #2F0200",
|
||||
"&@ c #90C6FB",
|
||||
"*@ c #8BBFFB",
|
||||
"=@ c #94CBFC",
|
||||
"-@ c #AFEFFB",
|
||||
";@ c #7DABA0",
|
||||
">@ c #3C2521",
|
||||
",@ c #C88484",
|
||||
"'@ c #C57C7D",
|
||||
")@ c #C17273",
|
||||
"!@ c #B86060",
|
||||
"~@ c #AB4343",
|
||||
"{@ c #A73939",
|
||||
"]@ c #A32F2F",
|
||||
"^@ c #9B1C1D",
|
||||
"/@ c #961313",
|
||||
"(@ c #96090A",
|
||||
"_@ c #3C0202",
|
||||
":@ c #4E0202",
|
||||
"<@ c #300000",
|
||||
"[@ c #3E5378",
|
||||
"}@ c #7EABF9",
|
||||
"|@ c #84B5FC",
|
||||
"1@ c #96CDFB",
|
||||
"2@ c #B2F2FA",
|
||||
"3@ c #C4FFFA",
|
||||
"4@ c #2E3FFD",
|
||||
"5@ c #3346FD",
|
||||
"6@ c #2A3AFD",
|
||||
"7@ c #161EFE",
|
||||
"8@ c #1B25FD",
|
||||
"9@ c #1F25B4",
|
||||
"0@ c #7C6196",
|
||||
"a@ c #AA6075",
|
||||
"b@ c #AC5763",
|
||||
"c@ c #AD5155",
|
||||
"d@ c #AD4645",
|
||||
"e@ c #A83938",
|
||||
"f@ c #A3302E",
|
||||
"g@ c #A02624",
|
||||
"h@ c #9B1C1B",
|
||||
"i@ c #971311",
|
||||
"j@ c #930A09",
|
||||
"k@ c #900300",
|
||||
"l@ c #900505",
|
||||
"m@ c #660007",
|
||||
"n@ c #00000D",
|
||||
"o@ c #200112",
|
||||
"p@ c #597F88",
|
||||
"q@ c #6E97FD",
|
||||
"r@ c #384CFD",
|
||||
"s@ c #394EFD",
|
||||
"t@ c #2D3EFD",
|
||||
"u@ c #151DFE",
|
||||
"v@ c #1821FE",
|
||||
"w@ c #3C52FD",
|
||||
"x@ c #6388FC",
|
||||
"y@ c #9CD6FB",
|
||||
"z@ c #D0FFFA",
|
||||
"A@ c #AEEEFB",
|
||||
"B@ c #749FFF",
|
||||
"C@ c #3F5DFF",
|
||||
"D@ c #4165FF",
|
||||
"E@ c #525AE3",
|
||||
"F@ c #6153C4",
|
||||
"G@ c #672D8D",
|
||||
"H@ c #6C1B6A",
|
||||
"I@ c #722164",
|
||||
"J@ c #75225E",
|
||||
"K@ c #731D57",
|
||||
"L@ c #701653",
|
||||
"M@ c #690E52",
|
||||
"N@ c #5F0050",
|
||||
"O@ c #562086",
|
||||
"P@ c #11108D",
|
||||
"Q@ c #2330BE",
|
||||
"R@ c #344AE1",
|
||||
"S@ c #4E6BFF",
|
||||
"T@ c #4E6BFD",
|
||||
"U@ c #597AFC",
|
||||
"V@ c #6184FC",
|
||||
"W@ c #7099FC",
|
||||
"X@ c #8BBEFB",
|
||||
"Y@ c #95CCFB",
|
||||
"Z@ c #5B7CFC",
|
||||
"`@ c #1C26FD",
|
||||
" # c #121AFE",
|
||||
".# c #9ED7FB",
|
||||
"+# c #81B4FF",
|
||||
"@# c #6893FF",
|
||||
"## c #6997FF",
|
||||
"$# c #6695FF",
|
||||
"%# c #6390FF",
|
||||
"&# c #618DFF",
|
||||
"*# c #608DFF",
|
||||
"=# c #618EFF",
|
||||
"-# c #6391FF",
|
||||
";# c #6898FF",
|
||||
"># c #6B9AFF",
|
||||
",# c #5171ED",
|
||||
"'# c #90C4FF",
|
||||
")# c #7EABFC",
|
||||
"!# c #729CFC",
|
||||
"~# c #6287FC",
|
||||
"{# c #4761FD",
|
||||
"]# c #070AFE",
|
||||
"^# c #6084FC",
|
||||
"/# c #9AD2FB",
|
||||
"(# c #A2DDFB",
|
||||
"_# c #8ABDFB",
|
||||
":# c #2B3AFD",
|
||||
"<# c #A9E8FB",
|
||||
"[# c #B9FCFA",
|
||||
"}# c #BAFEFA",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" . + @ # $ $ $ $ $ ",
|
||||
" % & * = - ; > $ $ , ' ) ! ~ { ] & $ $ $ ",
|
||||
" ^ / ( = _ : < [ } | $ 1 2 3 4 5 6 7 6 8 9 0 a b ",
|
||||
" c d e f g h i j k l m n 4 o p q r s t u v w x y z A ",
|
||||
" B C D * E F G H I J K L M N O O P Q R S T 9 U V W O X $ ",
|
||||
" Y Z ` ...+.@.#.$.%.&.*.=.-.;.w >.>.,.'.).).!.+ ~. .{.]. ",
|
||||
" ^./.(.y _.f :.) <.[.^ }.|.).1.2.3. .4.* 5. .6.1 4.7.8.9. ",
|
||||
" 0.a.b.c./ d.e.f.| g.h.9 i.* j.|.k.7.7.l.m.n.o.@.p.q.r.s. ",
|
||||
" t.u.v.w.x.y.% z.A.).B.C.D.m.E.{.F.F.G.r.H.I.J.k.K.L.M.N. ",
|
||||
" O.P.Q.R.S.T.U.V.W.q.X.r.Y.Z.`.Y. +`..+++{.@+#+$+++%+y. ",
|
||||
" &+*+W.=+-+;+X.>+y .+K.K.y y ,+'+)+!+~+{+]+^+].$+/+$+J. ",
|
||||
" (+_+:+U.$+<+[+}+/+h.=.|+1+2+3+4+5+6+7+8+9+0+_.a+/+0 b+ ",
|
||||
" c+d+h.a+/+++e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+$ ",
|
||||
" x+f.- y+w.z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+$ ",
|
||||
" R+S+T+U+V+W+F+X+H+I+Y+Z+`+ @.@+@@@#@$@%@$ ",
|
||||
"&@*@=@-@;@>@,@'@)@H+!@Y+K+~@{@]@+@^@/@(@_@:@<@[@}@|@1@2@3@ ",
|
||||
"4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@j@k@l@m@n@o@p@q@r@s@t@u@v@w@x@y@",
|
||||
" z@A@B@C@D@E@F@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #",
|
||||
" .#+#@###$#%#&#*#=#-#;#>#,#'# )#!#~#{#]#^#/#",
|
||||
" (#_#:#<#",
|
||||
" [#}#",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" "};
|
||||
"""
|
||||
|
||||
def weights(obj):
|
||||
""" Returns Ship weights list. If weights has not been sets,
|
||||
this tool creates it.
|
||||
@param obj Ship object
|
||||
@return Weights list. None if errors
|
||||
"""
|
||||
# Test if is a ship instance
|
||||
props = obj.PropertiesList
|
||||
try:
|
||||
props.index("IsShip")
|
||||
except ValueError:
|
||||
return None
|
||||
if not obj.IsShip:
|
||||
return None
|
||||
# Test if properties already exist
|
||||
try:
|
||||
props.index("WeightNames")
|
||||
except ValueError:
|
||||
tooltip = str(QtGui.QApplication.translate("Ship","Ship Weights names",None,QtGui.QApplication.UnicodeUTF8))
|
||||
lighweight = str(QtGui.QApplication.translate("Ship","Lightweight",None,QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyStringList","WeightNames","Ship", tooltip).WeightNames=[lighweight]
|
||||
try:
|
||||
props.index("WeightMass")
|
||||
except ValueError:
|
||||
# Compute mass aproximation
|
||||
from shipHydrostatics import Tools
|
||||
disp = Tools.displacement(obj,obj.Draft)
|
||||
tooltip = str(QtGui.QApplication.translate("Ship","Ship Weights masses",None,QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyFloatList","WeightMass","Ship", tooltip).WeightMass=[1000.0 * disp[0]]
|
||||
try:
|
||||
props.index("WeightPos")
|
||||
except ValueError:
|
||||
# Compute mass aproximation
|
||||
from shipHydrostatics import Tools
|
||||
disp = Tools.displacement(obj,obj.Draft)
|
||||
tooltip = str(QtGui.QApplication.translate("Ship","Ship Weights centers of gravity",None,QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyVectorList","WeightPos","Ship", tooltip).WeightPos=[Vector(disp[1].x,0.0,obj.Draft)]
|
||||
# Setup list
|
||||
weights = []
|
||||
for i in range(0,len(obj.WeightNames)):
|
||||
weights.append([obj.WeightNames[i], obj.WeightMass[i], obj.WeightPos[i]])
|
||||
return weights
|
||||
"""Returns the ship weights list. If weights has not been set this tool
|
||||
will generate the default ones.
|
||||
|
||||
Keyword arguments:
|
||||
obj -- Ship inmstance object.
|
||||
"""
|
||||
# Test if is a ship instance
|
||||
props = obj.PropertiesList
|
||||
try:
|
||||
props.index("IsShip")
|
||||
except ValueError:
|
||||
return None
|
||||
if not obj.IsShip:
|
||||
return None
|
||||
# Test if properties already exist
|
||||
try:
|
||||
props.index("WeightNames")
|
||||
except ValueError:
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"Ship",
|
||||
"Ship Weights names",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
lighweight = str(QtGui.QApplication.translate(
|
||||
"Ship",
|
||||
"Lightweight",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyStringList",
|
||||
"WeightNames",
|
||||
"Ship",
|
||||
tooltip).WeightNames = [lighweight]
|
||||
try:
|
||||
props.index("WeightMass")
|
||||
except ValueError:
|
||||
# Compute a mass aproximation
|
||||
from shipHydrostatics import Tools
|
||||
disp = Tools.displacement(obj, obj.Draft)
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"Ship",
|
||||
"Ship Weights masses [tons]",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyFloatList",
|
||||
"WeightMass",
|
||||
"Ship",
|
||||
tooltip).WeightMass = [1000.0 * disp[0]]
|
||||
try:
|
||||
props.index("WeightPos")
|
||||
except ValueError:
|
||||
# Compute a CoG aproximation
|
||||
from shipHydrostatics import Tools
|
||||
disp = Tools.displacement(obj, obj.Draft)
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"Ship",
|
||||
"Ship Weights centers of gravity",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
obj.addProperty("App::PropertyVectorList",
|
||||
"WeightPos",
|
||||
"Ship",
|
||||
tooltip).WeightPos = [Vector(disp[1].x,
|
||||
0.0,
|
||||
obj.Draft)]
|
||||
# Setup the weights list
|
||||
weights = []
|
||||
for i in range(len(obj.WeightNames)):
|
||||
weights.append([obj.WeightNames[i],
|
||||
obj.WeightMass[i],
|
||||
obj.WeightPos[i]])
|
||||
return weights
|
||||
|
||||
@@ -14,7 +14,6 @@ nobase_data_DATA = \
|
||||
resources/examples/s60_katamaran.fcstd \
|
||||
resources/examples/wigley.fcstd \
|
||||
resources/examples/wigley_katamaran.fcstd \
|
||||
resources/icons/Ico.xpm \
|
||||
resources/opencl/matrixGen.cl \
|
||||
resources/opencl/jacobi.cl \
|
||||
resources/opencl/minres.cl \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* 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) *
|
||||
@@ -21,133 +21,221 @@
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
import FreeCAD, FreeCADGui, os
|
||||
import PySide
|
||||
from PySide import QtCore, QtGui
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import os
|
||||
|
||||
# Load resources
|
||||
import Ship_rc
|
||||
|
||||
|
||||
FreeCADGui.addLanguagePath(":/Ship/translations")
|
||||
FreeCADGui.addIconPath(":/Ship/icons")
|
||||
|
||||
class LoadExample:
|
||||
|
||||
class LoadExample:
|
||||
def Activated(self):
|
||||
import shipLoadExample
|
||||
shipLoadExample.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_LoadExample', 'Load an example ship geometry')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_LoadExample', 'Load an example ship geometry able to be converted into a ship.')
|
||||
return {'Pixmap' : 'LoadIco', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_LoadExample',
|
||||
'Load an example ship geometry')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_LoadExample',
|
||||
'Load an example ship hull geometry.')
|
||||
return {'Pixmap': 'Ship_Load',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
class CreateShip:
|
||||
|
||||
class CreateShip:
|
||||
def Activated(self):
|
||||
import shipCreateShip
|
||||
shipCreateShip.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_CreateShip', 'Create a new ship')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_CreateShip', 'Create a new ship in order to work with them')
|
||||
return {'Pixmap' : 'Ico', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_CreateShip',
|
||||
'Create a new ship')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_CreateShip',
|
||||
'Create a new ship instance on top of the hull geometry')
|
||||
return {'Pixmap': 'Ship_Module',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
class OutlineDraw:
|
||||
|
||||
class OutlineDraw:
|
||||
def Activated(self):
|
||||
import shipOutlineDraw
|
||||
shipOutlineDraw.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_OutlineDraw', 'Outline draw')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_OutlineDraw', 'Plot ship outline draw')
|
||||
return {'Pixmap' : 'OutlineDrawIco', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_OutlineDraw',
|
||||
'Outline draw')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_OutlineDraw',
|
||||
'Plots the ship hull outline draw')
|
||||
return {'Pixmap': 'Ship_OutlineDraw',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
class AreasCurve:
|
||||
|
||||
class AreasCurve:
|
||||
def Activated(self):
|
||||
import shipAreasCurve
|
||||
shipAreasCurve.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_AreasCurve', 'Areas curve')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_AreasCurve', 'Plot transversal areas curve')
|
||||
return {'Pixmap' : 'AreaCurveIco', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_AreasCurve',
|
||||
'Areas curve')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_AreasCurve',
|
||||
'Plot the transversal areas curve')
|
||||
return {'Pixmap': 'Ship_AreaCurve',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
class Hydrostatics:
|
||||
|
||||
class Hydrostatics:
|
||||
def Activated(self):
|
||||
import shipHydrostatics
|
||||
shipHydrostatics.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_Hydrostatics', 'Hydrostatics')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_Hydrostatics', 'Plot ship hydrostatics')
|
||||
return {'Pixmap' : 'HydrostaticsIco', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
|
||||
class SetWeights:
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_Hydrostatics',
|
||||
'Hydrostatics')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_Hydrostatics',
|
||||
'Plot the ship hydrostatics')
|
||||
return {'Pixmap': 'HydrostaticsIco',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
|
||||
class SetWeights:
|
||||
def Activated(self):
|
||||
import tankWeights
|
||||
tankWeights.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_Weights', 'Set ship weights')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_Weights', 'Set ship weights, tanks must be added later')
|
||||
return {'Pixmap' : 'Weight', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_Weights',
|
||||
'Set ship weights')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_Weights',
|
||||
'Set the ship weights (tanks must be added later)')
|
||||
return {'Pixmap': 'Weight',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
class CreateTank:
|
||||
|
||||
class CreateTank:
|
||||
def Activated(self):
|
||||
import tankCreateTank
|
||||
tankCreateTank.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_CreateTank', 'Create a new tank')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_CreateTank', 'Create a new ship tank')
|
||||
return {'Pixmap' : 'Tank', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_CreateTank',
|
||||
'Create a new tank')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_CreateTank',
|
||||
'Create a new ship tank')
|
||||
return {'Pixmap': 'Tank',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
class GZ:
|
||||
|
||||
class GZ:
|
||||
def Activated(self):
|
||||
import tankGZ
|
||||
tankGZ.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_GZ', 'GZ curve')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_GZ', 'Transversal stability GZ curve computation')
|
||||
return {'Pixmap' : 'HydrostaticsIco', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_GZ',
|
||||
'GZ curve')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_GZ',
|
||||
'Transversal stability GZ curve computation')
|
||||
return {'Pixmap': 'HydrostaticsIco',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
class CreateSim:
|
||||
|
||||
class CreateSim:
|
||||
def Activated(self):
|
||||
import simCreate
|
||||
simCreate.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_CreateSim', 'Create a new simulation')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_CreateSim', 'Create a new simulation in order to process later')
|
||||
return {'Pixmap' : 'SimCreateIco', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_CreateSim',
|
||||
'Create a new simulation')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_CreateSim',
|
||||
'Create a new simulation in order to process later')
|
||||
return {'Pixmap': 'SimCreateIco',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
class RunSim:
|
||||
|
||||
class RunSim:
|
||||
def Activated(self):
|
||||
import simRun
|
||||
simRun.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_RunSim', 'Run a simulation')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_RunSim', 'Run a simulation')
|
||||
return {'Pixmap' : 'SimRunIco', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_RunSim',
|
||||
'Run a simulation')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_RunSim',
|
||||
'Run a simulation')
|
||||
return {'Pixmap': 'SimRunIco',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
class StopSim:
|
||||
|
||||
class StopSim:
|
||||
def Activated(self):
|
||||
import simRun
|
||||
simRun.stop()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_StopSim', 'Stop active simulation')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_StopSim', 'Stop active simulation')
|
||||
return {'Pixmap' : 'SimStopIco', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_StopSim',
|
||||
'Stop active simulation')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_StopSim',
|
||||
'Stop active simulation')
|
||||
return {'Pixmap': 'SimStopIco',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
class TrackSim:
|
||||
|
||||
class TrackSim:
|
||||
def Activated(self):
|
||||
import simPost
|
||||
simPost.load()
|
||||
|
||||
def GetResources(self):
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP('Ship_TrackSim', 'Track simulation')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP('Ship_TrackSim', 'Track simulation')
|
||||
return {'Pixmap' : 'SimPostIco', 'MenuText': MenuText, 'ToolTip': ToolTip}
|
||||
MenuText = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_TrackSim',
|
||||
'Track simulation')
|
||||
ToolTip = QtCore.QT_TRANSLATE_NOOP(
|
||||
'Ship_TrackSim',
|
||||
'Track simulation')
|
||||
return {'Pixmap': 'SimPostIco',
|
||||
'MenuText': MenuText,
|
||||
'ToolTip': ToolTip}
|
||||
|
||||
|
||||
FreeCADGui.addCommand('Ship_LoadExample', LoadExample())
|
||||
|
||||
16198
src/Mod/Ship/Ship_rc.py
16198
src/Mod/Ship/Ship_rc.py
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,12 @@
|
||||
<RCC>
|
||||
<qresource prefix="Ship">
|
||||
<file>icons/AreaCurveIco.png</file>
|
||||
<qresource>
|
||||
<file>icons/Ship_AreaCurve.svg</file>
|
||||
<file>icons/Ship_Instance.svg</file>
|
||||
<file>icons/Ship_Load.svg</file>
|
||||
<file>icons/Ship_Logo.svg</file>
|
||||
<file>icons/Ship_Module.svg</file>
|
||||
<file>icons/Ship_OutlineDraw.svg</file>
|
||||
<file>icons/HydrostaticsIco.png</file>
|
||||
<file>icons/Ico.png</file>
|
||||
<file>icons/LoadIco.png</file>
|
||||
<file>icons/OutlineDrawIco.png</file>
|
||||
<file>icons/SimCreateIco.png</file>
|
||||
<file>icons/SimPostIco.png</file>
|
||||
<file>icons/SimRunIco.png</file>
|
||||
|
||||
Binary file not shown.
400
src/Mod/Ship/resources/icons/Ship_AreaCurve.svg
Normal file
400
src/Mod/Ship/resources/icons/Ship_AreaCurve.svg
Normal file
@@ -0,0 +1,400 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2985"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="Ship_AreaCurve.svg">
|
||||
<defs
|
||||
id="defs2987">
|
||||
<linearGradient
|
||||
id="linearGradient4722">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4724" />
|
||||
<stop
|
||||
style="stop-color:#bebebe;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4726" />
|
||||
</linearGradient>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path3873"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
|
||||
transform="scale(0.4) rotate(180) translate(10,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path3867"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
|
||||
transform="scale(0.8) rotate(180) translate(12.5,0)" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
id="linearGradient3937">
|
||||
<stop
|
||||
style="stop-color:#be7328;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3939" />
|
||||
<stop
|
||||
style="stop-color:#dc962d;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3941" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3929">
|
||||
<stop
|
||||
id="stop3931"
|
||||
offset="0"
|
||||
style="stop-color:#c88c3c;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3933"
|
||||
offset="1"
|
||||
style="stop-color:#ffff96;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3893">
|
||||
<stop
|
||||
style="stop-color:#505050;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3895" />
|
||||
<stop
|
||||
style="stop-color:#aaaaaa;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3897" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3873">
|
||||
<stop
|
||||
style="stop-color:#f0be6e;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3875" />
|
||||
<stop
|
||||
style="stop-color:#c88228;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3877" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3863">
|
||||
<stop
|
||||
id="stop3865"
|
||||
offset="0"
|
||||
style="stop-color:#6e4b18;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3867"
|
||||
offset="1"
|
||||
style="stop-color:#c88228;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3979">
|
||||
<stop
|
||||
id="stop3981"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3983"
|
||||
offset="1"
|
||||
style="stop-color:#ff9600;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3971">
|
||||
<stop
|
||||
id="stop3973"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3975"
|
||||
offset="1"
|
||||
style="stop-color:#be7300;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Send"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path4031"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
|
||||
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Send"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path4049"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.3) rotate(180) translate(-2.3,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Sstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Sstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4046"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.3) translate(-2.3,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Mstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4040"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) translate(0,0)" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
id="linearGradient3900">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3902" />
|
||||
<stop
|
||||
style="stop-color:#a0a0a0;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3904" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3882">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3884" />
|
||||
<stop
|
||||
style="stop-color:#960000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3886" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3860">
|
||||
<stop
|
||||
style="stop-color:#1e76e3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3860-6"
|
||||
id="linearGradient3866-5"
|
||||
x1="31.125395"
|
||||
y1="61.410763"
|
||||
x2="30.113636"
|
||||
y2="12.160761"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3860-6">
|
||||
<stop
|
||||
style="stop-color:#5a9ff5;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862-4" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864-4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3873"
|
||||
id="linearGradient3871"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="38.907837"
|
||||
y1="51.470051"
|
||||
x2="45.302406"
|
||||
y2="54.091148" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3863"
|
||||
id="linearGradient3891"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="51.657837"
|
||||
y1="34.470051"
|
||||
x2="45.427406"
|
||||
y2="32.216148" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3893"
|
||||
id="linearGradient3899"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="51.657837"
|
||||
y1="34.470051"
|
||||
x2="45.427406"
|
||||
y2="32.216148" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3903"
|
||||
cx="53.748837"
|
||||
cy="4.9173141"
|
||||
fx="53.748837"
|
||||
fy="4.9173141"
|
||||
r="3.2874005"
|
||||
gradientTransform="matrix(2.3303929,-1.4921636,1.0936999,1.7080907,-77.643882,78.644487)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3929"
|
||||
id="radialGradient3927"
|
||||
cx="15.125"
|
||||
cy="48.035076"
|
||||
fx="15.125"
|
||||
fy="48.035076"
|
||||
r="18.875"
|
||||
gradientTransform="matrix(2.7636523,-0.71644256,0.733044,2.8276918,-61.887066,-71.992203)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3937"
|
||||
id="radialGradient3943"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.40097726,-0.37931652,0.11734116,0.12404187,14.422507,4.6205505)"
|
||||
cx="-14.308363"
|
||||
cy="14.910047"
|
||||
fx="-14.308363"
|
||||
fy="14.910047"
|
||||
r="18.875" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3929"
|
||||
id="radialGradient3949"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.7636523,-0.71644256,0.733044,2.8276918,-61.887066,-71.992203)"
|
||||
cx="15.125"
|
||||
cy="48.035076"
|
||||
fx="15.125"
|
||||
fy="48.035076"
|
||||
r="18.875" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3937"
|
||||
id="radialGradient3951"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.40097726,-0.37931652,0.11734116,0.12404187,14.422507,4.6205505)"
|
||||
cx="-14.308363"
|
||||
cy="14.910047"
|
||||
fx="-14.308363"
|
||||
fy="14.910047"
|
||||
r="18.875" />
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend-3"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3873-0"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
|
||||
</marker>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4722"
|
||||
id="radialGradient4730"
|
||||
cx="22.399223"
|
||||
cy="27.920977"
|
||||
fx="22.399223"
|
||||
fy="27.920977"
|
||||
r="25.5625"
|
||||
gradientTransform="matrix(0.61346721,-0.22517965,0.21191717,0.57733561,2.1543769,16.986575)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6568543"
|
||||
inkscape:cx="47.014405"
|
||||
inkscape:cy="15.321975"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="722"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2990">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<path
|
||||
style="fill:url(#radialGradient4730);fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 4,59.875 c 3.4375,0 6.125,-43.375 24,-43.375 17.875,0 16.875,43.25 26.625,43.25"
|
||||
id="path4720"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
|
||||
d="m 4.25,61 0,-58.375"
|
||||
id="path3066"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
|
||||
d="m 3,59.75 58.375,0"
|
||||
id="path3066-6"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
319
src/Mod/Ship/resources/icons/Ship_Instance.svg
Normal file
319
src/Mod/Ship/resources/icons/Ship_Instance.svg
Normal file
@@ -0,0 +1,319 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2985"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="Ship_Module.svg">
|
||||
<defs
|
||||
id="defs2987">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Send"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path4031"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
|
||||
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Send"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path4049"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.3) rotate(180) translate(-2.3,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Sstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Sstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4046"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.3) translate(-2.3,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Mstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4040"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) translate(0,0)" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
id="linearGradient3900">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3902" />
|
||||
<stop
|
||||
style="stop-color:#a0a0a0;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3904" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3882">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3884" />
|
||||
<stop
|
||||
style="stop-color:#960000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3886" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3860">
|
||||
<stop
|
||||
style="stop-color:#1e76e3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3860-6"
|
||||
id="linearGradient3866-5"
|
||||
x1="31.125395"
|
||||
y1="61.410763"
|
||||
x2="30.113636"
|
||||
y2="12.160761"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3860-6">
|
||||
<stop
|
||||
style="stop-color:#5a9ff5;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862-4" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864-4" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3890"
|
||||
cx="25.629292"
|
||||
cy="38.444794"
|
||||
fx="25.629292"
|
||||
fy="38.444794"
|
||||
r="11.769514"
|
||||
gradientTransform="matrix(1.7159608,-0.59513916,0.29226939,0.84269877,-28.848719,13.387411)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3898"
|
||||
cx="31.803391"
|
||||
cy="31.659325"
|
||||
fx="31.803391"
|
||||
fy="31.659325"
|
||||
r="3.417994"
|
||||
gradientTransform="matrix(4.734087,-1.1798961,0.73145851,2.9348253,-139.28906,-25.817159)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3906"
|
||||
cx="20.211554"
|
||||
cy="12.140632"
|
||||
fx="20.211554"
|
||||
fy="12.140632"
|
||||
r="15.992805"
|
||||
gradientTransform="matrix(1.6937502,-0.50833021,0.26447657,0.88123273,-17.232683,18.826666)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3914"
|
||||
cx="44.852757"
|
||||
cy="22.63999"
|
||||
fx="44.852757"
|
||||
fy="22.63999"
|
||||
r="5.0740972"
|
||||
gradientTransform="matrix(1,0,0,1.5705123,0,-16.367411)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3926"
|
||||
cx="18.050617"
|
||||
cy="25.765184"
|
||||
fx="18.050617"
|
||||
fy="25.765184"
|
||||
r="2.4997866"
|
||||
gradientTransform="matrix(1.1875159,0.30002561,-0.66139805,2.6178455,13.656265,-48.87061)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3930"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1875159,0.30002561,-0.66139805,2.6178455,13.656265,-48.87061)"
|
||||
cx="17.915045"
|
||||
cy="24.185383"
|
||||
fx="17.915045"
|
||||
fy="24.185383"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3936"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(3.980826,0.90111766,-0.59612552,2.6334762,-39.306292,-60.304205)"
|
||||
cx="18.420965"
|
||||
cy="23.089165"
|
||||
fx="18.420965"
|
||||
fy="23.089165"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3946"
|
||||
cx="16.274988"
|
||||
cy="23.718588"
|
||||
fx="16.274988"
|
||||
fy="23.718588"
|
||||
r="3.6819806"
|
||||
gradientTransform="matrix(1.1622967,-0.42417542,0.71241125,1.9521011,-19.727075,-16.498215)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="-6.1454977"
|
||||
inkscape:cy="13.674344"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="722"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2990">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
id="g3977"
|
||||
transform="matrix(1.6428611,0,0,1.6428611,-22.221039,-15.973411)">
|
||||
<g
|
||||
id="g3968">
|
||||
<g
|
||||
id="g3953">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3938"
|
||||
d="m 16.528621,30.942758 0.707107,-7.778175 c 0,0 0.795495,-1.767767 2.563262,-1.767767 1.767767,0 2.032932,1.06066 2.032932,1.06066 l 1.06066,8.220117 z"
|
||||
style="fill:url(#radialGradient3946);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<g
|
||||
id="g3948">
|
||||
<path
|
||||
style="fill:url(#radialGradient3926);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 18.73833,21.286331 1.657281,-0.729204 c 0,0 2.342292,1.546796 2.342292,3.601825 0,2.055029 0,7.159456 0,7.159456 l -3.987549,1.738087 0.05427,-7.748495 1.06066,-2.231805 c 0,0 -0.0221,-1.126952 -1.126951,-1.789864 z"
|
||||
id="path3918"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccsccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3928"
|
||||
d="m 18.73833,21.286331 1.657281,-0.729204 0.06629,-2.209709 -1.723573,0.618718 z"
|
||||
style="fill:url(#radialGradient3930);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3932"
|
||||
d="m 22.737903,31.318408 c 0,0 0,-5.104427 0,-7.159456 0,-2.055029 -2.342292,-3.601825 -2.342292,-3.601825 0,-0.927244 0.06629,-2.209709 0.06629,-2.209709 l 15.055864,4.034207 0,2.108783 c 0,0 -1.930193,-0.176776 -1.930193,1.502602 0,1.679379 0,7.51301 0,7.51301 z"
|
||||
style="fill:url(#radialGradient3936);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 23.776465,21.927147 32.15231,24.26278"
|
||||
id="path3966"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3960">
|
||||
<path
|
||||
style="fill:url(#radialGradient3890);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 42.02866,32.97569 c 0,0 -1.237437,-1.149049 -4.596194,-1.149049 -3.358758,0 -9.678525,1.723573 -11.136932,2.165515 -1.458408,0.441941 -6.805903,2.872621 -6.805903,2.872621 0,0 1.458408,1.016466 1.767767,1.325825 0.309359,0.309359 1.281631,1.325825 1.281631,1.325825 0,0 5.170718,1.37002 7.51301,1.37002 2.342291,0 7.73398,-0.751301 7.73398,-0.751301 0,0 3.756505,-4.375223 4.242641,-7.159456 z"
|
||||
id="path3870"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3874"
|
||||
d="m 37.786019,40.135146 c 0,0 3.756505,-4.375223 4.242641,-7.159456 1.723573,3.270369 1.59099,3.18198 1.59099,3.18198 0,0 -3.049398,3.402952 -5.833631,3.977476 z"
|
||||
style="fill:url(#radialGradient3898);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
style="fill:url(#radialGradient3914);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 45.829359,21.220039 c 0,4.065864 -3.800699,11.755651 -3.800699,11.755651 1.723573,3.270369 1.59099,3.18198 1.59099,3.18198 2.695845,-1.325825 7.557204,-8.529475 7.557204,-8.529475 0,0 -1.944544,-6.142991 -5.347495,-6.408156"
|
||||
id="path3876"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3878"
|
||||
d="m 14.84375,33.46875 c 0.18566,-1.505743 3.84375,-4.625 3.84375,-4.625 L 20.34375,30.5 c 0,0 2.21875,-1.5 4.15625,-2.28125 C 26.4375,27.4375 30.53125,26.25 30.53125,26.25 l 0.9375,-4.4375 c 0,0 5.471217,-3.903672 14.360609,-0.592461 0,4.065864 -3.800699,11.755651 -3.800699,11.755651 0,0 -1.237437,-1.149049 -4.596194,-1.149049 -3.358758,0 -9.678525,1.723573 -11.136932,2.165515 -1.458408,0.441941 -6.805903,2.872621 -6.805903,2.872621 0,0 -3.770881,-3.083527 -4.645881,-3.396027"
|
||||
style="fill:url(#radialGradient3906);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
sodipodi:nodetypes="cccsccccsscc" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
452
src/Mod/Ship/resources/icons/Ship_Load.svg
Normal file
452
src/Mod/Ship/resources/icons/Ship_Load.svg
Normal file
@@ -0,0 +1,452 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2985"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="Ship_Load.svg">
|
||||
<defs
|
||||
id="defs2987">
|
||||
<linearGradient
|
||||
id="linearGradient3979">
|
||||
<stop
|
||||
id="stop3981"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3983"
|
||||
offset="1"
|
||||
style="stop-color:#ff9600;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3971">
|
||||
<stop
|
||||
id="stop3973"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3975"
|
||||
offset="1"
|
||||
style="stop-color:#be7300;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Send"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path4031"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
|
||||
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Send"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path4049"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.3) rotate(180) translate(-2.3,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Sstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Sstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4046"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.3) translate(-2.3,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Mstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4040"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) translate(0,0)" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
id="linearGradient3900">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3902" />
|
||||
<stop
|
||||
style="stop-color:#a0a0a0;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3904" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3882">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3884" />
|
||||
<stop
|
||||
style="stop-color:#960000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3886" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3860">
|
||||
<stop
|
||||
style="stop-color:#1e76e3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3860-6"
|
||||
id="linearGradient3866-5"
|
||||
x1="31.125395"
|
||||
y1="61.410763"
|
||||
x2="30.113636"
|
||||
y2="12.160761"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3860-6">
|
||||
<stop
|
||||
style="stop-color:#5a9ff5;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862-4" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864-4" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3979"
|
||||
id="radialGradient3964"
|
||||
cx="-5.6195011"
|
||||
cy="1.8141681"
|
||||
fx="-5.6195011"
|
||||
fy="1.8141681"
|
||||
r="26.25"
|
||||
gradientTransform="matrix(1.8486536,-0.93638191,0.67849884,1.3395274,0.15759963,2.6203733)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3971"
|
||||
id="radialGradient3977"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.8486536,-0.93638191,0.67849884,1.3395274,0.15759963,2.6203733)"
|
||||
cx="14.92104"
|
||||
cy="5.9079928"
|
||||
fx="14.92104"
|
||||
fy="5.9079928"
|
||||
r="26.25" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient4009"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1622967,-0.42417542,0.71241125,1.9521011,-19.727075,-16.498215)"
|
||||
cx="16.274988"
|
||||
cy="23.718588"
|
||||
fx="16.274988"
|
||||
fy="23.718588"
|
||||
r="3.6819806" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient4011"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1875159,0.30002561,-0.66139805,2.6178455,13.656265,-48.87061)"
|
||||
cx="18.050617"
|
||||
cy="25.765184"
|
||||
fx="18.050617"
|
||||
fy="25.765184"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient4013"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1875159,0.30002561,-0.66139805,2.6178455,13.656265,-48.87061)"
|
||||
cx="17.915045"
|
||||
cy="24.185383"
|
||||
fx="17.915045"
|
||||
fy="24.185383"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient4015"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(3.980826,0.90111766,-0.59612552,2.6334762,-39.306292,-60.304205)"
|
||||
cx="18.420965"
|
||||
cy="23.089165"
|
||||
fx="18.420965"
|
||||
fy="23.089165"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient4017"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.7159608,-0.59513916,0.29226939,0.84269877,-28.848719,13.387411)"
|
||||
cx="25.629292"
|
||||
cy="38.444794"
|
||||
fx="25.629292"
|
||||
fy="38.444794"
|
||||
r="11.769514" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient4019"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(4.734087,-1.1798961,0.73145851,2.9348253,-139.28906,-25.817159)"
|
||||
cx="31.803391"
|
||||
cy="31.659325"
|
||||
fx="31.803391"
|
||||
fy="31.659325"
|
||||
r="3.417994" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient4021"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,1.5705123,0,-16.367411)"
|
||||
cx="44.852757"
|
||||
cy="22.63999"
|
||||
fx="44.852757"
|
||||
fy="22.63999"
|
||||
r="5.0740972" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient4023"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.6937502,-0.50833021,0.26447657,0.88123273,-17.232683,18.826666)"
|
||||
cx="20.211554"
|
||||
cy="12.140632"
|
||||
fx="20.211554"
|
||||
fy="12.140632"
|
||||
r="15.992805" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="-23.757069"
|
||||
inkscape:cy="20.751227"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="722"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2990">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3967"
|
||||
d="M 19.5,24.25 14.125,57 l 38.625,0 4.625,-32.75 -24.3125,0 -0.8125,-4.625 -9,0 z"
|
||||
style="fill:url(#radialGradient3977);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<g
|
||||
id="g3985"
|
||||
transform="translate(105.5,-0.75)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3856"
|
||||
d="m -55.356078,30.695806 c 0,0 1.811961,-1.281631 6.054602,-1.281631 4.24264,0 5.656854,1.502602 5.656854,1.502602"
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3860"
|
||||
d="m -103.0625,28.4375 c 0,0 0.9375,-0.9375 3.375,-0.9375 2.4375,0 5.25,1 5.25,1"
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3864"
|
||||
d="m -49.831806,29.458369 c 0,0 -3.623923,-1.679378 -10.208855,-1.679378 -6.584932,0 -10.606602,2.474873 -10.606602,2.474873"
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m -49.831806,29.458369 c 0,0 -3.623923,-1.679378 -10.208855,-1.679378 -6.584932,0 -10.606602,2.474873 -10.606602,2.474873"
|
||||
id="path3866"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
transform="translate(-104.5,-10.5)"
|
||||
id="g3977">
|
||||
<g
|
||||
id="g3968">
|
||||
<g
|
||||
id="g3953">
|
||||
<path
|
||||
style="fill:url(#radialGradient4009);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 16.528621,30.942758 0.707107,-7.778175 c 0,0 0.795495,-1.767767 2.563262,-1.767767 1.767767,0 2.032932,1.06066 2.032932,1.06066 l 1.06066,8.220117 z"
|
||||
id="path3938"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="g3948">
|
||||
<path
|
||||
sodipodi:nodetypes="ccsccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3918"
|
||||
d="m 18.73833,21.286331 1.657281,-0.729204 c 0,0 2.342292,1.546796 2.342292,3.601825 0,2.055029 0,7.159456 0,7.159456 l -3.987549,1.738087 0.05427,-7.748495 1.06066,-2.231805 c 0,0 -0.0221,-1.126952 -1.126951,-1.789864 z"
|
||||
style="fill:url(#radialGradient4011);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:url(#radialGradient4013);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 18.73833,21.286331 1.657281,-0.729204 0.06629,-2.209709 -1.723573,0.618718 z"
|
||||
id="path3928"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:url(#radialGradient4015);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 22.737903,31.318408 c 0,0 0,-5.104427 0,-7.159456 0,-2.055029 -2.342292,-3.601825 -2.342292,-3.601825 0,-0.927244 0.06629,-2.209709 0.06629,-2.209709 l 15.055864,4.034207 0,2.108783 c 0,0 -1.930193,-0.176776 -1.930193,1.502602 0,1.679379 0,7.51301 0,7.51301 z"
|
||||
id="path3932"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscc" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3966"
|
||||
d="M 23.776465,21.927147 32.15231,24.26278"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
</g>
|
||||
<g
|
||||
id="g3960">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3870"
|
||||
d="m 42.02866,32.97569 c 0,0 -1.237437,-1.149049 -4.596194,-1.149049 -3.358758,0 -9.678525,1.723573 -11.136932,2.165515 -1.458408,0.441941 -6.805903,2.872621 -6.805903,2.872621 0,0 1.458408,1.016466 1.767767,1.325825 0.309359,0.309359 1.281631,1.325825 1.281631,1.325825 0,0 5.170718,1.37002 7.51301,1.37002 2.342291,0 7.73398,-0.751301 7.73398,-0.751301 0,0 3.756505,-4.375223 4.242641,-7.159456 z"
|
||||
style="fill:url(#radialGradient4017);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="fill:url(#radialGradient4019);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 37.786019,40.135146 c 0,0 3.756505,-4.375223 4.242641,-7.159456 1.723573,3.270369 1.59099,3.18198 1.59099,3.18198 0,0 -3.049398,3.402952 -5.833631,3.977476 z"
|
||||
id="path3874"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3876"
|
||||
d="m 45.829359,21.220039 c 0,4.065864 -3.800699,11.755651 -3.800699,11.755651 1.723573,3.270369 1.59099,3.18198 1.59099,3.18198 2.695845,-1.325825 7.557204,-8.529475 7.557204,-8.529475 0,0 -1.944544,-6.142991 -5.347495,-6.408156"
|
||||
style="fill:url(#radialGradient4021);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccsccccsscc"
|
||||
style="fill:url(#radialGradient4023);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 14.84375,33.46875 c 0.18566,-1.505743 3.84375,-4.625 3.84375,-4.625 L 20.34375,30.5 c 0,0 2.21875,-1.5 4.15625,-2.28125 C 26.4375,27.4375 30.53125,26.25 30.53125,26.25 l 0.9375,-4.4375 c 0,0 5.471217,-3.903672 14.360609,-0.592461 0,4.065864 -3.800699,11.755651 -3.800699,11.755651 0,0 -1.237437,-1.149049 -4.596194,-1.149049 -3.358758,0 -9.678525,1.723573 -11.136932,2.165515 -1.458408,0.441941 -6.805903,2.872621 -6.805903,2.872621 0,0 -3.770881,-3.083527 -4.645881,-3.396027"
|
||||
id="path3878"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3082"
|
||||
d="m -98.8125,30.25 c 0,0 3.9375,-2.4375 9.5,-2.4375 5.5625,0 8.75,2.5625 15.8125,2.5625 7.0625,0 5.4375,-1.125 11.0625,-1.125 5.625,0 10.125001,3 10.125001,3"
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m -98.8125,30.25 c 0,0 3.9375,-2.4375 9.5,-2.4375 5.5625,0 8.75,2.5625 15.8125,2.5625 7.0625,0 5.4375,-1.125 11.0625,-1.125 5.625,0 10.125001,3 10.125001,3"
|
||||
id="path3852"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m -55.356078,30.695806 c 0,0 1.811961,-1.281631 6.054602,-1.281631 4.24264,0 5.656854,1.502602 5.656854,1.502602"
|
||||
id="path3858"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m -103.0625,28.4375 c 0,0 0.9375,-0.9375 3.375,-0.9375 2.4375,0 5.25,1 5.25,1"
|
||||
id="path3862"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:url(#radialGradient3964);stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0"
|
||||
d="m 14.125,57 38.625,0 -13.125,-32.875 -24.25,0 -4.75,-4.75 -7.5,0 -1.875,4.875 z"
|
||||
id="path3164"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="g5774"
|
||||
transform="matrix(0.99136339,-0.13114354,0.13114354,0.99136339,-15.325656,-9.4612023)">
|
||||
<path
|
||||
d="m 34.604037,49.371727 c 0,1.000719 -0.811242,1.811961 -1.811961,1.811961 -1.000718,0 -1.811961,-0.811242 -1.811961,-1.811961 0,-1.000719 0.811243,-1.811961 1.811961,-1.811961 1.000719,0 1.811961,0.811242 1.811961,1.811961 z"
|
||||
sodipodi:ry="1.8119612"
|
||||
sodipodi:rx="1.8119612"
|
||||
sodipodi:cy="49.371727"
|
||||
sodipodi:cx="32.792076"
|
||||
id="path4004"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4006"
|
||||
d="M 30.756005,53.250092 30.49874,52.450731 36.391621,50.871738 36.160297,50.008422"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4008"
|
||||
d="m 33.375,51.71875 2.385247,8.901862"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4010"
|
||||
d="m 29.40625,60.125 c 1.8125,0.9375 4.631882,0.963181 6.59375,0.4375 1.961869,-0.525681 4.116517,-2.098648 4.78125,-3.25"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow2Send)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5772"
|
||||
d="m 34.125,61.03125 0,-1.34375 2.53125,-0.96875 L 37.5625,60 37.125,61.03125 35.34375,61.625 z"
|
||||
style="fill:#000000;fill-opacity:1;stroke:none" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 20 KiB |
524
src/Mod/Ship/resources/icons/Ship_Logo.svg
Normal file
524
src/Mod/Ship/resources/icons/Ship_Logo.svg
Normal file
@@ -0,0 +1,524 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="256"
|
||||
height="256"
|
||||
id="svg2985"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="Ship_Module.svg">
|
||||
<defs
|
||||
id="defs2987">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Send"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4031"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Send"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Send"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4049"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-0.3,0,0,-0.3,0.69,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Sstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Sstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4046"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(0.3,0,0,0.3,-0.69,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Mstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4040"
|
||||
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="scale(0.6,0.6)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
id="linearGradient3900">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3902" />
|
||||
<stop
|
||||
style="stop-color:#a0a0a0;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3904" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3882">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3884" />
|
||||
<stop
|
||||
style="stop-color:#960000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3886" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3860">
|
||||
<stop
|
||||
style="stop-color:#1e76e3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3860-6"
|
||||
id="linearGradient3866-5"
|
||||
x1="31.125395"
|
||||
y1="61.410763"
|
||||
x2="30.113636"
|
||||
y2="12.160761"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3860-6">
|
||||
<stop
|
||||
style="stop-color:#5a9ff5;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862-4" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864-4" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3890"
|
||||
cx="25.629292"
|
||||
cy="38.444794"
|
||||
fx="25.629292"
|
||||
fy="38.444794"
|
||||
r="11.769514"
|
||||
gradientTransform="matrix(1.7159608,-0.59513916,0.29226939,0.84269877,-28.848719,13.387411)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3898"
|
||||
cx="31.803391"
|
||||
cy="31.659325"
|
||||
fx="31.803391"
|
||||
fy="31.659325"
|
||||
r="3.417994"
|
||||
gradientTransform="matrix(4.734087,-1.1798961,0.73145851,2.9348253,-139.28906,-25.817159)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3906"
|
||||
cx="20.211554"
|
||||
cy="12.140632"
|
||||
fx="20.211554"
|
||||
fy="12.140632"
|
||||
r="15.992805"
|
||||
gradientTransform="matrix(1.6937502,-0.50833021,0.26447657,0.88123273,-17.232683,18.826666)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3914"
|
||||
cx="44.852757"
|
||||
cy="22.63999"
|
||||
fx="44.852757"
|
||||
fy="22.63999"
|
||||
r="5.0740972"
|
||||
gradientTransform="matrix(1,0,0,1.5705123,0,-16.367411)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3926"
|
||||
cx="18.050617"
|
||||
cy="25.765184"
|
||||
fx="18.050617"
|
||||
fy="25.765184"
|
||||
r="2.4997866"
|
||||
gradientTransform="matrix(1.1875159,0.30002561,-0.66139805,2.6178455,13.656265,-48.87061)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3930"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1875159,0.30002561,-0.66139805,2.6178455,13.656265,-48.87061)"
|
||||
cx="17.915045"
|
||||
cy="24.185383"
|
||||
fx="17.915045"
|
||||
fy="24.185383"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3936"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(3.980826,0.90111766,-0.59612552,2.6334762,-39.306292,-60.304205)"
|
||||
cx="18.420965"
|
||||
cy="23.089165"
|
||||
fx="18.420965"
|
||||
fy="23.089165"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3946"
|
||||
cx="16.274988"
|
||||
cy="23.718588"
|
||||
fx="16.274988"
|
||||
fy="23.718588"
|
||||
r="3.6819806"
|
||||
gradientTransform="matrix(1.1622967,-0.42417542,0.71241125,1.9521011,-19.727075,-16.498215)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3081"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1622967,-0.42417542,0.71241125,1.9521011,-19.727075,-16.498215)"
|
||||
cx="16.274988"
|
||||
cy="23.718588"
|
||||
fx="16.274988"
|
||||
fy="23.718588"
|
||||
r="3.6819806" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3083"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1875159,0.30002561,-0.66139805,2.6178455,13.656265,-48.87061)"
|
||||
cx="18.050617"
|
||||
cy="25.765184"
|
||||
fx="18.050617"
|
||||
fy="25.765184"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3085"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1875159,0.30002561,-0.66139805,2.6178455,13.656265,-48.87061)"
|
||||
cx="17.915045"
|
||||
cy="24.185383"
|
||||
fx="17.915045"
|
||||
fy="24.185383"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3087"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(3.980826,0.90111766,-0.59612552,2.6334762,-39.306292,-60.304205)"
|
||||
cx="18.420965"
|
||||
cy="23.089165"
|
||||
fx="18.420965"
|
||||
fy="23.089165"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3089"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.7159608,-0.59513916,0.29226939,0.84269877,-28.848719,13.387411)"
|
||||
cx="25.629292"
|
||||
cy="38.444794"
|
||||
fx="25.629292"
|
||||
fy="38.444794"
|
||||
r="11.769514" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3091"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(4.734087,-1.1798961,0.73145851,2.9348253,-139.28906,-25.817159)"
|
||||
cx="31.803391"
|
||||
cy="31.659325"
|
||||
fx="31.803391"
|
||||
fy="31.659325"
|
||||
r="3.417994" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3093"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,1.5705123,0,-16.367411)"
|
||||
cx="44.852757"
|
||||
cy="22.63999"
|
||||
fx="44.852757"
|
||||
fy="22.63999"
|
||||
r="5.0740972" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3095"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.6937502,-0.50833021,0.26447657,0.88123273,-17.232683,18.826666)"
|
||||
cx="20.211554"
|
||||
cy="12.140632"
|
||||
fx="20.211554"
|
||||
fy="12.140632"
|
||||
r="15.992805" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="-38.366"
|
||||
inkscape:cy="88.055386"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="722"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2990">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
transform="translate(0,192)">
|
||||
<g
|
||||
id="g3045"
|
||||
transform="matrix(4.1291004,0,0,4.1291004,-0.58670633,-198.26865)">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3992"
|
||||
y="13.75"
|
||||
x="3.25"
|
||||
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:14px"
|
||||
y="13.75"
|
||||
x="3.25"
|
||||
id="tspan3994"
|
||||
sodipodi:role="line">FreeCAD</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3856"
|
||||
d="m 49.143922,41.195806 c 0,0 1.811961,-1.281631 6.054602,-1.281631 4.24264,0 5.656854,1.502602 5.656854,1.502602"
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3860"
|
||||
d="m 1.4375,38.9375 c 0,0 0.9375,-0.9375 3.375,-0.9375 2.4375001,0 5.25,1 5.25,1"
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3864"
|
||||
d="m 54.668194,39.958369 c 0,0 -3.623923,-1.679378 -10.208855,-1.679378 -6.584932,0 -10.606602,2.474873 -10.606602,2.474873"
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 54.668194,39.958369 c 0,0 -3.623923,-1.679378 -10.208855,-1.679378 -6.584932,0 -10.606602,2.474873 -10.606602,2.474873"
|
||||
id="path3866"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="g3977">
|
||||
<g
|
||||
id="g3968">
|
||||
<g
|
||||
id="g3953">
|
||||
<path
|
||||
style="fill:url(#radialGradient3081);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 16.528621,30.942758 0.707107,-7.778175 c 0,0 0.795495,-1.767767 2.563262,-1.767767 1.767767,0 2.032932,1.06066 2.032932,1.06066 l 1.06066,8.220117 z"
|
||||
id="path3938"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="g3948">
|
||||
<path
|
||||
sodipodi:nodetypes="ccsccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3918"
|
||||
d="m 18.73833,21.286331 1.657281,-0.729204 c 0,0 2.342292,1.546796 2.342292,3.601825 0,2.055029 0,7.159456 0,7.159456 l -3.987549,1.738087 0.05427,-7.748495 1.06066,-2.231805 c 0,0 -0.0221,-1.126952 -1.126951,-1.789864 z"
|
||||
style="fill:url(#radialGradient3083);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:url(#radialGradient3085);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 18.73833,21.286331 1.657281,-0.729204 0.06629,-2.209709 -1.723573,0.618718 z"
|
||||
id="path3928"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:url(#radialGradient3087);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 22.737903,31.318408 c 0,0 0,-5.104427 0,-7.159456 0,-2.055029 -2.342292,-3.601825 -2.342292,-3.601825 0,-0.927244 0.06629,-2.209709 0.06629,-2.209709 l 15.055864,4.034207 0,2.108783 c 0,0 -1.930193,-0.176776 -1.930193,1.502602 0,1.679379 0,7.51301 0,7.51301 z"
|
||||
id="path3932"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscc" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3966"
|
||||
d="M 23.776465,21.927147 32.15231,24.26278"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
</g>
|
||||
<g
|
||||
id="g3960">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3870"
|
||||
d="m 42.02866,32.97569 c 0,0 -1.237437,-1.149049 -4.596194,-1.149049 -3.358758,0 -9.678525,1.723573 -11.136932,2.165515 -1.458408,0.441941 -6.805903,2.872621 -6.805903,2.872621 0,0 1.458408,1.016466 1.767767,1.325825 0.309359,0.309359 1.281631,1.325825 1.281631,1.325825 0,0 5.170718,1.37002 7.51301,1.37002 2.342291,0 7.73398,-0.751301 7.73398,-0.751301 0,0 3.756505,-4.375223 4.242641,-7.159456 z"
|
||||
style="fill:url(#radialGradient3089);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
style="fill:url(#radialGradient3091);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 37.786019,40.135146 c 0,0 3.756505,-4.375223 4.242641,-7.159456 1.723573,3.270369 1.59099,3.18198 1.59099,3.18198 0,0 -3.049398,3.402952 -5.833631,3.977476 z"
|
||||
id="path3874"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3876"
|
||||
d="m 45.829359,21.220039 c 0,4.065864 -3.800699,11.755651 -3.800699,11.755651 1.723573,3.270369 1.59099,3.18198 1.59099,3.18198 2.695845,-1.325825 7.557204,-8.529475 7.557204,-8.529475 0,0 -1.944544,-6.142991 -5.347495,-6.408156"
|
||||
style="fill:url(#radialGradient3093);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccsccccsscc"
|
||||
style="fill:url(#radialGradient3095);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="m 14.84375,33.46875 c 0.18566,-1.505743 3.84375,-4.625 3.84375,-4.625 L 20.34375,30.5 c 0,0 2.21875,-1.5 4.15625,-2.28125 C 26.4375,27.4375 30.53125,26.25 30.53125,26.25 l 0.9375,-4.4375 c 0,0 5.471217,-3.903672 14.360609,-0.592461 0,4.065864 -3.800699,11.755651 -3.800699,11.755651 0,0 -1.237437,-1.149049 -4.596194,-1.149049 -3.358758,0 -9.678525,1.723573 -11.136932,2.165515 -1.458408,0.441941 -6.805903,2.872621 -6.805903,2.872621 0,0 -3.770881,-3.083527 -4.645881,-3.396027"
|
||||
id="path3878"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3082"
|
||||
d="m 5.6875001,40.75 c 0,0 3.9375,-2.4375 9.4999999,-2.4375 5.5625,0 8.75,2.5625 15.8125,2.5625 7.0625,0 5.4375,-1.125 11.0625,-1.125 5.625,0 10.125001,3 10.125001,3"
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 5.6875001,40.75 c 0,0 3.9375,-2.4375 9.4999999,-2.4375 5.5625,0 8.75,2.5625 15.8125,2.5625 7.0625,0 5.4375,-1.125 11.0625,-1.125 5.625,0 10.125001,3 10.125001,3"
|
||||
id="path3852"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 49.143922,41.195806 c 0,0 1.811961,-1.281631 6.054602,-1.281631 4.24264,0 5.656854,1.502602 5.656854,1.502602"
|
||||
id="path3858"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 1.4375,38.9375 c 0,0 0.9375,-0.9375 3.375,-0.9375 2.4375001,0 5.25,1 5.25,1"
|
||||
id="path3862"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3996"
|
||||
y="59.75"
|
||||
x="11.375"
|
||||
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:14px"
|
||||
y="59.75"
|
||||
x="11.375"
|
||||
id="tspan3998"
|
||||
sodipodi:role="line">Sh</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4000"
|
||||
y="59.125"
|
||||
x="42.75"
|
||||
style="font-size:14px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
|
||||
xml:space="preserve"><tspan
|
||||
y="59.125"
|
||||
x="42.75"
|
||||
id="tspan4002"
|
||||
sodipodi:role="line">p</tspan></text>
|
||||
<g
|
||||
transform="translate(0.53033009,0)"
|
||||
id="g5774">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
id="path4004"
|
||||
sodipodi:cx="32.792076"
|
||||
sodipodi:cy="49.371727"
|
||||
sodipodi:rx="1.8119612"
|
||||
sodipodi:ry="1.8119612"
|
||||
d="m 34.604037,49.371727 c 0,1.000719 -0.811242,1.811961 -1.811961,1.811961 -1.000718,0 -1.811961,-0.811242 -1.811961,-1.811961 0,-1.000719 0.811243,-1.811961 1.811961,-1.811961 1.000719,0 1.811961,0.811242 1.811961,1.811961 z" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 30.756005,53.250092 30.49874,52.450731 36.391621,50.871738 36.160297,50.008422"
|
||||
id="path4006"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 33.375,51.71875 2.385247,8.901862"
|
||||
id="path4008"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow2Send)"
|
||||
d="m 29.40625,60.125 c 1.8125,0.9375 4.631882,0.963181 6.59375,0.4375 1.961869,-0.525681 4.116517,-2.098648 4.78125,-3.25"
|
||||
id="path4010"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:none"
|
||||
d="m 34.125,61.03125 0,-1.34375 2.53125,-0.96875 L 37.5625,60 37.125,61.03125 35.34375,61.625 z"
|
||||
id="path5772"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
427
src/Mod/Ship/resources/icons/Ship_Module.svg
Normal file
427
src/Mod/Ship/resources/icons/Ship_Module.svg
Normal file
@@ -0,0 +1,427 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2985"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="Ship_Module.svg">
|
||||
<defs
|
||||
id="defs2987">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Send"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path4031"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
|
||||
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Send"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path4049"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.3) rotate(180) translate(-2.3,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Sstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Sstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4046"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.3) translate(-2.3,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Mstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4040"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) translate(0,0)" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
id="linearGradient3900">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3902" />
|
||||
<stop
|
||||
style="stop-color:#a0a0a0;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3904" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3882">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3884" />
|
||||
<stop
|
||||
style="stop-color:#960000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3886" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3860">
|
||||
<stop
|
||||
style="stop-color:#1e76e3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3860-6"
|
||||
id="linearGradient3866-5"
|
||||
x1="31.125395"
|
||||
y1="61.410763"
|
||||
x2="30.113636"
|
||||
y2="12.160761"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3860-6">
|
||||
<stop
|
||||
style="stop-color:#5a9ff5;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862-4" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864-4" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3890"
|
||||
cx="25.629292"
|
||||
cy="38.444794"
|
||||
fx="25.629292"
|
||||
fy="38.444794"
|
||||
r="11.769514"
|
||||
gradientTransform="matrix(1.7159608,-0.59513916,0.29226939,0.84269877,-28.848719,13.387411)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3898"
|
||||
cx="31.803391"
|
||||
cy="31.659325"
|
||||
fx="31.803391"
|
||||
fy="31.659325"
|
||||
r="3.417994"
|
||||
gradientTransform="matrix(4.734087,-1.1798961,0.73145851,2.9348253,-139.28906,-25.817159)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3906"
|
||||
cx="20.211554"
|
||||
cy="12.140632"
|
||||
fx="20.211554"
|
||||
fy="12.140632"
|
||||
r="15.992805"
|
||||
gradientTransform="matrix(1.6937502,-0.50833021,0.26447657,0.88123273,-17.232683,18.826666)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3914"
|
||||
cx="44.852757"
|
||||
cy="22.63999"
|
||||
fx="44.852757"
|
||||
fy="22.63999"
|
||||
r="5.0740972"
|
||||
gradientTransform="matrix(1,0,0,1.5705123,0,-16.367411)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3926"
|
||||
cx="18.050617"
|
||||
cy="25.765184"
|
||||
fx="18.050617"
|
||||
fy="25.765184"
|
||||
r="2.4997866"
|
||||
gradientTransform="matrix(1.1875159,0.30002561,-0.66139805,2.6178455,13.656265,-48.87061)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3930"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.1875159,0.30002561,-0.66139805,2.6178455,13.656265,-48.87061)"
|
||||
cx="17.915045"
|
||||
cy="24.185383"
|
||||
fx="17.915045"
|
||||
fy="24.185383"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3900"
|
||||
id="radialGradient3936"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(3.980826,0.90111766,-0.59612552,2.6334762,-39.306292,-60.304205)"
|
||||
cx="18.420965"
|
||||
cy="23.089165"
|
||||
fx="18.420965"
|
||||
fy="23.089165"
|
||||
r="2.4997866" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3946"
|
||||
cx="16.274988"
|
||||
cy="23.718588"
|
||||
fx="16.274988"
|
||||
fy="23.718588"
|
||||
r="3.6819806"
|
||||
gradientTransform="matrix(1.1622967,-0.42417542,0.71241125,1.9521011,-19.727075,-16.498215)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="-6.1454977"
|
||||
inkscape:cy="13.674344"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="722"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2990">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
|
||||
x="3.25"
|
||||
y="13.75"
|
||||
id="text3992"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3994"
|
||||
x="3.25"
|
||||
y="13.75"
|
||||
style="font-size:14px">FreeCAD</tspan></text>
|
||||
<path
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 49.143922,41.195806 c 0,0 1.811961,-1.281631 6.054602,-1.281631 4.24264,0 5.656854,1.502602 5.656854,1.502602"
|
||||
id="path3856"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 1.4375,38.9375 c 0,0 0.9375,-0.9375 3.375,-0.9375 2.4375001,0 5.25,1 5.25,1"
|
||||
id="path3860"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 54.668194,39.958369 c 0,0 -3.623923,-1.679378 -10.208855,-1.679378 -6.584932,0 -10.606602,2.474873 -10.606602,2.474873"
|
||||
id="path3864"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3866"
|
||||
d="m 54.668194,39.958369 c 0,0 -3.623923,-1.679378 -10.208855,-1.679378 -6.584932,0 -10.606602,2.474873 -10.606602,2.474873"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<g
|
||||
id="g3977">
|
||||
<g
|
||||
id="g3968">
|
||||
<g
|
||||
id="g3953">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3938"
|
||||
d="m 16.528621,30.942758 0.707107,-7.778175 c 0,0 0.795495,-1.767767 2.563262,-1.767767 1.767767,0 2.032932,1.06066 2.032932,1.06066 l 1.06066,8.220117 z"
|
||||
style="fill:url(#radialGradient3946);stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
|
||||
<g
|
||||
id="g3948">
|
||||
<path
|
||||
style="fill:url(#radialGradient3926);stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
|
||||
d="m 18.73833,21.286331 1.657281,-0.729204 c 0,0 2.342292,1.546796 2.342292,3.601825 0,2.055029 0,7.159456 0,7.159456 l -3.987549,1.738087 0.05427,-7.748495 1.06066,-2.231805 c 0,0 -0.0221,-1.126952 -1.126951,-1.789864 z"
|
||||
id="path3918"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccsccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3928"
|
||||
d="m 18.73833,21.286331 1.657281,-0.729204 0.06629,-2.209709 -1.723573,0.618718 z"
|
||||
style="fill:url(#radialGradient3930);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="cscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3932"
|
||||
d="m 22.737903,31.318408 c 0,0 0,-5.104427 0,-7.159456 0,-2.055029 -2.342292,-3.601825 -2.342292,-3.601825 0,-0.927244 0.06629,-2.209709 0.06629,-2.209709 l 15.055864,4.034207 0,2.108783 c 0,0 -1.930193,-0.176776 -1.930193,1.502602 0,1.679379 0,7.51301 0,7.51301 z"
|
||||
style="fill:url(#radialGradient3936);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="M 23.776465,21.927147 32.15231,24.26278"
|
||||
id="path3966"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3960">
|
||||
<path
|
||||
style="fill:url(#radialGradient3890);stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
|
||||
d="m 42.02866,32.97569 c 0,0 -1.237437,-1.149049 -4.596194,-1.149049 -3.358758,0 -9.678525,1.723573 -11.136932,2.165515 -1.458408,0.441941 -6.805903,2.872621 -6.805903,2.872621 0,0 1.458408,1.016466 1.767767,1.325825 0.309359,0.309359 1.281631,1.325825 1.281631,1.325825 0,0 5.170718,1.37002 7.51301,1.37002 2.342291,0 7.73398,-0.751301 7.73398,-0.751301 0,0 3.756505,-4.375223 4.242641,-7.159456 z"
|
||||
id="path3870"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3874"
|
||||
d="m 37.786019,40.135146 c 0,0 3.756505,-4.375223 4.242641,-7.159456 1.723573,3.270369 1.59099,3.18198 1.59099,3.18198 0,0 -3.049398,3.402952 -5.833631,3.977476 z"
|
||||
style="fill:url(#radialGradient3898);stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
style="fill:url(#radialGradient3914);stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
|
||||
d="m 45.829359,21.220039 c 0,4.065864 -3.800699,11.755651 -3.800699,11.755651 1.723573,3.270369 1.59099,3.18198 1.59099,3.18198 2.695845,-1.325825 7.557204,-8.529475 7.557204,-8.529475 0,0 -1.944544,-6.142991 -5.347495,-6.408156"
|
||||
id="path3876"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3878"
|
||||
d="m 14.84375,33.46875 c 0.18566,-1.505743 3.84375,-4.625 3.84375,-4.625 L 20.34375,30.5 c 0,0 2.21875,-1.5 4.15625,-2.28125 C 26.4375,27.4375 30.53125,26.25 30.53125,26.25 l 0.9375,-4.4375 c 0,0 5.471217,-3.903672 14.360609,-0.592461 0,4.065864 -3.800699,11.755651 -3.800699,11.755651 0,0 -1.237437,-1.149049 -4.596194,-1.149049 -3.358758,0 -9.678525,1.723573 -11.136932,2.165515 -1.458408,0.441941 -6.805903,2.872621 -6.805903,2.872621 0,0 -3.770881,-3.083527 -4.645881,-3.396027"
|
||||
style="fill:url(#radialGradient3906);stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;fill-opacity:1"
|
||||
sodipodi:nodetypes="cccsccccsscc" />
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#afffff;stroke-width:2.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 5.6875001,40.75 c 0,0 3.9375,-2.4375 9.4999999,-2.4375 5.5625,0 8.75,2.5625 15.8125,2.5625 7.0625,0 5.4375,-1.125 11.0625,-1.125 5.625,0 10.125001,3 10.125001,3"
|
||||
id="path3082"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3852"
|
||||
d="m 5.6875001,40.75 c 0,0 3.9375,-2.4375 9.4999999,-2.4375 5.5625,0 8.75,2.5625 15.8125,2.5625 7.0625,0 5.4375,-1.125 11.0625,-1.125 5.625,0 10.125001,3 10.125001,3"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3858"
|
||||
d="m 49.143922,41.195806 c 0,0 1.811961,-1.281631 6.054602,-1.281631 4.24264,0 5.656854,1.502602 5.656854,1.502602"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3862"
|
||||
d="m 1.4375,38.9375 c 0,0 0.9375,-0.9375 3.375,-0.9375 2.4375001,0 5.25,1 5.25,1"
|
||||
style="fill:none;stroke:#0000ff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
|
||||
x="11.375"
|
||||
y="59.75"
|
||||
id="text3996"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3998"
|
||||
x="11.375"
|
||||
y="59.75"
|
||||
style="font-size:14px">Sh</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Arial;-inkscape-font-specification:Arial"
|
||||
x="42.75"
|
||||
y="59.125"
|
||||
id="text4000"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4002"
|
||||
x="42.75"
|
||||
y="59.125">p</tspan></text>
|
||||
<g
|
||||
id="g5774"
|
||||
transform="translate(0.53033009,0)">
|
||||
<path
|
||||
d="m 34.604037,49.371727 c 0,1.000719 -0.811242,1.811961 -1.811961,1.811961 -1.000718,0 -1.811961,-0.811242 -1.811961,-1.811961 0,-1.000719 0.811243,-1.811961 1.811961,-1.811961 1.000719,0 1.811961,0.811242 1.811961,1.811961 z"
|
||||
sodipodi:ry="1.8119612"
|
||||
sodipodi:rx="1.8119612"
|
||||
sodipodi:cy="49.371727"
|
||||
sodipodi:cx="32.792076"
|
||||
id="path4004"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4006"
|
||||
d="M 30.756005,53.250092 30.49874,52.450731 36.391621,50.871738 36.160297,50.008422"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4008"
|
||||
d="m 33.375,51.71875 2.385247,8.901862"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4010"
|
||||
d="m 29.40625,60.125 c 1.8125,0.9375 4.631882,0.963181 6.59375,0.4375 1.961869,-0.525681 4.116517,-2.098648 4.78125,-3.25"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow2Send)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5772"
|
||||
d="m 34.125,61.03125 0,-1.34375 2.53125,-0.96875 L 37.5625,60 37.125,61.03125 35.34375,61.625 z"
|
||||
style="fill:#000000;fill-opacity:1;stroke:none" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 19 KiB |
399
src/Mod/Ship/resources/icons/Ship_OutlineDraw.svg
Normal file
399
src/Mod/Ship/resources/icons/Ship_OutlineDraw.svg
Normal file
@@ -0,0 +1,399 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2985"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="Ship_Load.svg">
|
||||
<defs
|
||||
id="defs2987">
|
||||
<linearGradient
|
||||
id="linearGradient3937">
|
||||
<stop
|
||||
style="stop-color:#be7328;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3939" />
|
||||
<stop
|
||||
style="stop-color:#dc962d;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3941" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3929">
|
||||
<stop
|
||||
id="stop3931"
|
||||
offset="0"
|
||||
style="stop-color:#c88c3c;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3933"
|
||||
offset="1"
|
||||
style="stop-color:#ffff96;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3893">
|
||||
<stop
|
||||
style="stop-color:#505050;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3895" />
|
||||
<stop
|
||||
style="stop-color:#aaaaaa;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3897" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3873">
|
||||
<stop
|
||||
style="stop-color:#f0be6e;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3875" />
|
||||
<stop
|
||||
style="stop-color:#c88228;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3877" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3863">
|
||||
<stop
|
||||
id="stop3865"
|
||||
offset="0"
|
||||
style="stop-color:#6e4b18;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3867"
|
||||
offset="1"
|
||||
style="stop-color:#c88228;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3979">
|
||||
<stop
|
||||
id="stop3981"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3983"
|
||||
offset="1"
|
||||
style="stop-color:#ff9600;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3971">
|
||||
<stop
|
||||
id="stop3973"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3975"
|
||||
offset="1"
|
||||
style="stop-color:#be7300;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Send"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path4031"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
|
||||
transform="scale(0.2) rotate(180) translate(6,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Send"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Send"
|
||||
style="overflow:visible;">
|
||||
<path
|
||||
id="path4049"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.3) rotate(180) translate(-2.3,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Sstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Sstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4046"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.3) translate(-2.3,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Mstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow2Mstart"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path4040"
|
||||
style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
|
||||
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||
transform="scale(0.6) translate(0,0)" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
id="linearGradient3900">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3902" />
|
||||
<stop
|
||||
style="stop-color:#a0a0a0;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3904" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3882">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3884" />
|
||||
<stop
|
||||
style="stop-color:#960000;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3886" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3860">
|
||||
<stop
|
||||
style="stop-color:#1e76e3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3860-6"
|
||||
id="linearGradient3866-5"
|
||||
x1="31.125395"
|
||||
y1="61.410763"
|
||||
x2="30.113636"
|
||||
y2="12.160761"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient3860-6">
|
||||
<stop
|
||||
style="stop-color:#5a9ff5;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3862-4" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3864-4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3873"
|
||||
id="linearGradient3871"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="38.907837"
|
||||
y1="51.470051"
|
||||
x2="45.302406"
|
||||
y2="54.091148" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3863"
|
||||
id="linearGradient3891"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="51.657837"
|
||||
y1="34.470051"
|
||||
x2="45.427406"
|
||||
y2="32.216148" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3893"
|
||||
id="linearGradient3899"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="51.657837"
|
||||
y1="34.470051"
|
||||
x2="45.427406"
|
||||
y2="32.216148" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3882"
|
||||
id="radialGradient3903"
|
||||
cx="53.748837"
|
||||
cy="4.9173141"
|
||||
fx="53.748837"
|
||||
fy="4.9173141"
|
||||
r="3.2874005"
|
||||
gradientTransform="matrix(2.3303929,-1.4921636,1.0936999,1.7080907,-77.643882,78.644487)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3929"
|
||||
id="radialGradient3927"
|
||||
cx="15.125"
|
||||
cy="48.035076"
|
||||
fx="15.125"
|
||||
fy="48.035076"
|
||||
r="18.875"
|
||||
gradientTransform="matrix(2.7636523,-0.71644256,0.733044,2.8276918,-61.887066,-71.992203)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3937"
|
||||
id="radialGradient3943"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.40097726,-0.37931652,0.11734116,0.12404187,14.422507,4.6205505)"
|
||||
cx="-14.308363"
|
||||
cy="14.910047"
|
||||
fx="-14.308363"
|
||||
fy="14.910047"
|
||||
r="18.875" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3929"
|
||||
id="radialGradient3949"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(2.7636523,-0.71644256,0.733044,2.8276918,-61.887066,-71.992203)"
|
||||
cx="15.125"
|
||||
cy="48.035076"
|
||||
fx="15.125"
|
||||
fy="48.035076"
|
||||
r="18.875" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3937"
|
||||
id="radialGradient3951"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.40097726,-0.37931652,0.11734116,0.12404187,14.422507,4.6205505)"
|
||||
cx="-14.308363"
|
||||
cy="14.910047"
|
||||
fx="-14.308363"
|
||||
fy="14.910047"
|
||||
r="18.875" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="8"
|
||||
inkscape:cx="43.350917"
|
||||
inkscape:cy="32.886977"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="722"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata2990">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
id="g3945">
|
||||
<path
|
||||
sodipodi:nodetypes="csccscscsc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3919"
|
||||
d="m 15.125,55.375 c 0,0 -7.75,-4.125 -7.75,-28.5 0,-9.375 2.125,-12.5 2.125,-12.5 L 15.375,8 c 0,0 4.125,-0.625 10.75,-0.625 6.625,0 15.625,1.25 15.625,1.25 0,0 -1.5,8.75 -1.5,18.625 0,9.875 3.875,21.125 3.875,21.125 0,0 -7.375,-0.25 -14.875,1.75 -7.5,2 -14.125,5.25 -14.125,5.25 z"
|
||||
style="fill:url(#radialGradient3949);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
style="fill:url(#radialGradient3951);fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 16.875,16.9375 C 14.5625,9.5625 9.5,14.375 9.5,14.375 L 15.375,8 c 0,0 3.3125,-1.375 1.5,8.9375"
|
||||
id="path3935"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3961"
|
||||
transform="translate(1.25,0.5)"
|
||||
style="stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none">
|
||||
<path
|
||||
sodipodi:nodetypes="ccssccsc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3953"
|
||||
d="m 17.5,14.5 0.375,17.125 c 0,0 1.75,11.25 5.875,10.875 4.125,-0.375 -0.625,-3.25 3,-3.125 3.625,0.125 5.375,6.5 10.375,6.875 m 0,0 C 36.125,42 35.465045,38.810263 34.625,33.875 33.625,28 32.5,11.75 32.5,11.75"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3957"
|
||||
d="m 19.625,14.125 c 0,0 0.370838,11.000136 0.5,14.875 0.125,3.75 7.437825,10.194757 15.437825,10.194757"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="csc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3959"
|
||||
d="m 21.743534,13.618642 c 0,0 0.884343,12.431507 1.06112,14.906381 0.176776,2.474873 2.828427,6.010407 11.932427,6.010407"
|
||||
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
</g>
|
||||
<g
|
||||
id="g3910">
|
||||
<g
|
||||
id="g3881">
|
||||
<path
|
||||
sodipodi:nodetypes="cscscsc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3869"
|
||||
d="m 39.125,51.4375 c 0,0 0.546875,-1.15625 1.203125,-0.78125 0.65625,0.375 0.546875,1.9375 0.546875,1.9375 0,0 0.625,-1.328125 1.5625,-0.921875 0.9375,0.40625 0.640625,1.828125 0.640625,1.828125 0,0 0.578125,-1.71875 1.453125,-1.34375 0.875,0.375 0.84375,1.28125 0.84375,1.28125 l -3.987156,4.839354 -1.988738,-0.574524 z"
|
||||
style="fill:url(#linearGradient3871);fill-opacity:1;stroke:#000000;stroke-width:0.10000000000000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.10000000000000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 41.387844,58.276854 -1.988738,-0.574524 0.353553,2.253903 z"
|
||||
id="path3879"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3905">
|
||||
<path
|
||||
style="fill:url(#linearGradient3891);fill-opacity:1;stroke:#000000;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 39.125,51.4375 c 0,0 0.546875,-1.15625 1.203125,-0.78125 0.65625,0.375 0.546875,1.9375 0.546875,1.9375 0,0 0.625,-1.328125 1.5625,-0.921875 0.9375,0.40625 0.640625,1.828125 0.640625,1.828125 0,0 0.578125,-1.71875 1.453125,-1.34375 0.875,0.375 0.84375,1.28125 0.84375,1.28125 l 12.1875,-37.375 c 0,0 -1.53125,-0.90625 -2.6875,-1.375 -1.15625,-0.46875 -3.25,-0.75 -3.25,-0.75 z"
|
||||
id="path3061"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscscsccscc" />
|
||||
<path
|
||||
sodipodi:nodetypes="csccscc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3885"
|
||||
d="m 57.5625,16.0625 c 0,0 -1.53125,-0.90625 -2.6875,-1.375 -1.15625,-0.46875 -3.25,-0.75 -3.25,-0.75 l 0.394091,-1.162722 c 0,0 2.244178,0.26484 3.322303,0.73359 1.078125,0.46875 2.565641,1.368987 2.565641,1.368987 z"
|
||||
style="fill:url(#linearGradient3899);fill-opacity:1;stroke:#000000;stroke-width:0.10000000000000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
style="fill:url(#radialGradient3903);fill-opacity:1;stroke:#000000;stroke-width:0.10000000000000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 52.019091,12.774778 c 0,0 2.244178,0.26484 3.322303,0.73359 1.078125,0.46875 2.565641,1.368987 2.565641,1.368987 l 0.561857,-1.568072 c 0,0 -0.665164,-1.448399 -2.342291,-2.099224 -1.480505,-0.574524 -3.469243,-0.132582 -3.469243,-0.132582 z"
|
||||
id="path3901"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csccscc" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 15 KiB |
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
/***************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2011, 2012 *
|
||||
* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
* *
|
||||
@@ -17,43 +18,8 @@
|
||||
* License along with this program; if not, write to the Free Software *
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* USA *
|
||||
*/
|
||||
|
||||
/** Get matrix column.
|
||||
* @param A Linear system matrix.
|
||||
* @param v Column vector (output).
|
||||
* @param col Column index.
|
||||
* @param n Linear system dimension.
|
||||
*/
|
||||
__kernel void column(__global float* A,
|
||||
__global float* v,
|
||||
unsigned int col,
|
||||
unsigned int n)
|
||||
{
|
||||
// find position in global arrays
|
||||
unsigned int i = get_global_id(0);
|
||||
if(i >= n)
|
||||
return;
|
||||
v[i] = A[i + col*n];
|
||||
}
|
||||
|
||||
/** Performs matrix column product by a constant.
|
||||
* @param A Linear system matrix.
|
||||
* @param c Constant.
|
||||
* @param col Column index.
|
||||
* @param n Linear system dimension.
|
||||
*/
|
||||
__kernel void prod_c_column(__global float* A,
|
||||
float c,
|
||||
unsigned int col,
|
||||
unsigned int n)
|
||||
{
|
||||
// find position in global arrays
|
||||
unsigned int i = get_global_id(0);
|
||||
if(i >= n)
|
||||
return;
|
||||
A[i + col*n] *= c;
|
||||
}
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
/** Compute residuals of the solution stimator for a linear system.
|
||||
* @param A Linear system matrix.
|
||||
|
||||
@@ -1,185 +1,207 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
import os
|
||||
# Qt library
|
||||
from PyQt4 import QtGui,QtCore
|
||||
# FreeCAD modules
|
||||
import FreeCAD,FreeCADGui
|
||||
from PySide import QtGui, QtCore
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from FreeCAD import Base
|
||||
import Image, ImageGui
|
||||
# FreeCADShip modules
|
||||
from shipUtils import Paths
|
||||
|
||||
|
||||
header = """ #################################################################
|
||||
|
||||
##### #### ### #### ##### # # ### ####
|
||||
# # # # # # # # # # # #
|
||||
# ## #### #### # # # # # # # # # # #
|
||||
#### # # # # # # # ##### # # ## ## ##### # ####
|
||||
# # #### #### # # # # # # # # # #
|
||||
# # # # # # # # # # # # # #
|
||||
# # #### #### ### # # #### ##### # # ### #
|
||||
##### #### ### #### ##### # # ### ####
|
||||
# # # # # # # # # # # #
|
||||
# ## #### #### # # # # # # # # # # #
|
||||
#### # # # # # # # ##### # # ## ## ##### # ####
|
||||
# # #### #### # # # # # # # # # #
|
||||
# # # # # # # # # # # # # #
|
||||
# # #### #### ### # # #### ##### # # ### #
|
||||
|
||||
#################################################################
|
||||
"""
|
||||
|
||||
|
||||
class Plot(object):
|
||||
def __init__(self, x, y, disp, xcb, ship):
|
||||
""" Constructor. performs plot and show it.
|
||||
@param x X coordinates.
|
||||
@param y Transversal areas.
|
||||
@param disp Ship displacement.
|
||||
@param xcb Bouyancy center length.
|
||||
@param ship Active ship instance.
|
||||
"""
|
||||
# Try to plot
|
||||
self.plot(x,y,disp,xcb,ship)
|
||||
# Save data
|
||||
if self.createDirectory():
|
||||
return
|
||||
if self.saveData(x,y,ship):
|
||||
return
|
||||
def __init__(self, x, y, disp, xcb, ship):
|
||||
""" Constructor. performs the plot and shows it.
|
||||
@param x X coordinates.
|
||||
@param y Transversal computed areas.
|
||||
@param disp Ship displacement.
|
||||
@param xcb Bouyancy center length.
|
||||
@param ship Active ship instance.
|
||||
"""
|
||||
self.plot(x, y, disp, xcb, ship)
|
||||
if self.createDirectory():
|
||||
return
|
||||
if self.saveData(x, y, ship):
|
||||
return
|
||||
|
||||
def plot(self, x, y, disp, xcb, ship):
|
||||
""" Perform areas curve plot.
|
||||
@param x X coordinates.
|
||||
@param y Transversal areas.
|
||||
@param disp Ship displacement.
|
||||
@param xcb Bouyancy center length.
|
||||
@param ship Active ship instance.
|
||||
@return True if error happens.
|
||||
"""
|
||||
# Create plot
|
||||
try:
|
||||
import Plot
|
||||
plt = Plot.figure('Areas curve')
|
||||
except ImportError:
|
||||
msg = QtGui.QApplication.translate("ship_console", "Plot module is disabled, can't perform plot",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintWarning(msg + '\n')
|
||||
return True
|
||||
# Plot areas curve
|
||||
areas = Plot.plot(x,y,r'Transversal areas')
|
||||
areas.line.set_linestyle('-')
|
||||
areas.line.set_linewidth(2.0)
|
||||
areas.line.set_color((0.0, 0.0, 0.0))
|
||||
# Get perpendiculars data
|
||||
Lpp = ship.Length
|
||||
FPx = 0.5*Lpp
|
||||
APx = -0.5*Lpp
|
||||
maxArea = max(y)
|
||||
# Plot perpendiculars
|
||||
FP = Plot.plot([FPx,FPx], [0.0,maxArea])
|
||||
FP.line.set_linestyle('-')
|
||||
FP.line.set_linewidth(1.0)
|
||||
FP.line.set_color((0.0, 0.0, 0.0))
|
||||
AP = Plot.plot([APx,APx], [0.0,maxArea])
|
||||
AP.line.set_linestyle('-')
|
||||
AP.line.set_linewidth(1.0)
|
||||
AP.line.set_color((0.0, 0.0, 0.0))
|
||||
# Add annotations for prependiculars
|
||||
ax = Plot.axes()
|
||||
ax.annotate('AP', xy=(APx+0.01*Lpp, 0.01*maxArea), size=15)
|
||||
ax.annotate('AP', xy=(APx+0.01*Lpp, 0.95*maxArea), size=15)
|
||||
ax.annotate('FP', xy=(FPx+0.01*Lpp, 0.01*maxArea), size=15)
|
||||
ax.annotate('FP', xy=(FPx+0.01*Lpp, 0.95*maxArea), size=15)
|
||||
# Add some additional data
|
||||
addInfo = r"""$XCB = %g \; \mathrm{m}$
|
||||
$Area_{max} = %g \; \mathrm{m}^2$
|
||||
$\bigtriangleup = %g \; \mathrm{tons}$""" % (xcb,maxArea,disp)
|
||||
ax.text(0.0, 0.01*maxArea, addInfo,
|
||||
verticalalignment='bottom',horizontalalignment='center', fontsize=20)
|
||||
# Write axes titles
|
||||
Plot.xlabel(r'$x \; \mathrm{m}$')
|
||||
Plot.ylabel(r'$Area \; \mathrm{m}^2$')
|
||||
ax.xaxis.label.set_fontsize(20)
|
||||
ax.yaxis.label.set_fontsize(20)
|
||||
# Show grid
|
||||
Plot.grid(True)
|
||||
# End
|
||||
plt.update()
|
||||
return False
|
||||
def plot(self, x, y, disp, xcb, ship):
|
||||
""" Perform the areas curve plot.
|
||||
@param x X coordinates.
|
||||
@param y Transversal areas.
|
||||
@param disp Ship displacement.
|
||||
@param xcb Bouyancy center length.
|
||||
@param ship Active ship instance.
|
||||
@return True if error happens.
|
||||
"""
|
||||
try:
|
||||
import Plot
|
||||
plt = Plot.figure('Areas curve')
|
||||
except ImportError:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Plot module is disabled, so I cannot perform the plot",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintWarning(msg + '\n')
|
||||
return True
|
||||
# Plot areas curve
|
||||
areas = Plot.plot(x, y, 'Transversal areas')
|
||||
areas.line.set_linestyle('-')
|
||||
areas.line.set_linewidth(2.0)
|
||||
areas.line.set_color((0.0, 0.0, 0.0))
|
||||
# Get perpendiculars data
|
||||
Lpp = ship.Length
|
||||
FPx = 0.5 * Lpp
|
||||
APx = -0.5 * Lpp
|
||||
maxArea = max(y)
|
||||
# Plot perpendiculars
|
||||
FP = Plot.plot([FPx, FPx], [0.0, maxArea])
|
||||
FP.line.set_linestyle('-')
|
||||
FP.line.set_linewidth(1.0)
|
||||
FP.line.set_color((0.0, 0.0, 0.0))
|
||||
AP = Plot.plot([APx, APx], [0.0, maxArea])
|
||||
AP.line.set_linestyle('-')
|
||||
AP.line.set_linewidth(1.0)
|
||||
AP.line.set_color((0.0, 0.0, 0.0))
|
||||
# Add annotations for prependiculars
|
||||
ax = Plot.axes()
|
||||
ax.annotate('AP', xy=(APx + 0.01 * Lpp, 0.01 * maxArea), size=15)
|
||||
ax.annotate('AP', xy=(APx + 0.01 * Lpp, 0.95 * maxArea), size=15)
|
||||
ax.annotate('FP', xy=(FPx + 0.01 * Lpp, 0.01 * maxArea), size=15)
|
||||
ax.annotate('FP', xy=(FPx + 0.01 * Lpp, 0.95 * maxArea), size=15)
|
||||
# Add some additional data
|
||||
addInfo = ("$XCB = {0} \\; \\mathrm{{m}}$\n"
|
||||
"$Area_{{max}} = {1} \\; \\mathrm{{m}}^2$\n"
|
||||
"$\\bigtriangleup = {2} \\; \\mathrm{{tons}}$".format(
|
||||
xcb,
|
||||
maxArea,
|
||||
disp))
|
||||
ax.text(0.0,
|
||||
0.01 * maxArea,
|
||||
addInfo,
|
||||
verticalalignment='bottom',
|
||||
horizontalalignment='center',
|
||||
fontsize=20)
|
||||
# Write axes titles
|
||||
Plot.xlabel(r'$x \; \mathrm{m}$')
|
||||
Plot.ylabel(r'$Area \; \mathrm{m}^2$')
|
||||
ax.xaxis.label.set_fontsize(20)
|
||||
ax.yaxis.label.set_fontsize(20)
|
||||
# Show grid
|
||||
Plot.grid(True)
|
||||
# End
|
||||
plt.update()
|
||||
return False
|
||||
|
||||
def createDirectory(self):
|
||||
""" Create needed folder to write data.
|
||||
@return True if error happens.
|
||||
"""
|
||||
self.path = FreeCAD.ConfigGet("UserAppData") + "ShipOutput/"
|
||||
if not os.path.exists(self.path):
|
||||
os.makedirs(self.path)
|
||||
if not os.path.exists(self.path):
|
||||
msg = QtGui.QApplication.translate("ship_console", "Can't create folder",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintError(msg + ':\n\t' + "\'"+ self.path + "\'\n")
|
||||
return True
|
||||
return False
|
||||
|
||||
def saveData(self,x,y,ship):
|
||||
""" Write data file.
|
||||
@param x X coordinates.
|
||||
@param y Transversal areas.
|
||||
@param ship Active ship instance.
|
||||
@return True if error happens.
|
||||
"""
|
||||
# Open the file
|
||||
filename = self.path + 'areas.dat'
|
||||
try:
|
||||
Output = open(filename, "w")
|
||||
except IOError:
|
||||
msg = QtGui.QApplication.translate("ship_console", "Can't write to file",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintError(msg + ':\n\t' + "\'"+ filename + "\'\n")
|
||||
return True
|
||||
# Print header
|
||||
Output.write(header)
|
||||
Output.write(" #\n")
|
||||
Output.write(" # File automatically exported by FreeCAD-Ship\n")
|
||||
Output.write(" # This file contains transversal areas data, filled with following columns:\n")
|
||||
Output.write(" # 1: X coordiante [m]\n")
|
||||
Output.write(" # 2: Transversal area [m2]\n")
|
||||
Output.write(" # 3: X FP coordinate [m]\n")
|
||||
Output.write(" # 4: Y FP coordinate (bounds in order to draw it)\n")
|
||||
Output.write(" # 3: X AP coordinate [m]\n")
|
||||
Output.write(" # 4: Y AP coordinate (bounds in order to draw it)\n")
|
||||
Output.write(" #\n")
|
||||
Output.write(" #################################################################\n")
|
||||
# Get perpendiculars data
|
||||
Lpp = ship.Length
|
||||
FPx = 0.5*Lpp
|
||||
APx = -0.5*Lpp
|
||||
maxArea = max(y)
|
||||
# Print data
|
||||
string = "%f %f %f %f %f %f\n" % (x[0], y[0], FPx, 0.0, APx, 0.0)
|
||||
Output.write(string)
|
||||
for i in range(1, len(x)):
|
||||
string = "%f %f %f %f %f %f\n" % (x[i], y[i], FPx, maxArea, APx, maxArea)
|
||||
Output.write(string)
|
||||
# Close file
|
||||
Output.close()
|
||||
self.dataFile = filename
|
||||
msg = QtGui.QApplication.translate("ship_console", "Data saved",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + ':\n\t' + "\'"+ self.dataFile + "\'\n")
|
||||
return False
|
||||
def createDirectory(self):
|
||||
""" Create the needed folder to write the output data.
|
||||
@return True if error happens.
|
||||
"""
|
||||
self.path = FreeCAD.ConfigGet("UserAppData") + "ShipOutput/"
|
||||
if not os.path.exists(self.path):
|
||||
os.makedirs(self.path)
|
||||
if not os.path.exists(self.path):
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Failure creating the folder",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintError(msg + ":\n\t'" + self.path + "'\n")
|
||||
return True
|
||||
return False
|
||||
|
||||
def saveData(self, x, y, ship):
|
||||
""" Write the output data file.
|
||||
@param x X coordinates.
|
||||
@param y Transversal areas.
|
||||
@param ship Active ship instance.
|
||||
@return True if error happens.
|
||||
"""
|
||||
filename = self.path + 'areas.dat'
|
||||
try:
|
||||
Output = open(filename, "w")
|
||||
except IOError:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Failure writing to file",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintError(msg + ":\n\t'" + filename + "'\n")
|
||||
return True
|
||||
# Print the header
|
||||
Output.write(header)
|
||||
Output.write(" #\n")
|
||||
Output.write(" # File automatically exported by FreeCAD-Ship\n")
|
||||
Output.write(" # This file contains transversal areas data, filled"
|
||||
" with following columns:\n")
|
||||
Output.write(" # 1: X coordiante [m]\n")
|
||||
Output.write(" # 2: Transversal area [m2]\n")
|
||||
Output.write(" # 3: X FP coordinate [m]\n")
|
||||
Output.write(" # 4: Y FP coordinate (bounds in order to draw it)\n")
|
||||
Output.write(" # 3: X AP coordinate [m]\n")
|
||||
Output.write(" # 4: Y AP coordinate (bounds in order to draw it)\n")
|
||||
Output.write(" #\n")
|
||||
Output.write(" ######################################################"
|
||||
"###########\n")
|
||||
# Get perpendiculars data
|
||||
Lpp = ship.Length
|
||||
FPx = 0.5 * Lpp
|
||||
APx = -0.5 * Lpp
|
||||
maxArea = max(y)
|
||||
# Print the data
|
||||
string = "{0} {1} {2} {3} {4} {5}\n".format(x[0],
|
||||
y[0],
|
||||
FPx,
|
||||
0.0,
|
||||
APx,
|
||||
0.0)
|
||||
Output.write(string)
|
||||
for i in range(1, len(x)):
|
||||
string = "{0} {1} {2} {3} {4} {5}\n".format(x[i],
|
||||
y[i],
|
||||
FPx,
|
||||
maxArea,
|
||||
APx,
|
||||
maxArea)
|
||||
Output.write(string)
|
||||
Output.close()
|
||||
self.dataFile = filename
|
||||
msg = QtGui.QApplication.translate("ship_console",
|
||||
"Data saved",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + ":\n\t'" + self.dataFile + "'\n")
|
||||
return False
|
||||
|
||||
@@ -1,78 +1,72 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
# FreeCAD modules
|
||||
import FreeCAD,FreeCADGui
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from FreeCAD import Base
|
||||
import Part
|
||||
# FreeCADShip modules
|
||||
import Units
|
||||
from shipUtils import Paths
|
||||
|
||||
|
||||
class Preview(object):
|
||||
def __init__(self):
|
||||
""" Constructor.
|
||||
"""
|
||||
self.reinit()
|
||||
def __init__(self):
|
||||
""" Constructor. """
|
||||
self.reinit()
|
||||
|
||||
def reinit(self):
|
||||
""" Reinitializate drawer.
|
||||
"""
|
||||
self.obj = None
|
||||
self.clean()
|
||||
def reinit(self):
|
||||
""" Reinitializate the drawer. """
|
||||
self.obj = None
|
||||
self.clean()
|
||||
|
||||
def update(self, draft, trim, ship):
|
||||
""" Update free surface 3D view
|
||||
@param traft Draft.
|
||||
@param trim Trim in degrees.
|
||||
"""
|
||||
# Destroy old object if exist
|
||||
self.clean()
|
||||
# Set free surface bounds
|
||||
bbox = ship.Shape.BoundBox
|
||||
L = 1.5 * bbox.XLength
|
||||
B = 3.0 * bbox.YLength
|
||||
# Create plane
|
||||
x = - 0.5 * L
|
||||
y = - 0.5 * B
|
||||
point = Base.Vector(x,y,0.0)
|
||||
plane = Part.makePlane(L,B, point, Base.Vector(0,0,1))
|
||||
# Set position
|
||||
plane.rotate(Base.Vector(0,0,0), Base.Vector(0,1,0), trim)
|
||||
plane.translate(Base.Vector(0,0,draft))
|
||||
# Create the FreeCAD object
|
||||
Part.show(plane)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.obj = objs[len(objs)-1]
|
||||
self.obj.Label = 'FreeSurface'
|
||||
# Set properties of object
|
||||
guiObj = FreeCADGui.ActiveDocument.getObject(self.obj.Name)
|
||||
guiObj.ShapeColor = (0.4,0.8,0.85)
|
||||
guiObj.Transparency = 50
|
||||
def update(self, draft, trim, ship):
|
||||
""" Update the free surface 3D view
|
||||
@param draft Draft.
|
||||
@param trim Trim in degrees.
|
||||
"""
|
||||
self.clean()
|
||||
# Set free surface bounds
|
||||
bbox = ship.Shape.BoundBox
|
||||
L = 1.5 * bbox.XLength
|
||||
B = 3.0 * bbox.YLength
|
||||
# Create the plane
|
||||
x = -0.5 * L
|
||||
y = -0.5 * B
|
||||
point = Base.Vector(x, y, 0.0)
|
||||
plane = Part.makePlane(L, B, point, Base.Vector(0, 0, 1))
|
||||
plane.rotate(Base.Vector(0, 0, 0), Base.Vector(0, 1, 0), trim)
|
||||
plane.translate(Base.Vector(0, 0, draft * Units.Metre.Value))
|
||||
Part.show(plane)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.obj = objs[len(objs) - 1]
|
||||
self.obj.Label = 'FreeSurface'
|
||||
guiObj = FreeCADGui.ActiveDocument.getObject(self.obj.Name)
|
||||
guiObj.ShapeColor = (0.4, 0.8, 0.85)
|
||||
guiObj.Transparency = 50
|
||||
|
||||
def clean(self):
|
||||
""" Erase all annotations from screen.
|
||||
"""
|
||||
if not self.obj:
|
||||
return
|
||||
FreeCAD.ActiveDocument.removeObject(self.obj.Name)
|
||||
self.obj=None
|
||||
def clean(self):
|
||||
""" Erase all the annotations from the 3D view. """
|
||||
if not self.obj:
|
||||
return
|
||||
FreeCAD.ActiveDocument.removeObject(self.obj.Name)
|
||||
self.obj = None
|
||||
|
||||
@@ -1,245 +1,322 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
import math
|
||||
# FreeCAD modules
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
# Qt library
|
||||
from PyQt4 import QtGui,QtCore
|
||||
# Module
|
||||
import Preview, PlotAux
|
||||
import Units
|
||||
from PySide import QtGui, QtCore
|
||||
import Preview
|
||||
import PlotAux
|
||||
import Instance
|
||||
from shipUtils import Paths
|
||||
from shipHydrostatics import Tools as Hydrostatics
|
||||
|
||||
|
||||
class TaskPanel:
|
||||
def __init__(self):
|
||||
self.ui = Paths.modulePath() + "/shipAreasCurve/TaskPanel.ui"
|
||||
self.preview = Preview.Preview()
|
||||
self.ship = None
|
||||
def __init__(self):
|
||||
self.ui = Paths.modulePath() + "/shipAreasCurve/TaskPanel.ui"
|
||||
self.preview = Preview.Preview()
|
||||
self.ship = None
|
||||
|
||||
def accept(self):
|
||||
if not self.ship:
|
||||
return False
|
||||
self.save()
|
||||
# Plot data
|
||||
data = Hydrostatics.displacement(self.ship,self.form.draft.value(),0.0,self.form.trim.value())
|
||||
disp = data[0]
|
||||
xcb = data[1].x
|
||||
data = Hydrostatics.areas(self.ship,self.form.draft.value(),0.0,self.form.trim.value())
|
||||
x = []
|
||||
y = []
|
||||
for i in range(0,len(data)):
|
||||
x.append(data[i][0])
|
||||
y.append(data[i][1])
|
||||
PlotAux.Plot(x,y,disp,xcb, self.ship)
|
||||
self.preview.clean()
|
||||
return True
|
||||
def accept(self):
|
||||
if not self.ship:
|
||||
return False
|
||||
self.save()
|
||||
# Plot data
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.draft = self.widget(QtGui.QDoubleSpinBox, "Draft")
|
||||
form.trim = self.widget(QtGui.QDoubleSpinBox, "Trim")
|
||||
data = Hydrostatics.displacement(self.ship,
|
||||
form.draft.value(),
|
||||
0.0,
|
||||
form.trim.value())
|
||||
disp = data[0]
|
||||
xcb = data[1].x
|
||||
data = Hydrostatics.areas(self.ship,
|
||||
form.draft.value(),
|
||||
0.0,
|
||||
form.trim.value())
|
||||
x = []
|
||||
y = []
|
||||
for i in range(0, len(data)):
|
||||
x.append(data[i][0])
|
||||
y.append(data[i][1])
|
||||
PlotAux.Plot(x, y, disp, xcb, self.ship)
|
||||
self.preview.clean()
|
||||
return True
|
||||
|
||||
def reject(self):
|
||||
self.preview.clean()
|
||||
return True
|
||||
def reject(self):
|
||||
self.preview.clean()
|
||||
return True
|
||||
|
||||
def clicked(self, index):
|
||||
pass
|
||||
def clicked(self, index):
|
||||
pass
|
||||
|
||||
def open(self):
|
||||
pass
|
||||
def open(self):
|
||||
pass
|
||||
|
||||
def needsFullSpace(self):
|
||||
return True
|
||||
def needsFullSpace(self):
|
||||
return True
|
||||
|
||||
def isAllowedAlterSelection(self):
|
||||
return False
|
||||
def isAllowedAlterSelection(self):
|
||||
return False
|
||||
|
||||
def isAllowedAlterView(self):
|
||||
return True
|
||||
def isAllowedAlterView(self):
|
||||
return True
|
||||
|
||||
def isAllowedAlterDocument(self):
|
||||
return False
|
||||
def isAllowedAlterDocument(self):
|
||||
return False
|
||||
|
||||
def helpRequested(self):
|
||||
pass
|
||||
def helpRequested(self):
|
||||
pass
|
||||
|
||||
def setupUi(self):
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.draft = form.findChild(QtGui.QDoubleSpinBox, "Draft")
|
||||
form.trim = form.findChild(QtGui.QDoubleSpinBox, "Trim")
|
||||
form.output = form.findChild(QtGui.QTextEdit, "OutputData")
|
||||
form.doc = QtGui.QTextDocument(form.output)
|
||||
self.form = form
|
||||
# Initial values
|
||||
if self.initValues():
|
||||
return True
|
||||
self.retranslateUi()
|
||||
# Connect Signals and Slots
|
||||
QtCore.QObject.connect(form.draft, QtCore.SIGNAL("valueChanged(double)"), self.onData)
|
||||
QtCore.QObject.connect(form.trim, QtCore.SIGNAL("valueChanged(double)"), self.onData)
|
||||
def setupUi(self):
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.draft = self.widget(QtGui.QDoubleSpinBox, "Draft")
|
||||
form.trim = self.widget(QtGui.QDoubleSpinBox, "Trim")
|
||||
form.output = self.widget(QtGui.QTextEdit, "OutputData")
|
||||
form.doc = QtGui.QTextDocument(form.output)
|
||||
self.form = form
|
||||
if self.initValues():
|
||||
return True
|
||||
self.retranslateUi()
|
||||
QtCore.QObject.connect(form.draft,
|
||||
QtCore.SIGNAL("valueChanged(double)"),
|
||||
self.onData)
|
||||
QtCore.QObject.connect(form.trim,
|
||||
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 getMainWindow(self):
|
||||
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 = QtGui.QApplication.translate("ship_console", "Ship instance must be selected (no object selected)",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
for i in range(0,len(selObjs)):
|
||||
obj = selObjs[i]
|
||||
# Test if is a ship instance
|
||||
props = obj.PropertiesList
|
||||
try:
|
||||
props.index("IsShip")
|
||||
except ValueError:
|
||||
continue
|
||||
if obj.IsShip:
|
||||
# Test if another ship already selected
|
||||
if self.ship:
|
||||
msg = QtGui.QApplication.translate("ship_console", "More than one ship selected (extra ships will be neglected)",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintWarning(msg + '\n')
|
||||
break
|
||||
self.ship = obj
|
||||
# Test if any valid ship was selected
|
||||
if not self.ship:
|
||||
msg = QtGui.QApplication.translate("ship_console",
|
||||
"Ship instance must be selected (no valid ship found at selected objects)",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
# Get bounds
|
||||
bbox = self.ship.Shape.BoundBox
|
||||
self.form.draft.setMaximum(bbox.ZMax)
|
||||
self.form.draft.setMinimum(bbox.ZMin)
|
||||
self.form.draft.setValue(self.ship.Draft)
|
||||
# Try to use saved values
|
||||
props = self.ship.PropertiesList
|
||||
flag = True
|
||||
try:
|
||||
props.index("AreaCurveDraft")
|
||||
except ValueError:
|
||||
flag = False
|
||||
if flag:
|
||||
self.form.draft.setValue(self.ship.AreaCurveDraft)
|
||||
flag = True
|
||||
try:
|
||||
props.index("AreaCurveTrim")
|
||||
except ValueError:
|
||||
flag = False
|
||||
if flag:
|
||||
self.form.trim.setValue(self.ship.AreaCurveTrim)
|
||||
# Update GUI
|
||||
self.preview.update(self.form.draft.value(), self.form.trim.value(), self.ship)
|
||||
self.onUpdate()
|
||||
return False
|
||||
def widget(self, class_id, name):
|
||||
"""Return the selected widget.
|
||||
|
||||
def retranslateUi(self):
|
||||
""" Set user interface locale strings.
|
||||
"""
|
||||
self.form.setWindowTitle(QtGui.QApplication.translate("ship_areas","Plot transversal areas curve",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QLabel, "DraftLabel").setText(QtGui.QApplication.translate("ship_areas","Draft",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QLabel, "TrimLabel").setText(QtGui.QApplication.translate("ship_areas","Trim",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
Keyword arguments:
|
||||
class_id -- Class identifier
|
||||
name -- Name of the widget
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
return form.findChild(class_id, name)
|
||||
|
||||
def onData(self, value):
|
||||
""" Method called when input data is changed.
|
||||
@param value Changed value.
|
||||
"""
|
||||
if not self.ship:
|
||||
return
|
||||
self.onUpdate()
|
||||
self.preview.update(self.form.draft.value(), self.form.trim.value(), self.ship)
|
||||
def initValues(self):
|
||||
""" Set initial values for fields
|
||||
"""
|
||||
selObjs = Gui.Selection.getSelection()
|
||||
if not selObjs:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"A ship instance must be selected before using this tool (no"
|
||||
" objects selected)",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
for i in range(0, len(selObjs)):
|
||||
obj = selObjs[i]
|
||||
props = obj.PropertiesList
|
||||
try:
|
||||
props.index("IsShip")
|
||||
except ValueError:
|
||||
continue
|
||||
if obj.IsShip:
|
||||
if self.ship:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"More than one ship have been selected (the extra"
|
||||
" ships will be ignored)",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintWarning(msg + '\n')
|
||||
break
|
||||
self.ship = obj
|
||||
if not self.ship:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"A ship instance must be selected before using this tool (no"
|
||||
" valid ship found at the selected objects)",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
# Get the bounds for the tools
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.draft = self.widget(QtGui.QDoubleSpinBox, "Draft")
|
||||
form.trim = self.widget(QtGui.QDoubleSpinBox, "Trim")
|
||||
bbox = self.ship.Shape.BoundBox
|
||||
form.draft.setMaximum(bbox.ZMax / Units.Metre.Value)
|
||||
form.draft.setMinimum(bbox.ZMin / Units.Metre.Value)
|
||||
form.draft.setValue(self.ship.Draft)
|
||||
# Try to use saved values
|
||||
props = self.ship.PropertiesList
|
||||
flag = True
|
||||
try:
|
||||
props.index("AreaCurveDraft")
|
||||
except ValueError:
|
||||
flag = False
|
||||
if flag:
|
||||
form.draft.setValue(self.ship.AreaCurveDraft)
|
||||
flag = True
|
||||
try:
|
||||
props.index("AreaCurveTrim")
|
||||
except ValueError:
|
||||
flag = False
|
||||
if flag:
|
||||
form.trim.setValue(self.ship.AreaCurveTrim)
|
||||
# Update GUI
|
||||
self.preview.update(form.draft.value(), form.trim.value(), self.ship)
|
||||
self.onUpdate()
|
||||
return False
|
||||
|
||||
def onUpdate(self):
|
||||
""" Method called when update data request.
|
||||
"""
|
||||
if not self.ship:
|
||||
return
|
||||
# Calculate drafts
|
||||
angle = math.radians(self.form.trim.value())
|
||||
L = self.ship.Length
|
||||
draftAP = self.form.draft.value() + 0.5*L*math.tan(angle)
|
||||
if draftAP < 0.0:
|
||||
draftAP = 0.0
|
||||
draftFP = self.form.draft.value() - 0.5*L*math.tan(angle)
|
||||
if draftFP < 0.0:
|
||||
draftFP = 0.0
|
||||
# Calculate hydrostatics involved
|
||||
data = Hydrostatics.displacement(self.ship,self.form.draft.value(),0.0,self.form.trim.value())
|
||||
# Prepare the string in html format
|
||||
string = 'L = %g [m]<BR>' % (self.ship.Length)
|
||||
string = string + 'B = %g [m]<BR>' % (self.ship.Beam)
|
||||
string = string + 'T = %g [m]<HR>' % (self.form.draft.value())
|
||||
string = string + 'Trim = %g [degrees]<BR>' % (self.form.trim.value())
|
||||
string = string + 'T<sub>AP</sub> = %g [m]<BR>' % (draftAP)
|
||||
string = string + 'T<sub>FP</sub> = %g [m]<HR>' % (draftFP)
|
||||
dispText = QtGui.QApplication.translate("ship_areas",'Displacement',
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
string = string + dispText + ' = %g [ton]<BR>' % (data[0])
|
||||
string = string + 'XCB = %g [m]' % (data[1].x)
|
||||
# Set the document
|
||||
self.form.output.setHtml(string)
|
||||
def retranslateUi(self):
|
||||
""" Set user interface locale strings. """
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.setWindowTitle(QtGui.QApplication.translate(
|
||||
"ship_areas",
|
||||
"Plot the transversal areas curve",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QLabel, "DraftLabel").setText(
|
||||
QtGui.QApplication.translate(
|
||||
"ship_areas",
|
||||
"Draft",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QLabel, "TrimLabel").setText(
|
||||
QtGui.QApplication.translate(
|
||||
"ship_areas",
|
||||
"Trim",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
def onData(self, value):
|
||||
""" Method called when the tool input data is touched.
|
||||
@param value Changed value.
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.draft = self.widget(QtGui.QDoubleSpinBox, "Draft")
|
||||
form.trim = self.widget(QtGui.QDoubleSpinBox, "Trim")
|
||||
if not self.ship:
|
||||
return
|
||||
self.onUpdate()
|
||||
self.preview.update(form.draft.value(), form.trim.value(), self.ship)
|
||||
|
||||
def onUpdate(self):
|
||||
""" Method called when the data update is requested. """
|
||||
if not self.ship:
|
||||
return
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.draft = self.widget(QtGui.QDoubleSpinBox, "Draft")
|
||||
form.trim = self.widget(QtGui.QDoubleSpinBox, "Trim")
|
||||
form.output = self.widget(QtGui.QTextEdit, "OutputData")
|
||||
# Calculate the drafts at each perpendicular
|
||||
angle = math.radians(form.trim.value())
|
||||
L = self.ship.Length
|
||||
draftAP = form.draft.value() + 0.5 * L * math.tan(angle)
|
||||
if draftAP < 0.0:
|
||||
draftAP = 0.0
|
||||
draftFP = form.draft.value() - 0.5 * L * math.tan(angle)
|
||||
if draftFP < 0.0:
|
||||
draftFP = 0.0
|
||||
# Calculate the involved hydrostatics
|
||||
data = Hydrostatics.displacement(self.ship,
|
||||
form.draft.value(),
|
||||
0.0,
|
||||
form.trim.value())
|
||||
# Setup the html string
|
||||
string = 'L = {0} [m]<BR>'.format(self.ship.Length)
|
||||
string = string + 'B = {0} [m]<BR>'.format(self.ship.Breadth)
|
||||
string = string + 'T = {0} [m]<HR>'.format(form.draft.value())
|
||||
string = string + 'Trim = {0} [degrees]<BR>'.format(form.trim.value())
|
||||
string = string + 'T<sub>AP</sub> = {0} [m]<BR>'.format(draftAP)
|
||||
string = string + 'T<sub>FP</sub> = {0} [m]<HR>'.format(draftFP)
|
||||
dispText = QtGui.QApplication.translate(
|
||||
"ship_areas",
|
||||
'Displacement',
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
string = string + dispText + ' = {0} [ton]<BR>'.format(data[0])
|
||||
string = string + 'XCB = {0} [m]'.format(data[1].x)
|
||||
form.output.setHtml(string)
|
||||
|
||||
def save(self):
|
||||
""" Saves the data into ship instance. """
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.draft = self.widget(QtGui.QDoubleSpinBox, "Draft")
|
||||
form.trim = self.widget(QtGui.QDoubleSpinBox, "Trim")
|
||||
props = self.ship.PropertiesList
|
||||
try:
|
||||
props.index("AreaCurveDraft")
|
||||
except ValueError:
|
||||
try:
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"ship_areas",
|
||||
"Areas curve tool draft selected [m]",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
except:
|
||||
tooltip = "Areas curve tool draft selected [m]"
|
||||
self.ship.addProperty("App::PropertyFloat",
|
||||
"AreaCurveDraft",
|
||||
"Ship",
|
||||
tooltip)
|
||||
self.ship.AreaCurveDraft = form.draft.value()
|
||||
try:
|
||||
props.index("AreaCurveTrim")
|
||||
except ValueError:
|
||||
try:
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"ship_areas",
|
||||
"Areas curve tool trim selected [deg]",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
except:
|
||||
tooltip = "Areas curve tool trim selected [deg]"
|
||||
self.ship.addProperty("App::PropertyFloat",
|
||||
"AreaCurveTrim",
|
||||
"Ship",
|
||||
tooltip)
|
||||
self.ship.AreaCurveTrim = form.trim.value()
|
||||
|
||||
def save(self):
|
||||
""" Saves data into ship instance.
|
||||
"""
|
||||
props = self.ship.PropertiesList
|
||||
try:
|
||||
props.index("AreaCurveDraft")
|
||||
except ValueError:
|
||||
tooltip = str(QtGui.QApplication.translate("ship_areas","Areas curve tool draft selected [m]",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.ship.addProperty("App::PropertyFloat","AreaCurveDraft","Ship", tooltip)
|
||||
self.ship.AreaCurveDraft = self.form.draft.value()
|
||||
try:
|
||||
props.index("AreaCurveTrim")
|
||||
except ValueError:
|
||||
tooltip = str(QtGui.QApplication.translate("ship_areas","Areas curve tool trim selected",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.ship.addProperty("App::PropertyFloat","AreaCurveTrim","Ship", tooltip)
|
||||
self.ship.AreaCurveTrim = self.form.trim.value()
|
||||
|
||||
def createTask():
|
||||
panel = TaskPanel()
|
||||
Gui.Control.showDialog(panel)
|
||||
if panel.setupUi():
|
||||
Gui.Control.closeDialog(panel)
|
||||
return None
|
||||
return panel
|
||||
panel = TaskPanel()
|
||||
Gui.Control.showDialog(panel)
|
||||
if panel.setupUi():
|
||||
Gui.Control.closeDialog(panel)
|
||||
return None
|
||||
return panel
|
||||
|
||||
@@ -1,36 +1,29 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* 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()
|
||||
""" Loads the tool """
|
||||
TaskPanel.createTask()
|
||||
|
||||
@@ -1,142 +1,195 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
# FreeCAD modules
|
||||
import FreeCAD,FreeCADGui
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from FreeCAD import Base
|
||||
import Part
|
||||
# Qt library
|
||||
from PyQt4 import QtGui,QtCore
|
||||
# FreeCADShip modules
|
||||
import Units
|
||||
from PySide import QtGui, QtCore
|
||||
from shipUtils import Paths
|
||||
|
||||
|
||||
class Preview(object):
|
||||
def __init__(self):
|
||||
""" Constructor.
|
||||
"""
|
||||
self.baseLine = None
|
||||
self.baseLineLabel = None
|
||||
self.reinit()
|
||||
def __init__(self):
|
||||
"""Constructor."""
|
||||
self.baseLine = None
|
||||
self.baseLineLabel = None
|
||||
self.reinit()
|
||||
|
||||
def reinit(self):
|
||||
""" Reinitializate drawer.
|
||||
"""
|
||||
self.clean()
|
||||
def reinit(self):
|
||||
"""Reinitializate drawer, removing all the previous annotations"""
|
||||
self.clean()
|
||||
|
||||
def update(self, L, B, T):
|
||||
""" Update the 3D view printing annotations.
|
||||
@param L Ship length.
|
||||
@param B Ship beam.
|
||||
@param T Ship draft.
|
||||
"""
|
||||
# Destroy all previous entities
|
||||
self.clean()
|
||||
# Draw base line
|
||||
xStart = -0.6*L;
|
||||
xEnd = 0.6*L;
|
||||
baseLine = Part.makeLine((xStart,0,0),(xEnd,0,0))
|
||||
Part.show(baseLine)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.baseLine = objs[len(objs)-1]
|
||||
self.baseLine.Label = 'BaseLine'
|
||||
text = str(QtGui.QApplication.translate("ship_create","Base line",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.baseLineLabel = DrawText('BaseLineText', text, Base.Vector(xEnd,0,0))
|
||||
# Draw free surface
|
||||
fsLine = Part.makeLine((xStart,0,T),(xEnd,0,T))
|
||||
Part.show(fsLine)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.fsLine = objs[len(objs)-1]
|
||||
self.fsLine.Label = 'FreeSurface'
|
||||
text = str(QtGui.QApplication.translate("ship_create","Free surface",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.fsLineLabel = DrawText('FSText', text, Base.Vector(xEnd,0,T))
|
||||
# Draw forward perpendicular
|
||||
zStart = -0.1*T
|
||||
zEnd = 1.1*T
|
||||
fpLine = Part.makeLine((0.5*L,0,zStart),(0.5*L,0,zEnd))
|
||||
Part.show(fpLine)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.fpLine = objs[len(objs)-1]
|
||||
self.fpLine.Label = 'ForwardPerpendicular'
|
||||
text = str(QtGui.QApplication.translate("ship_create","Forward perpendicular",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.fpLineLabel = DrawText('FPText', text, Base.Vector(0.5*L,0,zEnd))
|
||||
# Draw after perpendicular
|
||||
apLine = Part.makeLine((-0.5*L,0,zStart),(-0.5*L,0,zEnd))
|
||||
Part.show(apLine)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.apLine = objs[len(objs)-1]
|
||||
self.apLine.Label = 'AfterPerpendicular'
|
||||
text = str(QtGui.QApplication.translate("ship_create","After perpendicular",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.apLineLabel = DrawText('APText', text, Base.Vector(-0.5*L,0,zEnd))
|
||||
# Draw amin frame
|
||||
amLine = Part.makeLine((0,-0.5*B,zStart),(0,-0.5*B,zEnd))
|
||||
Part.show(amLine)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.amLine = objs[len(objs)-1]
|
||||
self.amLine.Label = 'AminFrame'
|
||||
text = str(QtGui.QApplication.translate("ship_create","Main frame",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.amLineLabel = DrawText('AMText', text, Base.Vector(0,-0.5*B,zEnd))
|
||||
|
||||
def clean(self):
|
||||
""" Erase all annotations from screen.
|
||||
"""
|
||||
if not self.baseLine:
|
||||
return
|
||||
FreeCAD.ActiveDocument.removeObject(self.baseLine.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.baseLineLabel.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.fsLine.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.fsLineLabel.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.fpLine.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.fpLineLabel.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.apLine.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.apLineLabel.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.amLine.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.amLineLabel.Name)
|
||||
def update(self, L, B, T):
|
||||
"""Update the 3D view printing the annotations.
|
||||
|
||||
def DrawText(name, string, position, displayMode="Screen", angle=0.0, justification="Left", colour=(0.00,0.00,0.00), size=12):
|
||||
""" Draws a text in a desired position.
|
||||
@param name Name of the object
|
||||
@param string Text to draw (recommended format u'')
|
||||
@param position Point to draw the text
|
||||
@param angle Counter clockwise rotation of text
|
||||
@param justification Alignement of the text ("Left", "Right" or "Center")
|
||||
@param colour Colour of the text
|
||||
@param size Font size
|
||||
@return FreeCAD annotation object
|
||||
"""
|
||||
# Create the object
|
||||
text = FreeCAD.ActiveDocument.addObject("App::Annotation",name)
|
||||
# Set the text
|
||||
text.LabelText = [string, u'']
|
||||
# Set the options
|
||||
text.Position = position
|
||||
FreeCADGui.ActiveDocument.getObject(text.Name).Rotation = angle
|
||||
FreeCADGui.ActiveDocument.getObject(text.Name).Justification = justification
|
||||
FreeCADGui.ActiveDocument.getObject(text.Name).FontSize = size
|
||||
FreeCADGui.ActiveDocument.getObject(text.Name).TextColor = colour
|
||||
FreeCADGui.ActiveDocument.getObject(text.Name).DisplayMode = displayMode
|
||||
return FreeCAD.ActiveDocument.getObject(text.Name)
|
||||
Keyword arguments:
|
||||
L -- Selected ship length.
|
||||
B -- Selected ship breadth.
|
||||
T -- Selected ship draft.
|
||||
"""
|
||||
self.clean()
|
||||
# Move to the international system units
|
||||
L *= Units.Metre.Value
|
||||
B *= Units.Metre.Value
|
||||
T *= Units.Metre.Value
|
||||
# Draw the base line
|
||||
xStart = -0.6 * L
|
||||
xEnd = 0.6 * L
|
||||
baseLine = Part.makeLine((xStart, 0, 0), (xEnd, 0, 0))
|
||||
Part.show(baseLine)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.baseLine = objs[len(objs) - 1]
|
||||
self.baseLine.Label = 'BaseLine'
|
||||
try:
|
||||
text = str(QtGui.QApplication.translate(
|
||||
"ship_create",
|
||||
"Base line",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
except:
|
||||
text = "Base line"
|
||||
self.baseLineLabel = DrawText('BaseLineText',
|
||||
text,
|
||||
Base.Vector(xEnd, 0, 0))
|
||||
# Draw the free surface line
|
||||
fsLine = Part.makeLine((xStart, 0, T), (xEnd, 0, T))
|
||||
Part.show(fsLine)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.fsLine = objs[len(objs) - 1]
|
||||
self.fsLine.Label = 'FreeSurface'
|
||||
try:
|
||||
text = str(QtGui.QApplication.translate(
|
||||
"ship_create",
|
||||
"Free surface",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
except:
|
||||
text = "Free surface"
|
||||
self.fsLineLabel = DrawText('FSText', text, Base.Vector(xEnd, 0, T))
|
||||
# Draw the forward perpendicular
|
||||
zStart = -0.1 * T
|
||||
zEnd = 1.1 * T
|
||||
fpLine = Part.makeLine((0.5 * L, 0, zStart), (0.5 * L, 0, zEnd))
|
||||
Part.show(fpLine)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.fpLine = objs[len(objs) - 1]
|
||||
self.fpLine.Label = 'ForwardPerpendicular'
|
||||
try:
|
||||
text = str(QtGui.QApplication.translate(
|
||||
"ship_create",
|
||||
"Forward perpendicular",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
except:
|
||||
text = "Forward perpendicular"
|
||||
self.fpLineLabel = DrawText('FPText',
|
||||
text,
|
||||
Base.Vector(0.5 * L, 0, zEnd))
|
||||
# Draw the after perpendicular
|
||||
apLine = Part.makeLine((-0.5 * L, 0, zStart), (-0.5 * L, 0, zEnd))
|
||||
Part.show(apLine)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.apLine = objs[len(objs) - 1]
|
||||
self.apLine.Label = 'AfterPerpendicular'
|
||||
try:
|
||||
text = str(QtGui.QApplication.translate(
|
||||
"ship_create",
|
||||
"After perpendicular",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
except:
|
||||
text = "After perpendicular"
|
||||
self.apLineLabel = DrawText('APText',
|
||||
text,
|
||||
Base.Vector(-0.5 * L, 0, zEnd))
|
||||
# Draw the amin frame
|
||||
amLine = Part.makeLine((0, -0.5 * B, zStart), (0, -0.5 * B, zEnd))
|
||||
Part.show(amLine)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.amLine = objs[len(objs) - 1]
|
||||
self.amLine.Label = 'AminFrame'
|
||||
try:
|
||||
text = str(QtGui.QApplication.translate(
|
||||
"ship_create",
|
||||
"Main frame",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
except:
|
||||
text = "Main frame"
|
||||
self.amLineLabel = DrawText('AMText',
|
||||
text,
|
||||
Base.Vector(0, -0.5 * B, zEnd))
|
||||
|
||||
def clean(self):
|
||||
"""Remove all previous annotations from screen."""
|
||||
if not self.baseLine:
|
||||
return
|
||||
FreeCAD.ActiveDocument.removeObject(self.baseLine.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.baseLineLabel.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.fsLine.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.fsLineLabel.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.fpLine.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.fpLineLabel.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.apLine.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.apLineLabel.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.amLine.Name)
|
||||
FreeCAD.ActiveDocument.removeObject(self.amLineLabel.Name)
|
||||
|
||||
|
||||
def DrawText(name,
|
||||
string,
|
||||
position,
|
||||
displayMode="Screen",
|
||||
angle=0.0,
|
||||
justification="Left",
|
||||
colour=(0.0, 0.0, 0.0),
|
||||
size=12):
|
||||
"""Draw a text in the screen.
|
||||
|
||||
Keyword arguments:
|
||||
name -- Name (label) of the object to generate.
|
||||
string -- Text to draw (it is strongly recommended to use format u'').
|
||||
position -- Point to draw the text.
|
||||
angle -- Counter clockwise rotation of text.
|
||||
justification -- Alignement of the text ("Left", "Right" or "Center").
|
||||
colour -- Colour of the text.
|
||||
size -- Font size (in points pt).
|
||||
|
||||
Returns:
|
||||
A FreeCAD annotation object
|
||||
"""
|
||||
# Create the object
|
||||
text = FreeCAD.ActiveDocument.addObject("App::Annotation", name)
|
||||
# Set the text
|
||||
text.LabelText = [string, u'']
|
||||
# Set the options
|
||||
text.Position = position
|
||||
doc = FreeCADGui.ActiveDocument
|
||||
doc.getObject(text.Name).Rotation = angle
|
||||
doc.getObject(text.Name).Justification = justification
|
||||
doc.getObject(text.Name).FontSize = size
|
||||
doc.getObject(text.Name).TextColor = colour
|
||||
doc.getObject(text.Name).DisplayMode = displayMode
|
||||
return FreeCAD.ActiveDocument.getObject(text.Name)
|
||||
|
||||
@@ -1,230 +1,291 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
# FreeCAD modules
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
# Qt library
|
||||
from PyQt4 import QtGui,QtCore
|
||||
# Module
|
||||
import Units
|
||||
from PySide import QtGui, QtCore
|
||||
import Preview
|
||||
import Instance
|
||||
from shipUtils import Paths
|
||||
|
||||
|
||||
class TaskPanel:
|
||||
def __init__(self):
|
||||
self.ui = Paths.modulePath() + "/shipCreateShip/TaskPanel.ui"
|
||||
self.preview = Preview.Preview()
|
||||
def __init__(self):
|
||||
"""Constructor"""
|
||||
self.ui = Paths.modulePath() + "/shipCreateShip/TaskPanel.ui"
|
||||
self.preview = Preview.Preview()
|
||||
|
||||
def accept(self):
|
||||
self.preview.clean()
|
||||
# Create new ship instance
|
||||
obj = App.ActiveDocument.addObject("Part::FeaturePython","Ship")
|
||||
ship = Instance.Ship(obj, self.solids)
|
||||
Instance.ViewProviderShip(obj.ViewObject)
|
||||
# Set main dimensions
|
||||
obj.Length = self.form.length.value()
|
||||
obj.Beam = self.form.beam.value()
|
||||
obj.Draft = self.form.draft.value()
|
||||
# Discretize it
|
||||
App.ActiveDocument.recompute()
|
||||
return True
|
||||
def accept(self):
|
||||
"""Create the ship instance"""
|
||||
self.preview.clean()
|
||||
obj = App.ActiveDocument.addObject("Part::FeaturePython", "Ship")
|
||||
ship = Instance.Ship(obj, self.solids)
|
||||
Instance.ViewProviderShip(obj.ViewObject)
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.length = self.widget(QtGui.QDoubleSpinBox, "Length")
|
||||
form.breadth = self.widget(QtGui.QDoubleSpinBox, "Breadth")
|
||||
form.draft = self.widget(QtGui.QDoubleSpinBox, "Draft")
|
||||
obj.Length = form.length.value()
|
||||
obj.Breadth = form.breadth.value()
|
||||
obj.Draft = form.draft.value()
|
||||
App.ActiveDocument.recompute()
|
||||
return True
|
||||
|
||||
def reject(self):
|
||||
self.preview.clean()
|
||||
return True
|
||||
def reject(self):
|
||||
"""Cancel the job"""
|
||||
self.preview.clean()
|
||||
return True
|
||||
|
||||
def clicked(self, index):
|
||||
pass
|
||||
def clicked(self, index):
|
||||
pass
|
||||
|
||||
def open(self):
|
||||
pass
|
||||
def open(self):
|
||||
pass
|
||||
|
||||
def needsFullSpace(self):
|
||||
return True
|
||||
def needsFullSpace(self):
|
||||
return True
|
||||
|
||||
def isAllowedAlterSelection(self):
|
||||
return False
|
||||
def isAllowedAlterSelection(self):
|
||||
return False
|
||||
|
||||
def isAllowedAlterView(self):
|
||||
return True
|
||||
def isAllowedAlterView(self):
|
||||
return True
|
||||
|
||||
def isAllowedAlterDocument(self):
|
||||
return False
|
||||
def isAllowedAlterDocument(self):
|
||||
return False
|
||||
|
||||
def helpRequested(self):
|
||||
pass
|
||||
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.draft = form.findChild(QtGui.QDoubleSpinBox, "Draft")
|
||||
form.mainLogo = form.findChild(QtGui.QLabel, "MainLogo")
|
||||
iconPath = Paths.iconsPath() + "/Ico.xpm"
|
||||
form.mainLogo.setPixmap(QtGui.QPixmap(iconPath))
|
||||
self.form = form
|
||||
# Initial values
|
||||
if self.initValues():
|
||||
return True
|
||||
self.retranslateUi()
|
||||
self.preview.update(self.L, self.B, self.T)
|
||||
# Connect Signals and Slots
|
||||
QtCore.QObject.connect(form.length, QtCore.SIGNAL("valueChanged(double)"), self.onData)
|
||||
QtCore.QObject.connect(form.beam, QtCore.SIGNAL("valueChanged(double)"), self.onData)
|
||||
QtCore.QObject.connect(form.draft, QtCore.SIGNAL("valueChanged(double)"), self.onData)
|
||||
def setupUi(self):
|
||||
"""Create and configurate the user interface"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.length = self.widget(QtGui.QDoubleSpinBox, "Length")
|
||||
form.breadth = self.widget(QtGui.QDoubleSpinBox, "Breadth")
|
||||
form.draft = self.widget(QtGui.QDoubleSpinBox, "Draft")
|
||||
form.mainLogo = self.widget(QtGui.QLabel, "MainLogo")
|
||||
form.mainLogo.setPixmap(QtGui.QPixmap(":/icons/Ship_Logo.svg"))
|
||||
self.form = form
|
||||
if self.initValues():
|
||||
return True
|
||||
self.retranslateUi()
|
||||
self.preview.update(self.L, self.B, self.T)
|
||||
QtCore.QObject.connect(
|
||||
form.length,
|
||||
QtCore.SIGNAL("valueChanged(double)"),
|
||||
self.onData)
|
||||
QtCore.QObject.connect(
|
||||
form.breadth,
|
||||
QtCore.SIGNAL("valueChanged(double)"),
|
||||
self.onData)
|
||||
QtCore.QObject.connect(
|
||||
form.draft,
|
||||
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 getMainWindow(self):
|
||||
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
|
||||
self.solids = None
|
||||
selObjs = Gui.Selection.getSelection()
|
||||
if not selObjs:
|
||||
msg = QtGui.QApplication.translate("ship_console",
|
||||
"Ship objects can only be created on top of hull geometry (any object selected)",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
msg = QtGui.QApplication.translate("ship_console",
|
||||
"Please create or load a ship hull geometry before using this tool",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
self.solids = []
|
||||
for i in range(0, len(selObjs)):
|
||||
solids = self.getSolids(selObjs[i])
|
||||
for j in range(0, len(solids)):
|
||||
self.solids.append(solids[j])
|
||||
if not self.solids:
|
||||
msg = QtGui.QApplication.translate("ship_console",
|
||||
"Ship objects can only be created on top of hull geometry (no solid found at selected objects)",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
msg = QtGui.QApplication.translate("ship_console",
|
||||
"Please create or load a ship hull geometry before using this tool",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
# Get bounds
|
||||
bounds = [0.0, 0.0, 0.0]
|
||||
bbox = self.solids[0].BoundBox
|
||||
minX = bbox.XMin
|
||||
maxX = bbox.XMax
|
||||
minY = bbox.YMin
|
||||
maxY = bbox.YMax
|
||||
minZ = bbox.ZMin
|
||||
maxZ = bbox.ZMax
|
||||
for i in range(1,len(self.solids)):
|
||||
bbox = self.solids[i].BoundBox
|
||||
if minX > bbox.XMin:
|
||||
minX = bbox.XMin
|
||||
if maxX < bbox.XMax:
|
||||
maxX = bbox.XMax
|
||||
if minY > bbox.YMin:
|
||||
minY = bbox.YMin
|
||||
if maxY < bbox.YMax:
|
||||
maxY = bbox.YMax
|
||||
if minZ > bbox.ZMin:
|
||||
minZ = bbox.ZMin
|
||||
if maxZ < bbox.ZMax:
|
||||
maxZ = bbox.ZMax
|
||||
bounds[0] = maxX - minX
|
||||
bounds[1] = max(maxY - minY, abs(maxY), abs(minY))
|
||||
bounds[2] = maxZ - minZ
|
||||
# Set UI fields
|
||||
self.form.length.setMaximum(bounds[0])
|
||||
self.form.length.setMinimum(0.001)
|
||||
self.form.length.setValue(bounds[0])
|
||||
self.L = bounds[0]
|
||||
self.form.beam.setMaximum(bounds[1])
|
||||
self.form.beam.setMinimum(0.001)
|
||||
self.form.beam.setValue(bounds[1])
|
||||
self.B = bounds[1]
|
||||
self.form.draft.setMaximum(bounds[2])
|
||||
self.form.draft.setMinimum(0.001)
|
||||
self.form.draft.setValue(0.5*bounds[2])
|
||||
self.T = 0.5*bounds[2]
|
||||
return False
|
||||
def widget(self, class_id, name):
|
||||
"""Return the selected widget.
|
||||
|
||||
def retranslateUi(self):
|
||||
""" Set user interface locale strings.
|
||||
"""
|
||||
self.form.setWindowTitle(QtGui.QApplication.translate("ship_create","Create a new ship",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QLabel, "LengthLabel").setText(QtGui.QApplication.translate("ship_create","Length",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QLabel, "BeamLabel").setText(QtGui.QApplication.translate("ship_create","Breadth",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QLabel, "DraftLabel").setText(QtGui.QApplication.translate("ship_create","Draft",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
Keyword arguments:
|
||||
class_id -- Class identifier
|
||||
name -- Name of the widget
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
return form.findChild(class_id, name)
|
||||
|
||||
def onData(self, value):
|
||||
""" Method called when ship data is changed.
|
||||
Annotations must be showed.
|
||||
@param value Changed value.
|
||||
"""
|
||||
self.L = self.form.length.value()
|
||||
self.B = self.form.beam.value()
|
||||
self.T = self.form.draft.value()
|
||||
self.preview.update(self.L, self.B, self.T)
|
||||
def initValues(self):
|
||||
"""Setup the initial values"""
|
||||
self.solids = None
|
||||
selObjs = Gui.Selection.getSelection()
|
||||
if not selObjs:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Ship objects can only be created on top of hull geometry"
|
||||
" (no objects selected)",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Please create or load a ship hull geometry before using"
|
||||
" this tool",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
self.solids = []
|
||||
for i in range(0, len(selObjs)):
|
||||
solids = self.getSolids(selObjs[i])
|
||||
for j in range(0, len(solids)):
|
||||
self.solids.append(solids[j])
|
||||
if not self.solids:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Ship objects can only be created on top of hull geometry"
|
||||
" (no solid found at selected objects)",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Please create or load a ship hull geometry before using"
|
||||
" this tool",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
# Get the ship bounds. The ship instance can not have dimensions
|
||||
# out of these values.
|
||||
bounds = [0.0, 0.0, 0.0]
|
||||
bbox = self.solids[0].BoundBox
|
||||
minX = bbox.XMin
|
||||
maxX = bbox.XMax
|
||||
minY = bbox.YMin
|
||||
maxY = bbox.YMax
|
||||
minZ = bbox.ZMin
|
||||
maxZ = bbox.ZMax
|
||||
for i in range(1, len(self.solids)):
|
||||
bbox = self.solids[i].BoundBox
|
||||
if minX > bbox.XMin:
|
||||
minX = bbox.XMin
|
||||
if maxX < bbox.XMax:
|
||||
maxX = bbox.XMax
|
||||
if minY > bbox.YMin:
|
||||
minY = bbox.YMin
|
||||
if maxY < bbox.YMax:
|
||||
maxY = bbox.YMax
|
||||
if minZ > bbox.ZMin:
|
||||
minZ = bbox.ZMin
|
||||
if maxZ < bbox.ZMax:
|
||||
maxZ = bbox.ZMax
|
||||
bounds[0] = maxX - minX
|
||||
bounds[1] = max(maxY - minY, abs(maxY), abs(minY))
|
||||
bounds[2] = maxZ - minZ
|
||||
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.length = self.widget(QtGui.QDoubleSpinBox, "Length")
|
||||
form.breadth = self.widget(QtGui.QDoubleSpinBox, "Breadth")
|
||||
form.draft = self.widget(QtGui.QDoubleSpinBox, "Draft")
|
||||
|
||||
form.length.setMaximum(bounds[0] / Units.Metre.Value)
|
||||
form.length.setMinimum(0.001)
|
||||
form.length.setValue(bounds[0] / Units.Metre.Value)
|
||||
self.L = bounds[0] / Units.Metre.Value
|
||||
form.breadth.setMaximum(bounds[1] / Units.Metre.Value)
|
||||
form.breadth.setMinimum(0.001)
|
||||
form.breadth.setValue(bounds[1] / Units.Metre.Value)
|
||||
self.B = bounds[1] / Units.Metre.Value
|
||||
form.draft.setMaximum(bounds[2] / Units.Metre.Value)
|
||||
form.draft.setMinimum(0.001)
|
||||
form.draft.setValue(0.5 * bounds[2] / Units.Metre.Value)
|
||||
self.T = 0.5 * bounds[2] / Units.Metre.Value
|
||||
return False
|
||||
|
||||
def retranslateUi(self):
|
||||
"""Set the user interface locale strings."""
|
||||
self.form.setWindowTitle(QtGui.QApplication.translate(
|
||||
"ship_create",
|
||||
"Create a new ship",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QLabel, "LengthLabel").setText(
|
||||
QtGui.QApplication.translate(
|
||||
"ship_create",
|
||||
"Length",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QLabel, "BreadthLabel").setText(
|
||||
QtGui.QApplication.translate(
|
||||
"ship_create",
|
||||
"Breadth",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QLabel, "DraftLabel").setText(
|
||||
QtGui.QApplication.translate(
|
||||
"ship_create",
|
||||
"Draft",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
def onData(self, value):
|
||||
"""Updates the 3D preview on data changes.
|
||||
|
||||
Keyword arguments:
|
||||
value -- Edited value. This parameter is required in order to use this
|
||||
method as a callback function, but it is unuseful.
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.length = self.widget(QtGui.QDoubleSpinBox, "Length")
|
||||
form.breadth = self.widget(QtGui.QDoubleSpinBox, "Breadth")
|
||||
form.draft = self.widget(QtGui.QDoubleSpinBox, "Draft")
|
||||
|
||||
self.L = form.length.value()
|
||||
self.B = form.breadth.value()
|
||||
self.T = form.draft.value()
|
||||
self.preview.update(self.L, self.B, self.T)
|
||||
|
||||
def getSolids(self, obj):
|
||||
"""Returns the solid entities from an object
|
||||
Keyword arguments:
|
||||
obj -- FreeCAD object to extract the solids from.
|
||||
|
||||
Returns:
|
||||
The solid entities, None if no solid have been found.
|
||||
"""
|
||||
if not obj:
|
||||
return None
|
||||
if obj.isDerivedFrom('Part::Feature'):
|
||||
# get shape
|
||||
shape = obj.Shape
|
||||
if not shape:
|
||||
return None
|
||||
obj = shape
|
||||
if not obj.isDerivedFrom('Part::TopoShape'):
|
||||
return None
|
||||
# get face
|
||||
solids = obj.Solids
|
||||
if not solids:
|
||||
return None
|
||||
return solids
|
||||
|
||||
def getSolids(self, obj):
|
||||
""" Returns object solids (list of them)
|
||||
@param obj Object to extract solids.
|
||||
@return Solids. None if errors happens
|
||||
"""
|
||||
if not obj:
|
||||
return None
|
||||
if obj.isDerivedFrom('Part::Feature'):
|
||||
# get shape
|
||||
shape = obj.Shape
|
||||
if not shape:
|
||||
return None
|
||||
obj = shape
|
||||
if not obj.isDerivedFrom('Part::TopoShape'):
|
||||
return None
|
||||
# get face
|
||||
solids = obj.Solids
|
||||
if not solids:
|
||||
return None
|
||||
return solids
|
||||
|
||||
def createTask():
|
||||
panel = TaskPanel()
|
||||
Gui.Control.showDialog(panel)
|
||||
if panel.setupUi():
|
||||
Gui.Control.closeDialog(panel)
|
||||
return None
|
||||
return panel
|
||||
panel = TaskPanel()
|
||||
Gui.Control.showDialog(panel)
|
||||
if panel.setupUi():
|
||||
Gui.Control.closeDialog(panel)
|
||||
return None
|
||||
return panel
|
||||
|
||||
@@ -111,6 +111,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="LengthUnits">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>m</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -128,14 +141,14 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="BeamLabel">
|
||||
<widget class="QLabel" name="BreadthLabel">
|
||||
<property name="text">
|
||||
<string>Beam</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="Beam">
|
||||
<widget class="QDoubleSpinBox" name="Breadth">
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
@@ -144,6 +157,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="BreadthUnits">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>m</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -177,6 +203,19 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="DraftUnits">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>m</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -1,36 +1,29 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* 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()
|
||||
"""Loads the tool in the task panel"""
|
||||
TaskPanel.createTask()
|
||||
|
||||
@@ -1,35 +1,32 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
import math
|
||||
# FreeCAD modules
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
from FreeCAD import Base, Vector
|
||||
import Part
|
||||
# Qt library
|
||||
from PyQt4 import QtGui,QtCore
|
||||
# Module
|
||||
import PlotAux
|
||||
import Instance
|
||||
from shipUtils import Paths
|
||||
|
||||
@@ -1,38 +1,37 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
import math
|
||||
# FreeCAD modules
|
||||
from FreeCAD import Vector
|
||||
import Part
|
||||
import Units
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
# Module
|
||||
import Instance
|
||||
from shipUtils import Math
|
||||
|
||||
def areas(ship, draft, roll=0.0, trim=0.0, yaw=0.0, n=30):
|
||||
""" Compute ship transversal areas.
|
||||
""" Compute the ship transversal areas.
|
||||
@param ship Ship instance.
|
||||
@param draft Ship draft.
|
||||
@param roll Ship roll angle.
|
||||
@@ -45,38 +44,42 @@ def areas(ship, draft, roll=0.0, trim=0.0, yaw=0.0, n=30):
|
||||
"""
|
||||
if n < 2:
|
||||
return []
|
||||
# We will take a duplicate of ship shape in order to place it
|
||||
# We will take a duplicate of ship shape in order to conviniently place it
|
||||
shape = ship.Shape.copy()
|
||||
shape.translate(Vector(0.0,0.0,-draft))
|
||||
shape.translate(Vector(0.0,0.0,-draft*Units.Metre.Value))
|
||||
# Rotations composition is Roll->Trim->Yaw
|
||||
shape.rotate(Vector(0.0,0.0,0.0), Vector(1.0,0.0,0.0), roll)
|
||||
shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,-1.0,0.0), trim)
|
||||
shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,0.0,1.0), yaw)
|
||||
# Now we need to know the x range of values
|
||||
# Now we need to know the x range of values to perform the sections
|
||||
bbox = shape.BoundBox
|
||||
xmin = bbox.XMin
|
||||
xmax = bbox.XMax
|
||||
dx = (xmax - xmin) / (n-1.0)
|
||||
# First area is equal to zero.
|
||||
areas = [[xmin, 0.0]]
|
||||
# Since we need face entities, in order to compute sections we will
|
||||
# create boxes with front face at transversal area position,
|
||||
# compute solid common, divide by faces, and preserve only desired
|
||||
# ones.
|
||||
# Since we are computing in the total length (not in the perpendiculars one),
|
||||
# we can grant that the starting and ending sections are null
|
||||
areas = [[xmin/Units.Metre.Value, 0.0]]
|
||||
# And since we need only face entities, in order to compute sections we will
|
||||
# create boxes with front face at the desired transversal area position,
|
||||
# computing the common solid part, dividing it by faces, and getting only
|
||||
# the desired ones.
|
||||
App.Console.PrintMessage("Computing transversal areas...\n")
|
||||
App.Console.PrintMessage("Some Inventor representation errors can be shown, ignore it please.\n")
|
||||
App.Console.PrintMessage("Some Inventor representation errors can be shown, please ignore it.\n")
|
||||
for i in range(1,n-1):
|
||||
App.Console.PrintMessage("%d / %d\n" % (i, n-2))
|
||||
App.Console.PrintMessage("{0} / {1}\n".format(i, n-2))
|
||||
x = xmin + i*dx
|
||||
area = 0.0
|
||||
# Create the box
|
||||
L = xmax - xmin
|
||||
B = bbox.YMax - bbox.YMin
|
||||
p = Vector(-1.5*L, -1.5*B, bbox.ZMin - 1.0)
|
||||
box = Part.makeBox(1.5*L + x, 3.0*B, - bbox.ZMin + 1.0, p)
|
||||
# Compute common part with ship
|
||||
p = Vector(-1.5*L, -1.5*B, bbox.ZMin)
|
||||
try:
|
||||
box = Part.makeBox(1.5*L + x, 3.0*B, - bbox.ZMin, p)
|
||||
except:
|
||||
areas.append([x, area])
|
||||
continue
|
||||
# Compute the common part with ship
|
||||
for s in shape.Solids:
|
||||
# Get solids intersection
|
||||
try:
|
||||
common = box.common(s)
|
||||
except:
|
||||
@@ -89,7 +92,7 @@ def areas(ship, draft, roll=0.0, trim=0.0, yaw=0.0, n=30):
|
||||
Part.show(common)
|
||||
except:
|
||||
continue
|
||||
# Divide by faces and compute only section placed ones
|
||||
# Divide the solid by faces and compute only the well placed ones
|
||||
faces = common.Faces
|
||||
for f in faces:
|
||||
faceBounds = f.BoundBox
|
||||
@@ -99,19 +102,18 @@ def areas(ship, draft, roll=0.0, trim=0.0, yaw=0.0, n=30):
|
||||
# Place filter
|
||||
if abs(faceBounds.XMax - x) > 0.00001:
|
||||
continue
|
||||
# Valid face, compute area
|
||||
area = area + f.Area
|
||||
# Destroy last object generated
|
||||
# It is a valid face, so we can add this area
|
||||
area = area + f.Area/Units.Metre.Value**2
|
||||
# Destroy the last generated object
|
||||
App.ActiveDocument.removeObject(App.ActiveDocument.Objects[-1].Name)
|
||||
# Append transversal area
|
||||
areas.append([x, area])
|
||||
# Last area is equal to zero
|
||||
areas.append([xmax, 0.0])
|
||||
areas.append([x/Units.Metre.Value, area])
|
||||
# Last area is equal to zero (see some lines above)
|
||||
areas.append([xmax/Units.Metre.Value, 0.0])
|
||||
App.Console.PrintMessage("Done!\n")
|
||||
return areas
|
||||
|
||||
def displacement(ship, draft, roll=0.0, trim=0.0, yaw=0.0):
|
||||
""" Compute ship displacement.
|
||||
""" Compute the ship displacement.
|
||||
@param ship Ship instance.
|
||||
@param draft Ship draft.
|
||||
@param roll Ship roll angle.
|
||||
@@ -119,15 +121,15 @@ def displacement(ship, draft, roll=0.0, trim=0.0, yaw=0.0):
|
||||
@param yaw Ship yaw angle. Ussually you don't want to use this
|
||||
value.
|
||||
@return [disp, B, Cb], \n
|
||||
disp = Ship displacement [ton].
|
||||
B = Bouyance center [m].
|
||||
Cb = Block coefficient.
|
||||
@note Bouyance center will returned as FreeCAD.Vector class.
|
||||
@note Returned Bouyance center is in non modified ship coordinates
|
||||
- disp = Ship displacement [ton].
|
||||
- B = Bouyance center [m].
|
||||
- Cb = Block coefficient.
|
||||
@note Bouyance center will returned as a FreeCAD.Vector instance.
|
||||
@note Returned Bouyance center is in the non modified ship coordinates
|
||||
"""
|
||||
# We will take a duplicate of ship shape in order to place it
|
||||
# We will take a duplicate of ship shape in order to conviniently place it
|
||||
shape = ship.Shape.copy()
|
||||
shape.translate(Vector(0.0,0.0,-draft))
|
||||
shape.translate(Vector(0.0,0.0,-draft*Units.Metre.Value))
|
||||
# Rotations composition is Roll->Trim->Yaw
|
||||
shape.rotate(Vector(0.0,0.0,0.0), Vector(1.0,0.0,0.0), roll)
|
||||
shape.rotate(Vector(0.0,0.0,0.0), Vector(0.0,-1.0,0.0), trim)
|
||||
@@ -139,27 +141,30 @@ def displacement(ship, draft, roll=0.0, trim=0.0, yaw=0.0):
|
||||
# Create the box
|
||||
L = xmax - xmin
|
||||
B = bbox.YMax - bbox.YMin
|
||||
p = Vector(-1.5*L, -1.5*B, bbox.ZMin - 1.0)
|
||||
box = Part.makeBox(3.0*L, 3.0*B, -bbox.ZMin + 1.0, p)
|
||||
p = Vector(-1.5*L, -1.5*B, bbox.ZMin)
|
||||
try:
|
||||
box = Part.makeBox(3.0*L, 3.0*B, - bbox.ZMin, p)
|
||||
except:
|
||||
return [0.0, Vector(), 0.0]
|
||||
vol = 0.0
|
||||
cog = Vector()
|
||||
for solid in shape.Solids:
|
||||
# Compute common part with ship
|
||||
# Compute the common part with the ship
|
||||
try:
|
||||
common = box.common(solid)
|
||||
except:
|
||||
continue
|
||||
# Get data
|
||||
vol = vol + common.Volume
|
||||
# Get the data
|
||||
vol = vol + common.Volume/Units.Metre.Value**3
|
||||
for s in common.Solids:
|
||||
sCoG = s.CenterOfMass
|
||||
cog.x = cog.x + sCoG.x*s.Volume
|
||||
cog.y = cog.y + sCoG.y*s.Volume
|
||||
cog.z = cog.z + sCoG.z*s.Volume
|
||||
cog.x = cog.x + sCoG.x*s.Volume/Units.Metre.Value**4
|
||||
cog.y = cog.y + sCoG.y*s.Volume/Units.Metre.Value**4
|
||||
cog.z = cog.z + sCoG.z*s.Volume/Units.Metre.Value**4
|
||||
cog.x = cog.x / vol
|
||||
cog.y = cog.y / vol
|
||||
cog.z = cog.z / vol
|
||||
Vol = L*B*abs(bbox.ZMin)
|
||||
Vol = L*B*abs(bbox.ZMin)/Units.Metre.Value**3
|
||||
# Undo transformations
|
||||
B = Vector()
|
||||
B.x = cog.x*math.cos(math.radians(-yaw)) - cog.y*math.sin(math.radians(-yaw))
|
||||
|
||||
@@ -1,35 +1,29 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
|
||||
# FreeCAD modules
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
# Qt libraries
|
||||
from PyQt4 import QtGui,QtCore
|
||||
|
||||
# Main object
|
||||
import TaskPanel
|
||||
|
||||
def load():
|
||||
|
||||
@@ -1,108 +1,124 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
# FreeCAD modules
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
# Qt library
|
||||
from PyQt4 import QtGui,QtCore
|
||||
# Module
|
||||
from PySide import QtGui, QtCore
|
||||
from shipUtils import Paths
|
||||
|
||||
|
||||
class TaskPanel:
|
||||
def __init__(self):
|
||||
self.ui = Paths.modulePath() + "/shipLoadExample/TaskPanel.ui"
|
||||
def __init__(self):
|
||||
"""Constructor."""
|
||||
self.ui = Paths.modulePath() + "/shipLoadExample/TaskPanel.ui"
|
||||
|
||||
def accept(self):
|
||||
path = Paths.modulePath() + "/resources/examples/"
|
||||
if(self.form.ship.currentIndex() == 0): # s60 from Iowa University
|
||||
App.open(path + "s60.fcstd")
|
||||
elif(self.form.ship.currentIndex() == 1): # Wigley canonical ship
|
||||
App.open(path + "wigley.fcstd")
|
||||
elif(self.form.ship.currentIndex() == 2): # s60 (Katamaran)
|
||||
App.open(path + "s60_katamaran.fcstd")
|
||||
elif(self.form.ship.currentIndex() == 2): # Wigley (Katamaran)
|
||||
App.open(path + "wigley_katamaran.fcstd")
|
||||
return True
|
||||
def accept(self):
|
||||
"""Load the selected hull example."""
|
||||
path = Paths.modulePath() + "/resources/examples/"
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.ship = self.widget(QtGui.QComboBox, "Ship")
|
||||
if(form.ship.currentIndex() == 0): # s60 from Iowa University
|
||||
App.open(path + "s60.fcstd")
|
||||
elif(form.ship.currentIndex() == 1): # Wigley canonical ship
|
||||
App.open(path + "wigley.fcstd")
|
||||
elif(form.ship.currentIndex() == 2): # s60 (Katamaran)
|
||||
App.open(path + "s60_katamaran.fcstd")
|
||||
elif(form.ship.currentIndex() == 2): # Wigley (Katamaran)
|
||||
App.open(path + "wigley_katamaran.fcstd")
|
||||
return True
|
||||
|
||||
def reject(self):
|
||||
return True
|
||||
def reject(self):
|
||||
"""Cancel the job"""
|
||||
return True
|
||||
|
||||
def clicked(self, index):
|
||||
pass
|
||||
def clicked(self, index):
|
||||
pass
|
||||
|
||||
def open(self):
|
||||
pass
|
||||
def open(self):
|
||||
pass
|
||||
|
||||
def needsFullSpace(self):
|
||||
return True
|
||||
def needsFullSpace(self):
|
||||
return True
|
||||
|
||||
def isAllowedAlterSelection(self):
|
||||
return False
|
||||
def isAllowedAlterSelection(self):
|
||||
return False
|
||||
|
||||
def isAllowedAlterView(self):
|
||||
return True
|
||||
def isAllowedAlterView(self):
|
||||
return True
|
||||
|
||||
def isAllowedAlterDocument(self):
|
||||
return False
|
||||
def isAllowedAlterDocument(self):
|
||||
return False
|
||||
|
||||
def helpRequested(self):
|
||||
pass
|
||||
def helpRequested(self):
|
||||
pass
|
||||
|
||||
def setupUi(self):
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.ship = form.findChild(QtGui.QComboBox, "Ship")
|
||||
form.mainLogo = form.findChild(QtGui.QLabel, "MainLogo")
|
||||
iconPath = Paths.iconsPath() + "/Ico.xpm"
|
||||
form.mainLogo.setPixmap(QtGui.QPixmap(iconPath))
|
||||
self.form = form
|
||||
self.retranslateUi()
|
||||
def setupUi(self):
|
||||
"""Setup the task panel user interface."""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.ship = self.widget(QtGui.QComboBox, "Ship")
|
||||
form.mainLogo = self.widget(QtGui.QLabel, "MainLogo")
|
||||
form.mainLogo.setPixmap(QtGui.QPixmap(":/icons/Ship_Logo.svg"))
|
||||
self.form = form
|
||||
self.retranslateUi()
|
||||
|
||||
def getMainWindow(self):
|
||||
"returns the main window"
|
||||
# using QtGui.qApp.activeWindow() isn't very reliable because if another
|
||||
# widget than the mainwindow is active (e.g. a dialog) the wrong widget is
|
||||
# returned
|
||||
toplevel = QtGui.qApp.topLevelWidgets()
|
||||
for i in toplevel:
|
||||
if i.metaObject().className() == "Gui::MainWindow":
|
||||
return i
|
||||
raise Exception("No main window found")
|
||||
def getMainWindow(self):
|
||||
toplevel = QtGui.qApp.topLevelWidgets()
|
||||
for i in toplevel:
|
||||
if i.metaObject().className() == "Gui::MainWindow":
|
||||
return i
|
||||
raise Exception("No main window found")
|
||||
|
||||
def widget(self, class_id, name):
|
||||
"""Return the selected widget.
|
||||
|
||||
Keyword arguments:
|
||||
class_id -- Class identifier
|
||||
name -- Name of the widget
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
return form.findChild(class_id, name)
|
||||
|
||||
def retranslateUi(self):
|
||||
"""Set the user interface locale strings."""
|
||||
self.form.setWindowTitle(QtGui.QApplication.translate(
|
||||
"ship_load",
|
||||
"Load example ship",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QGroupBox, "ShipSelectionBox").setTitle(
|
||||
QtGui.QApplication.translate("ship_load",
|
||||
"Select ship example geometry",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
def retranslateUi(self):
|
||||
""" Set user interface locale strings.
|
||||
"""
|
||||
self.form.setWindowTitle(QtGui.QApplication.translate("ship_load","Load example ship",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QGroupBox, "ShipSelectionBox").setTitle(QtGui.QApplication.translate("ship_load",
|
||||
"Select ship example geometry",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
def createTask():
|
||||
panel = TaskPanel()
|
||||
Gui.Control.showDialog(panel)
|
||||
if panel.setupUi():
|
||||
Gui.Control.closeDialog(panel)
|
||||
return None
|
||||
return panel
|
||||
panel = TaskPanel()
|
||||
Gui.Control.showDialog(panel)
|
||||
if panel.setupUi():
|
||||
Gui.Control.closeDialog(panel)
|
||||
return None
|
||||
return panel
|
||||
|
||||
@@ -1,36 +1,29 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* 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()
|
||||
"""Load the examples importing tool"""
|
||||
TaskPanel.createTask()
|
||||
|
||||
@@ -1,127 +1,145 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
# Qt library
|
||||
from PyQt4 import QtGui,QtCore
|
||||
# FreeCAD modules
|
||||
import FreeCAD,FreeCADGui
|
||||
from PySide import QtGui, QtCore
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from FreeCAD import Base, Vector
|
||||
import Part
|
||||
# FreeCADShip modules
|
||||
import Units
|
||||
from shipUtils import Paths
|
||||
|
||||
|
||||
def Plot(scale, sections, shape):
|
||||
""" Creates the outline draw.
|
||||
@param scale Plane scale (format 1:scale)
|
||||
@param sections Sections computed.
|
||||
@param shape Ship surfaces shell
|
||||
@return plotted object (DocumentObject)
|
||||
"""
|
||||
msg = QtGui.QApplication.translate("ship_console", "Performing plot",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + ' (1:%d)...\n' % (scale))
|
||||
scale = 1000.0 / scale
|
||||
# Take positions
|
||||
bounds = [0.0, 0.0, 0.0]
|
||||
bbox = shape.BoundBox
|
||||
bounds[0] = bbox.XLength
|
||||
bounds[1] = bbox.YLength
|
||||
bounds[2] = bbox.ZLength
|
||||
xTot = scale*bounds[1] + 32.0 + scale*bounds[0]
|
||||
yTot = scale*bounds[2] + 32.0 + scale*bounds[1]
|
||||
xMid = 210.0
|
||||
yMid = 185.0
|
||||
x0 = xMid - 0.5*xTot
|
||||
y0 = 297.0 - yMid - 0.5*yTot # 297 = A3_width
|
||||
# Get border
|
||||
edges = getEdges([shape])
|
||||
border = edges[0]
|
||||
for i in range(0,len(edges)):
|
||||
border = border.oldFuse(edges[i]) # Only group objects, don't try to build more complex entities
|
||||
border = border.oldFuse(edges[i].mirror(Vector(0.0, 0.0, 0.0),Vector(0.0, 1.0, 0.0)))
|
||||
# Fuse sections & borders
|
||||
# obj = sections.oldFuse(border)
|
||||
obj = border.oldFuse(sections)
|
||||
# Send to 3D view
|
||||
Part.show(obj)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
obj = objs[len(objs)-1]
|
||||
# Create a new plane
|
||||
FreeCAD.ActiveDocument.addObject('Drawing::FeaturePage','OutlineDrawPlot')
|
||||
FreeCAD.ActiveDocument.OutlineDrawPlot.Template = FreeCAD.getResourceDir()+'Mod/Drawing/Templates/A3_Landscape.svg'
|
||||
# Side view
|
||||
FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart','OutlineDrawSideView')
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.Source = obj
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.Direction = (1.0,0.0,0.0)
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.Rotation = -90.0
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.Scale = scale
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.X = 420.0 - x0 - 0.5*scale*bounds[1] # 420 = A3_height
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.Y = y0 + 0.5*scale*bounds[2]
|
||||
FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(FreeCAD.ActiveDocument.OutlineDrawSideView)
|
||||
# Front view
|
||||
FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart','OutlineDrawFrontView')
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.Source = obj
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.Direction = (0.0,1.0,0.0)
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.Rotation = -90.0
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.Scale = scale
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.X = 420.0 - x0 - scale*bounds[1] - 32 - 0.5*scale*bounds[0]
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.Y = y0 + 0.5*scale*bounds[2]
|
||||
FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(FreeCAD.ActiveDocument.OutlineDrawFrontView)
|
||||
# Up view
|
||||
FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart','OutlineDrawUpView')
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView.Source = obj
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView.Direction = (0.0,0.0,1.0)
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView.Scale = scale
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView.X = 420.0 - x0 - scale*bounds[1] - 32 - 0.5*scale*bounds[0]
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView.Y = y0 + scale*bounds[2] + 32
|
||||
FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(FreeCAD.ActiveDocument.OutlineDrawUpView)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return obj
|
||||
""" Creates the outline draw.
|
||||
@param scale Plane scale (format 1:scale)
|
||||
@param sections Computed sections.
|
||||
@param shape Ship surfaces
|
||||
@return plotted object (DocumentObject)
|
||||
"""
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Performing plot",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + ' (1:{0})...\n'.format(scale))
|
||||
scale = 1.0 / scale
|
||||
# Take positions
|
||||
bounds = [0.0, 0.0, 0.0]
|
||||
bbox = shape.BoundBox
|
||||
bounds[0] = bbox.XLength
|
||||
bounds[1] = bbox.YLength
|
||||
bounds[2] = bbox.ZLength
|
||||
xTot = scale * bounds[1] + 32.0 + scale * bounds[0]
|
||||
yTot = scale * bounds[2] + 32.0 + scale * bounds[1]
|
||||
xMid = 210.0
|
||||
yMid = 185.0
|
||||
x0 = xMid - 0.5 * xTot
|
||||
y0 = 297.0 - yMid - 0.5 * yTot # 297 = A3_width
|
||||
# Get border
|
||||
edges = getEdges([shape])
|
||||
border = edges[0]
|
||||
for i in range(0, len(edges)):
|
||||
border = border.oldFuse(edges[i])
|
||||
border = border.oldFuse(edges[i].mirror(Vector(0.0, 0.0, 0.0),
|
||||
Vector(0.0, 1.0, 0.0)))
|
||||
# Fuse sections & borders
|
||||
obj = border.oldFuse(sections)
|
||||
# Send to 3D view
|
||||
Part.show(obj)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
obj = objs[len(objs) - 1]
|
||||
# Create a new plane
|
||||
FreeCAD.ActiveDocument.addObject('Drawing::FeaturePage',
|
||||
'OutlineDrawPlot')
|
||||
FreeCAD.ActiveDocument.OutlineDrawPlot.Template = (
|
||||
FreeCAD.getResourceDir() + 'Mod/Drawing/Templates/A3_Landscape.svg')
|
||||
# Side view
|
||||
FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart',
|
||||
'OutlineDrawSideView')
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.Source = obj
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.Direction = (1.0, 0.0, 0.0)
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.Rotation = -90.0
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.Scale = scale
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.X = (
|
||||
420.0 - x0 - 0.5 * scale * bounds[1]) # 420 = A3_height
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView.Y = (
|
||||
y0 + 0.5 * scale * bounds[2])
|
||||
FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(
|
||||
FreeCAD.ActiveDocument.OutlineDrawSideView)
|
||||
# Front view
|
||||
FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart',
|
||||
'OutlineDrawFrontView')
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.Source = obj
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.Direction = (0.0, 1.0, 0.0)
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.Rotation = -90.0
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.Scale = scale
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.X = (
|
||||
420.0 - x0 - scale * bounds[1] - 32 - 0.5 * scale * bounds[0])
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView.Y = (
|
||||
y0 + 0.5 * scale * bounds[2])
|
||||
FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(
|
||||
FreeCAD.ActiveDocument.OutlineDrawFrontView)
|
||||
# Up view
|
||||
FreeCAD.ActiveDocument.addObject('Drawing::FeatureViewPart',
|
||||
'OutlineDrawUpView')
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView.Source = obj
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView.Direction = (0.0, 0.0, 1.0)
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView.Scale = scale
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView.X = (
|
||||
420.0 - x0 - scale * bounds[1] - 32 - 0.5 * scale * bounds[0])
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView.Y = (
|
||||
y0 + scale * bounds[2] + 32)
|
||||
FreeCAD.ActiveDocument.OutlineDrawPlot.addObject(
|
||||
FreeCAD.ActiveDocument.OutlineDrawUpView)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return obj
|
||||
|
||||
|
||||
def getEdges(objs=None):
|
||||
""" Returns object edges (list of them)
|
||||
@param objs Object to get the faces, none if selected
|
||||
object may used.
|
||||
@return Selected edges. None if errors happens
|
||||
"""
|
||||
edges = []
|
||||
if not objs:
|
||||
objs = FreeCADGui.Selection.getSelection()
|
||||
if not objs:
|
||||
return None
|
||||
for i in range(0, len(objs)):
|
||||
obj = objs[i]
|
||||
if obj.isDerivedFrom('Part::Feature'):
|
||||
# get shape
|
||||
shape = obj.Shape
|
||||
if not shape:
|
||||
return None
|
||||
obj = shape
|
||||
if not obj.isDerivedFrom('Part::TopoShape'):
|
||||
return None
|
||||
objEdges = obj.Edges
|
||||
if not objEdges:
|
||||
continue
|
||||
for j in range(0, len(objEdges)):
|
||||
edges.append(objEdges[j])
|
||||
return edges
|
||||
""" Returns object edges (a list of them)
|
||||
@param objs Object to get the faces, none if the selected object may be
|
||||
used.
|
||||
@return Selected edges. None if errors happened
|
||||
"""
|
||||
edges = []
|
||||
if not objs:
|
||||
objs = FreeCADGui.Selection.getSelection()
|
||||
if not objs:
|
||||
return None
|
||||
for i in range(0, len(objs)):
|
||||
obj = objs[i]
|
||||
if obj.isDerivedFrom('Part::Feature'):
|
||||
# get shape
|
||||
shape = obj.Shape
|
||||
if not shape:
|
||||
return None
|
||||
obj = shape
|
||||
if not obj.isDerivedFrom('Part::TopoShape'):
|
||||
return None
|
||||
objEdges = obj.Edges
|
||||
if not objEdges:
|
||||
continue
|
||||
for j in range(0, len(objEdges)):
|
||||
edges.append(objEdges[j])
|
||||
return edges
|
||||
|
||||
@@ -1,151 +1,151 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
# Qt library
|
||||
from PyQt4 import QtGui,QtCore
|
||||
# FreeCAD modules
|
||||
import FreeCAD,FreeCADGui
|
||||
from PySide import QtGui, QtCore
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from FreeCAD import Base, Vector
|
||||
import Part
|
||||
# FreeCADShip modules
|
||||
import Units
|
||||
from shipUtils import Paths
|
||||
|
||||
|
||||
class Preview(object):
|
||||
def __init__(self):
|
||||
""" Constructor.
|
||||
"""
|
||||
self.obj = None
|
||||
self.reinit()
|
||||
def __init__(self):
|
||||
""" Constructor. """
|
||||
self.obj = None
|
||||
self.reinit()
|
||||
|
||||
def reinit(self):
|
||||
""" Reinitializate drawer.
|
||||
"""
|
||||
self.clean()
|
||||
def reinit(self):
|
||||
""" Reinitializate the drawer. """
|
||||
self.clean()
|
||||
|
||||
def update(self, L, B, T, sectionsL, sectionsB, sectionsT, shape):
|
||||
""" Update the 3D view printing annotations.
|
||||
@param L Ship Lpp.
|
||||
@param B Ship beam.
|
||||
@param T Ship draft.
|
||||
@param sectionsL Transversal sections.
|
||||
@param sectionsB Longitudinal sections.
|
||||
@param sectionsT Water lines.
|
||||
@param shape Ship surfaces shell
|
||||
@return Sections object. None if errors happens.
|
||||
"""
|
||||
msg = QtGui.QApplication.translate("ship_console", "Computing sections",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + '...\n')
|
||||
# Destroy all previous entities
|
||||
self.clean()
|
||||
# Receive data
|
||||
nL = len(sectionsL)
|
||||
nB = len(sectionsB)
|
||||
nT = len(sectionsT)
|
||||
if not (nL or nB or nT):
|
||||
return None
|
||||
# Found sections
|
||||
sections = []
|
||||
for i in range(0,nL):
|
||||
pos = sectionsL[i]
|
||||
# Cut ship
|
||||
section = shape.slice(Vector(1.0,0.0,0.0), pos)
|
||||
for j in range(0,len(section)):
|
||||
edges = section[j].Edges
|
||||
# We have 3 cases,
|
||||
# * when section is before midship, then only starboard section will be considered
|
||||
# * When section is midship, then all section must be preserved
|
||||
# * When section is after midship, then only board will be considered
|
||||
if pos > 0.01:
|
||||
# Look for edges at the wrong side and delete it
|
||||
for k in range(len(edges)-1,-1,-1):
|
||||
edge = edges[k]
|
||||
bbox = edge.BoundBox
|
||||
if bbox.YMin < -0.001:
|
||||
del edges[k]
|
||||
elif pos < -0.01:
|
||||
# Look for edges at the wrong side and delete it
|
||||
for k in range(len(edges)-1,-1,-1):
|
||||
edge = edges[k]
|
||||
bbox = edge.BoundBox
|
||||
if bbox.YMax > 0.001:
|
||||
del edges[k]
|
||||
sections.extend(edges)
|
||||
for i in range(0,nB):
|
||||
pos = sectionsB[i]
|
||||
section = shape.slice(Vector(0.0,1.0,0.0), pos)
|
||||
for j in range(0,len(section)):
|
||||
edges = section[j].Edges
|
||||
# Longitudinal sections will preserve board and starboard ever. Since we take from one side,
|
||||
# we nned to mirror it.
|
||||
section[j] = section[j].mirror(Vector(0.0, 0.0, 0.0),Vector(0.0, 1.0, 0.0))
|
||||
edges2 = section[j].Edges
|
||||
sections.extend(edges)
|
||||
sections.extend(edges2)
|
||||
for i in range(0,nT):
|
||||
pos = sectionsT[i]
|
||||
section = shape.slice(Vector(0.0,0.0,1.0), pos)
|
||||
for j in range(0,len(section)):
|
||||
edges = section[j].Edges
|
||||
# We have 3 cases,
|
||||
# * when section is below draft, then only board section will be considered
|
||||
# * When section is draft, then all section must be preserved
|
||||
# * When section is above draft, then only starboard will be considered
|
||||
if pos > T + 0.01:
|
||||
# Look for edges at the wrong side and delete it
|
||||
for k in range(len(edges)-1,-1,-1):
|
||||
edge = edges[k]
|
||||
bbox = edge.BoundBox
|
||||
if bbox.YMax > 0.001:
|
||||
del edges[k]
|
||||
elif pos < T - 0.01:
|
||||
# Look for edges at the wrong side and delete it
|
||||
for k in range(len(edges)-1,-1,-1):
|
||||
edge = edges[k]
|
||||
bbox = edge.BoundBox
|
||||
if bbox.YMin < -0.001:
|
||||
del edges[k]
|
||||
sections.extend(edges)
|
||||
# Convert all BSplines into a shape
|
||||
if not sections:
|
||||
msg = QtGui.QApplication.translate("ship_console", "Any valid ship section found",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintWarning(msg + '\n')
|
||||
return
|
||||
obj = sections[0]
|
||||
for i in range(1,len(sections)):
|
||||
obj = obj.oldFuse(sections[i]) # Only group the edges, don't try to build more complex entities
|
||||
# Create the representable object
|
||||
Part.show(obj)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.obj = objs[len(objs)-1]
|
||||
self.obj.Label = 'OutlineDraw'
|
||||
return self.obj
|
||||
|
||||
def clean(self):
|
||||
""" Erase all annotations from screen.
|
||||
"""
|
||||
if not self.obj:
|
||||
return
|
||||
FreeCAD.ActiveDocument.removeObject(self.obj.Name)
|
||||
self.obj = None
|
||||
def update(self, L, B, T, sectionsL, sectionsB, sectionsT, shape):
|
||||
""" Update the 3D view annotations.
|
||||
@param L Ship Lpp.
|
||||
@param B Ship beam.
|
||||
@param T Ship draft.
|
||||
@param sectionsL Transversal sections.
|
||||
@param sectionsB Longitudinal sections.
|
||||
@param sectionsT Water lines.
|
||||
@param shape Ship surfaces shell
|
||||
@return Sections object. None if errors happens.
|
||||
"""
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Computing sections",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintMessage(msg + '...\n')
|
||||
# Destroy all previous entities
|
||||
self.clean()
|
||||
# Receive data
|
||||
nL = len(sectionsL)
|
||||
nB = len(sectionsB)
|
||||
nT = len(sectionsT)
|
||||
if not (nL or nB or nT):
|
||||
return None
|
||||
# Found sections
|
||||
sections = []
|
||||
for i in range(0, nL):
|
||||
pos = sectionsL[i] * Units.Metre.Value
|
||||
# Cut ship
|
||||
section = shape.slice(Vector(1.0, 0.0, 0.0), pos)
|
||||
for j in range(0, len(section)):
|
||||
edges = section[j].Edges
|
||||
# We have 3 cases,
|
||||
# * when the section is before midship (starboard side drawn)
|
||||
# * When the section is midship (both sides drawn)
|
||||
# * When the section is after midship (board side drawn)
|
||||
if pos > 0.01 * L * Units.Metre.Value:
|
||||
for k in range(len(edges) - 1, -1, -1):
|
||||
edge = edges[k]
|
||||
bbox = edge.BoundBox
|
||||
if bbox.YMin < -0.01 * B * Units.Metre.Value:
|
||||
del edges[k]
|
||||
elif pos < -0.01 * L * Units.Metre.Value:
|
||||
for k in range(len(edges) - 1, -1, -1):
|
||||
edge = edges[k]
|
||||
bbox = edge.BoundBox
|
||||
if bbox.YMax > 0.01 * B * Units.Metre.Value:
|
||||
del edges[k]
|
||||
sections.extend(edges)
|
||||
for i in range(0, nB):
|
||||
pos = sectionsB[i] * Units.Metre.Value
|
||||
section = shape.slice(Vector(0.0, 1.0, 0.0), pos)
|
||||
for j in range(0, len(section)):
|
||||
edges = section[j].Edges
|
||||
# The longitudinal sections are printed in both sides.
|
||||
section[j] = section[j].mirror(Vector(0.0, 0.0, 0.0),
|
||||
Vector(0.0, 1.0, 0.0))
|
||||
edges2 = section[j].Edges
|
||||
sections.extend(edges)
|
||||
sections.extend(edges2)
|
||||
for i in range(0, nT):
|
||||
pos = sectionsT[i] * Units.Metre.Value
|
||||
section = shape.slice(Vector(0.0, 0.0, 1.0), pos)
|
||||
for j in range(0, len(section)):
|
||||
edges = section[j].Edges
|
||||
# We have 3 cases,
|
||||
# * when the section is below draft (starboard side drawn)
|
||||
# * When the section is draft (both sides drawn)
|
||||
# * When the section is above draft (starboard side drawn)
|
||||
if pos > T * 1.01 * Units.Metre.Value:
|
||||
for k in range(len(edges) - 1, -1, -1):
|
||||
edge = edges[k]
|
||||
bbox = edge.BoundBox
|
||||
if bbox.YMax > 0.01 * B * Units.Metre.Value:
|
||||
del edges[k]
|
||||
elif pos < T * 0.99 * Units.Metre.Value:
|
||||
for k in range(len(edges) - 1, -1, -1):
|
||||
edge = edges[k]
|
||||
bbox = edge.BoundBox
|
||||
if bbox.YMin < -0.01 * B * Units.Metre.Value:
|
||||
del edges[k]
|
||||
sections.extend(edges)
|
||||
# Trabform and join all the BSplines into a shape
|
||||
if not sections:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"Any valid ship section found",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
FreeCAD.Console.PrintWarning(msg + '\n')
|
||||
return
|
||||
obj = sections[0]
|
||||
for i in range(1, len(sections)):
|
||||
# Just create a group of edges
|
||||
obj = obj.oldFuse(sections[i])
|
||||
Part.show(obj)
|
||||
objs = FreeCAD.ActiveDocument.Objects
|
||||
self.obj = objs[len(objs) - 1]
|
||||
self.obj.Label = 'OutlineDraw'
|
||||
return self.obj
|
||||
|
||||
def clean(self):
|
||||
""" Erase all the annotations from the screen.
|
||||
"""
|
||||
if not self.obj:
|
||||
return
|
||||
FreeCAD.ActiveDocument.removeObject(self.obj.Name)
|
||||
self.obj = None
|
||||
|
||||
@@ -1,373 +1,504 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
# FreeCAD modules
|
||||
import FreeCAD as App
|
||||
import FreeCADGui as Gui
|
||||
# Qt library
|
||||
from PyQt4 import QtGui,QtCore
|
||||
# Module
|
||||
import Preview, Plot
|
||||
from PySide import QtGui, QtCore
|
||||
import Preview
|
||||
import Plot
|
||||
import Instance
|
||||
from shipUtils import Paths
|
||||
|
||||
|
||||
class TaskPanel:
|
||||
def __init__(self):
|
||||
self.ui = Paths.modulePath() + "/shipOutlineDraw/TaskPanel.ui"
|
||||
self.ship = None
|
||||
self.skip = False
|
||||
self.LSections = []
|
||||
self.BSections = []
|
||||
self.TSections = []
|
||||
self.obj = None
|
||||
self.preview = Preview.Preview()
|
||||
def __init__(self):
|
||||
self.ui = Paths.modulePath() + "/shipOutlineDraw/TaskPanel.ui"
|
||||
self.ship = None
|
||||
self.skip = False
|
||||
self.LSections = []
|
||||
self.BSections = []
|
||||
self.TSections = []
|
||||
self.obj = None
|
||||
self.preview = Preview.Preview()
|
||||
|
||||
def accept(self):
|
||||
self.saveSections()
|
||||
self.obj = Plot.Plot(self.form.scale.value(), self.obj.Shape, self.ship.Shape)
|
||||
self.preview.clean()
|
||||
self.obj.Label = 'OutlineDraw'
|
||||
return True
|
||||
def accept(self):
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.scale = self.widget(QtGui.QSpinBox, "Scale")
|
||||
|
||||
def reject(self):
|
||||
self.preview.clean()
|
||||
return True
|
||||
self.saveSections()
|
||||
self.obj = Plot.Plot(form.scale.value(),
|
||||
self.obj.Shape,
|
||||
self.ship.Shape)
|
||||
self.preview.clean()
|
||||
self.obj.Label = 'OutlineDraw'
|
||||
return True
|
||||
|
||||
def clicked(self, index):
|
||||
pass
|
||||
def reject(self):
|
||||
self.preview.clean()
|
||||
return True
|
||||
|
||||
def open(self):
|
||||
pass
|
||||
def clicked(self, index):
|
||||
pass
|
||||
|
||||
def needsFullSpace(self):
|
||||
return True
|
||||
def open(self):
|
||||
pass
|
||||
|
||||
def isAllowedAlterSelection(self):
|
||||
return False
|
||||
def needsFullSpace(self):
|
||||
return True
|
||||
|
||||
def isAllowedAlterView(self):
|
||||
return True
|
||||
def isAllowedAlterSelection(self):
|
||||
return False
|
||||
|
||||
def isAllowedAlterDocument(self):
|
||||
return False
|
||||
def isAllowedAlterView(self):
|
||||
return True
|
||||
|
||||
def helpRequested(self):
|
||||
pass
|
||||
def isAllowedAlterDocument(self):
|
||||
return False
|
||||
|
||||
def setupUi(self):
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.sections = form.findChild(QtGui.QTableWidget, "Sections")
|
||||
try:
|
||||
form.sections.setInputMethodHints(QtCore.Qt.ImhFormattedNumbersOnly)
|
||||
hasImhFormattedNumbersOnly = True
|
||||
except:
|
||||
hasImhFormattedNumbersOnly = False
|
||||
form.sectionType = form.findChild(QtGui.QComboBox, "SectionType")
|
||||
form.deleteButton = form.findChild(QtGui.QPushButton, "DeleteButton")
|
||||
form.nSections = form.findChild(QtGui.QSpinBox, "NSections")
|
||||
form.createButton = form.findChild(QtGui.QPushButton, "CreateButton")
|
||||
form.scale = form.findChild(QtGui.QSpinBox, "Scale")
|
||||
self.form = form
|
||||
# Initial values
|
||||
if self.initValues():
|
||||
return True
|
||||
self.retranslateUi()
|
||||
self.obj = self.preview.update(self.ship.Length, self.ship.Beam, self.ship.Draft, self.LSections,self.BSections,self.TSections, self.ship.Shape)
|
||||
# Connect Signals and Slots
|
||||
QtCore.QObject.connect(form.sectionType,QtCore.SIGNAL("activated(QString)"),self.onSectionType)
|
||||
QtCore.QObject.connect(form.sections,QtCore.SIGNAL("cellChanged(int,int)"),self.onTableItem);
|
||||
QtCore.QObject.connect(form.deleteButton,QtCore.SIGNAL("pressed()"),self.onDeleteButton)
|
||||
QtCore.QObject.connect(form.createButton,QtCore.SIGNAL("pressed()"),self.onCreateButton)
|
||||
def helpRequested(self):
|
||||
pass
|
||||
|
||||
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 setupUi(self):
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.sections = self.widget(QtGui.QTableWidget, "Sections")
|
||||
try:
|
||||
form.sections.setInputMethodHints(
|
||||
QtCore.Qt.ImhFormattedNumbersOnly)
|
||||
hasImhFormattedNumbersOnly = True
|
||||
except:
|
||||
hasImhFormattedNumbersOnly = False
|
||||
form.sectionType = self.widget(QtGui.QComboBox, "SectionType")
|
||||
form.deleteButton = self.widget(QtGui.QPushButton, "DeleteButton")
|
||||
form.nSections = self.widget(QtGui.QSpinBox, "NSections")
|
||||
form.createButton = self.widget(QtGui.QPushButton, "CreateButton")
|
||||
form.scale = self.widget(QtGui.QSpinBox, "Scale")
|
||||
self.form = form
|
||||
# Initial values
|
||||
if self.initValues():
|
||||
return True
|
||||
self.retranslateUi()
|
||||
self.obj = self.preview.update(self.ship.Length,
|
||||
self.ship.Breadth,
|
||||
self.ship.Draft,
|
||||
self.LSections,
|
||||
self.BSections,
|
||||
self.TSections,
|
||||
self.ship.Shape)
|
||||
# Connect Signals and Slots
|
||||
QtCore.QObject.connect(
|
||||
form.sectionType,
|
||||
QtCore.SIGNAL("activated(QString)"),
|
||||
self.onSectionType)
|
||||
QtCore.QObject.connect(
|
||||
form.sections,
|
||||
QtCore.SIGNAL("cellChanged(int,int)"),
|
||||
self.onTableItem)
|
||||
QtCore.QObject.connect(
|
||||
form.deleteButton,
|
||||
QtCore.SIGNAL("pressed()"),
|
||||
self.onDeleteButton)
|
||||
QtCore.QObject.connect(
|
||||
form.createButton,
|
||||
QtCore.SIGNAL("pressed()"),
|
||||
self.onCreateButton)
|
||||
|
||||
def initValues(self):
|
||||
""" Set initial values for fields
|
||||
"""
|
||||
# Get selected objects
|
||||
selObjs = Gui.Selection.getSelection()
|
||||
if not selObjs:
|
||||
msg = QtGui.QApplication.translate("ship_console",
|
||||
"Ship instance must be selected (no object selected)",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
for i in range(0,len(selObjs)):
|
||||
obj = selObjs[i]
|
||||
# Test if is a ship instance
|
||||
props = obj.PropertiesList
|
||||
try:
|
||||
props.index("IsShip")
|
||||
except ValueError:
|
||||
continue
|
||||
if obj.IsShip:
|
||||
# Test if another ship already selected
|
||||
if self.ship:
|
||||
msg = QtGui.QApplication.translate("ship_console",
|
||||
"More than one ship selected (extra ships will be neglected)",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintWarning(msg + '\n')
|
||||
break
|
||||
self.ship = obj
|
||||
# Test if any valid ship was selected
|
||||
if not self.ship:
|
||||
msg = QtGui.QApplication.translate("ship_console",
|
||||
"Ship instance must be selected (no valid ship found at selected objects)",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
# Load sections (if exist)
|
||||
self.loadSections()
|
||||
return False
|
||||
def getMainWindow(self):
|
||||
toplevel = QtGui.qApp.topLevelWidgets()
|
||||
for i in toplevel:
|
||||
if i.metaObject().className() == "Gui::MainWindow":
|
||||
return i
|
||||
raise Exception("No main window found")
|
||||
|
||||
def retranslateUi(self):
|
||||
""" Set user interface locale strings.
|
||||
"""
|
||||
self.form.setWindowTitle(QtGui.QApplication.translate("ship_outline","Outline draw",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QGroupBox, "AutoCreateBox").setTitle(QtGui.QApplication.translate("ship_outline","Auto create",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QGroupBox, "ScaleBox").setTitle(QtGui.QApplication.translate("ship_outline","Scale",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QPushButton, "DeleteButton").setText(QtGui.QApplication.translate("ship_outline",
|
||||
"Delete all sections",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QPushButton, "CreateButton").setText(QtGui.QApplication.translate("ship_outline",
|
||||
"Create sections",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QComboBox, "SectionType").setItemText(0, QtGui.QApplication.translate("ship_outline",
|
||||
"Transversal",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QComboBox, "SectionType").setItemText(1, QtGui.QApplication.translate("ship_outline",
|
||||
"Longitudinal",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.form.findChild(QtGui.QComboBox, "SectionType").setItemText(2, QtGui.QApplication.translate("ship_outline",
|
||||
"Water lines",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
def widget(self, class_id, name):
|
||||
"""Return the selected widget.
|
||||
|
||||
def onSectionType(self):
|
||||
""" Function called when the section type is changed.
|
||||
"""
|
||||
# Search section type
|
||||
ID = self.form.sectionType.currentIndex()
|
||||
self.setSectionType(ID)
|
||||
Keyword arguments:
|
||||
class_id -- Class identifier
|
||||
name -- Name of the widget
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
return form.findChild(class_id, name)
|
||||
|
||||
def setSectionType(self, ID):
|
||||
""" Function that set the type section related table.
|
||||
@param ID Id of the section to set: \n
|
||||
0 = Transversal sections \n
|
||||
1 = Longitudinal sections \n
|
||||
2 = Water lines
|
||||
"""
|
||||
SectionList = []
|
||||
if ID == 0:
|
||||
SectionList = self.LSections[:]
|
||||
elif ID == 1:
|
||||
SectionList = self.BSections[:]
|
||||
elif ID == 2:
|
||||
SectionList = self.TSections[:]
|
||||
nRow = len(SectionList)
|
||||
self.form.sections.clearContents()
|
||||
self.form.sections.setRowCount(nRow+1)
|
||||
if not nRow:
|
||||
self.obj = self.preview.update(self.ship.Length, self.ship.Beam, self.ship.Draft, self.LSections,self.BSections,self.TSections, self.ship.Shape)
|
||||
return
|
||||
self.skip = True # Avoid recursive call to OnItem
|
||||
for i in range(0,nRow):
|
||||
if i == nRow-1:
|
||||
self.skip = False
|
||||
string = '%f' % (SectionList[i])
|
||||
item = QtGui.QTableWidgetItem(string)
|
||||
self.form.sections.setItem(i,0,item)
|
||||
def initValues(self):
|
||||
""" Set initial values for fields
|
||||
"""
|
||||
# Get selected objects
|
||||
selObjs = Gui.Selection.getSelection()
|
||||
if not selObjs:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"A ship instance must be selected before use this tool (no"
|
||||
" objects selected)",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
for i in range(0, len(selObjs)):
|
||||
obj = selObjs[i]
|
||||
# Test if is a ship instance
|
||||
props = obj.PropertiesList
|
||||
try:
|
||||
props.index("IsShip")
|
||||
except ValueError:
|
||||
continue
|
||||
if obj.IsShip:
|
||||
# Test if another ship already selected
|
||||
if self.ship:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"More than one ship has been selected (just the first"
|
||||
" one will be used)",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintWarning(msg + '\n')
|
||||
break
|
||||
self.ship = obj
|
||||
# Test if any valid ship was selected
|
||||
if not self.ship:
|
||||
msg = QtGui.QApplication.translate(
|
||||
"ship_console",
|
||||
"A ship instance must be selected before use this tool (no"
|
||||
"valid ships found in the selected objects)",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintError(msg + '\n')
|
||||
return True
|
||||
# Load sections (if exist)
|
||||
self.loadSections()
|
||||
return False
|
||||
|
||||
def onTableItem(self, row, column):
|
||||
""" Function called when an item of table is changed.
|
||||
@param row Changed item row
|
||||
@param column Changed item column
|
||||
"""
|
||||
if self.skip:
|
||||
return
|
||||
# Ensure that exist one empty item at least
|
||||
nRow = self.form.sections.rowCount()
|
||||
item = self.form.sections.item(nRow-1,0)
|
||||
if item :
|
||||
if(item.text() != ''):
|
||||
self.form.sections.setRowCount(nRow+1)
|
||||
# Ensure that new item is a number
|
||||
ID = self.form.sectionType.currentIndex()
|
||||
if ID == 0:
|
||||
SectionList = self.LSections[:]
|
||||
elif ID == 1:
|
||||
SectionList = self.BSections[:]
|
||||
elif ID == 2:
|
||||
SectionList = self.TSections[:]
|
||||
item = self.form.sections.item(row,column)
|
||||
(number,flag) = item.text().toFloat()
|
||||
if not flag:
|
||||
if len(SectionList) > nRow-1:
|
||||
number = SectionList[nRow-1]
|
||||
else:
|
||||
number = 0.0
|
||||
string = '%f' % (number)
|
||||
item.setText(string)
|
||||
# Regenerate the list
|
||||
SectionList = []
|
||||
for i in range(0,nRow):
|
||||
item = self.form.sections.item(i,0)
|
||||
if item:
|
||||
(number,flag) = item.text().toFloat()
|
||||
SectionList.append(number)
|
||||
# Paste it into the class list
|
||||
ID = self.form.sectionType.currentIndex()
|
||||
if ID == 0:
|
||||
self.LSections = SectionList[:]
|
||||
elif ID == 1:
|
||||
self.BSections = SectionList[:]
|
||||
elif ID == 2:
|
||||
self.TSections = SectionList[:]
|
||||
self.obj = self.preview.update(self.ship.Length, self.ship.Beam, self.ship.Draft, self.LSections,self.BSections,self.TSections, self.ship.Shape)
|
||||
|
||||
def onDeleteButton(self):
|
||||
""" Function called when the delete button is pressed.
|
||||
All sections mustt be erased
|
||||
"""
|
||||
self.form.sections.clearContents()
|
||||
self.form.sections.setRowCount(1)
|
||||
# Clear active list
|
||||
ID = self.form.sectionType.currentIndex()
|
||||
if ID == 0:
|
||||
self.LSections = []
|
||||
elif ID == 1:
|
||||
self.BSections = []
|
||||
elif ID == 2:
|
||||
self.TSections = []
|
||||
self.setSectionType(ID)
|
||||
|
||||
def onCreateButton(self):
|
||||
""" Function called when create button is pressed.
|
||||
Several sections must be added to list
|
||||
"""
|
||||
# Recolect data
|
||||
nSections = self.form.nSections.value()
|
||||
SectionList = []
|
||||
L = 0.0
|
||||
ID = self.form.sectionType.currentIndex()
|
||||
if ID == 0:
|
||||
L = self.ship.Length
|
||||
d = L / (nSections-1) # Distance between sections
|
||||
start = - L/2.0 # Ship must have 0.0 at coordinates origin
|
||||
elif ID == 1:
|
||||
L = -0.5*self.ship.Beam # Ship must be in y<0.0
|
||||
d = L / (nSections+1.0) # Distance between sections
|
||||
start = d
|
||||
elif ID == 2:
|
||||
L = self.ship.Draft
|
||||
d = L / (nSections) # Distance between sections
|
||||
start = d
|
||||
# Calculate sections
|
||||
for i in range(0,nSections):
|
||||
sec = i*d + start
|
||||
SectionList.append(sec)
|
||||
# Paste into class table
|
||||
if ID == 0:
|
||||
self.LSections = SectionList[:]
|
||||
elif ID == 1:
|
||||
self.BSections = SectionList[:]
|
||||
elif ID == 2:
|
||||
self.TSections = SectionList[:]
|
||||
# Print the table
|
||||
self.setSectionType(ID)
|
||||
def retranslateUi(self):
|
||||
"""Set the user interface locale strings."""
|
||||
self.form.setWindowTitle(QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Outline draw",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QGroupBox, "AutoCreateBox").setTitle(
|
||||
QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Auto create",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QGroupBox, "ScaleBox").setTitle(
|
||||
QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Scale",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QPushButton, "DeleteButton").setText(
|
||||
QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Delete all sections",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QPushButton, "CreateButton").setText(
|
||||
QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Create sections",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QComboBox, "SectionType").setItemText(
|
||||
0,
|
||||
QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Transversal",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QComboBox, "SectionType").setItemText(
|
||||
1,
|
||||
QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Longitudinal",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.widget(QtGui.QComboBox, "SectionType").setItemText(
|
||||
2,
|
||||
QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Water lines",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
def loadSections(self):
|
||||
""" Loads from ship object previously selected sections.
|
||||
"""
|
||||
# Load sections
|
||||
props = self.ship.PropertiesList
|
||||
flag=True
|
||||
try:
|
||||
props.index("LSections")
|
||||
except ValueError:
|
||||
flag=False
|
||||
if flag:
|
||||
self.LSections = self.ship.LSections[:]
|
||||
self.BSections = self.ship.BSections[:]
|
||||
self.TSections = self.ship.TSections[:]
|
||||
# Load scale too
|
||||
flag=True
|
||||
try:
|
||||
props.index("PlotScale")
|
||||
except ValueError:
|
||||
flag=False
|
||||
if flag:
|
||||
self.form.scale.setValue(self.ship.PlotScale)
|
||||
# Set UI
|
||||
self.setSectionType(self.form.sectionType.currentIndex())
|
||||
def onSectionType(self):
|
||||
""" Function called when the section type is changed.
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.sectionType = self.widget(QtGui.QComboBox, "SectionType")
|
||||
|
||||
ID = form.sectionType.currentIndex()
|
||||
self.setSectionType(ID)
|
||||
|
||||
def setSectionType(self, ID):
|
||||
""" Set the table depending on the selected section type.
|
||||
@param ID Id of the section type to set:
|
||||
- 0 = Transversal sections
|
||||
- 1 = Longitudinal sections
|
||||
- 2 = Water lines
|
||||
"""
|
||||
SectionList = []
|
||||
if ID == 0:
|
||||
SectionList = self.LSections[:]
|
||||
elif ID == 1:
|
||||
SectionList = self.BSections[:]
|
||||
elif ID == 2:
|
||||
SectionList = self.TSections[:]
|
||||
nRow = len(SectionList)
|
||||
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.sections = self.widget(QtGui.QTableWidget, "Sections")
|
||||
|
||||
form.sections.clearContents()
|
||||
form.sections.setRowCount(nRow + 1)
|
||||
self.skip = True
|
||||
for i in range(0, nRow):
|
||||
string = '{0}'.format(SectionList[i])
|
||||
item = QtGui.QTableWidgetItem(string)
|
||||
form.sections.setItem(i, 0, item)
|
||||
self.skip = False
|
||||
self.obj = self.preview.update(self.ship.Length,
|
||||
self.ship.Breadth,
|
||||
self.ship.Draft,
|
||||
self.LSections,
|
||||
self.BSections,
|
||||
self.TSections,
|
||||
self.ship.Shape)
|
||||
|
||||
|
||||
def onTableItem(self, row, column):
|
||||
""" Function called when an item of the table is touched.
|
||||
@param row Changed item row
|
||||
@param column Changed item column
|
||||
"""
|
||||
if self.skip:
|
||||
return
|
||||
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.sections = self.widget(QtGui.QTableWidget, "Sections")
|
||||
form.sectionType = self.widget(QtGui.QComboBox, "SectionType")
|
||||
|
||||
nRow = form.sections.rowCount()
|
||||
item = form.sections.item(nRow - 1, 0)
|
||||
if item:
|
||||
if(item.text() != ''):
|
||||
form.sections.setRowCount(nRow + 1)
|
||||
# Ensure that the new introduced item is a number
|
||||
ID = form.sectionType.currentIndex()
|
||||
if ID == 0:
|
||||
SectionList = self.LSections[:]
|
||||
elif ID == 1:
|
||||
SectionList = self.BSections[:]
|
||||
elif ID == 2:
|
||||
SectionList = self.TSections[:]
|
||||
item = form.sections.item(row, column)
|
||||
(number, flag) = item.text().toFloat()
|
||||
if not flag:
|
||||
if len(SectionList) > nRow - 1:
|
||||
number = SectionList[nRow - 1]
|
||||
else:
|
||||
number = 0.0
|
||||
string = '{0}'.format(number)
|
||||
item.setText(string)
|
||||
# Regenerate the list
|
||||
SectionList = []
|
||||
for i in range(0, nRow):
|
||||
item = form.sections.item(i, 0)
|
||||
if item:
|
||||
(number, flag) = item.text().toFloat()
|
||||
SectionList.append(number)
|
||||
# Paste it into the section type list
|
||||
ID = form.sectionType.currentIndex()
|
||||
if ID == 0:
|
||||
self.LSections = SectionList[:]
|
||||
elif ID == 1:
|
||||
self.BSections = SectionList[:]
|
||||
elif ID == 2:
|
||||
self.TSections = SectionList[:]
|
||||
self.obj = self.preview.update(self.ship.Length,
|
||||
self.ship.Breadth,
|
||||
self.ship.Draft,
|
||||
self.LSections,
|
||||
self.BSections,
|
||||
self.TSections,
|
||||
self.ship.Shape)
|
||||
|
||||
def onDeleteButton(self):
|
||||
""" Function called when the delete button is pressed.
|
||||
All the sections of the active type must be erased therefore.
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.sections = self.widget(QtGui.QTableWidget, "Sections")
|
||||
form.sectionType = self.widget(QtGui.QComboBox, "SectionType")
|
||||
|
||||
form.sections.clearContents()
|
||||
form.sections.setRowCount(1)
|
||||
ID = form.sectionType.currentIndex()
|
||||
if ID == 0:
|
||||
self.LSections = []
|
||||
elif ID == 1:
|
||||
self.BSections = []
|
||||
elif ID == 2:
|
||||
self.TSections = []
|
||||
self.setSectionType(ID)
|
||||
|
||||
def onCreateButton(self):
|
||||
""" Function called when automatic creating button is pressed.
|
||||
Several sections must be added to the active sections list
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.sectionType = self.widget(QtGui.QComboBox, "SectionType")
|
||||
form.nSections = self.widget(QtGui.QSpinBox, "NSections")
|
||||
|
||||
# Recolect data
|
||||
nSections = form.nSections.value()
|
||||
SectionList = []
|
||||
L = 0.0
|
||||
ID = form.sectionType.currentIndex()
|
||||
if ID == 0:
|
||||
L = self.ship.Length
|
||||
d = L / (nSections - 1)
|
||||
start = - L / 2.0
|
||||
elif ID == 1:
|
||||
L = -0.5 * self.ship.Breadth
|
||||
d = L / (nSections + 1)
|
||||
start = d
|
||||
elif ID == 2:
|
||||
L = self.ship.Draft
|
||||
d = L / (nSections)
|
||||
start = d
|
||||
# Compute the sections positions
|
||||
for i in range(0, nSections):
|
||||
sec = i * d + start
|
||||
SectionList.append(sec)
|
||||
# Paste it into the corresponding section list
|
||||
if ID == 0:
|
||||
self.LSections = SectionList[:]
|
||||
elif ID == 1:
|
||||
self.BSections = SectionList[:]
|
||||
elif ID == 2:
|
||||
self.TSections = SectionList[:]
|
||||
self.setSectionType(ID)
|
||||
|
||||
def loadSections(self):
|
||||
""" Loads from the ship object all the previously selected sections.
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.sectionType = self.widget(QtGui.QComboBox, "SectionType")
|
||||
form.scale = self.widget(QtGui.QSpinBox, "Scale")
|
||||
|
||||
# Load sections
|
||||
props = self.ship.PropertiesList
|
||||
flag = True
|
||||
try:
|
||||
props.index("LSections")
|
||||
except ValueError:
|
||||
flag = False
|
||||
if flag:
|
||||
self.LSections = self.ship.LSections[:]
|
||||
self.BSections = self.ship.BSections[:]
|
||||
self.TSections = self.ship.TSections[:]
|
||||
# Load scale too
|
||||
flag = True
|
||||
try:
|
||||
props.index("PlotScale")
|
||||
except ValueError:
|
||||
flag = False
|
||||
if flag:
|
||||
form.scale.setValue(self.ship.PlotScale)
|
||||
# Set UI
|
||||
self.setSectionType(form.sectionType.currentIndex())
|
||||
|
||||
def saveSections(self):
|
||||
""" Save the selected sections into ship object.
|
||||
"""
|
||||
mw = self.getMainWindow()
|
||||
form = mw.findChild(QtGui.QWidget, "TaskPanel")
|
||||
form.scale = self.widget(QtGui.QSpinBox, "Scale")
|
||||
|
||||
props = self.ship.PropertiesList
|
||||
try:
|
||||
props.index("LSections")
|
||||
except ValueError:
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Transversal section positions [m]",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.ship.addProperty("App::PropertyFloatList",
|
||||
"LSections",
|
||||
"Ship",
|
||||
tooltip).LSections = []
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Longitudinal section positions [m]",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.ship.addProperty("App::PropertyFloatList",
|
||||
"BSections",
|
||||
"Ship",
|
||||
tooltip).BSections = []
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Water line positions [m]",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.ship.addProperty("App::PropertyFloatList",
|
||||
"TSections",
|
||||
"Ship",
|
||||
tooltip).TSections = []
|
||||
# Save the sections
|
||||
self.ship.LSections = self.LSections[:]
|
||||
self.ship.BSections = self.BSections[:]
|
||||
self.ship.TSections = self.TSections[:]
|
||||
# Save the scale as well
|
||||
try:
|
||||
props.index("PlotScale")
|
||||
except ValueError:
|
||||
tooltip = str(QtGui.QApplication.translate(
|
||||
"ship_outline",
|
||||
"Plot scale (1:scale format)",
|
||||
None,
|
||||
QtGui.QApplication.UnicodeUTF8))
|
||||
self.ship.addProperty("App::PropertyInteger",
|
||||
"PlotScale",
|
||||
"Ship",
|
||||
tooltip).PlotScale = 250
|
||||
self.ship.PlotScale = form.scale.value()
|
||||
|
||||
def saveSections(self):
|
||||
""" Save selected sections into ship object.
|
||||
"""
|
||||
# Test if previous section have been created
|
||||
props = self.ship.PropertiesList
|
||||
try:
|
||||
props.index("LSections")
|
||||
except ValueError:
|
||||
# Create new sections list
|
||||
tooltip = str(QtGui.QApplication.translate("ship_outline","Transversal sections position [m]",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.ship.addProperty("App::PropertyFloatList","LSections","Ship", tooltip).LSections=[]
|
||||
tooltip = str(QtGui.QApplication.translate("ship_outline","Longitudinal sections position [m]",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.ship.addProperty("App::PropertyFloatList","BSections","Ship", tooltip).BSections=[]
|
||||
tooltip = str(QtGui.QApplication.translate("ship_outline","Water lines position [m]",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.ship.addProperty("App::PropertyFloatList","TSections","Ship", tooltip).TSections=[]
|
||||
# Save sections
|
||||
self.ship.LSections = self.LSections[:]
|
||||
self.ship.BSections = self.BSections[:]
|
||||
self.ship.TSections = self.TSections[:]
|
||||
# Save also scale
|
||||
try:
|
||||
props.index("PlotScale")
|
||||
except ValueError:
|
||||
tooltip = str(QtGui.QApplication.translate("ship_outline","Plot scale (1:scale format)",
|
||||
None,QtGui.QApplication.UnicodeUTF8))
|
||||
self.ship.addProperty("App::PropertyInteger","PlotScale","Ship", tooltip).PlotScale=250
|
||||
self.ship.PlotScale = self.form.scale.value()
|
||||
|
||||
def createTask():
|
||||
panel = TaskPanel()
|
||||
Gui.Control.showDialog(panel)
|
||||
if panel.setupUi():
|
||||
Gui.Control.closeDialog(panel)
|
||||
return None
|
||||
return panel
|
||||
panel = TaskPanel()
|
||||
Gui.Control.showDialog(panel)
|
||||
if panel.setupUi():
|
||||
Gui.Control.closeDialog(panel)
|
||||
return None
|
||||
return panel
|
||||
|
||||
@@ -1,36 +1,29 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* 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()
|
||||
""" Loads the tool """
|
||||
TaskPanel.createTask()
|
||||
|
||||
@@ -36,7 +36,7 @@ def modulePath():
|
||||
def iconsPath():
|
||||
"""returns the current Ship design module icons path
|
||||
@return Icons path"""
|
||||
path = modulePath() + "/resources/icons"
|
||||
path = modulePath() + "/Resources/icons"
|
||||
return path
|
||||
|
||||
def getPathFromFile(fileName):
|
||||
|
||||
@@ -75,8 +75,8 @@ class TaskPanel:
|
||||
App.Console.PrintMessage(msg + "...\n")
|
||||
# Build simulation thread
|
||||
simulator = Sim(device, endTime, output, self.sim, FSMesh, FSData, waves, SeaNx, SeaNy)
|
||||
simulator.start() # Activate me for final release
|
||||
# simulator.run() # Activate me for development (i will show python fails)
|
||||
# simulator.start() # Activate me for final release
|
||||
simulator.run() # Activate me for development (I will show python fails)
|
||||
msg = QtGui.QApplication.translate("ship_console","Done",
|
||||
None,QtGui.QApplication.UnicodeUTF8)
|
||||
App.Console.PrintMessage(msg + "!\n")
|
||||
|
||||
@@ -45,8 +45,8 @@ class simBEMSolver_cl:
|
||||
potentials for the other ones).
|
||||
@param bem Boundary Element Method instance.
|
||||
"""
|
||||
"""
|
||||
[bem['gradp'], r, iters] = self.solver.solve(bem['A'], bem['B'], bem['gradp'])
|
||||
# Take care, LSQR expects that x0 = 0
|
||||
[bem['gradp'], r, iters] = self.solver.solve(bem['A'], bem['B'])
|
||||
if(iters >= 300):
|
||||
FreeCAD.Console.PrintError("\t\t[Sim]: Solving velocity potentials.\n")
|
||||
FreeCAD.Console.PrintError("\t\t\tSolutions seems don't convergs after 300 iterations (%g residual)\n" % (r))
|
||||
@@ -58,4 +58,4 @@ class simBEMSolver_cl:
|
||||
if(rank < bem['N']):
|
||||
FreeCAD.Console.PrintError("\t\t[Sim]: Solving velocity potentials.\n")
|
||||
FreeCAD.Console.PrintError("\t\t\tEffective rank of linear system matrix is {0} (N = {1})\n".format(rank, bem['N']))
|
||||
|
||||
"""
|
||||
|
||||
@@ -48,11 +48,29 @@ class jacobi:
|
||||
self.B = None
|
||||
self.X0 = None
|
||||
self.X = None
|
||||
self.R = None
|
||||
self.x = None
|
||||
self.n = 0
|
||||
# Create dot operator
|
||||
self.dot = ReductionKernel(context, np.float32, neutral="0",
|
||||
reduce_expr="a+b", map_expr="x[i]*y[i]",
|
||||
arguments="__global float *x, __global float *y")
|
||||
# self.dot = ReductionKernel(context, np.float32, neutral="0",
|
||||
# reduce_expr="a+b", map_expr="x[i]*y[i]",
|
||||
# arguments="__global float *x, __global float *y")
|
||||
|
||||
def rnorm2(self, X):
|
||||
""" Compute the norm square of the residuals.
|
||||
@param X Result of the last iteration (pyopencl.array object).
|
||||
@return norm square of the residuals.
|
||||
"""
|
||||
n = np.uint32(self.n)
|
||||
gSize = (clUtils.globalSize(n),)
|
||||
kernelargs = (self.A,
|
||||
self.B.data,
|
||||
X.data,
|
||||
self.R.data,
|
||||
n)
|
||||
# Test if the final result has been reached
|
||||
self.program.r(self.queue, gSize, None, *(kernelargs))
|
||||
return cl_array.dot(self.R,self.R).get()
|
||||
|
||||
def solve(self, A, B, x0=None, tol=10e-6, iters=300, w=1.0):
|
||||
r""" Solve linear system of equations by a Jacobi
|
||||
@@ -64,7 +82,8 @@ class jacobi:
|
||||
\$ \vert\vert B - A \, x \vert \vert_\infty /
|
||||
\vert\vert B \vert \vert_\infty \$
|
||||
@param iters Maximum number of iterations.
|
||||
@param w Relaxation factor
|
||||
@param w Relaxation factor (could be autoupdated
|
||||
if the method diverges)
|
||||
"""
|
||||
# Create/set OpenCL buffers
|
||||
w = np.float32(w)
|
||||
@@ -73,47 +92,47 @@ class jacobi:
|
||||
n = np.uint32(len(B))
|
||||
gSize = (clUtils.globalSize(n),)
|
||||
# Get a norm to can compare later for valid result
|
||||
B_cl = cl_array.to_device(self.context,self.queue,B)
|
||||
bnorm2 = self.dot(B_cl,B_cl).get()
|
||||
w = w / bnorm2
|
||||
bnorm2 = cl_array.dot(self.B,self.B).get()
|
||||
FreeCAD.Console.PrintMessage(bnorm2)
|
||||
FreeCAD.Console.PrintMessage("\n")
|
||||
rnorm2 = 0.
|
||||
# Iterate while the result converges or maximum number
|
||||
# of iterations is reached.
|
||||
for i in range(0,iters):
|
||||
kernelargs = (self.A,
|
||||
self.B,
|
||||
self.X0,
|
||||
self.X,
|
||||
n)
|
||||
# Test if the final result has been reached
|
||||
self.program.r(self.queue, gSize, None, *(kernelargs))
|
||||
cl.enqueue_read_buffer(self.queue, self.X, self.x).wait()
|
||||
x_cl = cl_array.to_device(self.context,self.queue,self.x)
|
||||
rnorm2 = self.dot(x_cl,x_cl).get()
|
||||
rnorm2 = self.rnorm2(self.X0)
|
||||
FreeCAD.Console.PrintMessage("\t")
|
||||
FreeCAD.Console.PrintMessage(rnorm2)
|
||||
FreeCAD.Console.PrintMessage(" -> ")
|
||||
FreeCAD.Console.PrintMessage(rnorm2 / bnorm2)
|
||||
FreeCAD.Console.PrintMessage("\n")
|
||||
if np.sqrt(rnorm2 / bnorm2) <= tol:
|
||||
break
|
||||
# Iterate
|
||||
kernelargs = (self.A,
|
||||
self.B,
|
||||
self.X0,
|
||||
self.X,
|
||||
self.B.data,
|
||||
self.X0.data,
|
||||
self.X.data,
|
||||
w,
|
||||
n)
|
||||
self.program.jacobi(self.queue, gSize, None, *(kernelargs))
|
||||
# Test if the result is diverging
|
||||
temp_rnorm2 = self.rnorm2(self.X)
|
||||
if(temp_rnorm2 > rnorm2):
|
||||
FreeCAD.Console.PrintMessage("\t\tDivergence found...\n\t\tw = ")
|
||||
w = w * rnorm2 / temp_rnorm2
|
||||
FreeCAD.Console.PrintMessage(w)
|
||||
FreeCAD.Console.PrintMessage("\n")
|
||||
# Discard the result
|
||||
continue
|
||||
kernelargs = (self.A,
|
||||
self.B,
|
||||
self.X,
|
||||
self.X0,
|
||||
self.B.data,
|
||||
self.X.data,
|
||||
self.X0.data,
|
||||
w,
|
||||
n)
|
||||
self.program.jacobi(self.queue, gSize, None, *(kernelargs))
|
||||
# Return result computed
|
||||
cl.enqueue_read_buffer(self.queue, self.X0, self.x).wait()
|
||||
cl.enqueue_read_buffer(self.queue, self.X0.data, self.x).wait()
|
||||
return (np.copy(self.x), np.sqrt(rnorm2 / bnorm2), i)
|
||||
|
||||
def setBuffers(self, A,B,x0):
|
||||
@@ -141,15 +160,17 @@ class jacobi:
|
||||
if not self.A:
|
||||
mf = cl.mem_flags
|
||||
self.A = cl.Buffer( self.context, mf.READ_ONLY, size = n*n * np.dtype('float32').itemsize )
|
||||
self.B = cl.Buffer( self.context, mf.READ_ONLY, size = n * np.dtype('float32').itemsize )
|
||||
self.X0 = cl.Buffer( self.context, mf.READ_WRITE, size = n * np.dtype('float32').itemsize )
|
||||
self.X = cl.Buffer( self.context, mf.READ_WRITE, size = n * np.dtype('float32').itemsize )
|
||||
self.B = cl_array.zeros(self.context,self.queue, (n), np.float32)
|
||||
self.X0 = cl_array.zeros(self.context,self.queue, (n), np.float32)
|
||||
self.X = cl_array.zeros(self.context,self.queue, (n), np.float32)
|
||||
self.R = cl_array.zeros(self.context,self.queue, (n), np.float32)
|
||||
self.x = np.zeros((n), dtype=np.float32)
|
||||
self.n = n
|
||||
# Transfer data to buffers
|
||||
events = []
|
||||
events.append(cl.enqueue_write_buffer(self.queue, self.A, A.reshape((n*n)) ))
|
||||
events.append(cl.enqueue_write_buffer(self.queue, self.B, B))
|
||||
events.append(cl.enqueue_write_buffer(self.queue, self.X0, x0))
|
||||
events.append(cl.enqueue_write_buffer(self.queue, self.B.data, B))
|
||||
events.append(cl.enqueue_write_buffer(self.queue, self.X0.data, x0))
|
||||
for e in events:
|
||||
e.wait()
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
#***************************************************************************
|
||||
#* *
|
||||
#* Copyright (c) 2011, 2012 *
|
||||
#* Jose Luis Cercos Pita <jlcercos@gmail.com> *
|
||||
#* *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* 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 *
|
||||
#* *
|
||||
#* USA *
|
||||
#* *
|
||||
#***************************************************************************
|
||||
|
||||
# numpy
|
||||
@@ -46,14 +46,11 @@ class lsqr:
|
||||
# Create OpenCL objects as null objects, that we will generate
|
||||
# at the first iteration
|
||||
self.A = None
|
||||
self.B = None
|
||||
self.X0 = None
|
||||
self.X = None
|
||||
self.R = None
|
||||
# Create dot operator
|
||||
self.dot = ReductionKernel(context, np.float32, neutral="0",
|
||||
reduce_expr="a+b", map_expr="x[i]*y[i]",
|
||||
arguments="__global float *x, __global float *y")
|
||||
self.b = None
|
||||
self.x0 = None
|
||||
self.x = None
|
||||
self.r = None
|
||||
# Create some useful operators
|
||||
self.dot_c_vec = ElementwiseKernel(context,
|
||||
"float c, float *v",
|
||||
"v[i] *= c")
|
||||
@@ -66,42 +63,66 @@ class lsqr:
|
||||
"float b, float *y",
|
||||
"z[i] = a*x[i] + b*y[i]")
|
||||
self.prod = ElementwiseKernel(context,
|
||||
"float* z,"
|
||||
"float *z,"
|
||||
"float *x, float *y",
|
||||
"z[i] = x[i]*y[i]")
|
||||
|
||||
def solve(self, A, B, x0=None, tol=10e-6, iters=300):
|
||||
def symOrtho(self, a, b):
|
||||
""" Computes the radius, cosine, and sine for the
|
||||
orthogonal transformation.
|
||||
@param a x vector.
|
||||
@param b y vector.
|
||||
@return [c,s,r]. Cosine value, Sine value, and the radius.
|
||||
"""
|
||||
s = 0
|
||||
c = 0
|
||||
r = 0
|
||||
if not b:
|
||||
r = np.abs(a)
|
||||
c = np.copysign(1,0,a)
|
||||
elif not a:
|
||||
r = np.abs(b)
|
||||
s = np.copysign(1,0,b)
|
||||
elif np.abs(b) > np.abs(a):
|
||||
t = a / b
|
||||
s = np.copysign(1.0,b) / np.sqrt(1.0 + t**2)
|
||||
c = s * t
|
||||
r = b / s
|
||||
else:
|
||||
t = b / a
|
||||
c = np.copysign(1.0,a) / np.sqrt(1.0 + t**2)
|
||||
s = c * t
|
||||
r = a / c
|
||||
return [c,s,r]
|
||||
|
||||
def solve(self, A, b, x0=None, tol=10e-5, iters=300):
|
||||
r""" Solve linear system of equations by a Jacobi
|
||||
iterative method.
|
||||
@param A Linear system matrix.
|
||||
@param B Linear system independent term.
|
||||
@param b Linear system independent term.
|
||||
@param x0 Initial aproximation of the solution.
|
||||
@param tol Relative error tolerance: \n
|
||||
\$ \vert\vert B - A \, x \vert \vert_\infty /
|
||||
\vert\vert B \vert \vert_\infty \$
|
||||
\$ \vert\vert b - A \, x \vert \vert_\infty /
|
||||
\vert\vert b \vert \vert_\infty \$
|
||||
@param iters Maximum number of iterations.
|
||||
"""
|
||||
# Create/set OpenCL buffers
|
||||
self.setBuffers(A,B,x0)
|
||||
self.setBuffers(A,b,x0)
|
||||
# Get dimensions for OpenCL execution
|
||||
n = np.uint32(len(B))
|
||||
n = np.uint32(len(b))
|
||||
gSize = (clUtils.globalSize(n),)
|
||||
# Preconditionate matrix
|
||||
self.precondition(n)
|
||||
# Get a norm to can compare later for valid result
|
||||
bnorm = np.sqrt(self.dot(self.b,self.b).get())
|
||||
FreeCAD.Console.PrintMessage(bnorm)
|
||||
FreeCAD.Console.PrintMessage("\n")
|
||||
bnorm = np.sqrt(cl_array.dot(self.b,self.b).get())
|
||||
# Initialize the problem
|
||||
beta = bnorm
|
||||
self.dot_c_vec(1.0/beta, self.u)
|
||||
kernelargs = (self.A,self.u.data,self.v.data,n)
|
||||
self.program.dot_matT_vec(self.queue, gSize, None, *(kernelargs))
|
||||
alpha = np.sqrt(self.dot(self.v,self.v).get())
|
||||
alpha = np.sqrt(cl_array.dot(self.v,self.v).get())
|
||||
self.dot_c_vec(1.0/alpha, self.v)
|
||||
self.copy_vec(self.w, self.v)
|
||||
rhobar = alpha
|
||||
phibar = beta
|
||||
rhobar = alpha
|
||||
# Iterate while the result converges or maximum number
|
||||
# of iterations is reached.
|
||||
for i in range(0,iters):
|
||||
@@ -112,50 +133,41 @@ class lsqr:
|
||||
self.r.data,
|
||||
n)
|
||||
self.program.r(self.queue, gSize, None, *(kernelargs))
|
||||
rnorm = np.sqrt(self.dot(self.r,self.r).get())
|
||||
FreeCAD.Console.PrintMessage("\t")
|
||||
FreeCAD.Console.PrintMessage(rnorm)
|
||||
FreeCAD.Console.PrintMessage("\n")
|
||||
rnorm = np.sqrt(cl_array.dot(self.r,self.r).get())
|
||||
# Test if the final result has been reached
|
||||
if rnorm / bnorm <= tol:
|
||||
break
|
||||
# Compute next alpha, beta, u, v
|
||||
kernelargs = (self.A,self.u.data,self.v.data,self.u.data,alpha,n)
|
||||
self.program.u(self.queue, gSize, None, *(kernelargs))
|
||||
beta = np.sqrt(self.dot(self.u,self.u).get())
|
||||
FreeCAD.Console.PrintMessage("\t beta=")
|
||||
FreeCAD.Console.PrintMessage(beta)
|
||||
FreeCAD.Console.PrintMessage("\n")
|
||||
beta = np.sqrt(cl_array.dot(self.u,self.u).get())
|
||||
if not beta:
|
||||
break
|
||||
self.dot_c_vec(1.0/beta, self.u)
|
||||
kernelargs = (self.A,self.u.data,self.v.data,self.v.data,beta,n)
|
||||
self.program.v(self.queue, gSize, None, *(kernelargs))
|
||||
alpha = np.sqrt(self.dot(self.v,self.v).get())
|
||||
FreeCAD.Console.PrintMessage("\t alpha=")
|
||||
FreeCAD.Console.PrintMessage(alpha)
|
||||
FreeCAD.Console.PrintMessage("\n")
|
||||
alpha = np.sqrt(cl_array.dot(self.v,self.v).get())
|
||||
if not alpha:
|
||||
break
|
||||
self.dot_c_vec(1.0/alpha, self.v)
|
||||
# Apply the orthogonal transformation
|
||||
rho = np.sqrt(rhobar*rhobar + beta*beta)
|
||||
c = rhobar/rho
|
||||
s = beta*rho
|
||||
theta = s*alpha
|
||||
rhobar = -c*alpha
|
||||
phi = c*phibar
|
||||
phibar = s*phibar
|
||||
c,s,rho = self.symOrtho(rhobar,beta)
|
||||
theta = s * alpha
|
||||
rhobar = -c * alpha
|
||||
phi = c * phibar
|
||||
phibar = s * phibar
|
||||
# Update x and w
|
||||
self.linear_comb(self.x, 1, self.x, phi/rho, self.w)
|
||||
self.linear_comb(self.w, 1, self.v, theta/rho, self.w)
|
||||
# Correct returned result due to the precoditioning
|
||||
self.prod(self.x, self.xf, self.x)
|
||||
self.linear_comb(self.x, 1.0, self.x, phi/rho, self.w)
|
||||
self.linear_comb(self.w, 1.0, self.v, -theta/rho, self.w)
|
||||
# Return result computed
|
||||
x = np.zeros((n), dtype=np.float32)
|
||||
cl.enqueue_read_buffer(self.queue, self.x.data, x).wait()
|
||||
return (x, rnorm / bnorm, i)
|
||||
return (x, rnorm / bnorm, i+1)
|
||||
|
||||
def setBuffers(self, A,B,x0):
|
||||
def setBuffers(self, A,b,x0):
|
||||
""" Create/set OpenCL required buffers.
|
||||
@param A Linear system matrix.
|
||||
@param B Independent linear term.
|
||||
@param b Independent linear term.
|
||||
@param x0 Initial solution estimator.
|
||||
"""
|
||||
# Get dimensions
|
||||
@@ -164,22 +176,20 @@ class lsqr:
|
||||
raise ValueError, 'Matrix A must be 2 dimensional array'
|
||||
if shape[0] != shape[1]:
|
||||
raise ValueError, 'Square linear system matrix expected'
|
||||
if len(B) != shape[0]:
|
||||
raise ValueError, 'Matrix and independet term dimensions does not match'
|
||||
n = len(B)
|
||||
if len(b) != shape[0]:
|
||||
raise ValueError, 'Matrix and independet term dimensions must match'
|
||||
n = len(b)
|
||||
# Set x0 if not provided
|
||||
if x0 != None:
|
||||
if len(x0) != n:
|
||||
raise ValueError, 'Initial solution estimator length does not match with linear system dimensions'
|
||||
if x0 == None:
|
||||
x0 = B
|
||||
x0 = np.zeros((n), dtype=np.float32)
|
||||
if len(x0) != n:
|
||||
raise ValueError, 'Initial solution estimator length does not match with linear system dimensions'
|
||||
# Create OpenCL objects if not already generated
|
||||
if not self.A:
|
||||
mf = cl.mem_flags
|
||||
self.A = cl.Buffer( self.context, mf.READ_WRITE, size = n*n * np.dtype('float32').itemsize )
|
||||
self.b = cl_array.zeros(self.context,self.queue, (n), np.float32)
|
||||
self.x = cl_array.zeros(self.context,self.queue, (n), np.float32)
|
||||
self.xf = cl_array.zeros(self.context,self.queue, (n), np.float32)
|
||||
self.r = cl_array.zeros(self.context,self.queue, (n), np.float32)
|
||||
self.u = cl_array.zeros(self.context,self.queue, (n), np.float32)
|
||||
self.v = cl_array.zeros(self.context,self.queue, (n), np.float32)
|
||||
@@ -187,43 +197,9 @@ class lsqr:
|
||||
# Transfer data to buffers
|
||||
events = []
|
||||
events.append(cl.enqueue_write_buffer(self.queue, self.A, A.reshape((n*n)) ))
|
||||
self.b.set(B)
|
||||
self.b.set(b)
|
||||
self.x.set(x0)
|
||||
self.u.set(B)
|
||||
self.u.set(b)
|
||||
for e in events:
|
||||
e.wait()
|
||||
|
||||
def precondition(self, n):
|
||||
""" Preconditionate matrix, ensuring that all linear system
|
||||
matrix columns has an acceptable norm. Of course, final
|
||||
solution vector must be corrected conveniently.
|
||||
@param n Linear system dimension.
|
||||
"""
|
||||
gSize = (clUtils.globalSize(n),)
|
||||
xf = np.ones((n), dtype=np.float32)
|
||||
for i in range(0,n):
|
||||
col = np.uint32(i)
|
||||
# Compute column norm
|
||||
# We can use v as column vector because has not been used yet
|
||||
kernelargs = (self.A,
|
||||
self.v.data,
|
||||
col,
|
||||
n)
|
||||
self.program.column(self.queue, gSize, None, *(kernelargs))
|
||||
norm = np.sqrt(self.dot(self.v,self.v).get())
|
||||
FreeCAD.Console.PrintMessage("col ")
|
||||
FreeCAD.Console.PrintMessage(i)
|
||||
FreeCAD.Console.PrintMessage(", norm=")
|
||||
FreeCAD.Console.PrintMessage(norm)
|
||||
FreeCAD.Console.PrintMessage("\n")
|
||||
if norm < 1.0:
|
||||
continue
|
||||
fact = np.float32(1.0/norm)
|
||||
xf[i] = fact
|
||||
kernelargs = (self.A,
|
||||
fact,
|
||||
col,
|
||||
n)
|
||||
self.program.prod_c_column(self.queue, gSize, None, *(kernelargs))
|
||||
self.x.set(xf)
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ def path():
|
||||
""" Gets the OpenCL kernels path
|
||||
@return OpenCL kernels path
|
||||
"""
|
||||
path = Paths.modulePath() + "/resources/opencl"
|
||||
path = Paths.modulePath() + "/Resources/opencl"
|
||||
return path
|
||||
|
||||
def globalSize(n):
|
||||
|
||||
@@ -67,22 +67,23 @@ class simEvolution_cl:
|
||||
bem['dpdt'][i*ny+j] = - 0.5 * gradp**2.0 - 9.81*z
|
||||
fs['vel'][i,j,2] = gradp
|
||||
# Since the inverse method returns significant errors near
|
||||
# to the free surface borders, we will modify 3 area
|
||||
# to the free surface borders, we will modify "nBC" area
|
||||
# elements of the border such that the last one will be
|
||||
# exactly the analytic solution. Also we will use it as
|
||||
# numerical beach in order to disipate waves generated
|
||||
# inside the domain (that will be refelceted otherwise)
|
||||
nBC = 10
|
||||
# 1.- Corners
|
||||
for i in range(0,4)+range(nx-4,nx):
|
||||
if i in range(0,4):
|
||||
fx = 1. - i/4.
|
||||
for i in range(0,nBC)+range(nx-nBC,nx):
|
||||
if i in range(0,nBC):
|
||||
fx = 1. - i/float(nBC)
|
||||
else:
|
||||
fx = (i - nx + 5) / 4.
|
||||
for j in range(0,4)+range(ny-4,ny):
|
||||
if j in range(0,4):
|
||||
fy = 1. - j/4.
|
||||
fx = (i - nx + nBC+1.) / nBC
|
||||
for j in range(0,nBC)+range(ny-nBC,ny):
|
||||
if j in range(0,nBC):
|
||||
fy = 1. - j/float(nBC)
|
||||
else:
|
||||
fy = (j - ny + 5) / 4.
|
||||
fy = (j - ny + nBC+1.) / nBC
|
||||
factor = max(fx,fy)
|
||||
pos = fs['pos'][i,j]
|
||||
dpdt = 0.
|
||||
@@ -103,12 +104,12 @@ class simEvolution_cl:
|
||||
bem['dpdt'][i*ny+j] = factor*dpdt + (1.-factor)*bem['dpdt'][i*ny+j]
|
||||
fs['vel'][i,j,2] = factor*vel + (1.-factor)*fs['vel'][i,j,2]
|
||||
# 2.- rows
|
||||
for i in range(0,4)+range(nx-4,nx):
|
||||
if i in range(0,4):
|
||||
factor = 1. - i/4.
|
||||
for i in range(0,nBC)+range(nx-nBC,nx):
|
||||
if i in range(0,nBC):
|
||||
factor = 1. - i/float(nBC)
|
||||
else:
|
||||
factor = (i - nx + 5) / 4.
|
||||
for j in range(4, ny-4):
|
||||
factor = (i - nx + nBC+1.) / nBC
|
||||
for j in range(nBC, ny-nBC):
|
||||
pos = fs['pos'][i,j]
|
||||
dpdt = 0.
|
||||
vel = 0.
|
||||
@@ -128,12 +129,12 @@ class simEvolution_cl:
|
||||
bem['dpdt'][i*ny+j] = factor*dpdt + (1.-factor)*bem['dpdt'][i*ny+j]
|
||||
fs['vel'][i,j,2] = factor*vel + (1.-factor)*fs['vel'][i,j,2]
|
||||
# 3.- columns
|
||||
for j in range(0,4)+range(ny-4,ny):
|
||||
if j in range(0,4):
|
||||
factor = 1. - j/4.
|
||||
for j in range(0,nBC)+range(ny-nBC,ny):
|
||||
if j in range(0,nBC):
|
||||
factor = 1. - j/float(nBC)
|
||||
else:
|
||||
factor = (j - ny + 5) / 4.
|
||||
for i in range(4, nx-4):
|
||||
factor = (j - ny + nBC+1.) / nBC
|
||||
for i in range(nBC, nx-nBC):
|
||||
pos = fs['pos'][i,j]
|
||||
dpdt = 0.
|
||||
vel = 0.
|
||||
@@ -169,22 +170,23 @@ class simEvolution_cl:
|
||||
bem['p'][i*ny+j] = bem['p'][i*ny+j] + dt * bem['dpdt'][i*ny+j]
|
||||
fs['pos'][i,j,2] = fs['pos'][i,j,2] + dt * fs['vel'][i,j,2]
|
||||
# Since the inverse method returns significant errors near
|
||||
# to the free surface borders, we will modify 3 area
|
||||
# to the free surface borders, we will modify "nBC" area
|
||||
# elements of the border such that the last one will be
|
||||
# exactly the analytic solution. Also we will use it as
|
||||
# numerical beach in order to disipate waves generated
|
||||
# inside the domain (that will be refelceted otherwise)
|
||||
nBC = 10
|
||||
# 1.- Corners
|
||||
for i in range(0,4)+range(nx-4,nx):
|
||||
if i in range(0,4):
|
||||
fx = 1. - i/4.
|
||||
for i in range(0,nBC)+range(nx-nBC,nx):
|
||||
if i in range(0,nBC):
|
||||
fx = 1. - i/float(nBC)
|
||||
else:
|
||||
fx = (i - nx + 5) / 4.
|
||||
for j in range(0,4)+range(ny-4,ny):
|
||||
if j in range(0,4):
|
||||
fy = 1. - j/4.
|
||||
fx = (i - nx + nBC+1.) / nBC
|
||||
for j in range(0,nBC)+range(ny-nBC,ny):
|
||||
if j in range(0,nBC):
|
||||
fy = 1. - j/float(nBC)
|
||||
else:
|
||||
fy = (j - ny + 5) / 4.
|
||||
fy = (j - ny + nBC+1.) / nBC
|
||||
factor = max(fx,fy)
|
||||
pos = fs['pos'][i,j]
|
||||
phi = 0.
|
||||
@@ -205,12 +207,12 @@ class simEvolution_cl:
|
||||
bem['p'][i*ny+j] = factor*phi + (1.-factor)*bem['p'][i*ny+j]
|
||||
fs['pos'][i,j,2] = factor*z + (1.-factor)*fs['pos'][i,j,2]
|
||||
# 2.- rows
|
||||
for i in range(0,4)+range(nx-4,nx):
|
||||
if i in range(0,4):
|
||||
factor = 1. - i/4.
|
||||
for i in range(0,nBC)+range(nx-nBC,nx):
|
||||
if i in range(0,nBC):
|
||||
factor = 1. - i/float(nBC)
|
||||
else:
|
||||
factor = (i - nx + 5) / 4.
|
||||
for j in range(4, ny-4):
|
||||
factor = (i - nx + nBC+1.) / nBC
|
||||
for j in range(nBC, ny-nBC):
|
||||
pos = fs['pos'][i,j]
|
||||
phi = 0.
|
||||
z = 0.
|
||||
@@ -230,12 +232,12 @@ class simEvolution_cl:
|
||||
bem['p'][i*ny+j] = factor*phi + (1.-factor)*bem['p'][i*ny+j]
|
||||
fs['pos'][i,j,2] = factor*z + (1.-factor)*fs['pos'][i,j,2]
|
||||
# 3.- columns
|
||||
for j in range(0,4)+range(ny-4,ny):
|
||||
if j in range(0,4):
|
||||
factor = 1. - j/4.
|
||||
for j in range(0,nBC)+range(ny-nBC,ny):
|
||||
if j in range(0,nBC):
|
||||
factor = 1. - j/float(nBC)
|
||||
else:
|
||||
factor = (j - ny + 5) / 4.
|
||||
for i in range(4, nx-4):
|
||||
factor = (j - ny + nBC+1.) / nBC
|
||||
for i in range(nBC, nx-nBC):
|
||||
pos = fs['pos'][i,j]
|
||||
phi = 0.
|
||||
z = 0.
|
||||
|
||||
BIN
src/Mod/Ship/simRun/theory/linearsystem.wxmx
Normal file
BIN
src/Mod/Ship/simRun/theory/linearsystem.wxmx
Normal file
Binary file not shown.
Reference in New Issue
Block a user