#*************************************************************************** #* * #* Copyright (c) 2011, 2016 * #* Jose Luis Cercos Pita * #* * #* This program is free software; you can redistribute it and/or modify * #* it under the terms of the GNU Lesser General Public License (LGPL) * #* as published by the Free Software Foundation; either version 2 of * #* the License, or (at your option) any later version. * #* for detail see the LICENCE text file. * #* * #* This program is distributed in the hope that it will be useful, * #* but WITHOUT ANY WARRANTY; without even the implied warranty of * #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * #* GNU Library General Public License for more details. * #* * #* You should have received a copy of the GNU Library General Public * #* License along with this program; if not, write to the Free Software * #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * #* USA * #* * #*************************************************************************** import math import FreeCAD as App import FreeCADGui as Gui import Units from PySide import QtGui, QtCore from . import Preview from . import PlotAux import Instance from shipUtils import Paths import shipUtils.Units as USys import shipUtils.Locale as Locale 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 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.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") form.num = self.widget(QtGui.QSpinBox, "Num") draft = Units.parseQuantity(Locale.fromString(form.draft.text())) trim = Units.parseQuantity(Locale.fromString(form.trim.text())) num = form.num.value() disp, B, _ = Hydrostatics.displacement(self.ship, draft, Units.parseQuantity("0 deg"), trim) xcb = Units.Quantity(B.x, Units.Length) data = Hydrostatics.areas(self.ship, num, draft=draft, trim=trim) x = [] y = [] for i in range(0, len(data)): x.append(data[i][0].getValueAs("m").Value) y.append(data[i][1].getValueAs("m^2").Value) PlotAux.Plot(x, y, disp, xcb, self.ship) self.preview.clean() return True def reject(self): self.preview.clean() 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.draft = self.widget(QtGui.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") form.num = self.widget(QtGui.QSpinBox, "Num") 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): toplevel = QtGui.qApp.topLevelWidgets() for i in toplevel: if i.metaObject().className() == "Gui::MainWindow": return i raise RuntimeError("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 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) 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) 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) App.Console.PrintError(msg + '\n') return True length_format = USys.getLengthFormat() angle_format = USys.getAngleFormat() mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.draft = self.widget(QtGui.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") form.num = self.widget(QtGui.QSpinBox, "Num") form.draft.setText(Locale.toString(length_format.format( self.ship.Draft.getValueAs(USys.getLengthUnits()).Value))) form.trim.setText(Locale.toString(angle_format.format(0.0))) # Try to use saved values props = self.ship.PropertiesList try: props.index("AreaCurveDraft") form.draft.setText(Locale.toString(length_format.format( self.ship.AreaCurveDraft.getValueAs( USys.getLengthUnits()).Value))) except: pass try: props.index("AreaCurveTrim") form.trim.setText(Locale.toString(angle_format.format( self.ship.AreaCurveTrim.getValueAs( USys.getAngleUnits()).Value))) except ValueError: pass try: props.index("AreaCurveNum") form.num.setValue(self.ship.AreaCurveNum) except ValueError: pass # Update GUI draft = Units.Quantity(form.draft.text()).getValueAs('m').Value trim = Units.Quantity(form.trim.text()).getValueAs('deg').Value self.preview.update(draft, trim, self.ship) self.onUpdate() return False 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)) self.widget(QtGui.QLabel, "DraftLabel").setText( QtGui.QApplication.translate( "ship_areas", "Draft", None)) self.widget(QtGui.QLabel, "TrimLabel").setText( QtGui.QApplication.translate( "ship_areas", "Trim angle", None)) self.widget(QtGui.QLabel, "NumLabel").setText( QtGui.QApplication.translate( "ship_areas", "Number of points", None)) def clampValue(self, widget, val_min, val_max, val): if val_min <= val <= val_max: return val val = min(val_max, max(val_min, val)) widget.setText(val.UserString) return val def onData(self, value): """ Method called when the tool input data is touched. @param value Changed value. """ if not self.ship: return mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.draft = self.widget(QtGui.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") # Get the values (or fix them in bad setting case) try: draft = Units.parseQuantity(Locale.fromString(form.draft.text())) except: draft = self.ship.Draft form.draft.setText(draft.UserString) try: trim = Units.parseQuantity(Locale.fromString(form.trim.text())) except: trim = Units.parseQuantity("0 deg") form.trim.setText(trim.UserString) bbox = self.ship.Shape.BoundBox draft_min = Units.Quantity(bbox.ZMin, Units.Length) draft_max = Units.Quantity(bbox.ZMax, Units.Length) draft = self.clampValue(form.draft, draft_min, draft_max, draft) trim_min = Units.parseQuantity("-180 deg") trim_max = Units.parseQuantity("180 deg") trim = self.clampValue(form.trim, trim_min, trim_max, trim) self.onUpdate() self.preview.update(draft, trim, 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.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") form.output = self.widget(QtGui.QTextEdit, "OutputData") draft = Units.parseQuantity(Locale.fromString(form.draft.text())) trim = Units.parseQuantity(Locale.fromString(form.trim.text())) # Calculate the drafts at each perpendicular angle = trim.getValueAs("rad").Value L = self.ship.Length.getValueAs('m').Value B = self.ship.Breadth.getValueAs('m').Value draftAP = draft + 0.5 * self.ship.Length * math.tan(angle) if draftAP < 0.0: draftAP = 0.0 draftFP = draft - 0.5 * self.ship.Length * math.tan(angle) if draftFP < 0.0: draftFP = 0.0 # Calculate the involved hydrostatics disp, B, _ = Hydrostatics.displacement(self.ship, draft, Units.parseQuantity("0 deg"), trim) xcb = Units.Quantity(B.x, Units.Length) # Setup the html string string = u'L = {0}
'.format(self.ship.Length.UserString) string += u'B = {0}
'.format(self.ship.Breadth.UserString) string += u'T = {0}
'.format(draft.UserString) string += u'Trim = {0}
'.format(trim.UserString) string += u'TAP = {0}
'.format(draftAP.UserString) string += u'TFP = {0}
'.format(draftFP.UserString) dispText = QtGui.QApplication.translate( "ship_areas", 'Displacement', None) string += dispText + u' = {0}
'.format(disp.UserString) string += u'XCB = {0}'.format(xcb.UserString) 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.QLineEdit, "Draft") form.trim = self.widget(QtGui.QLineEdit, "Trim") form.num = self.widget(QtGui.QSpinBox, "Num") draft = Units.parseQuantity(Locale.fromString(form.draft.text())) trim = Units.parseQuantity(Locale.fromString(form.trim.text())) num = form.num.value() 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)) except: tooltip = "Areas curve tool draft selected [m]" self.ship.addProperty("App::PropertyLength", "AreaCurveDraft", "Ship", tooltip) self.ship.AreaCurveDraft = draft try: props.index("AreaCurveTrim") except ValueError: try: tooltip = str(QtGui.QApplication.translate( "ship_areas", "Areas curve tool trim selected [deg]", None)) except: tooltip = "Areas curve tool trim selected [deg]" self.ship.addProperty("App::PropertyAngle", "AreaCurveTrim", "Ship", tooltip) self.ship.AreaCurveTrim = trim try: props.index("AreaCurveNum") except ValueError: try: tooltip = str(QtGui.QApplication.translate( "ship_areas", "Areas curve tool number of points", None)) except: tooltip = "Areas curve tool number of points" self.ship.addProperty("App::PropertyInteger", "AreaCurveNum", "Ship", tooltip) self.ship.AreaCurveNum = num def createTask(): panel = TaskPanel() Gui.Control.showDialog(panel) if panel.setupUi(): Gui.Control.closeDialog(panel) return None return panel