How varied is my obstacle course? Background

I have constructed a simple obstacle course by placing boxes in a rectangular room.
Now I want to count the number of essentially different ways in which it can be solved.
I need you to write me a program for that.

Input

Your input is a non-empty rectangular array of the characters .#.
The dots . are empty space, and the # are obstacles.

A path through the obstacle course begins at the top left corner and ends at the bottom right corner, and goes only right or down.
Also, a valid path cannot go through an obstacle.
Here are some examples drawn with +-characters:

Valid path  Invalid path  Invalid path  Invalid path
++........   ++........    +++++.....    ..+.......
.++++++#..   .+.....#..    ....+++#++    ..++...#..
......+#..   .+.++++#..    .......#.+    ...+++.#..
....#.++++   .+++#.++++    ....#....+    ....#+....


Two paths are essentially similar1 if one can be transformed into the other by moving one + at a time.
The intermediate paths must also be valid, so you can't bend a path over an obstacle.
For example, the first two paths here are essentially similar, but the third is essentially different from them, since it can't be wiggled over the two obstacles:

++........   +.........   +++++++++.
.+++++.#..   ++.....#..   .......#+.
.....+.#..   .++++++#..   .......#++
....#+++++   ....#.++++   ....#....+


Output

Your output is the number of essentially different paths through the obstacle course.
In other words, if all the valid paths are divided into classes of essentially similar paths, the output is the number of classes.
Note that this number may be 0, if there are no valid paths.

Rules and scoring

You can write a full program or a function.
The lowest byte count wins, and standard loopholes are disallowed.
There are no time bounds, except that you should evaluate your program on every test case before submitting it.

Test cases

....
....
.... =&gt; 1

...#
....
...# =&gt; 0

#..#
..#.
.... =&gt; 0

......
......
..##..
......
...... =&gt; 2

......
...#..
......
..#...
#..... =&gt; 3

......
..#...
......
....#.
#..... =&gt; 4

.......
##.....
....###
...#...
..##.#.
#....#.
..#.... =&gt; 0

......#.
..##....
...#....
.......#
....#...
.##...#.
....#...
##...... =&gt; 7

.........
.#.#.#.#.
.........
#.#...#.#
.........
.#.#.#.#.
......... =&gt; 17

..........
.#........
..........
.....#....
#.........
........#.
......#...
.......... =&gt; 10

.........
.#.......
.........
...#.....
.........
.....#...
.........
.......#.
......... =&gt; 16


1 The correct technical term is "homotopic".
Python 2, 170 131 112 bytes

def f(C,t=1):i="#".join(C).find("#")+1;return([]&lt;C)*(i&lt;1or(i&lt;t
and f([r[i:]for r in C],t-i))+(i&gt;1)*f(C[1:],i-1))


A function, f, taking the obstacle course as a list of rows, and returning the number of essentially different paths.

Explanation

The basic concept is this:
We choose a certain obstacle, o, such that there are no other obstacles in the box bounding o and the top-left corner.

+--+....
|..|....  
+--#&lt;==== o
.....#..
.#......
........


We then consider the two sub-courses to the east and to the south of o.
We only consider either of these sub-courses if o can actually be crossed from a direction that leads to them, that is, crossed from the north to get to the east, and crossed from the west to get to the south.
We solve the problem for each of the selected sub-courses, and return the sum of the results.
These numbers correspond to the number of essentially different paths when crossing o from the left and from the right, respectively,
therefore the two resulting sets of paths are essentially different.
Since there are no obstacles between the starting point and o, there is a path between the starting point and any entry point into each of these regions, and all such paths that lead to the same point are essentially similar, hence the above sum is the complete number of essentially different paths in the entire course.

                               A
_
........       ...|////      |....
........       ...|////      |....
...#....  --&gt;  ...#////  --&gt;  ....
.#....#.       .#..//#/       ..#.
........       ....////       ....

   |                           |
   v                           v
                  B
........       ___
........       .#....#.
___#....  --&gt;  ........  --&gt;   +
/#////#/       
////////       


Things are slightly complicated by the fact that the obstacle course alone doesn't convey all the information needed.
For example, consider course B in the diagram above.
Taken by itself, we can't determine whether each of the obstacles can be crossed from the north.
If B were the input course, then, since all paths start at the top-left corner, neither obstacle could have been crossed from the north, but, since we can reach B from either side of the left obstacle when crossing o from the east, we should treat this obstacle as though it can be crossed from the north when solving the course; the same doesn't hold for the right obstacle, however, which can't be crossed from this direction.

We convery this extra information by specifying, along with the obstacle course, the number of characters along the first row, starting from the left, that the path can start at.
In the diagram above, this is depcited as the solid line next to each course.
While, technically, we also need to specify the corresponding number of characters along the first column that the path can start at, as in the case of sub-course A, in practice we always selected the highest obstacle, so this information is not required.

The actual selection of o is as follows:
We pretend that each row, other than the last, is followed by an obstacle (i.e., has a # appended to it), and select the first obstacle in the resulting course, in reading order.
For rows (other than the last) that had no obstacle originally, this effectively mean that we skip them (while noting that the path below may start at any character along the top row).
Eventually, we end up with a course that has a single row with no obstacles, for which there is only one possible path.