Auto Reverse Shells in Houdini

Auto Reverse Houdini file

As I heard lots of positive remarks about Redshift for Houdini I decided to to test it for myself. So I dug up a few old car models I had built for a project at uni to assemble a test scene. They were modelled in Maya and since some mirrored objects (tires, rims, etc.) had negative scaling, parts of the mesh appeared flipped upon import. I never really liked how Maya would quietly set the “Opposite” flag on a shapes display settings when freezing negative transforms (although it can be handy when mirroring instanced objects)

Naturally I completely erased my initial plan and instead spent the afternoon finding a procedural method to automatically reverse the flipped shells. The models were exported as .obj files so everything was collapsed into a single mesh with no trace of object transforms. After some research I found a great answer on stackoverflow addressing this exact issue.

Its a very simple method: For a closed surface we may intersect a vector from every point in the direction of its normal. If the number of intersections is zero or even, the normals must be pointing outwards. Else the origin of the intersection vector would be inside the mesh, hence the normals pointing inwards.

    float max_dist = chf("max_dist");
    vector dir = normalize(v@N)*max_dist;
    vector bias = dir * chf("bias");
    vector pos = v@P + bias;
    vector hit_pos, hit_uv;
    int hit_prim = 0;
    int count = -1;
    
    while(hit_prim != -1) {
        hit_prim = intersect(0, pos, dir, hit_pos, hit_uv);
        pos = hit_pos + bias;
        count++;
    }
    i@flipped = count%2;
    

Theres two things I learned about the intersect() method here which I think are worth highlighting. Primarily that the length of the vector determines the maximum search distance. This is mentioned in the docs but of course I overlooked it and wasted a good 20 minutes figuring it out ^^. Secondly, adding a small bias along the normal to the vector origin helps deescalating floating point inaccuracy and is really important to get the expected result from intersect().

As you can see this method works pretty well – the reversed shells are highlighted in red. Unfortunately, since I have to close the meshes it will also reverse shells that are concave like parts of the rims and the interior. This is consistent with the underlying logic though, and in the end I had to manually reverse only 5 shells instead of ~100…so in my eyes its still successful.

The cars interior, showing the intersection rays and hits

Leave a Reply

Your email address will not be published. Required fields are marked *