Animating a punctured torus
This question is a nice example for showing how to morph one mesh into another. Lets take a general approach that will work on multiple shapes and lets make the morphing nice (where non-linear morphing is needed).

First we will need the start and end meshes. In this example, the diameter of the hole of the start torus is the same like thickness of the end torus. Because the diameter of subdivision surfaces is different than the control cage, I chose to work with real geometry. This method shouldn't depend on vertex count anyway, so let's have some nicely detailed toruses (subdiv surfaces don't produce perfectly circular shapes).

I obtained these by spinning touching circles around 3d cursor locations:



There are 32 rings with 32 vertices each on both toruses. Now we could map the start vertices to the end vertices (by fiddling with their id, or based on vertex paint, or UV unwrap data,..) and make appropriate shape-key (by scripting), but this is not the intention, because such morphing will result in linear ugly motion, which could cause self-intersecting and other non-desired results.

We will convert edges of the meridians of the start torus into bone chains, and rotate them into the final positions as equators of the end torus. Then we will skin a mesh to this armature and render it.

As the bones will come from Skin modifier, we need to mark the root vertices and also split the toruses for chain ends first (seen as 2 hard lines in shading - because of duplicite vertices, you can split vertices with V when the ring is selected). Unwanted edges were removed, to leave only the chains:



Let's put Skin modifiers on, adjust the thickness and set the root vertices. Setting the roots location and where the chains end will shape the look of animation (roots highlighted and ends visible by shading):



Both toruses are still separate objects, so we'll get 2 armatures. Delete unwanted bones, you'll end up with 2 bone chains per ring:



Similarly we can map any corresponding topologies onto each other to morph them.

The corresponding start and end bones have to have a corresponding name inside those armatures. To fix it, here is a script to name the root bones based on shared location and direction and the chain bones based on chain distance (parent count) from roots. The bones also get a start/end prefix, because we will merge them into single armature later (to have a clean scene). Name the start armature Start, and the end one End: 

import bpy

start = bpy.data.objects["Start"]
end = bpy.data.objects["End"]

i = 0
for pboneA in start.pose.bones:
    for pboneB in end.pose.bones:
        if ((pboneB.head - pboneA.head).length_squared &lt; 0.001 and
            ((pboneA.tail - pboneA.head).dot(pboneB.tail - pboneB.head) &gt; 0)):

            pboneA.name = "Start_Chain_" + str(i) + "_Bone_0"
            pboneB.name = "End_Chain_" + str(i) + "_Bone_0"
            i += 1
            break

for object in [start, end]:
    for pbone in object.pose.bones:
        parents = pbone.parent_recursive
        if len(parents):
            pbone.name = parents[-1].name[:-1] + str(len(parents))

for pbone in start.data.bones:
    pbone.use_inherit_rotation = False
    pbone.use_inherit_scale = False

for pbone in end.data.bones:
    pbone.use_deform = False


You can now join the armatures together Ctrl+J. The deformation on end bones was also deactivated by the script.

The next script will create a custom property on the armature to drive the blending:

import bpy

def add_driver(expression, item, property, property_index = -1):

    driver = item.driver_add(property, property_index)
    driver.driver.type = 'SCRIPTED'
    driver.driver.expression = expression
    var = driver.driver.variables.get("blend")
    var = driver.driver.variables.new()
    var.name = "blend"
    var.targets[0].id = bpy.context.active_object
    var.type = 'SINGLE_PROP'
    var.targets[0].data_path = 'data["blend"]'

bpy.context.active_object.data["blend"] = 0.0
bpy.context.active_object.data["_RNA_UI"] = {"blend": {"min":0.0,
                                                       "max":1.0,
                                                       "soft_min":0.0,
                                                       "soft_max":1.0}}

pbones = bpy.context.active_object.pose.bones

for pboneA in [pbone for pbone in pbones if "Start" in pbone.name]:

    pboneB = pbones[pboneA.name.replace("Start","End")]

    constraint = pboneA.constraints.new('COPY_ROTATION')
    constraint.target = bpy.context.active_object
    constraint.subtarget = pboneB.name
    add_driver("blend", constraint, "influence")

    l_A = (pboneA.head - pboneA.tail).length
    l_B = (pboneB.head - pboneB.tail).length
    add_driver("(1-blend) + blend * " + str(l_B/l_A), pboneA, "scale", 1)


This is the result with skinned mesh:



Lastly we will unwrap the torus mesh into a single rectangle UV with the point where the hole will be in the middle. The intention is to animate a material mask to create the transparent hole. In the picture are marked seams and the UV map - I used UV Squares addon to have such nice regular UV map:



In the material lets use a procedural gradient texture set to Quadratic Sphere, offset into the center of UV space, with an animated threshold (the Color Ramp node is animated):



The only problem is that the texture does not warp with the hole. Good news is the procedural spherical gradient to drive the texture warping effect is already in place:



There is the displacement mask on the left, UV coordinates in the middle with progressively blended displacement from 0 to 100% influence and the warped texture on the right.

This is the final result:



And a finished .blend to peak into: