#*************************************************************************** #* * #* Copyright (c) 2011, 2012 * #* 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 FreeCAD as App import FreeCADGui as Gui import Units from PySide import QtGui, QtCore import Preview import Instance from shipUtils import Paths import shipUtils.Units as USys import shipUtils.Locale as Locale class TaskPanel: def __init__(self): """Constructor""" self.ui = Paths.modulePath() + "/shipCreateShip/TaskPanel.ui" self.preview = Preview.Preview() 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.QLineEdit, "Length") form.breadth = self.widget(QtGui.QLineEdit, "Breadth") form.draft = self.widget(QtGui.QLineEdit, "Draft") obj.Length = form.length.text() obj.Breadth = form.breadth.text() obj.Draft = form.draft.text() App.ActiveDocument.recompute() return True def reject(self): """Cancel the job""" 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): """Create and configurate the user interface""" mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.length = self.widget(QtGui.QLineEdit, "Length") form.breadth = self.widget(QtGui.QLineEdit, "Breadth") form.draft = self.widget(QtGui.QLineEdit, "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): 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): """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. self.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 self.bounds[0] = maxX - minX self.bounds[1] = max(maxY - minY, abs(maxY), abs(minY)) self.bounds[2] = maxZ - minZ input_format = USys.getLengthFormat() mw = self.getMainWindow() form = mw.findChild(QtGui.QWidget, "TaskPanel") form.length = self.widget(QtGui.QLineEdit, "Length") form.breadth = self.widget(QtGui.QLineEdit, "Breadth") form.draft = self.widget(QtGui.QLineEdit, "Draft") qty = Units.Quantity(self.bounds[0], Units.Length) form.length.setText(Locale.toString(input_format.format( qty.getValueAs(USys.getLengthUnits()).Value))) self.L = self.bounds[0] / Units.Metre.Value qty = Units.Quantity(self.bounds[1], Units.Length) form.breadth.setText(Locale.toString(input_format.format( qty.getValueAs(USys.getLengthUnits()).Value))) self.B = self.bounds[1] / Units.Metre.Value qty = Units.Quantity(self.bounds[2], Units.Length) form.draft.setText(Locale.toString(input_format.format( 0.5 * qty.getValueAs(USys.getLengthUnits()).Value))) self.T = 0.5 * self.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 clampVal(self, widget, val_min, val_max, val): if val >= val_min and val <= val_max: return val input_format = USys.getLengthFormat() val = min(val_max, max(val_min, val)) qty = Units.Quantity('{} m'.format(val)) widget.setText(Locale.toString(input_format.format( qty.getValueAs(USys.getLengthUnits()).Value))) return val 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.QLineEdit, "Length") form.breadth = self.widget(QtGui.QLineEdit, "Breadth") form.draft = self.widget(QtGui.QLineEdit, "Draft") qty = Units.Quantity(form.length.text()) val_min = 0.001 val_max = self.bounds[0] / Units.Metre.Value val = qty.getValueAs('m').Value self.L = self.clampVal(form.length, val_min, val_max, val) qty = Units.Quantity(form.breadth.text()) val_min = 0.001 val_max = self.bounds[1] / Units.Metre.Value val = qty.getValueAs('m').Value self.B = self.clampVal(form.breadth, val_min, val_max, val) qty = Units.Quantity(form.draft.text()) val_min = 0.001 val_max = self.bounds[2] / Units.Metre.Value val = qty.getValueAs('m').Value self.T = self.clampVal(form.draft, val_min, val_max, val) 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 createTask(): panel = TaskPanel() Gui.Control.showDialog(panel) if panel.setupUi(): Gui.Control.closeDialog(panel) return None return panel