From b11ff9b9403941357ef0849e230a56440c868a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20pita?= Date: Fri, 13 Jan 2012 16:02:58 +0100 Subject: [PATCH] Started areas curve tool redevelope --- src/Mod/Ship/CMakeLists.txt | 16 +- src/Mod/Ship/Makefile.am | 4 + src/Mod/Ship/ShipGui.py | 2 +- src/Mod/Ship/shipAreasCurve/Preview.py | 130 +++++++++++++++ src/Mod/Ship/shipAreasCurve/TaskPanel.py | 193 +++++++++++++++++++++++ src/Mod/Ship/shipAreasCurve/TaskPanel.ui | 112 +++++++++++++ src/Mod/Ship/shipAreasCurve/__init__.py | 36 +++++ 7 files changed, 491 insertions(+), 2 deletions(-) create mode 100644 src/Mod/Ship/shipAreasCurve/Preview.py create mode 100644 src/Mod/Ship/shipAreasCurve/TaskPanel.py create mode 100644 src/Mod/Ship/shipAreasCurve/TaskPanel.ui create mode 100644 src/Mod/Ship/shipAreasCurve/__init__.py diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index e446440ef..783f641b0 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -49,6 +49,14 @@ SET(ShipOutlineDraw_SRCS ) SOURCE_GROUP("shipoutlinedraw" FILES ${ShipOutlineDraw_SRCS}) +SET(ShipAreasCurve_SRCS + shipAreasCurve/__init__.py + shipAreasCurve/Preview.py + shipAreasCurve/TaskPanel.py + shipAreasCurve/TaskPanel.ui +) +SOURCE_GROUP("shipareascurve" FILES ${ShipAreasCurve_SRCS}) + SET(ShipUtils_SRCS shipUtils/__init__.py shipUtils/Math.py @@ -57,7 +65,7 @@ SET(ShipUtils_SRCS ) SOURCE_GROUP("shiputils" FILES ${ShipUtils_SRCS}) -SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipUtils_SRCS}) +SET(all_files ${ShipMain_SRCS} ${ShipIcons_SRCS} ${ShipCreateShip_SRCS} ${ShipOutlineDraw_SRCS} ${ShipAreasCurve_SRCS} ${ShipUtils_SRCS}) ADD_CUSTOM_TARGET(Ship ALL SOURCES ${all_files} @@ -83,6 +91,12 @@ INSTALL( DESTINATION Mod/Ship/shipOutlineDraw ) +INSTALL( + FILES + ${ShipAreasCurve_SRCS} + DESTINATION + Mod/Ship/shipAreasCurve +) INSTALL( FILES ${ShipUtils_SRCS} diff --git a/src/Mod/Ship/Makefile.am b/src/Mod/Ship/Makefile.am index 333680262..4cba953c0 100644 --- a/src/Mod/Ship/Makefile.am +++ b/src/Mod/Ship/Makefile.am @@ -39,6 +39,10 @@ nobase_data_DATA = \ shipOutlineDraw/Preview.py \ shipOutlineDraw/TaskPanel.py \ shipOutlineDraw/TaskPanel.ui \ + shipAreasCurve/__init__.py \ + shipAreasCurve/Preview.py \ + shipAreasCurve/TaskPanel.py \ + shipAreasCurve/TaskPanel.ui \ shipUtils/__init__.py \ shipUtils/Math.py \ shipUtils/Paths.py \ diff --git a/src/Mod/Ship/ShipGui.py b/src/Mod/Ship/ShipGui.py index 1ebeb9287..2059565bf 100644 --- a/src/Mod/Ship/ShipGui.py +++ b/src/Mod/Ship/ShipGui.py @@ -48,7 +48,7 @@ class OutlineDraw: ToolTip = str(Translator.translate('Plot ship outline draw')) return {'Pixmap' : IconPath, 'MenuText': MenuText, 'ToolTip': ToolTip} -class OutlineDraw: +class AreasCurve: def Activated(self): import shipAreasCurve shipAreasCurve.load() diff --git a/src/Mod/Ship/shipAreasCurve/Preview.py b/src/Mod/Ship/shipAreasCurve/Preview.py new file mode 100644 index 000000000..b4d9e39b9 --- /dev/null +++ b/src/Mod/Ship/shipAreasCurve/Preview.py @@ -0,0 +1,130 @@ +#*************************************************************************** +#* * +#* 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 * +#* * +#*************************************************************************** + +# 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) diff --git a/src/Mod/Ship/shipAreasCurve/TaskPanel.py b/src/Mod/Ship/shipAreasCurve/TaskPanel.py new file mode 100644 index 000000000..09433b90c --- /dev/null +++ b/src/Mod/Ship/shipAreasCurve/TaskPanel.py @@ -0,0 +1,193 @@ +#*************************************************************************** +#* * +#* 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 * +#* * +#*************************************************************************** + +# 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() + "/shipAreasCurve/TaskPanel.ui" + self.preview = Preview.Preview() + self.ship = None + + def accept(self): + if not self.ship: + return False + self.save() + 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 = form.findChild(QtGui.QDoubleSpinBox, "Draft") + form.trim = form.findChild(QtGui.QDoubleSpinBox, "Trim") + 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) + QtCore.QObject.connect(form.findChild(QtGui.QPushButton, "UpdateButton"),QtCore.SIGNAL("pressed()"),self.onUpdate) + + 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 + selObjs = Geometry.getSelectedObjs() + if not selObjs: + msg = Translator.translate("Ship instance must be selected (any object selected)\n") + App.Console.PrintError(msg) + 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 = Translator.translate("More than one ship selected (extra ship will be neglected)\n") + App.Console.PrintWarning(msg) + break + self.ship = obj + # Test if any valid ship was selected + if not self.ship: + msg = Translator.translate("Ship instance must be selected (any valid ship found at selected objects)\n") + App.Console.PrintError(msg) + 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) + 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("Plot transversal areas curve")) + self.form.findChild(QtGui.QLabel, "DraftLabel").setText(Translator.translate("Draft")) + self.form.findChild(QtGui.QLabel, "TrimLabel").setText(Translator.translate("Trim")) + self.form.findChild(QtGui.QPushButton, "UpdateButton").setText(Translator.translate("Update Data")) + + def onData(self, value): + """ Method called when input data is changed. + @param value Changed value. + """ + pass + + def onUpdate(self): + """ Method called when update data request. + """ + pass + + def save(self): + """ Saves data into ship instance. + """ + props = self.ship.PropertiesList + try: + props.index("AreaCurveDraft") + except ValueError: + self.ship.addProperty("App::PropertyFloat","AreaCurveDraft","Ship", str(Translator.translate("Areas curve draft selected [m]"))) + self.ship.AreaCurveDraft = self.form.draft.value() + try: + props.index("AreaCurveTrim") + except ValueError: + self.ship.addProperty("App::PropertyFloat","AreaCurveTrim","Ship", str(Translator.translate("Areas curve trim selected [m]"))) + self.ship.AreaCurveTrim = self.form.draft.value() + +def createTask(): + panel = TaskPanel() + Gui.Control.showDialog(panel) + if panel.setupUi(): + Gui.Control.closeDialog(panel) + return None + return panel diff --git a/src/Mod/Ship/shipAreasCurve/TaskPanel.ui b/src/Mod/Ship/shipAreasCurve/TaskPanel.ui new file mode 100644 index 000000000..0aaf1abcd --- /dev/null +++ b/src/Mod/Ship/shipAreasCurve/TaskPanel.ui @@ -0,0 +1,112 @@ + + + TaskPanel + + + + 0 + 0 + 260 + 256 + + + + Create new ship + + + + + + + + Draft + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 3 + + + 0.100000000000000 + + + + + + + + 24 + 16777215 + + + + m + + + + + + + + + + + Trim + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 1 + + + -45.000000000000000 + + + 45.000000000000000 + + + + + + + + 24 + 16777215 + + + + Deg + + + + + + + + + Update data + + + + + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + diff --git a/src/Mod/Ship/shipAreasCurve/__init__.py b/src/Mod/Ship/shipAreasCurve/__init__.py new file mode 100644 index 000000000..cbfb57d75 --- /dev/null +++ b/src/Mod/Ship/shipAreasCurve/__init__.py @@ -0,0 +1,36 @@ +#*************************************************************************** +#* * +#* 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 * +#* * +#*************************************************************************** + +# FreeCAD modules +import FreeCAD +import FreeCADGui + +# Qt libraries +from PyQt4 import QtGui,QtCore + +# Main object +import TaskPanel + +def load(): + """ Loads the tool """ + TaskPanel.createTask()