Added Ship design module sources

This commit is contained in:
Jose Luis Cercós pita
2011-12-30 11:34:46 +01:00
committed by Yorik van Havre
parent 75323e068e
commit aa5fae41a2
39 changed files with 14850 additions and 0 deletions

View File

@@ -0,0 +1,127 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# Author: 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 General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# FreeCAD modules
import FreeCAD,FreeCADGui
from FreeCAD import Base
from FreeCAD import Part
# FreeCADShip modules
from shipUtils import Paths, Translator
class Preview(object):
def __init__(self):
""" Constructor.
"""
self.baseLine = None
self.baseLineLabel = None
self.reinit()
def reinit(self):
""" Reinitializate drawer.
"""
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'
self.baseLineLabel = DrawText('BaseLineText', str(Translator.translate('Base line')), 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'
self.fsLineLabel = DrawText('FSText', str(Translator.translate('Free surface')), 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'
self.fpLineLabel = DrawText('FPText', str(Translator.translate('Forward perpendicular')), 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'
self.apLineLabel = DrawText('APText', str(Translator.translate('After perpendicular')), 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'
self.amLineLabel = DrawText('AMText', str(Translator.translate('Amin frame')), 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 DrawText(name, string, position, displayMode="Screen", angle=0.0, justification="Left", colour=(0.00,0.00,0.00), size=12):
""" Draws a text in a desired position.
@param name Name of the object
@param string Text to draw (recommended format u'')
@param position Point to draw the text
@param angle Counter clockwise rotation of text
@param justification Alignement of the text ("Left", "Right" or "Center")
@param colour Colour of the text
@param size Font size
@return FreeCAD annotation object
"""
# Create the object
text = FreeCAD.ActiveDocument.addObject("App::Annotation",name)
# Set the text
text.LabelText = [string, u'']
# Set the options
text.Position = position
FreeCADGui.ActiveDocument.getObject(text.Name).Rotation = angle
FreeCADGui.ActiveDocument.getObject(text.Name).Justification = justification
FreeCADGui.ActiveDocument.getObject(text.Name).FontSize = size
FreeCADGui.ActiveDocument.getObject(text.Name).TextColor = colour
FreeCADGui.ActiveDocument.getObject(text.Name).DisplayMode = displayMode
return FreeCAD.ActiveDocument.getObject(text.Name)

View File

@@ -0,0 +1,196 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# Author: 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 General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# FreeCAD modules
import FreeCAD as App
import FreeCADGui as Gui
# Qt library
from PyQt4 import QtGui,QtCore
# Module
import Preview
import Instance
from shipUtils import Paths, Translator
from surfUtils import Geometry
class TaskPanel:
def __init__(self):
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("App::FeaturePython","Ship")
ship = Instance.Ship(obj, self.faces)
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
ship.discretize(self.form.nSections.value(), self.form.nPoints.value())
return True
def reject(self):
self.preview.clean()
self.close()
return True
def clicked(self, index):
pass
def open(self):
pass
def needsFullSpace(self):
return True
def isAllowedAlterSelection(self):
return False
def isAllowedAlterView(self):
return True
def isAllowedAlterDocument(self):
return False
def helpRequested(self):
pass
def setupUi(self):
mw = self.getMainWindow()
form = mw.findChild(QtGui.QWidget, "TaskPanel")
form.length = form.findChild(QtGui.QDoubleSpinBox, "Length")
form.beam = form.findChild(QtGui.QDoubleSpinBox, "Beam")
form.draft = form.findChild(QtGui.QDoubleSpinBox, "Draft")
form.nSections = form.findChild(QtGui.QSpinBox, "NSections")
form.nPoints = form.findChild(QtGui.QSpinBox, "NPoints")
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)
QtCore.QObject.connect(form.nSections, QtCore.SIGNAL("valueChanged(int)"), self.onDiscretization)
QtCore.QObject.connect(form.nPoints, QtCore.SIGNAL("valueChanged(int)"), self.onDiscretization)
def getMainWindow(self):
"returns the main window"
# using QtGui.qApp.activeWindow() isn't very reliable because if another
# widget than the mainwindow is active (e.g. a dialog) the wrong widget is
# returned
toplevel = QtGui.qApp.topLevelWidgets()
for i in toplevel:
if i.metaObject().className() == "Gui::MainWindow":
return i
raise Exception("No main window found")
def initValues(self):
""" Set initial values for fields
"""
# Get objects
self.faces = None
selObjs = Geometry.getSelectedObjs()
if not selObjs:
msg = Translator.translate("All ship surfaces must be selected (Any object has been selected)\n")
App.Console.PrintError(msg)
return True
self.faces = []
for i in range(0, len(selObjs)):
faces = Geometry.getFaces(selObjs[i])
for j in range(0, len(faces)):
self.faces.append(faces[j])
if not self.faces:
msg = Translator.translate("All ship surfaces must be selected (Any face found into selected objects)\n")
App.Console.PrintError(msg)
return True
# Get bounds
bounds = [0.0, 0.0, 0.0]
bbox = self.faces[0].BoundBox
bounds[0] = bbox.XLength
bounds[1] = bbox.YLength
bounds[2] = bbox.ZLength
for i in range(1,len(self.faces)):
bbox = self.faces[i].BoundBox
if bounds[0] < bbox.XLength:
bounds[0] = bbox.XLength
if bounds[1] < bbox.YLength:
bounds[1] = bbox.YLength
if bounds[2] < bbox.ZLength:
bounds[2] = bbox.ZLength
# Set UI fields
self.form.length.setMaximum(bounds[0])
self.form.length.setValue(bounds[0])
self.L = bounds[0]
self.form.beam.setMaximum(2.0*bounds[1])
self.form.beam.setValue(2.0*bounds[1])
self.B = 2.0*bounds[1]
self.form.draft.setMaximum(bounds[2])
self.form.draft.setValue(0.5*bounds[2])
self.T = 0.5*bounds[2]
msg = Translator.translate("Ready to work\n")
App.Console.PrintMessage(msg)
return False
def retranslateUi(self):
""" Set user interface locale strings.
"""
self.form.setWindowTitle(Translator.translate("Create a new ship"))
self.form.findChild(QtGui.QLabel, "LengthLabel").setText(Translator.translate("Length"))
self.form.findChild(QtGui.QLabel, "BeamLabel").setText(Translator.translate("Beam"))
self.form.findChild(QtGui.QLabel, "DraftLabel").setText(Translator.translate("Draft"))
self.form.findChild(QtGui.QLabel, "NSectionsLabel").setText(Translator.translate("Number of sections"))
self.form.findChild(QtGui.QLabel, "NPointsLabel").setText(Translator.translate("Points per section"))
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 onDiscretization(self, value):
""" Method called when discretization data is changed.
Annotations must be showed.
@param value Changed value.
"""
pass
def close(self):
""" Destroy all dependant objects
"""
def createTask():
panel = TaskPanel()
Gui.Control.showDialog(panel)
if panel.setupUi():
Gui.Control.closeDialog(panel)
return None
return panel

View File

@@ -0,0 +1,299 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskPanel</class>
<widget class="QWidget" name="TaskPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>260</width>
<height>514</height>
</rect>
</property>
<property name="windowTitle">
<string>Create new ship</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="MainLogo">
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap>../Icons/Ico.xpm</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="ShipDataBox">
<property name="minimumSize">
<size>
<width>240</width>
<height>160</height>
</size>
</property>
<property name="title">
<string>Ship data</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<widget class="QWidget" name="verticalLayoutWidget_2">
<property name="geometry">
<rect>
<x>0</x>
<y>20</y>
<width>241</width>
<height>141</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0,0,0">
<property name="spacing">
<number>6</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="LengthLabel">
<property name="text">
<string>Length</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="Length">
<property name="decimals">
<number>3</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="BeamLabel">
<property name="text">
<string>Beam</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="Beam">
<property name="decimals">
<number>3</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="DraftLabel">
<property name="text">
<string>Draft</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="Draft">
<property name="decimals">
<number>3</number>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QGroupBox" name="DiscretizationBox">
<property name="minimumSize">
<size>
<width>240</width>
<height>160</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="title">
<string>Discretization</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget_3">
<property name="geometry">
<rect>
<x>0</x>
<y>20</y>
<width>241</width>
<height>101</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="NSectionsLabel">
<property name="text">
<string>Number of sections</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="NSections">
<property name="minimum">
<number>50</number>
</property>
<property name="maximum">
<number>500</number>
</property>
<property name="singleStep">
<number>50</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>10</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="NPointsLabel">
<property name="text">
<string>Points per section</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="NPoints">
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>500</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,33 @@
# ##### BEGIN GPL LICENSE BLOCK #####
#
# Author: 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 General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# FreeCAD modules
import FreeCAD
import FreeCADGui
# Qt libraries
from PyQt4 import QtGui,QtCore
# Main object
import TaskPanel
def load():
""" Loads the tool """
TaskPanel.createTask()