| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | """@package importAirfoilDAT |
| | Airfoil (.dat) file importer |
| | |
| | This module provides support for importing airfoil .dat files. |
| | """ |
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | __title__ = "FreeCAD Draft Workbench - Airfoil data importer" |
| | __author__ = "Heiko Jakob <heiko.jakob@gediegos.de>" |
| | __url__ = "https://www.freecad.org" |
| |
|
| | import re |
| | import os |
| | import FreeCAD |
| | import Draft |
| | import Part |
| | from FreeCAD import Vector |
| | from FreeCAD import Console as FCC |
| | from draftutils.utils import pyopen |
| |
|
| | if FreeCAD.GuiUp: |
| | from draftutils.translate import translate |
| | else: |
| |
|
| | def translate(context, txt): |
| | return txt |
| |
|
| |
|
| | useDraftWire = True |
| |
|
| |
|
| | def open(filename): |
| | """Open filename and parse. |
| | |
| | Parameters |
| | ---------- |
| | filename : str |
| | The path to the filename to be opened. |
| | |
| | Returns |
| | ------- |
| | App::Document |
| | The new FreeCAD document object created, with the parsed information. |
| | """ |
| | docname = os.path.splitext(os.path.basename(filename))[0] |
| | doc = FreeCAD.newDocument(docname) |
| | doc.Label = docname |
| | process(filename) |
| | doc.recompute() |
| |
|
| |
|
| | def insert(filename, docname): |
| | """Get an active document and parse. |
| | |
| | If no document exists, it is created. |
| | |
| | Parameters |
| | ---------- |
| | filename : str |
| | The path to the filename to be opened. |
| | docname : str |
| | The name of the active App::Document if one exists, or |
| | of the new one created. |
| | |
| | Returns |
| | ------- |
| | App::Document |
| | The active FreeCAD document, or the document created if none exists, |
| | with the parsed information. |
| | """ |
| | groupname = os.path.splitext(os.path.basename(filename))[0] |
| | try: |
| | doc = FreeCAD.getDocument(docname) |
| | except NameError: |
| | doc = FreeCAD.newDocument(docname) |
| | obj = process(filename) |
| | if obj is not None: |
| | importgroup = doc.addObject("App::DocumentObjectGroup", groupname) |
| | importgroup.Group = [obj] |
| | doc.recompute() |
| |
|
| |
|
| | def process(filename): |
| | """Process the filename and create a Draft Wire from the data. |
| | |
| | The common airfoil dat format has many flavors. |
| | This code should work with almost every dialect. |
| | |
| | Parameters |
| | ---------- |
| | filename : str |
| | The path to the filename to be opened. |
| | |
| | Returns |
| | ------- |
| | Part::Feature or None. |
| | The created object or None if the file contains fewer |
| | than 3 points. |
| | """ |
| | |
| | xval = r"(?P<xval>\-?\s*\d*\.*\d*([Ee]\-?\d+)?)" |
| | yval = r"(?P<yval>\-?\s*\d*\.*\d*([Ee]\-?\d+)?)" |
| | _regex = r"^\s*" + xval + r"\,?\s*" + yval + r"\s*$" |
| |
|
| | regex = re.compile(_regex) |
| | afile = pyopen(filename, "r") |
| | |
| | airfoilname = afile.readline().strip() |
| |
|
| | coords = [] |
| | |
| | |
| |
|
| | |
| | for lin in afile: |
| | curdat = regex.match(lin) |
| | if curdat is not None and curdat.group("xval") and curdat.group("yval"): |
| | x = float(curdat.group("xval")) |
| | y = float(curdat.group("yval")) |
| |
|
| | |
| | |
| | |
| | |
| | if x < 2 and y < 2: |
| | |
| | coords.append(Vector(x, y, 0)) |
| |
|
| | afile.close() |
| |
|
| | if len(coords) < 3: |
| | FCC.PrintError(translate("ImportAirfoilDAT", "Did not find enough coordinates") + "\n") |
| | return None |
| |
|
| | |
| | |
| | |
| | if coords[0:-1].count(coords[0]) > 1: |
| | flippoint = coords.index(coords[0], 1) |
| | upper = coords[0:flippoint] |
| | lower = coords[flippoint + 1 :] |
| | lower.reverse() |
| | for i in lower: |
| | upper.append(i) |
| | coords = upper |
| |
|
| | |
| | if useDraftWire: |
| | obj = Draft.make_wire(coords, True) |
| | |
| | else: |
| | |
| | lines = [] |
| | first_v = None |
| | last_v = None |
| | for v in coords: |
| | if first_v is None: |
| | first_v = v |
| |
|
| | |
| | if (last_v is not None) and (last_v != v): |
| | lines.append(Part.makeLine(last_v, v)) |
| |
|
| | |
| | last_v = v |
| |
|
| | |
| | if last_v != first_v: |
| | lines.append(Part.makeLine(last_v, first_v)) |
| |
|
| | wire = Part.Wire(lines) |
| | face = Part.Face(wire) |
| | obj = FreeCAD.ActiveDocument.addObject("Part::Feature", airfoilname) |
| | obj.Shape = face |
| |
|
| | return obj |
| |
|