# ##### BEGIN GPL LICENSE BLOCK ##### # # Author: Jose Luis Cercos Pita # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ##### END GPL LICENSE BLOCK ##### import time # COIN from pivy.coin import * from pivy import coin # FreeCAD import FreeCAD,FreeCADGui from FreeCAD import Part, Base, Vector # Ship design module from shipUtils import Paths, Translator, Math class Ship: def __init__(self, obj, faces): """ Creates a new ship on active document. @param faces Ship faces (Part::Shape entities). """ self.faces = faces # Add uniqueness property to identify Ship instances obj.addProperty("App::PropertyBool","IsShip","Ship", str(Translator.translate("True if is a valid ship instance"))).IsShip=True # Add main dimensions obj.addProperty("App::PropertyLength","Length","Ship", str(Translator.translate("Ship length (Lpp) [m]"))).Length=0.0 obj.addProperty("App::PropertyLength","Beam","Ship", str(Translator.translate("Ship beam (B) [m]"))).Beam=0.0 obj.addProperty("App::PropertyLength","Draft","Ship", str(Translator.translate("Ship draft (T) [m]"))).Draft=0.0 # Add shapes obj.addProperty("Part::PropertyPartShape","Shape","Ship", str(Translator.translate("Ship surfaces"))).Shape = Part.makeShell(self.faces) obj.Proxy = self self.obj = obj def execute(self, obj): pass def discretize(self, nS, nP): """ Discretize the surface. @param nS Number of sections @param nP Number of points per section """ self.obj.addProperty("App::PropertyInteger","nSections","Ship", str(Translator.translate("Number of sections"))).nSections=nS self.obj.addProperty("App::PropertyIntegerList","nPoints","Ship", str(Translator.translate("List of number of points per sections (accumulated histogram)"))).nPoints=[0] self.obj.addProperty("App::PropertyFloatList","xSection","Ship", str(Translator.translate("List of sections x coordinate"))).xSection=[] self.obj.addProperty("App::PropertyVectorList","mSections","Ship", str(Translator.translate("List of sections points"))).mSections=[] # Get bounds shape = self.obj.Shape bbox = shape.BoundBox x0 = bbox.XMin x1 = bbox.XMax y0 = bbox.YMin y1 = bbox.YMax z0 = bbox.ZMin z1 = bbox.ZMax # Create a set of planes to perfom edges sections planes = [] dz = (z1 - z0) / (nP - 1) for j in range(0,nP): z = z0 + j*dz rX = x1 - x0 rY = y1 - 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) for i in range(0,nS): section = [] x = x0 + i*dx self.obj.xSection.append(x) percen = i*100 / (nS-1) FreeCAD.Console.PrintMessage('%d%%\n' % (percen)); # Slice the surface to get curves wires = shape.slice(Vector(1.0,0.0,0.0), x) if not wires: if (i != 0) or (i != nS-1): msg = 'Found empty section at x=%g\n' msg = Translator.translate(msg) FreeCAD.Console.PrintWarning(msg) FreeCAD.Console.PrintWarning('\tThis may happens if a bad defined (or really complex) surface has been provided.\n') FreeCAD.Console.PrintWarning('\tPlease, ensure that this section is correct, or fix surfaces and create a new ship.\n') self.obj.nPoints.append(0) # Desarrollate wires into edges list edges = [] for j in range(0,len(wires)): wire = wires[j].Edges for k in range(0,len(wire)): 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): aux = self.lineFaceSection(edges[j], planes[k]) if not aux: points.append(Vector(x,0,z0 + k*dz)) for l in range(0,len(aux)): points.append(Vector(aux[l].X, aux[l].Y, aux[l].Z)) # Sort section points at Y direction aux = [] for j in range(0,len(points)): aux.append(points[j].y) aux.sort() for j in range(0,len(points)): section.append(Vector(points[j].x, aux[j], points[j].z)) # Store points self.obj.nPoints.append(len(points)) for j in range(0,len(points)): self.obj.mSections.append(points[j]) def lineFaceSection(self,line,surface): """ Returns the point of section of a line with a face @param line Line object, that can be a curve. @param surface Surface object (must be a Part::Shape) @return Section points array, [] if line don't cut surface """ # Get initial data result = [] vertexes = line.Vertexes nVertex = len(vertexes) # Perform the cut section = line.cut(surface) # Filter all old points points = section.Vertexes nPoint = len(points) if nPoint <= nVertex: # Any valid point result for i in range(0,nPoint): disp = len(result) flag = 0 if not Math.isAprox(points[i].X,vertexes[i-disp].X,0.0001): flag = flag+1 if not Math.isAprox(points[i].Y,vertexes[i-disp].Y,0.0001): flag = flag+1 if not Math.isAprox(points[i].Z,vertexes[i-disp].Z,0.0001): flag = flag+1 if flag > 0: result.append(points[i]) return result class ViewProviderShip: def __init__(self, obj): "Set this object to the proxy object of the actual view provider" obj.Proxy = self def getIcon(self): return """ /* XPM */ static char * Ship_xpm[] = { "32 32 396 2", " c None", ". c #2C2C2C", "+ c #3A3A3A", "@ c #585857", "# c #161616", "$ c #000000", "% c #363636", "& c #333333", "* c #B3B3B3", "= c #B4B4B4", "- c #949494", "; c #565653", "> c #141414", ", c #080807", "' c #585858", ") c #878787", "! c #9F9E9F", "~ c #9F9F9E", "{ c #8F8F90", "] c #6B6B6B", "^ c #101010", "/ c #737373", "( c #4C4C4C", "_ c #B1B1B7", ": c #9090C0", "< c #A7A7B2", "[ c #87878E", "} c #4F4F52", "| c #191919", "1 c #656565", "2 c #D1D1D2", "3 c #D1D1D1", "4 c #CECECE", "5 c #CDCCCC", "6 c #CCCCCC", "7 c #CCCCCB", "8 c #CDCECD", "9 c #BDBDBD", "0 c #424242", "a c #373737", "b c #0A0A0A", "c c #241414", "d c #0E0C0C", "e c #929393", "f c #383738", "g c #9B9B9A", "h c #A0A0AF", "i c #2929E4", "j c #2525E5", "k c #3F3FD7", "l c #5B5BC8", "m c #535368", "n c #686866", "o c #C8C8C8", "p c #C8C8C7", "q c #C7C6C7", "r c #C6C6C6", "s c #C5C5C5", "t c #C4C5C5", "u c #C3C4C3", "v c #C3C3C2", "w c #BCBCBC", "x c #595959", "y c #A6A6A6", "z c #969696", "A c #0B0B0B", "B c #0D0707", "C c #894646", "D c #1C1A1A", "E c #525252", "F c #6C6D6C", "G c #A3A3A2", "H c #A3A296", "I c #8E8F98", "J c #6F6EA5", "K c #5354AF", "L c #373753", "M c #8D8D8B", "N c #C5C5C4", "O c #C2C2C2", "P c #C1C1C1", "Q c #C0C0C0", "R c #C0BFBF", "S c #BFBFBF", "T c #BEBEBE", "U c #B1B2B2", "V c #404040", "W c #ABAAAA", "X c #797979", "Y c #2A1212", "Z c #662828", "` c #3D403F", " . c #B5B5B5", ".. c #6B6A6B", "+. c #4A4A4A", "@. c #9A9A9A", "#. c #909090", "$. c #8B8B8A", "%. c #898A86", "&. c #84837F", "*. c #3D3D3C", "=. c #9E9E9E", "-. c #BFBFBE", ";. c #BDBEBD", ">. c #BBBBBB", ",. c #BABABA", "'. c #B9B9B9", "). c #B8B8B8", "!. c #999999", "~. c #BABAB9", "{. c #ABABAB", "]. c #292929", "^. c #381212", "/. c #4C1514", "(. c #535656", "_. c #717171", ":. c #919090", "<. c #818181", "[. c #4E4E4E", "}. c #4B4B4B", "|. c #B1B1B1", "1. c #B8B7B8", "2. c #B6B6B6", "3. c #B6B5B5", "4. c #B4B5B4", "5. c #B2B3B2", "6. c #5C5D5C", "7. c #AFAFAF", "8. c #ADACAC", "9. c #5B5B5B", "0. c #410C0C", "a. c #3E0707", "b. c #525555", "c. c #9C9C9C", "d. c #2D2D2D", "e. c #757575", "f. c #474747", "g. c #484848", "h. c #9F9F9F", "i. c #B3B3B4", "j. c #B2B2B2", "k. c #B0B0B0", "l. c #ADAEAD", "m. c #ADADAD", "n. c #B0B1B0", "o. c #1E1E1E", "p. c #ACABAC", "q. c #AAA9A9", "r. c #A8A8A8", "s. c #5D5D5D", "t. c #290202", "u. c #281010", "v. c #272828", "w. c #767777", "x. c #505050", "y. c #1F1F1F", "z. c #5E5E5D", "A. c #A4A5A5", "B. c #B1B2B1", "C. c #AEAEAE", "D. c #AEADAD", "E. c #ABACAC", "F. c #AAAAAA", "G. c #A9A8A8", "H. c #ABABAC", "I. c #7B7B7B", "J. c #2B2B2B", "K. c #A4A4A4", "L. c #A6A5A6", "M. c #888888", "N. c #0E0E0E", "O. c #101312", "P. c #7E8080", "Q. c #5E5E5E", "R. c #242424", "S. c #555555", "T. c #7F7F7F", "U. c #A4A3A4", "V. c #B3B3B2", "W. c #ACACAC", "X. c #A9A9A9", "Y. c #A8A7A7", "Z. c #A7A6A7", "`. c #A7A7A7", " + c #A8A8A7", ".+ c #A5A5A5", "++ c #A2A2A2", "@+ c #222122", "#+ c #7E7E7E", "$+ c #A3A3A3", "%+ c #9B9B9B", "&+ c #050505", "*+ c #6E6E6E", "=+ c #A7A7A6", "-+ c #989898", ";+ c #A5A4A4", ">+ c #A7A7A8", ",+ c #A5A6A7", "'+ c #979A99", ")+ c #818383", "!+ c #757878", "~+ c #757979", "{+ c #878A8A", "]+ c #A3A5A5", "^+ c #828282", "/+ c #A0A0A0", "(+ c #232323", "_+ c #939393", ":+ c #A5A6A5", "<+ c #A2A3A2", "[+ c #A2A1A1", "}+ c #A1A0A1", "|+ c #939292", "1+ c #636262", "2+ c #554D4D", "3+ c #634C4C", "4+ c #755555", "5+ c #936464", "6+ c #9F6868", "7+ c #9B6060", "8+ c #804A4A", "9+ c #5C3737", "0+ c #1D1616", "a+ c #A1A1A1", "b+ c #010101", "c+ c #151516", "d+ c #707070", "e+ c #9D9E9E", "f+ c #8C8D8D", "g+ c #8B8888", "h+ c #726A6A", "i+ c #6D5959", "j+ c #866261", "k+ c #C18B8B", "l+ c #D79696", "m+ c #D18C8C", "n+ c #CB8180", "o+ c #C57575", "p+ c #BF6B6A", "q+ c #BB6161", "r+ c #B95958", "s+ c #9C4544", "t+ c #2E1212", "u+ c #6F6C6C", "v+ c #A0A1A1", "w+ c #575757", "x+ c #0C0C0C", "y+ c #9C9D9D", "z+ c #7A7272", "A+ c #876F6F", "B+ c #977070", "C+ c #C28C8C", "D+ c #D59595", "E+ c #D08A8A", "F+ c #C67D7D", "G+ c #C07272", "H+ c #BC6969", "I+ c #B85F5F", "J+ c #B35656", "K+ c #B04C4C", "L+ c #AB4243", "M+ c #A63939", "N+ c #591B1B", "O+ c #6A2121", "P+ c #542323", "Q+ c #585A5A", "R+ c #191515", "S+ c #706262", "T+ c #A58080", "U+ c #B58383", "V+ c #CE8F8F", "W+ c #CD8989", "X+ c #C17372", "Y+ c #B45656", "Z+ c #AF4C4C", "`+ c #AB4242", " @ c #A73A39", ".@ c #A3302F", "+@ c #9F2626", "@@ c #8E1A1A", "#@ c #2C0808", "$@ c #91191A", "%@ c #2F0200", "&@ c #90C6FB", "*@ c #8BBFFB", "=@ c #94CBFC", "-@ c #AFEFFB", ";@ c #7DABA0", ">@ c #3C2521", ",@ c #C88484", "'@ c #C57C7D", ")@ c #C17273", "!@ c #B86060", "~@ c #AB4343", "{@ c #A73939", "]@ c #A32F2F", "^@ c #9B1C1D", "/@ c #961313", "(@ c #96090A", "_@ c #3C0202", ":@ c #4E0202", "<@ c #300000", "[@ c #3E5378", "}@ c #7EABF9", "|@ c #84B5FC", "1@ c #96CDFB", "2@ c #B2F2FA", "3@ c #C4FFFA", "4@ c #2E3FFD", "5@ c #3346FD", "6@ c #2A3AFD", "7@ c #161EFE", "8@ c #1B25FD", "9@ c #1F25B4", "0@ c #7C6196", "a@ c #AA6075", "b@ c #AC5763", "c@ c #AD5155", "d@ c #AD4645", "e@ c #A83938", "f@ c #A3302E", "g@ c #A02624", "h@ c #9B1C1B", "i@ c #971311", "j@ c #930A09", "k@ c #900300", "l@ c #900505", "m@ c #660007", "n@ c #00000D", "o@ c #200112", "p@ c #597F88", "q@ c #6E97FD", "r@ c #384CFD", "s@ c #394EFD", "t@ c #2D3EFD", "u@ c #151DFE", "v@ c #1821FE", "w@ c #3C52FD", "x@ c #6388FC", "y@ c #9CD6FB", "z@ c #D0FFFA", "A@ c #AEEEFB", "B@ c #749FFF", "C@ c #3F5DFF", "D@ c #4165FF", "E@ c #525AE3", "F@ c #6153C4", "G@ c #672D8D", "H@ c #6C1B6A", "I@ c #722164", "J@ c #75225E", "K@ c #731D57", "L@ c #701653", "M@ c #690E52", "N@ c #5F0050", "O@ c #562086", "P@ c #11108D", "Q@ c #2330BE", "R@ c #344AE1", "S@ c #4E6BFF", "T@ c #4E6BFD", "U@ c #597AFC", "V@ c #6184FC", "W@ c #7099FC", "X@ c #8BBEFB", "Y@ c #95CCFB", "Z@ c #5B7CFC", "`@ c #1C26FD", " # c #121AFE", ".# c #9ED7FB", "+# c #81B4FF", "@# c #6893FF", "## c #6997FF", "$# c #6695FF", "%# c #6390FF", "&# c #618DFF", "*# c #608DFF", "=# c #618EFF", "-# c #6391FF", ";# c #6898FF", "># c #6B9AFF", ",# c #5171ED", "'# c #90C4FF", ")# c #7EABFC", "!# c #729CFC", "~# c #6287FC", "{# c #4761FD", "]# c #070AFE", "^# c #6084FC", "/# c #9AD2FB", "(# c #A2DDFB", "_# c #8ABDFB", ":# c #2B3AFD", "<# c #A9E8FB", "[# c #B9FCFA", "}# c #BAFEFA", " ", " ", " ", " ", " ", " ", " ", " . + @ # $ $ $ $ $ ", " % & * = - ; > $ $ , ' ) ! ~ { ] & $ $ $ ", " ^ / ( = _ : < [ } | $ 1 2 3 4 5 6 7 6 8 9 0 a b ", " c d e f g h i j k l m n 4 o p q r s t u v w x y z A ", " B C D * E F G H I J K L M N O O P Q R S T 9 U V W O X $ ", " Y Z ` ...+.@.#.$.%.&.*.=.-.;.w >.>.,.'.).).!.+ ~. .{.]. ", " ^./.(.y _.f :.) <.[.^ }.|.).1.2.3. .4.* 5. .6.1 4.7.8.9. ", " 0.a.b.c./ d.e.f.| g.h.9 i.* j.|.k.7.7.l.m.n.o.@.p.q.r.s. ", " t.u.v.w.x.y.% z.A.).B.C.D.m.E.{.F.F.G.r.H.I.J.k.K.L.M.N. ", " O.P.Q.R.S.T.U.V.W.q.X.r.Y.Z.`.Y. +`..+++{.@+#+$+++%+y. ", " &+*+W.=+-+;+X.>+y .+K.K.y y ,+'+)+!+~+{+]+^+].$+/+$+J. ", " (+_+:+U.$+<+[+}+/+h.=.|+1+2+3+4+5+6+7+8+9+0+_.a+/+0 b+ ", " c+d+h.a+/+++e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+$ ", " x+f.- y+w.z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+P+Q+$ ", " R+S+T+U+V+W+F+X+H+I+Y+Z+`+ @.@+@@@#@$@%@$ ", "&@*@=@-@;@>@,@'@)@H+!@Y+K+~@{@]@+@^@/@(@_@:@<@[@}@|@1@2@3@ ", "4@5@6@7@8@9@0@a@b@c@d@e@f@g@h@i@j@k@l@m@n@o@p@q@r@s@t@u@v@w@x@y@", " z@A@B@C@D@E@F@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #", " .#+#@###$#%#&#*#=#-#;#>#,#'# )#!#~#{#]#^#/#", " (#_#:#<#", " [#}#", " ", " ", " ", " "}; """ def sections(obj): """ Returns the discretization points of sections, with the advantage that is a list of nSections lists, with the points. @param Ship object @return Sections points """ histogram = obj.nPoints[:] points = obj.mSections[:] sections = [] for i in range(0, len(histogram) - 1): sections.append([]) for j in range(histogram[i],histogram[i+1]): sections[i].append(points[j]) return sections