importAirfoilDAT.py

Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 #***************************************************************************
00003 #*                                                                         *
00004 #*   Copyright (c) 2010 Heiko Jakob <heiko.jakob@gediegos.de>              *
00005 #*                                                                         *
00006 #*   This program is free software; you can redistribute it and/or modify  *
00007 #*   it under the terms of the GNU General Public License (GPL)            *
00008 #*   as published by the Free Software Foundation; either version 2 of     *
00009 #*   the License, or (at your option) any later version.                   *
00010 #*   for detail see the LICENCE text file.                                 *
00011 #*                                                                         *
00012 #*   This program is distributed in the hope that it will be useful,       *
00013 #*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014 #*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015 #*   GNU Library General Public License for more details.                  *
00016 #*                                                                         *
00017 #*   You should have received a copy of the GNU Library General Public     *
00018 #*   License along with this program; if not, write to the Free Software   *
00019 #*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
00020 #*   USA                                                                   *
00021 #*                                                                         *
00022 #***************************************************************************
00023 
00024 __title__="FreeCAD Draft Workbench - Airfoil data importer"
00025 __author__ = "Heiko Jakob <heiko.jakob@gediegos.de>"
00026 
00027 import re, FreeCAD, FreeCADGui, Part, cProfile, os, string
00028 from FreeCAD import Vector, Base
00029 from Draft import *
00030 
00031 pythonopen = open
00032 useDraftWire = True
00033 
00034 def decodeName(name):
00035         "decodes encoded strings"
00036         try:
00037                 decodedName = (name.decode("utf8"))
00038         except UnicodeDecodeError:
00039                 try:
00040                         decodedName = (name.decode("latin1"))
00041                 except UnicodeDecodeError:
00042                         print "AirfoilDAT: error: couldn't determine character encoding"
00043                         decodedName = name
00044         return decodedName
00045 
00046 def open(filename):
00047         "called when freecad opens a file"
00048         docname = os.path.splitext(os.path.basename(filename))[0]
00049         doc = FreeCAD.newDocument(docname)
00050         doc.Label = decodeName(docname[:-4])
00051         process(doc,filename)
00052 
00053 def insert(filename,docname):
00054         "called when freecad imports a file"
00055         groupname = os.path.splitext(os.path.basename(filename))[0]
00056         try:
00057                 doc=FreeCAD.getDocument(docname)
00058         except:
00059                 doc=FreeCAD.newDocument(docname)
00060         importgroup = doc.addObject("App::DocumentObjectGroup",groupname)
00061         importgroup.Label = decodeName(groupname)
00062         process(doc,filename)
00063 
00064 def process(doc,filename):    
00065         # The common airfoil dat format has many flavors
00066         # This code should work with almost every dialect
00067     
00068         # Regex to identify data rows and throw away unused metadata
00069         expre = r"^\s*(?P<xval>\-*\d*?\.\d\d+)\s+(?P<yval>\-*\d*?\.\d+)\s*$"
00070         afile = pythonopen(filename,'r')
00071         # read the airfoil name which is always at the first line
00072         airfoilname = afile.readline().strip()
00073     
00074         upper=[]
00075         lower=[]
00076         upside=True
00077         last_x=None
00078     
00079 
00080         # Collect the data for the upper and the lower side seperately if possible     
00081         for lin in afile:
00082                 curdat = re.match(expre,lin)
00083                 if curdat != None:         
00084                         x = float(curdat.group("xval"))
00085                         y = float(curdat.group("yval"))
00086 
00087                         if last_x == None:
00088                                 last_x=x
00089 
00090                         # Separation between the sides is done in many different ways.
00091                         # The only way to safely detect the swap is when x is getting smaller
00092                         if x < last_x:
00093                                 # The swap
00094                                 upside=False        
00095                                 # Not needed because this will happen anyhow at the end of the loop last_x=x 
00096 
00097                         # the normal processing
00098                         if upside:
00099                                 upper.append(Vector(x,y,0))
00100                         else:
00101                                 lower.append(Vector(x,y,0))              
00102                         last_x=x
00103                 # End of if curdat != None
00104         # End of for lin in file
00105         afile.close()
00106   
00107         # reverse the lower side and append it to the upper to 
00108         # make the complete data be oriented clockwise
00109         lower.reverse() 
00110         for i in lower:
00111                 upper.append(i)
00112         # End of for i in lower
00113        
00114         # do we use the parametric Draft Wire?
00115         if useDraftWire:
00116                 face = makeWire ( upper, True, None, True )
00117         else:
00118                 # alternate solution, uses common Part Faces
00119                 lines = []
00120                 first_v = None
00121                 last_v = None
00122                 for v in upper:
00123                         if first_v == None:
00124                                 first_v = v
00125                         # End of if first_v == None
00126     
00127                         # Line between v and last_v if they're not equal
00128                         if (last_v != None) and (last_v != v):
00129                                 lines.append(Part.makeLine(last_v, v))       
00130                         # End of if (last_v != None) and (last_v != v)
00131                         # The new last_v
00132                         last_v = v     
00133                 # End of for v in upper
00134                 # close the wire if needed
00135                 if last_v != first_v:
00136                         lines.append(Part.makeLine(last_v, first_v))
00137                 # End of if last_v != first_v
00138   
00139                 wire = Part.Wire(lines)
00140                 face = Part.Face(wire)  
00141                 Part.show(face)
00142   
00143         doc.recompute()

Generated on Wed Nov 23 19:00:18 2011 for FreeCAD by  doxygen 1.6.1