From a615380027ced6e1fdd0c3a6daee397682c5bf91 Mon Sep 17 00:00:00 2001 From: Jose Luis Cercos Pita Date: Sat, 23 Jan 2016 14:21:25 +0100 Subject: [PATCH] Added a console interface to the weights generation --- src/Mod/Ship/CMakeLists.txt | 1 + src/Mod/Ship/Ship.py | 3 +- src/Mod/Ship/WeightInstance.py | 49 +++++++----- src/Mod/Ship/shipCreateWeight/TaskPanel.py | 33 +------- src/Mod/Ship/shipCreateWeight/Tools.py | 91 ++++++++++++++++++++++ 5 files changed, 126 insertions(+), 51 deletions(-) create mode 100644 src/Mod/Ship/shipCreateWeight/Tools.py diff --git a/src/Mod/Ship/CMakeLists.txt b/src/Mod/Ship/CMakeLists.txt index c44c5e7e9..50e42a3c2 100644 --- a/src/Mod/Ship/CMakeLists.txt +++ b/src/Mod/Ship/CMakeLists.txt @@ -63,6 +63,7 @@ SET(ShipCreateWeight_SRCS shipCreateWeight/__init__.py shipCreateWeight/TaskPanel.py shipCreateWeight/TaskPanel.ui + shipCreateWeight/Tools.py ) SOURCE_GROUP("shipcreateweight" FILES ${ShipCreateWeight_SRCS}) diff --git a/src/Mod/Ship/Ship.py b/src/Mod/Ship/Ship.py index bea30aae5..1509f38e2 100644 --- a/src/Mod/Ship/Ship.py +++ b/src/Mod/Ship/Ship.py @@ -31,4 +31,5 @@ __doc__="The Ships module provide a set of tools to make some specific Naval" \ from shipCreateShip.Tools import createShip from shipHydrostatics.Tools import areas, displacement, wettedArea, moment, - floatingArea, BMT, mainFrameCoeff \ No newline at end of file + floatingArea, BMT, mainFrameCoeff +from shipCreateWeight.Tools import createWeight \ No newline at end of file diff --git a/src/Mod/Ship/WeightInstance.py b/src/Mod/Ship/WeightInstance.py index c524c85db..8a78c5d61 100644 --- a/src/Mod/Ship/WeightInstance.py +++ b/src/Mod/Ship/WeightInstance.py @@ -36,7 +36,7 @@ class Weight: def __init__(self, obj, shapes, ship): """ Transform a generic object to a ship instance. - Keyword arguments: + Position arguments: obj -- Part::FeaturePython created object which should be transformed in a weight instance. shapes -- Set of shapes which will compound the weight element. @@ -75,7 +75,7 @@ class Weight: # Add the area density property for surface elements tooltip = str(QtGui.QApplication.translate( "ship_weight", - "Area density [kg / m^3]", + "Area density [kg / m^2]", None, QtGui.QApplication.UnicodeUTF8)) obj.addProperty("App::PropertyFloat", @@ -100,7 +100,7 @@ class Weight: def onChanged(self, fp, prop): """Detects the ship data changes. - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. prop -- Modified property name. """ @@ -110,7 +110,7 @@ class Weight: def execute(self, fp): """Detects the entity recomputations. - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. """ pass @@ -118,7 +118,7 @@ class Weight: def _getPuntualMass(self, fp, shape): """Compute the mass of a puntual element. - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. shape -- Vertex shape object. """ @@ -127,7 +127,7 @@ class Weight: def _getLinearMass(self, fp, shape): """Compute the mass of a linear element. - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. shape -- Edge shape object. """ @@ -138,7 +138,7 @@ class Weight: def _getAreaMass(self, fp, shape): """Compute the mass of an area element. - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. shape -- Face shape object. """ @@ -149,7 +149,7 @@ class Weight: def _getVolumetricMass(self, fp, shape): """Compute the mass of a volumetric element. - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. shape -- Solid shape object. """ @@ -161,24 +161,27 @@ class Weight: """Compute the mass of the object, already taking into account the type of subentities. - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. + + Returned value: + Object mass """ m = Units.parseQuantity('0 kg') for s in fp.Shape.Solids: - m = m + self._getVolumetricMass(fp, s) + m += self._getVolumetricMass(fp, s) for f in fp.Shape.Faces: - m = m + self._getAreaMass(fp, f) + m += self._getAreaMass(fp, f) for e in fp.Shape.Edges: - m = m + self._getLinearMass(fp, e) + m += self._getLinearMass(fp, e) for v in fp.Shape.Vertexes: - m = m + self._getPuntualMass(fp, v) + m += self._getPuntualMass(fp, v) return m def _getPuntualMoment(self, fp, shape): """Compute the moment of a puntual element (respect to 0, 0, 0). - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. shape -- Vertex shape object. """ @@ -191,7 +194,7 @@ class Weight: def _getLinearMoment(self, fp, shape): """Compute the mass of a linear element (respect to 0, 0, 0). - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. shape -- Edge shape object. """ @@ -205,7 +208,7 @@ class Weight: def _getAreaMoment(self, fp, shape): """Compute the mass of an area element (respect to 0, 0, 0). - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. shape -- Face shape object. """ @@ -219,7 +222,7 @@ class Weight: def _getVolumetricMoment(self, fp, shape): """Compute the mass of a volumetric element (respect to 0, 0, 0). - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. shape -- Solid shape object. """ @@ -234,8 +237,11 @@ class Weight: """Compute the mass of the object, already taking into account the type of subentities. - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. + + Returned value: + List of moments toward x, y and z """ m = [Units.parseQuantity('0 kg*m'), Units.parseQuantity('0 kg*m'), @@ -262,15 +268,18 @@ class Weight: """Compute the mass of the object, already taking into account the type of subentities. - Keyword arguments: + Position arguments: fp -- Part::FeaturePython object affected. + + Returned value: + Center of Mass vector """ mass = self.getMass(fp) moment = self.getMoment(fp) cog = [] for i in range(len(moment)): cog.append(moment[i] / mass) - return cog + return Vector(cog[0].Value, cog[1].Value, cog[2].Value) class ViewProviderWeight: diff --git a/src/Mod/Ship/shipCreateWeight/TaskPanel.py b/src/Mod/Ship/shipCreateWeight/TaskPanel.py index cd8a312a5..390ce04b6 100644 --- a/src/Mod/Ship/shipCreateWeight/TaskPanel.py +++ b/src/Mod/Ship/shipCreateWeight/TaskPanel.py @@ -25,6 +25,7 @@ import FreeCAD as App import FreeCADGui as Gui import Units from PySide import QtGui, QtCore +import Tools import WeightInstance as Instance from shipUtils import Paths import shipUtils.Units as USys @@ -42,38 +43,10 @@ class TaskPanel: form.ship = self.widget(QtGui.QComboBox, "Ship") form.weight = self.widget(QtGui.QLineEdit, "Weight") - # Create the object ship = self.ships[form.ship.currentIndex()] - obj = App.ActiveDocument.addObject("Part::FeaturePython", "Weight") - weight = Instance.Weight(obj, self.shapes, ship) - Instance.ViewProviderWeight(obj.ViewObject) + density = Units.parseQuantity(Locale.fromString(form.weight.text())) - # Set the mass/density - m_unit = USys.getMassUnits() - l_unit = USys.getLengthUnits() - qty = Units.parseQuantity(Locale.fromString(form.weight.text())) - if self.elem_type == 1: - w_unit = m_unit - obj.Mass = qty.getValueAs(w_unit).Value - elif self.elem_type == 2: - w_unit = m_unit + '/' + l_unit - obj.LineDens = qty.getValueAs(w_unit).Value - elif self.elem_type == 3: - w_unit = m_unit + '/' + l_unit + '^2' - obj.AreaDens = qty.getValueAs(w_unit).Value - elif self.elem_type == 4: - w_unit = m_unit + '/' + l_unit + '^3' - obj.Dens = qty.getValueAs(w_unit).Value - - # Set it as a child of the ship - weights = ship.Weights[:] - weights.append(obj.Name) - ship.Weights = weights - ship.Proxy.cleanWeights(ship) - ship.Proxy.cleanTanks(ship) - ship.Proxy.cleanLoadConditions(ship) - - App.ActiveDocument.recompute() + Tools.createWeight(self.shapes, ship, density) return True def reject(self): diff --git a/src/Mod/Ship/shipCreateWeight/Tools.py b/src/Mod/Ship/shipCreateWeight/Tools.py new file mode 100644 index 000000000..112edb632 --- /dev/null +++ b/src/Mod/Ship/shipCreateWeight/Tools.py @@ -0,0 +1,91 @@ +#*************************************************************************** +#* * +#* Copyright (c) 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 FreeCAD as App +import Units +import WeightInstance as Instance +import shipUtils.Units as USys + + +def createWeight(shapes, ship, density): + """Create a new weight instance + + Position arguments: + shapes -- List of shapes of the weight + ship -- Ship owner + density -- Density of the object. 4 possibilities are considered here: + * Density as Mass/Volume: then the weight will be considered as a + volumetric object. Used for blocks or similar. + * Density as Mass/Area: then the weight will be considered as an area + element. Used for structural shells. + * Density as Mass/Length: then the weight will be cosidered as a linear + element. Used for linear structural reinforcements. + * Mass: Then a punctual mass will be considered. Used for complex + weights, like engines or other machines. + + Returned value: + The new weight object + + It is strongly recommended to pass just shapes matching with the provided + density, e.g. don't use volumetric shapes with a linear density value (kg/m) + + The tool will claim the new weight as a child of the ship object. Please do + not remove the partner ship object before removing this new weight before. + """ + # Create the object + obj = App.ActiveDocument.addObject("Part::FeaturePython", "Weight") + weight = Instance.Weight(obj, shapes, ship) + Instance.ViewProviderWeight(obj.ViewObject) + + # Setup the mass/density value + m_unit = "kg" + l_unit = "m" + m_qty = Units.Quantity(1, Units.Mass) + l_qty = Units.Quantity(1, Units.Length) + a_qty = Units.Quantity(1, Units.Area) + v_qty = Units.Quantity(1, Units.Volume) + if density.Unit == m_qty.Unit: + w_unit = m_unit + obj.Mass = density.getValueAs(w_unit).Value + elif density.Unit == (m_qty / l_qty).Unit: + w_unit = m_unit + '/' + l_unit + obj.LineDens = density.getValueAs(w_unit).Value + elif density.Unit == (m_qty / a_qty).Unit: + w_unit = m_unit + '/' + l_unit + '^2' + obj.AreaDens = density.getValueAs(w_unit).Value + elif density.Unit == (m_qty / v_qty).Unit: + w_unit = m_unit + '/' + l_unit + '^3' + obj.Dens = density.getValueAs(w_unit).Value + + # Set it as a child of the ship + weights = ship.Weights[:] + weights.append(obj.Name) + ship.Weights = weights + ship.Proxy.cleanWeights(ship) + ship.Proxy.cleanTanks(ship) + ship.Proxy.cleanLoadConditions(ship) + + App.ActiveDocument.recompute() + + return obj \ No newline at end of file