]> git.mxchange.org Git - flightgear.git/blobdiff - utils/Modeller/yasim_import.py
Merge branch 'next' of git://gitorious.org/fg/flightgear into next
[flightgear.git] / utils / Modeller / yasim_import.py
index 69b370dd66dcfbae009a9f714aa536c1d369a470..6a862cbd6008254610d10cb76b3aeaf5c6c08d3d 100644 (file)
@@ -9,7 +9,7 @@
 
 __author__ = "Melchior FRANZ < mfranz # aon : at >"
 __url__ = ["http://www.flightgear.org/", "http://cvs.flightgear.org/viewvc/source/utils/Modeller/yasim_import.py"]
 
 __author__ = "Melchior FRANZ < mfranz # aon : at >"
 __url__ = ["http://www.flightgear.org/", "http://cvs.flightgear.org/viewvc/source/utils/Modeller/yasim_import.py"]
-__version__ = "0.1"
+__version__ = "0.2"
 __bpydoc__ = """\
 yasim_import.py loads and visualizes a YASim FDM geometry
 =========================================================
 __bpydoc__ = """\
 yasim_import.py loads and visualizes a YASim FDM geometry
 =========================================================
@@ -20,7 +20,7 @@ It is recommended to load the model superimposed over a greyed out and immutable
   (1) load or import aircraft model (menu -> "File" -> "Import" -> "AC3D (.ac) ...")
   (2) create new *empty* scene (menu -> arrow button left of "SCE:scene1" combobox -> "ADD NEW" -> "empty")
   (3) rename scene to yasim (not required)
   (1) load or import aircraft model (menu -> "File" -> "Import" -> "AC3D (.ac) ...")
   (2) create new *empty* scene (menu -> arrow button left of "SCE:scene1" combobox -> "ADD NEW" -> "empty")
   (3) rename scene to yasim (not required)
-  (4) link to scene1 (F10 -> "Output" tab -> arrow button left of text entry "No Set Scene" -> "scene1")
+  (4) link to scene1 (F10 -> "Output" tab in "Buttons Window" -> arrow button left of text entry "No Set Scene" -> "scene1")
   (5) now load the YASim config file (menu -> "File" -> "Import" -> "YASim (.xml) ...")
 
 This is good enough for simple checks. But if you are working on the YASim configuration, then you need a
   (5) now load the YASim config file (menu -> "File" -> "Import" -> "YASim (.xml) ...")
 
 This is good enough for simple checks. But if you are working on the YASim configuration, then you need a
@@ -58,9 +58,9 @@ Possible variables are:
 
 Of course, absolute FDM coordinates can then no longer directly be read from Blender's 3D view.
 The cursor coordinates display in the script area, however, shows the coordinates in YASim space.
 
 Of course, absolute FDM coordinates can then no longer directly be read from Blender's 3D view.
 The cursor coordinates display in the script area, however, shows the coordinates in YASim space.
-Note that object names don't contain XML indices but element numbers. YASim_hstab#2 is the third
-hstab in the whole file, not necessarily in its parent XML group. A floating point part in the
-object name (e.g. YASim_hstab#2.004) only means that the geometry has been reloaded that often.
+Note that object names don't contain XML indices but element numbers. YASim_flap0#2 is the third
+flap0 in the whole file, not necessarily in its parent XML group. A floating point part in the
+object name (e.g. YASim_flap0#2.004) only means that the geometry has been reloaded that often.
 It's an unavoidable consequence of how Blender deals with meshes.
 
 
 It's an unavoidable consequence of how Blender deals with meshes.
 
 
@@ -68,22 +68,40 @@ Elements are displayed as follows:
 
   cockpit                             -> monkey head
   fuselage                            -> blue "tube" (with only 12 sides for less clutter); center at "a"
 
   cockpit                             -> monkey head
   fuselage                            -> blue "tube" (with only 12 sides for less clutter); center at "a"
-  vstab                               -> red with yellow flaps
-  wing/mstab/hstab                    -> green with yellow flaps/spoilers/slats (always 20 cm deep);
-                                         symmetric surfaces are only displayed on the left side
+  vstab                               -> red with yellow control surfaces (flap0, flap1, slat, spoiler)
+  wing/mstab/hstab                    -> green with yellow control surfaces (which are always 20 cm deep);
+                                         symmetric surfaces are only displayed on the left side, unless
+                                         the "Mirror" button is active
   thrusters (jet/propeller/thruster)  -> dashed line from center to actionpt;
                                          arrow from actionpt along thrust vector (always 1 m long);
                                          propeller circle
   thrusters (jet/propeller/thruster)  -> dashed line from center to actionpt;
                                          arrow from actionpt along thrust vector (always 1 m long);
                                          propeller circle
-  rotor                               -> radius and rel_len_blade_start circle, direction arrow,
-                                         normal and forward vector, one blade at phi0
+  rotor                               -> radius and rel_len_blade_start circle, normal and forward vector,
+                                         one blade at phi0 with direction arrow near blade tip
   gear                                -> contact point and compression vector (no arrow head)
   gear                                -> contact point and compression vector (no arrow head)
-  tank                                -> cube (10 cm side length)
-  weight                              -> inverted cone
-  ballast                             -> cylinder
-  hitch                               -> circle (10 cm diameter)
+  tank                                -> magenta cube (10 cm side length)
+  weight                              -> inverted cyan cone
+  ballast                             -> yellow cylinder
+  hitch                               -> hexagon (10 cm diameter)
   hook                                -> dashed line for up angle, T-line for down angle
   launchbar                           -> dashed line for up angles, T-line for down angles
   hook                                -> dashed line for up angle, T-line for down angle
   launchbar                           -> dashed line for up angles, T-line for down angles
+                                         (launchbar and holdback each)
 
 
+
+The Mirror button complements symmetrical surfaces (wing/hstab/mstab) and control surfaces
+(flap0/flap1/slat/spoiler). This is useful for asymmetrical aircraft, but has the disadvantage
+that it moves the surfaces' object centers from their usual place, yasim's [x, y, z] value,
+to [0, 0, 0]. Turning mirroring off restores the object center.
+
+
+
+Environment variable BLENDER_YASIM_IMPORT can be set to a space-separated list of options:
+
+  $ BLENDER_YASIM_IMPORT="mirror verbose"  blender
+
+whereby:
+
+  verbose  ... enables verbose logs
+  mirror   ... enables mirroring of symmetric surfaces
 """
 
 
 """
 
 
@@ -106,11 +124,12 @@ Elements are displayed as follows:
 #--------------------------------------------------------------------------------
 
 
 #--------------------------------------------------------------------------------
 
 
-import Blender, BPyMessages, string, math
+import Blender, BPyMessages, string, math, os
 from Blender.Mathutils import *
 from xml.sax import handler, make_parser
 
 
 from Blender.Mathutils import *
 from xml.sax import handler, make_parser
 
 
+CONFIG = string.split(os.getenv("BLENDER_YASIM_IMPORT") or "")
 YASIM_MATRIX = Matrix([-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
 ORIGIN = Vector(0, 0, 0)
 X = Vector(1, 0, 0)
 YASIM_MATRIX = Matrix([-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1])
 ORIGIN = Vector(0, 0, 0)
 X = Vector(1, 0, 0)
@@ -119,33 +138,35 @@ Z = Vector(0, 0, 1)
 DEG2RAD = math.pi / 180
 RAD2DEG = 180 / math.pi
 
 DEG2RAD = math.pi / 180
 RAD2DEG = 180 / math.pi
 
+NO_EVENT = 0
+RELOAD_BUTTON = 1
+CURSOR_BUTTON = 2
+MIRROR_BUTTON = 3
+
+
 
 class Global:
 
 class Global:
+       verbose = "verbose" in CONFIG
        path = ""
        matrix = None
        path = ""
        matrix = None
+       data = None
        cursor = ORIGIN
        last_cursor = Vector(Blender.Window.GetCursorPos())
        cursor = ORIGIN
        last_cursor = Vector(Blender.Window.GetCursorPos())
+       mirror_button = Blender.Draw.Create("mirror" in CONFIG)
+
 
 
 class Abort(Exception):
 
 
 class Abort(Exception):
-       def __init__(self, msg):
+       def __init__(self, msg, term = None):
                self.msg = msg
                self.msg = msg
+               self.term = term
 
 
 
 
-def log(msg):
-       #print(msg)     # uncomment to get verbose log messages
-       pass
-
-
-def error(msg):
-       print(("\033[31;1mError: %s\033[m" % msg))
-       Blender.Draw.PupMenu("Error%t|" + msg)
 
 
+def log(msg):
+       if Global.verbose:
+               print(msg)
 
 
-def getfloat(attrs, key, default):
-       if attrs.has_key(key):
-               return float(attrs[key])
-       return default
 
 
 def draw_dashed_line(mesh, start, end):
 
 
 def draw_dashed_line(mesh, start, end):
@@ -154,13 +175,14 @@ def draw_dashed_line(mesh, start, end):
        n = len(mesh.verts)
        for i in range(int(1 + 0.5 * (end - start).length / w)):
                a = start + 2 * i * step
        n = len(mesh.verts)
        for i in range(int(1 + 0.5 * (end - start).length / w)):
                a = start + 2 * i * step
-               b = start + (2 * i + 1) * step
+               b = a + step
                if (b - end).length < step.length:
                        b = end
                mesh.verts.extend([a, b])
                mesh.edges.extend([n + 2 * i, n + 2 * i + 1])
 
 
                if (b - end).length < step.length:
                        b = end
                mesh.verts.extend([a, b])
                mesh.edges.extend([n + 2 * i, n + 2 * i + 1])
 
 
+
 def draw_arrow(mesh, start, end):
        v = end - start
        m = v.toTrackQuat('x', 'z').toMatrix().resize4x4() * TranslationMatrix(start)
 def draw_arrow(mesh, start, end):
        v = end - start
        m = v.toTrackQuat('x', 'z').toMatrix().resize4x4() * TranslationMatrix(start)
@@ -171,6 +193,7 @@ def draw_arrow(mesh, start, end):
        mesh.edges.extend([[n, n + 1], [n + 1, n + 2], [n + 1, n + 3], [n + 4, n + 5]])
 
 
        mesh.edges.extend([[n, n + 1], [n + 1, n + 2], [n + 1, n + 3], [n + 4, n + 5]])
 
 
+
 def draw_circle(mesh, numpoints, radius, matrix):
        n = len(mesh.verts)
        for i in range(numpoints):
 def draw_circle(mesh, numpoints, radius, matrix):
        n = len(mesh.verts)
        for i in range(numpoints):
@@ -182,6 +205,7 @@ def draw_circle(mesh, numpoints, radius, matrix):
                mesh.edges.extend([[n + i, n + i1]])
 
 
                mesh.edges.extend([[n + i, n + i1]])
 
 
+
 class Item:
        scene = Blender.Scene.GetCurrent()
 
 class Item:
        scene = Blender.Scene.GetCurrent()
 
@@ -190,13 +214,21 @@ class Item:
                for f in mesh.faces:
                        f.mode |= Blender.Mesh.FaceModes.TWOSIDE | Blender.Mesh.FaceModes.OBCOL
 
                for f in mesh.faces:
                        f.mode |= Blender.Mesh.FaceModes.TWOSIDE | Blender.Mesh.FaceModes.OBCOL
 
-       def set_color(self, mesh, name, color):
-               mat = Blender.Material.New(name)
+       def set_color(self, obj, color):
+               mat = Blender.Material.New()
                mat.setRGBCol(color[0], color[1], color[2])
                mat.setAlpha(color[3])
                mat.mode |= Blender.Material.Modes.ZTRANSP | Blender.Material.Modes.TRANSPSHADOW
                mat.setRGBCol(color[0], color[1], color[2])
                mat.setAlpha(color[3])
                mat.mode |= Blender.Material.Modes.ZTRANSP | Blender.Material.Modes.TRANSPSHADOW
+               obj.transp = True
+
+               mesh = obj.getData(mesh = True)
                mesh.materials += [mat]
 
                mesh.materials += [mat]
 
+               for f in mesh.faces:
+                       f.smooth = True
+               mesh.calcNormals()
+
+
 
 class Cockpit(Item):
        def __init__(self, center):
 
 class Cockpit(Item):
        def __init__(self, center):
@@ -206,12 +238,15 @@ class Cockpit(Item):
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
 
 
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
 
 
+
 class Tank(Item):
        def __init__(self, name, center):
                mesh = Blender.Mesh.Primitives.Cube()
                mesh.transform(ScaleMatrix(0.05, 4))
                obj = self.scene.objects.new(mesh, name)
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
 class Tank(Item):
        def __init__(self, name, center):
                mesh = Blender.Mesh.Primitives.Cube()
                mesh.transform(ScaleMatrix(0.05, 4))
                obj = self.scene.objects.new(mesh, name)
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
+               self.set_color(obj, [1, 0, 1, 0.5])
+
 
 
 class Ballast(Item):
 
 
 class Ballast(Item):
@@ -220,6 +255,8 @@ class Ballast(Item):
                mesh.transform(ScaleMatrix(0.05, 4))
                obj = self.scene.objects.new(mesh, name)
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
                mesh.transform(ScaleMatrix(0.05, 4))
                obj = self.scene.objects.new(mesh, name)
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
+               self.set_color(obj, [1, 1, 0, 0.5])
+
 
 
 class Weight(Item):
 
 
 class Weight(Item):
@@ -228,6 +265,8 @@ class Weight(Item):
                mesh.transform(ScaleMatrix(0.05, 4))
                obj = self.scene.objects.new(mesh, name)
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
                mesh.transform(ScaleMatrix(0.05, 4))
                obj = self.scene.objects.new(mesh, name)
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
+               self.set_color(obj, [0, 1, 1, 0.5])
+
 
 
 class Gear(Item):
 
 
 class Gear(Item):
@@ -239,6 +278,7 @@ class Gear(Item):
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
 
 
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
 
 
+
 class Hook(Item):
        def __init__(self, name, center, length, up_angle, dn_angle):
                mesh = Blender.Mesh.New()
 class Hook(Item):
        def __init__(self, name, center, length, up_angle, dn_angle):
                mesh = Blender.Mesh.New()
@@ -252,6 +292,7 @@ class Hook(Item):
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
 
 
                obj.setMatrix(TranslationMatrix(center) * Global.matrix)
 
 
+
 class Launchbar(Item):
        def __init__(self, name, lb, lb_length, hb, hb_length, up_angle, dn_angle):
                mesh = Blender.Mesh.New()
 class Launchbar(Item):
        def __init__(self, name, lb, lb_length, hb, hb_length, up_angle, dn_angle):
                mesh = Blender.Mesh.New()
@@ -266,13 +307,15 @@ class Launchbar(Item):
                obj.setMatrix(TranslationMatrix(lb) * Global.matrix)
 
 
                obj.setMatrix(TranslationMatrix(lb) * Global.matrix)
 
 
+
 class Hitch(Item):
        def __init__(self, name, center):
 class Hitch(Item):
        def __init__(self, name, center):
-               mesh = Blender.Mesh.Primitives.Circle(8, 0.1)
+               mesh = Blender.Mesh.Primitives.Circle(6, 0.1)
                obj = self.scene.objects.new(mesh, name)
                obj.setMatrix(RotationMatrix(90, 4, "x") * TranslationMatrix(center) * Global.matrix)
 
 
                obj = self.scene.objects.new(mesh, name)
                obj.setMatrix(RotationMatrix(90, 4, "x") * TranslationMatrix(center) * Global.matrix)
 
 
+
 class Thrust:
        def set_actionpt(self, p):
                self.actionpt = p
 class Thrust:
        def set_actionpt(self, p):
                self.actionpt = p
@@ -281,6 +324,7 @@ class Thrust:
                self.thrustvector = d
 
 
                self.thrustvector = d
 
 
+
 class Thruster(Thrust, Item):
        def __init__(self, name, center, thrustvector):
                (self.name, self.center, self.actionpt, self.thrustvector) = (name, center, center, thrustvector)
 class Thruster(Thrust, Item):
        def __init__(self, name, center, thrustvector):
                (self.name, self.center, self.actionpt, self.thrustvector) = (name, center, center, thrustvector)
@@ -294,6 +338,7 @@ class Thruster(Thrust, Item):
                obj.setMatrix(TranslationMatrix(self.center) * Global.matrix)
 
 
                obj.setMatrix(TranslationMatrix(self.center) * Global.matrix)
 
 
+
 class Propeller(Thrust, Item):
        def __init__(self, name, center, radius):
                (self.name, self.center, self.radius, self.actionpt, self.thrustvector) = (name, center, radius, center, -X)
 class Propeller(Thrust, Item):
        def __init__(self, name, center, radius):
                (self.name, self.center, self.radius, self.actionpt, self.thrustvector) = (name, center, radius, center, -X)
@@ -313,6 +358,7 @@ class Propeller(Thrust, Item):
                obj.setMatrix(TranslationMatrix(self.center) * Global.matrix)
 
 
                obj.setMatrix(TranslationMatrix(self.center) * Global.matrix)
 
 
+
 class Jet(Thrust, Item):
        def __init__(self, name, center, rotate):
                (self.name, self.center, self.actionpt) = (name, center, center)
 class Jet(Thrust, Item):
        def __init__(self, name, center, rotate):
                (self.name, self.center, self.actionpt) = (name, center, center)
@@ -327,6 +373,7 @@ class Jet(Thrust, Item):
                obj.setMatrix(TranslationMatrix(self.center) * Global.matrix)
 
 
                obj.setMatrix(TranslationMatrix(self.center) * Global.matrix)
 
 
+
 class Fuselage(Item):
        def __init__(self, name, a, b, width, taper, midpoint):
                numvert = 12
 class Fuselage(Item):
        def __init__(self, name, a, b, width, taper, midpoint):
                numvert = 12
@@ -351,10 +398,10 @@ class Fuselage(Item):
                        mesh.faces.extend([[i + numvert, i1 + numvert, i1 + 2 * numvert, i + 2 * numvert]])
 
                mesh.verts.extend([ORIGIN, length * X])
                        mesh.faces.extend([[i + numvert, i1 + numvert, i1 + 2 * numvert, i + 2 * numvert]])
 
                mesh.verts.extend([ORIGIN, length * X])
-               self.set_color(mesh, name + "mat", [0, 0, 0.5, 0.4])
                obj = self.scene.objects.new(mesh, name)
                obj = self.scene.objects.new(mesh, name)
-               obj.transp = True
                obj.setMatrix(axis.toTrackQuat('x', 'y').toMatrix().resize4x4() * TranslationMatrix(a) * Global.matrix)
                obj.setMatrix(axis.toTrackQuat('x', 'y').toMatrix().resize4x4() * TranslationMatrix(a) * Global.matrix)
+               self.set_color(obj, [0, 0, 0.5, 0.4])
+
 
 
 class Rotor(Item):
 
 
 class Rotor(Item):
@@ -375,17 +422,18 @@ class Rotor(Item):
                draw_arrow(mesh, ORIGIN, up * invert)
                draw_arrow(mesh, ORIGIN, fwd * invert)
                b += 0.1 * X + direction * chord * Y
                draw_arrow(mesh, ORIGIN, up * invert)
                draw_arrow(mesh, ORIGIN, fwd * invert)
                b += 0.1 * X + direction * chord * Y
-               draw_arrow(mesh, b, b + 0.5 * radius * direction * Y)
+               draw_arrow(mesh, b, b + min(0.5 * radius, 1) * direction * Y)
                obj = self.scene.objects.new(mesh, name)
                obj.setMatrix(matrix * TranslationMatrix(center) * Global.matrix)
 
 
                obj = self.scene.objects.new(mesh, name)
                obj.setMatrix(matrix * TranslationMatrix(center) * Global.matrix)
 
 
+
 class Wing(Item):
        def __init__(self, name, root, length, chord, incidence, twist, taper, sweep, dihedral):
                #  <1--0--2
                #   \  |  /
                #    4-3-5
 class Wing(Item):
        def __init__(self, name, root, length, chord, incidence, twist, taper, sweep, dihedral):
                #  <1--0--2
                #   \  |  /
                #    4-3-5
-               is_vstab = name.startswith("YASim_vstab")
+               self.is_symmetric = not name.startswith("YASim_vstab#")
                mesh = Blender.Mesh.New()
                mesh.verts.extend([ORIGIN, ORIGIN + 0.5 * chord * X, ORIGIN - 0.5 * chord * X])
                tip = ORIGIN + math.cos(sweep * DEG2RAD) * length * Y - math.sin(sweep * DEG2RAD) * length * X
                mesh = Blender.Mesh.New()
                mesh.verts.extend([ORIGIN, ORIGIN + 0.5 * chord * X, ORIGIN - 0.5 * chord * X])
                tip = ORIGIN + math.cos(sweep * DEG2RAD) * length * Y - math.sin(sweep * DEG2RAD) * length * X
@@ -394,16 +442,23 @@ class Wing(Item):
                mesh.verts.extend([tip, tipfore, tipaft])
                mesh.faces.extend([[0, 1, 4, 3], [2, 0, 3, 5]])
 
                mesh.verts.extend([tip, tipfore, tipaft])
                mesh.faces.extend([[0, 1, 4, 3], [2, 0, 3, 5]])
 
-               self.set_color(mesh, name + "mat", [[0, 0.5, 0, 0.5], [0.5, 0, 0, 0.5]][is_vstab])
                self.make_twosided(mesh)
 
                obj = self.scene.objects.new(mesh, name)
                self.make_twosided(mesh)
 
                obj = self.scene.objects.new(mesh, name)
-               obj.transp = True
-               m = Euler(dihedral, -incidence, 0).toMatrix().resize4x4()
-               m *= TranslationMatrix(root)
-               obj.setMatrix(m * Global.matrix)
+               mesh.transform(Euler(dihedral, -incidence, 0).toMatrix().resize4x4())
+               self.set_color(obj, [[0.5, 0.0, 0, 0.5], [0.0, 0.5, 0, 0.5]][self.is_symmetric])
                (self.obj, self.mesh) = (obj, mesh)
 
                (self.obj, self.mesh) = (obj, mesh)
 
+               if self.is_symmetric and Global.mirror_button.val:
+                       mod = obj.modifiers.append(Blender.Modifier.Type.MIRROR)
+                       mod[Blender.Modifier.Settings.AXIS_X] = False
+                       mod[Blender.Modifier.Settings.AXIS_Y] = True
+                       mod[Blender.Modifier.Settings.AXIS_Z] = False
+                       mesh.transform(TranslationMatrix(root)) # must move object center to x axis
+                       obj.setMatrix(Global.matrix)
+               else:
+                       obj.setMatrix(TranslationMatrix(root) * Global.matrix)
+
        def add_flap(self, name, start, end):
                a = Vector(self.mesh.verts[2].co)
                b = Vector(self.mesh.verts[5].co)
        def add_flap(self, name, start, end):
                a = Vector(self.mesh.verts[2].co)
                b = Vector(self.mesh.verts[5].co)
@@ -416,55 +471,57 @@ class Wing(Item):
                mesh.verts.extend([i0, i1, i0 + c, i1 + c])
                mesh.faces.extend([[0, 1, 3, 2]])
 
                mesh.verts.extend([i0, i1, i0 + c, i1 + c])
                mesh.faces.extend([[0, 1, 3, 2]])
 
-               self.set_color(mesh, name + "mat", [0.8, 0.8, 0, 0.9])
                self.make_twosided(mesh)
 
                obj = self.scene.objects.new(mesh, name)
                self.make_twosided(mesh)
 
                obj = self.scene.objects.new(mesh, name)
-               obj.transp = True
                obj.setMatrix(m)
                obj.setMatrix(m)
+               self.set_color(obj, [0.8, 0.8, 0, 0.9])
+
+               if self.is_symmetric and Global.mirror_button.val:
+                       mod = obj.modifiers.append(Blender.Modifier.Type.MIRROR)
+                       mod[Blender.Modifier.Settings.AXIS_X] = False
+                       mod[Blender.Modifier.Settings.AXIS_Y] = True
+                       mod[Blender.Modifier.Settings.AXIS_Z] = False
 
 
 
 
-class import_yasim(handler.ContentHandler):
+
+class import_yasim(handler.ErrorHandler, handler.ContentHandler):
        ignored = ["cruise", "approach", "control-input", "control-output", "control-speed", \
                        "control-setting", "stall", "airplane", "piston-engine", "turbine-engine", \
                        "rotorgear", "tow", "winch", "solve-weight"]
 
        ignored = ["cruise", "approach", "control-input", "control-output", "control-speed", \
                        "control-setting", "stall", "airplane", "piston-engine", "turbine-engine", \
                        "rotorgear", "tow", "winch", "solve-weight"]
 
+
        # err_handler
        # err_handler
+       def warning(self, exception):
+               print((self.error_string("Warning", exception)))
+
        def error(self, exception):
        def error(self, exception):
-               raise Abort(str(exception))
+               print((self.error_string("Error", exception)))
 
        def fatalError(self, exception):
 
        def fatalError(self, exception):
-               raise Abort(str(exception))
+               raise Abort(str(exception), self.error_string("Fatal", exception))
+
+       def error_string(self, tag, e):
+               (column, line) = (e.getColumnNumber(), e.getLineNumber())
+               return "%s: %s\n%s%s^"  % (tag, str(e), Global.data[line - 1], column * ' ')
 
 
-       def warning(self, exception):
-               print(("WARNING: " + str(exception)))
 
        # doc_handler
 
        # doc_handler
-       def setDocumentLocator(self, whatever):
-               pass
+       def setDocumentLocator(self, locator):
+               self.locator = locator
 
        def startDocument(self):
                self.tags = []
                self.counter = {}
                self.items = [None]
 
        def startDocument(self):
                self.tags = []
                self.counter = {}
                self.items = [None]
-               pass
 
        def endDocument(self):
                for o in Item.scene.objects:
                        o.sel = True
 
 
        def endDocument(self):
                for o in Item.scene.objects:
                        o.sel = True
 
-       def characters(self, data):
-               pass
-
-       def ignorableWhitespace(self, data, start, length):
-               pass
-
-       def processingInstruction(self, target, data):
-               pass
-
        def startElement(self, tag, attrs):
                if len(self.tags) == 0 and tag != "airplane":
        def startElement(self, tag, attrs):
                if len(self.tags) == 0 and tag != "airplane":
-                       raise Abort("this isn't a YASim config file")
+                       raise Abort("this isn't a YASim config file (bad root tag at line %d)" % self.locator.getLineNumber())
 
                self.tags.append(tag)
                path = string.join(self.tags, '/')
 
                self.tags.append(tag)
                path = string.join(self.tags, '/')
@@ -485,15 +542,15 @@ class import_yasim(handler.ContentHandler):
                        a = Vector(float(attrs["ax"]), float(attrs["ay"]), float(attrs["az"]))
                        b = Vector(float(attrs["bx"]), float(attrs["by"]), float(attrs["bz"]))
                        width = float(attrs["width"])
                        a = Vector(float(attrs["ax"]), float(attrs["ay"]), float(attrs["az"]))
                        b = Vector(float(attrs["bx"]), float(attrs["by"]), float(attrs["bz"]))
                        width = float(attrs["width"])
-                       taper = getfloat(attrs, "taper", 1)
-                       midpoint = getfloat(attrs, "midpoint", 0.5)
+                       taper = float(attrs.get("taper", 1))
+                       midpoint = float(attrs.get("midpoint", 0.5))
                        log("\033[32mfuselage ax=%f ay=%f az=%f bx=%f by=%f bz=%f width=%f taper=%f midpoint=%f\033[m" % \
                                        (a[0], a[1], a[2], b[0], b[1], b[2], width, taper, midpoint))
                        item = Fuselage("YASim_%s#%d" % (tag, self.counter[tag]), a, b, width, taper, midpoint)
 
                elif tag == "gear":
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
                        log("\033[32mfuselage ax=%f ay=%f az=%f bx=%f by=%f bz=%f width=%f taper=%f midpoint=%f\033[m" % \
                                        (a[0], a[1], a[2], b[0], b[1], b[2], width, taper, midpoint))
                        item = Fuselage("YASim_%s#%d" % (tag, self.counter[tag]), a, b, width, taper, midpoint)
 
                elif tag == "gear":
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
-                       compression = getfloat(attrs, "compression", 1)
+                       compression = float(attrs.get("compression", 1))
                        up = Z * compression
                        if attrs.has_key("upx"):
                                up = Vector(float(attrs["upx"]), float(attrs["upy"]), float(attrs["upz"])).normalize() * compression
                        up = Z * compression
                        if attrs.has_key("upx"):
                                up = Vector(float(attrs["upx"]), float(attrs["upy"]), float(attrs["upz"])).normalize() * compression
@@ -503,7 +560,7 @@ class import_yasim(handler.ContentHandler):
 
                elif tag == "jet":
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
 
                elif tag == "jet":
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
-                       rotate = getfloat(attrs, "rotate", 0.0)
+                       rotate = float(attrs.get("rotate", 0))
                        log("\033[36;1mjet x=%f y=%f z=%f rotate=%f\033[m" % (c[0], c[1], c[2], rotate))
                        item = Jet("YASim_jet#%d" % self.counter[tag], c, rotate)
 
                        log("\033[36;1mjet x=%f y=%f z=%f rotate=%f\033[m" % (c[0], c[1], c[2], rotate))
                        item = Jet("YASim_jet#%d" % self.counter[tag], c, rotate)
 
@@ -521,7 +578,8 @@ class import_yasim(handler.ContentHandler):
 
                elif tag == "actionpt":
                        if not isinstance(parent, Thrust):
 
                elif tag == "actionpt":
                        if not isinstance(parent, Thrust):
-                               raise Abort("%s is not part of a thruster/propeller/jet" % path)
+                               raise Abort("%s is not part of a thruster/propeller/jet at line %d" \
+                                               % (path, self.locator.getLineNumber()))
 
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
                        log("\t\033[36mactionpt x=%f y=%f z=%f\033[m" % (c[0], c[1], c[2]))
 
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
                        log("\t\033[36mactionpt x=%f y=%f z=%f\033[m" % (c[0], c[1], c[2]))
@@ -529,7 +587,8 @@ class import_yasim(handler.ContentHandler):
 
                elif tag == "dir":
                        if not isinstance(parent, Thrust):
 
                elif tag == "dir":
                        if not isinstance(parent, Thrust):
-                               raise Abort("%s is not part of a thruster/propeller/jet" % path)
+                               raise Abort("%s is not part of a thruster/propeller/jet at line %d" \
+                                               % (path, self.locator.getLineNumber()))
 
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
                        log("\t\033[36mdir x=%f y=%f z=%f\033[m" % (c[0], c[1], c[2]))
 
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
                        log("\t\033[36mdir x=%f y=%f z=%f\033[m" % (c[0], c[1], c[2]))
@@ -552,9 +611,9 @@ class import_yasim(handler.ContentHandler):
 
                elif tag == "hook":
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
 
                elif tag == "hook":
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
-                       length = getfloat(attrs, "length", 1.0)
-                       up_angle = getfloat(attrs, "up-angle", 0.0)
-                       down_angle = getfloat(attrs, "down-angle", 70.0)
+                       length = float(attrs.get("length", 1))
+                       up_angle = float(attrs.get("up-angle", 0))
+                       down_angle = float(attrs.get("down-angle", 70))
                        log("\033[35m%s x=%f y=%f z=%f length=%f up-angle=%f down-angle=%f\033[m" \
                                        % (tag, c[0], c[1], c[2], length, up_angle, down_angle))
                        item = Hook("YASim_hook#%d" % self.counter[tag], c, length, up_angle, down_angle)
                        log("\033[35m%s x=%f y=%f z=%f length=%f up-angle=%f down-angle=%f\033[m" \
                                        % (tag, c[0], c[1], c[2], length, up_angle, down_angle))
                        item = Hook("YASim_hook#%d" % self.counter[tag], c, length, up_angle, down_angle)
@@ -566,11 +625,11 @@ class import_yasim(handler.ContentHandler):
 
                elif tag == "launchbar":
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
 
                elif tag == "launchbar":
                        c = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
-                       length = getfloat(attrs, "length", 1.0)
-                       up_angle = getfloat(attrs, "up-angle", -45.0)
-                       down_angle = getfloat(attrs, "down-angle", 45.0)
-                       holdback = Vector(getfloat(attrs, "holdback-x", c[0]), getfloat(attrs, "holdback-y", c[1]), getfloat(attrs, "holdback-z", c[2]))
-                       holdback_length = getfloat(attrs, "holdback-length", 2.0)
+                       length = float(attrs.get("length", 1))
+                       up_angle = float(attrs.get("up-angle", -45))
+                       down_angle = float(attrs.get("down-angle", 45))
+                       holdback = Vector(float(attrs.get("holdback-x", c[0])), float(attrs.get("holdback-y", c[1])), float(attrs.get("holdback-z", c[2])))
+                       holdback_length = float(attrs.get("holdback-length", 2))
                        log("\033[35m%s x=%f y=%f z=%f length=%f down-angle=%f up-angle=%f holdback-x=%f holdback-y=%f holdback-z+%f holdback-length=%f\033[m" \
                                        % (tag, c[0], c[1], c[2], length, down_angle, up_angle, \
                                        holdback[0], holdback[1], holdback[2], holdback_length))
                        log("\033[35m%s x=%f y=%f z=%f length=%f down-angle=%f up-angle=%f holdback-x=%f holdback-y=%f holdback-z+%f holdback-length=%f\033[m" \
                                        % (tag, c[0], c[1], c[2], length, down_angle, up_angle, \
                                        holdback[0], holdback[1], holdback[2], holdback_length))
@@ -580,18 +639,19 @@ class import_yasim(handler.ContentHandler):
                        root = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
                        length = float(attrs["length"])
                        chord = float(attrs["chord"])
                        root = Vector(float(attrs["x"]), float(attrs["y"]), float(attrs["z"]))
                        length = float(attrs["length"])
                        chord = float(attrs["chord"])
-                       incidence = getfloat(attrs, "incidence", 0.0)
-                       twist = getfloat(attrs, "twist", 0.0)
-                       taper = getfloat(attrs, "taper", 1.0)
-                       sweep = getfloat(attrs, "sweep", 0.0)
-                       dihedral = getfloat(attrs, "dihedral", [0.0, 90.0][tag == "vstab"])
+                       incidence = float(attrs.get("incidence", 0))
+                       twist = float(attrs.get("twist", 0))
+                       taper = float(attrs.get("taper", 1))
+                       sweep = float(attrs.get("sweep", 0))
+                       dihedral = float(attrs.get("dihedral", [0, 90][tag == "vstab"]))
                        log("\033[33;1m%s x=%f y=%f z=%f length=%f chord=%f incidence=%f twist=%f taper=%f sweep=%f dihedral=%f\033[m" \
                                        % (tag, root[0], root[1], root[2], length, chord, incidence, twist, taper, sweep, dihedral))
                        item = Wing("YASim_%s#%d" % (tag, self.counter[tag]), root, length, chord, incidence, twist, taper, sweep, dihedral)
 
                elif tag == "flap0" or tag == "flap1" or tag == "slat" or tag == "spoiler":
                        if not isinstance(parent, Wing):
                        log("\033[33;1m%s x=%f y=%f z=%f length=%f chord=%f incidence=%f twist=%f taper=%f sweep=%f dihedral=%f\033[m" \
                                        % (tag, root[0], root[1], root[2], length, chord, incidence, twist, taper, sweep, dihedral))
                        item = Wing("YASim_%s#%d" % (tag, self.counter[tag]), root, length, chord, incidence, twist, taper, sweep, dihedral)
 
                elif tag == "flap0" or tag == "flap1" or tag == "slat" or tag == "spoiler":
                        if not isinstance(parent, Wing):
-                               raise Abort("%s is not part of a wing or stab" % path)
+                               raise Abort("%s is not part of a wing or stab at line %d" \
+                                               % (path, self.locator.getLineNumber()))
 
                        start = float(attrs["start"])
                        end = float(attrs["end"])
 
                        start = float(attrs["start"])
                        end = float(attrs["end"])
@@ -599,17 +659,17 @@ class import_yasim(handler.ContentHandler):
                        parent.add_flap("YASim_%s#%d" % (tag, self.counter[tag]), start, end)
 
                elif tag == "rotor":
                        parent.add_flap("YASim_%s#%d" % (tag, self.counter[tag]), start, end)
 
                elif tag == "rotor":
-                       c = Vector(getfloat(attrs, "x", 0.0), getfloat(attrs, "y", 0.0), getfloat(attrs, "z", 0.0))
-                       norm = Vector(getfloat(attrs, "nx", 0.0), getfloat(attrs, "ny", 0.0), getfloat(attrs, "nz", 1.0))
-                       fwd = Vector(getfloat(attrs, "fx", 1.0), getfloat(attrs, "fy", 0.0), getfloat(attrs, "fz", 0.0))
-                       diameter = getfloat(attrs, "diameter", 10.2)
-                       numblades = int(getfloat(attrs, "numblades", 4))
-                       chord = getfloat(attrs, "chord", 0.3)
-                       twist = getfloat(attrs, "twist", 0.0)
-                       taper = getfloat(attrs, "taper", 1.0)
-                       rel_len_blade_start = getfloat(attrs, "rel-len-blade-start", 0.0)
-                       phi0 = getfloat(attrs, "phi0", 0)
-                       ccw = not not getfloat(attrs, "ccw", 0)
+                       c = Vector(float(attrs.get("x", 0)), float(attrs.get("y", 0)), float(attrs.get("z", 0)))
+                       norm = Vector(float(attrs.get("nx", 0)), float(attrs.get("ny", 0)), float(attrs.get("nz", 1)))
+                       fwd = Vector(float(attrs.get("fx", 1)), float(attrs.get("fy", 0)), float(attrs.get("fz", 0)))
+                       diameter = float(attrs.get("diameter", 10.2))
+                       numblades = int(attrs.get("numblades", 4))
+                       chord = float(attrs.get("chord", 0.3))
+                       twist = float(attrs.get("twist", 0))
+                       taper = float(attrs.get("taper", 1))
+                       rel_len_blade_start = float(attrs.get("rel-len-blade-start", 0))
+                       phi0 = float(attrs.get("phi0", 0))
+                       ccw = not not int(attrs.get("ccw", 0))
 
                        log(("\033[36;1mrotor x=%f y=%f z=%f nx=%f ny=%f nz=%f fx=%f fy=%f fz=%f numblades=%d diameter=%f " \
                                        + "chord=%f twist=%f taper=%f rel_len_blade_start=%f phi0=%f ccw=%d\033[m") \
 
                        log(("\033[36;1mrotor x=%f y=%f z=%f nx=%f ny=%f nz=%f fx=%f fy=%f fz=%f numblades=%d diameter=%f " \
                                        + "chord=%f twist=%f taper=%f rel_len_blade_start=%f phi0=%f ccw=%d\033[m") \
@@ -628,11 +688,11 @@ class import_yasim(handler.ContentHandler):
                self.items.pop()
 
 
                self.items.pop()
 
 
-def extract_matrix(path, tag):
+
+def extract_matrix(filedata, tag):
        v = { 'x': 0.0, 'y': 0.0, 'z': 0.0, 'h': 0.0, 'p': 0.0, 'r': 0.0 }
        has_offsets = False
        v = { 'x': 0.0, 'y': 0.0, 'z': 0.0, 'h': 0.0, 'p': 0.0, 'r': 0.0 }
        has_offsets = False
-       f = open(path)
-       for line in f.readlines():
+       for line in filedata:
                line = string.strip(line)
                if not line.startswith("<!--") or not line.endswith("-->"):
                        continue
                line = string.strip(line)
                if not line.startswith("<!--") or not line.endswith("-->"):
                        continue
@@ -644,23 +704,21 @@ def extract_matrix(path, tag):
                        (key, value) = string.split(assignment, '=', 2)
                        v[string.strip(key)] = float(string.strip(value))
                        has_offsets = True
                        (key, value) = string.split(assignment, '=', 2)
                        v[string.strip(key)] = float(string.strip(value))
                        has_offsets = True
-       f.close()
-       matrix = None
-       if has_offsets:
-               print(("using offsets: x=%f y=%f z=%f h=%f p=%f r=%f" % (v['x'], v['y'], v['z'], v['h'], v['p'], v['r'])))
-               matrix = Euler(v['r'], v['p'], v['h']).toMatrix().resize4x4()
-               matrix *= TranslationMatrix(Vector(v['x'], v['y'], v['z']))
-       return matrix
+
+       if not has_offsets:
+               return None
+
+       print(("using offsets: x=%f y=%f z=%f h=%f p=%f r=%f" % (v['x'], v['y'], v['z'], v['h'], v['p'], v['r'])))
+       return Euler(v['r'], v['p'], v['h']).toMatrix().resize4x4() * TranslationMatrix(Vector(v['x'], v['y'], v['z']))
 
 
 
 
-def run_parser(path):
+
+def load_yasim_config(path):
        if BPyMessages.Error_NoFile(path):
                return
 
        if BPyMessages.Error_NoFile(path):
                return
 
-       editmode = Blender.Window.EditMode()
-       if editmode:
-               Blender.Window.EditMode(0)
        Blender.Window.WaitCursor(1)
        Blender.Window.WaitCursor(1)
+       Blender.Window.EditMode(0)
 
        print(("loading '%s'" % path))
        try:
 
        print(("loading '%s'" % path))
        try:
@@ -668,80 +726,99 @@ def run_parser(path):
                        if o.name.startswith("YASim_"):
                                Item.scene.objects.unlink(o)
 
                        if o.name.startswith("YASim_"):
                                Item.scene.objects.unlink(o)
 
+               f = open(path)
+               Global.data = f.readlines()
+               f.close
+
+               Global.path = path
                Global.matrix = YASIM_MATRIX
                Global.matrix = YASIM_MATRIX
-               matrix = extract_matrix(path, "offsets")
+               matrix = extract_matrix(Global.data, "offsets")
                if matrix:
                        Global.matrix *= matrix.invert()
 
                if matrix:
                        Global.matrix *= matrix.invert()
 
-               yasim = make_parser()
-               yasim.setContentHandler(import_yasim())
-               yasim.setErrorHandler(import_yasim())
-               yasim.parse(path)
-
+               Global.yasim.parse(path)
                Blender.Registry.SetKey("FGYASimImportExport", { "path": path }, False)
                Blender.Registry.SetKey("FGYASimImportExport", { "path": path }, False)
-               Global.path = path
+               Global.data = None
 
        except Abort, e:
 
        except Abort, e:
-               print "Error:", e.msg, "  -> aborting ...\n"
+               print(("%s\nAborting ..." % (e.term or e.msg)))
                Blender.Draw.PupMenu("Error%t|" + e.msg)
 
        Blender.Window.RedrawAll()
        Blender.Window.WaitCursor(0)
                Blender.Draw.PupMenu("Error%t|" + e.msg)
 
        Blender.Window.RedrawAll()
        Blender.Window.WaitCursor(0)
-       if editmode:
-               Blender.Window.EditMode(1)
 
 
 
 
-def draw():
+
+def gui_draw():
        from Blender import BGL, Draw
        (width, height) = Blender.Window.GetAreaSize()
 
        BGL.glClearColor(0.4, 0.4, 0.45, 1)
        BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
        from Blender import BGL, Draw
        (width, height) = Blender.Window.GetAreaSize()
 
        BGL.glClearColor(0.4, 0.4, 0.45, 1)
        BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
-       Draw.PushButton("Reload YASim", 0, 5, 5, 100, 28)
-       Draw.PushButton("Update Cursor", 1, width - 650, 5, 100, 28)
+
        BGL.glColor3f(1, 1, 1)
        BGL.glColor3f(1, 1, 1)
+       BGL.glRasterPos2f(5, 55)
+       Draw.Text("FlightGear YASim Import:   '%s'" % Global.path)
 
 
-       BGL.glRasterPos2f(120, 15)
-       Draw.Text(Global.path)
+       Draw.PushButton("Reload", RELOAD_BUTTON, 5, 5, 80, 32, "reload YASim config file")
+       Global.mirror_button = Draw.Toggle("Mirror", MIRROR_BUTTON, 100, 5, 50, 16, Global.mirror_button.val, \
+                       "show symmetric surfaces on both sides (reloads config)")
+       Draw.PushButton("Update Cursor", CURSOR_BUTTON, width - 650, 5, 100, 32, "update cursor display (in YASim coordinate system)")
 
 
-       BGL.glRasterPos2f(width - 530 + Blender.Draw.GetStringWidth("Distance from last") - Blender.Draw.GetStringWidth("Current"), 24)
+       BGL.glRasterPos2f(width - 530 + Blender.Draw.GetStringWidth("Vector from last") - Blender.Draw.GetStringWidth("Current"), 24)
        Draw.Text("Current cursor pos:    x = %+.3f    y = %+.3f    z = %+.3f" % tuple(Global.cursor))
 
        c = Global.cursor - Global.last_cursor
        BGL.glRasterPos2f(width - 530, 7)
        Draw.Text("Current cursor pos:    x = %+.3f    y = %+.3f    z = %+.3f" % tuple(Global.cursor))
 
        c = Global.cursor - Global.last_cursor
        BGL.glRasterPos2f(width - 530, 7)
-       Draw.Text("Distance from last cursor pos:    x = %+.3f    y = %+.3f    z = %+.3f    length = %.3f" % (c[0], c[1], c[2], c.length))
+       Draw.Text("Vector from last cursor pos:    x = %+.3f    y = %+.3f    z = %+.3f    length = %.3f m" % (c[0], c[1], c[2], c.length))
 
 
 
 
-def event(ev, value):
+
+def gui_event(ev, value):
        if ev == Blender.Draw.ESCKEY:
                Blender.Draw.Exit()
 
 
        if ev == Blender.Draw.ESCKEY:
                Blender.Draw.Exit()
 
 
-def button(n):
-       if n == 0:
-               run_parser(Global.path)
-       elif n == 1:
+
+def gui_button(n):
+       if n == NO_EVENT:
+               return
+
+       elif n == RELOAD_BUTTON:
+               load_yasim_config(Global.path)
+
+       elif n == CURSOR_BUTTON:
                Global.last_cursor = Global.cursor
                Global.cursor = Vector(Blender.Window.GetCursorPos()) * Global.matrix.invert()
                d = Global.cursor - Global.last_cursor
                print(("cursor:   x=\"%f\" y=\"%f\" z=\"%f\"   dx=%f dy=%f dz=%f   length=%f" \
                                % (Global.cursor[0], Global.cursor[1], Global.cursor[2], d[0], d[1], d[2], d.length)))
                Global.last_cursor = Global.cursor
                Global.cursor = Vector(Blender.Window.GetCursorPos()) * Global.matrix.invert()
                d = Global.cursor - Global.last_cursor
                print(("cursor:   x=\"%f\" y=\"%f\" z=\"%f\"   dx=%f dy=%f dz=%f   length=%f" \
                                % (Global.cursor[0], Global.cursor[1], Global.cursor[2], d[0], d[1], d[2], d.length)))
+
+       elif n == MIRROR_BUTTON:
+               load_yasim_config(Global.path)
+
        Blender.Draw.Redraw(1)
 
 
        Blender.Draw.Redraw(1)
 
 
+
 def main():
 def main():
+       log(6 * "\n")
        registry = Blender.Registry.GetKey("FGYASimImportExport", False)
        if registry and "path" in registry and Blender.sys.exists(Blender.sys.expandpath(registry["path"])):
                path = registry["path"]
        else:
                path = ""
 
        registry = Blender.Registry.GetKey("FGYASimImportExport", False)
        if registry and "path" in registry and Blender.sys.exists(Blender.sys.expandpath(registry["path"])):
                path = registry["path"]
        else:
                path = ""
 
+       xml_handler = import_yasim()
+       Global.yasim = make_parser()
+       Global.yasim.setContentHandler(xml_handler)
+       Global.yasim.setErrorHandler(xml_handler)
 
 
-       log(6 * "\n")
        if Blender.Window.GetScreenInfo(Blender.Window.Types.SCRIPT):
        if Blender.Window.GetScreenInfo(Blender.Window.Types.SCRIPT):
-               Blender.Draw.Register(draw, event, button)
+               Blender.Draw.Register(gui_draw, gui_event, gui_button)
+
+       Blender.Window.FileSelector(load_yasim_config, "Import YASim Configuration File", path)
 
 
-       Blender.Window.FileSelector(run_parser, "Import YASim Configuration File", path)
 
 
 main()
 
 
 main()