I'm really surprised at the whole filtering the rotation matrices thing, to me it is like, the long side of the piece is an arrow, that arrow can be pointed in one of six directions, I can rotate in one of four directions after that, so there's 24 orientations:
orientations = concat [
[
[(0,0,0), (t,0,0), (2*t,0,0), (3*t,0,0), (2*t, a, b)],
[(0,0,0), (0,t,0), (0,2*t,0), (0,3*t,0), (a,2*t,b)],
[(0,0,0), (0,0,t), (0,0,2*t), (0,0,3*t), (a,b,2*t)]
] | (a, b) <- [(1,0), (-1, 0), (0, 1), (0, -1)], t <- [1, -1]]
With translations, okay, there's 40 of those per piece and figuring out the right direction to go with those requires a cross product, sure, let's just generate 5×5×5 = 125 of them and filter out the right 40. But doing 20,000 determinants and whatever it was, 10-15 paragraphs, to filter out the right 24 orientations doesn't make as much sense to me.