From 1a88ead7ab6e57e5f2e633530280c324fd8d4f0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Luis=20Cerc=C3=B3s=20Pita?= Date: Wed, 1 Feb 2012 14:02:27 +0100 Subject: [PATCH] Added multibody support. --- src/Mod/Ship/Instance.py | 37 ++++----- src/Mod/Ship/shipCreateShip/TaskPanel.py | 2 +- src/Mod/Ship/shipHydrostatics/Tools.py | 96 +++++++++++++++++++++--- 3 files changed, 105 insertions(+), 30 deletions(-) diff --git a/src/Mod/Ship/Instance.py b/src/Mod/Ship/Instance.py index 49cb37a51..64eecd5cc 100644 --- a/src/Mod/Ship/Instance.py +++ b/src/Mod/Ship/Instance.py @@ -120,7 +120,7 @@ class Ship: for j in range(0,nP): z = z0 + j*dz rX = x1 - x0 - rY = y1 - y0 + rY = max(y1 - y0, abs(y1), abs(y0)) planes.append(Part.makePlane(4*rX,4*rY,Base.Vector(-2*rX,-2*rY,z),Base.Vector(0,0,1))) # Division are performed at x axis dx = (x1 - x0) / (nS - 1.0) @@ -149,23 +149,23 @@ class Ship: edges.append(wire[k]) # Slice curves to get points (Length based) points = [] - for j in range(0,len(edges)): - for k in range(0,nP): + for k in range(0,nP): + planePoints = [] + for j in range(0,len(edges)): aux = self.lineFaceSection(edges[j], planes[k]) - if not aux: # No section - points.append(Vector(x,0,z0 + k*dz)) - if len(aux) == 1: # Single point section - points.append(Vector(aux[0].X, aux[0].Y, aux[0].Z)) - else: # Several points, so ship has more than one body - # Get Y coordinates - auxY = [] - for l in range(0,len(aux)): - auxY.append(aux[l].Y) - # Sort them - auxY.sort() - # And store - for l in range(0,len(aux)): - points.append(Vector(aux[l].X, auxY[l], aux[l].Z)) + for l in range(0,len(aux)): + planePoints.append(Vector(aux[l].X, aux[l].Y, aux[l].Z)) + if not planePoints: # No section found, symmetry plane point will used + planePoints.append(Vector(x,0,z0 + k*dz)) + # Get Y coordinates + auxY = [] + for l in range(0,len(planePoints)): + auxY.append(planePoints[l].y) + # Sort them + auxY.sort() + # And store + for l in range(0,len(planePoints)): + points.append(Vector(planePoints[l].x, auxY[l], planePoints[l].z)) # Store points section = points[:] nPoints.append(len(section)) @@ -177,6 +177,9 @@ class Ship: self.obj.nPoints = nPoints[:] self.obj.xSection = xSection[:] self.obj.mSections = mSections[:] + msg = '%d Discretization points performed\n' % (len(mSections)) + msg = Translator.translate(msg) + FreeCAD.Console.PrintMessage(msg) class ViewProviderShip: def __init__(self, obj): diff --git a/src/Mod/Ship/shipCreateShip/TaskPanel.py b/src/Mod/Ship/shipCreateShip/TaskPanel.py index c323957a8..7fab02097 100644 --- a/src/Mod/Ship/shipCreateShip/TaskPanel.py +++ b/src/Mod/Ship/shipCreateShip/TaskPanel.py @@ -159,7 +159,7 @@ class TaskPanel: if maxZ < bbox.ZMax: maxZ = bbox.ZMax bounds[0] = maxX - minX - bounds[1] = maxY - minY + bounds[1] = max(maxY - minY, abs(maxY), abs(minY)) bounds[2] = maxZ - minZ # Set UI fields self.form.length.setMaximum(bounds[0]) diff --git a/src/Mod/Ship/shipHydrostatics/Tools.py b/src/Mod/Ship/shipHydrostatics/Tools.py index 32ce25dc0..3792708c9 100644 --- a/src/Mod/Ship/shipHydrostatics/Tools.py +++ b/src/Mod/Ship/shipHydrostatics/Tools.py @@ -27,6 +27,7 @@ import FreeCAD as App import FreeCADGui as Gui # Module import Instance +from shipUtils import Math def Displacement(ship, draft, trim): """ Calculate ship displacement. @@ -75,20 +76,91 @@ def Displacement(ship, draft, trim): z0 = section[n-1].z y1 = section[n].y z1 = section[n].z - factor = (Z - z0) / (z1 - z0) - y = y0 + factor*(y1 - y0) - points.append(App.Base.Vector(x,y,Z)) + if (Z > z0) and not (Math.isAprox(Z,z0)): + factor = (Z - z0) / (z1 - z0) + y = y0 + factor*(y1 - y0) + points.append(App.Base.Vector(x,y,Z)) + # Convert into array with n elements (Number of points by sections) + # with m elements into them (Number of points with the same height, + # typical of multibody) + section = [] + nPoints = 0 + j = 0 + while j < len(points)-1: + section.append([points[j]]) + k = j+1 + while(Math.isAprox(points[j].z, points[k].z)): + section[nPoints].append(points[k]) + k = k+1 + nPoints = nPoints + 1 + j = k # Integrate area area = 0.0 - for j in range(0, len(points)-1): - y0 = abs(points[j].y) - z0 = points[j].z - y1 = abs(points[j+1].y) - z1 = points[j+1].z - y = 0.5 * (y0 + y1) - dz = z1 - z0 - area = area + 2.0*y*dz # 2x because only half ship is represented - areas.append(area) + for j in range(0, len(section)-1): + for k in range(0, min(len(section[j])-1, len(section[j+1])-1)): + # y11,z11 ------- y01,z01 + # | | + # | | + # | | + # y10,z10 ------- y00,z00 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = 0.5*((y00 - y10) + (y01 - y11)) + dz = 0.5*((z01 - z00) + (z11 - z10)) + area = area + dy*dz + if(len(section[j]) < len(section[j+1])): + # y01,z01 ------- y11,z11 + # | __/ + # | __/ + # | / + # y00,z00 + k = len(section[j])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + y11 = abs(section[j+1][k+1].y) + z11 = section[j+1][k+1].z + dy = y01 - y11 + dz = z01 - z00 + area = area + 0.5*dy*dz + elif(len(section[j]) > len(section[j+1])): + # y01,z01 + # | \__ + # | \__ + # | \ + # y00,z00 ------- y10,z10 + k = len(section[j+1])-1 + y00 = abs(section[j][k].y) + z00 = section[j][k].z + y10 = abs(section[j][k+1].y) + z10 = section[j][k+1].z + y01 = abs(section[j+1][k].y) + z01 = section[j+1][k].z + dy = y00 - y10 + dz = z01 - z00 + area = area + 0.5*dy*dz + elif(len(section[j]) == 1): + # y1,z1 ------- + # | + # | + # | + # y0,z0 ------- + k = 0 + y0 = abs(section[j][k].y) + z0 = section[j][k].z + y1 = abs(section[j+1][k].y) + z1 = section[j+1][k].z + dy = 0.5 * (y0 + y1) + dz = z1 - z0 + area = area + dy*dz + areas.append(2.0*area) # 2x because only half ship is represented # Add volume & moment if proceed if i > 0: dx = xCoord[i] - xCoord[i-1]