I use a variety, of, methods to set the loop normals but want to read them to do some raycasting.

I thought I had to call calc_normals_split() then match up vertices via their vertex_index. However the result I get seems off from that shown by entering mesh edit mode and turning on show_normal_loop ("Display vertex-per-face normals as lines").

Here're are the results with colour names in top right describing each:

Image showing results

I want to get the magenta one which is produced by Blender itself.

Red and yellow are the untransformed and transformed point normals. The yellow ones correctly line-up with the blender-displayed point normals when turned on. That implies I'm using the correct matrix for transforming them from local to world (I used the inverse transpose technique explained here and here).

The black and cyan are the untransformed and transformed loop normals. Obviously they aren't near the magenta ones.

And finally a code excerpt. Obviously I'm using the GreasePencil API to do the drawing.

def getFirstLinkedLoopForVertex(objData, v):
    for l in objData.loops:
        if l.vertex_index == v.index:
            return l

def getMatrixForNormals(obj):
    return obj.matrix_world.inverted().transposed().to_3x3()

normalMatrix = getMatrixForNormals(raysSource)
 # TODO: Restore retro-normalized() -- non-uniform scale messes it up.
for l in [(p.co * raysSource.matrix_world, p.co * raysSource.matrix_world + (getFirstLinkedLoopForVertex(raysSource.data, p).normal * normalMatrix) * 0.2) for p in pointsToRaycast]:
    debugDrawLine(l, Color((0, 1, 1)), "loop * normalsMatrix = broken?") # cyan = loop * normalsMatrix = good?

Any help appreciated. Thanks in advance!

p.s. If I don't issue calc_normals_split() then the loop normals are all zero. Since I now suspect they're not the normals I'm looking for, I guess it's no value but I thought it'd be good to mention.



You must log in to answer this question.

Browse other questions tagged .