Python: Imported Curve points lose Z coordinate in Edit Mode I'm trying to use bezier curves for editing paths of a custom game file format.

A weird bug (?) when switching to Edit Mode makes the bezier spline points lose their Z coordinate, it being set to 0, and I have no clue why.

Here's the code that simply creates a new bezier curve, adds a spline with enough points and feeds it the coordinates of the control points and handles.

# Create a bezier curve object representing the Path.
cu = bpy.data.curves.new("Path", 'CURVE')
ob = bpy.data.objects.new("Path", cu)
self.context.scene.objects.link(ob)
self.context.scene.objects.active = ob
# Add the points to a new spline.
sp = cu.splines.new('BEZIER')
sp.use_cyclic_u = path["IsClosed"]
points = path["PathPt"]
sp.bezier_points.add(len(points) - 1)  # There is already one point in new curves, so add one less.
for i, point in enumerate(points):
    pt = sp.bezier_points[i]
    pt.co = vector_from_dict(point["Translate"], invert_z=True)
    pt.handle_left = vector_from_dict(point["ControlPoints"][0], invert_z=True)
    pt.handle_right = vector_from_dict(point["ControlPoints"][1], invert_z=True)
# Lock the transform as paths are always in the global coordinate system.
ob.lock_location = [True] * 3
ob.lock_rotation = [True] * 3
ob.lock_scale = [True] * 3
return ob

def vector_from_dict(dictionary, invert_z=False):
    # Game file format is right handed with Y up, convert accordingly.
    if invert_z:
        return dictionary["X"], -dictionary["Z"], dictionary["Y"]
    else:
        return dictionary["X"], dictionary["Z"], dictionary["Y"]


As said, this imports fine and looks well at first. Hence this path of birds flying around the palm trees and above the house ceiling in the front:



But as soon as I enter Edit Mode, the path drops down to the floor, the Z coordinate of all points has become 0 (0 is far below the game model)!



It's indeed just Z losing its value, I imported the path again without editing it this time, making it very clear - the correct one is above, the one with the edit attempt lieing flat below:



Going back to Object Mode keeps these "corrupted" coordinates! What is going wrong here?

The file format itself is stored as binary, but also nothing special, and a Path in it can be represented as dictionaries and arrays like this:

{
    "IsClosed": True,
    "PathPoints":
    [
        {
            "Handles":
            [
                {"X": -2374.132, "Y": 2985.336, "Z": 2211.747},
                {"X": -2318.274, "Y": 2964.664, "Z": 1901.128}
            ],
            # Can't import Rotate since no Blender support for bezier point normals =(
            "Rotate": {"X": -2.684734, "Y": 0.167497, "Z": -3.044649},
            "Translate": {"X": -2346.203, "Y": 2975, "Z": 2056.438}
        },
        {
            "Handles":
            [
                {"X": -2277.908, "Y": 2960.383, "Z": 1596.964},
                {"X": -2294.248, "Y": 2989.617, "Z": 1175.442}
            ],
            "Rotate": {"X": -2.808016, "Y": -0.1063031, "Z": 3.136256},
            "Translate": {"X": -2286.078, "Y": 2975, "Z": 1386.203}
        },
        # ... and so on for each point ...
    ]
}
I'm not much into scripting or coding and now very little about Python myself, so apologies if this doesn't fix your problem, but I believe this is happening because your bezier curve seems to be in 2D mode (in your first screenshot), hence when entering edit mode it will automatically ignore any Z coordinates that it should not have in the first place.

Set your bezier curve to 3D either through the Properties Window > Object Data (Curve) > Shape > 3D or using the Pyhton API through bpy.types.Curve.dimensions setting it to 3D