Plot 3D triangle mesh with different colours on front and back side

Guess this is so trivial no one bothered to ask… :wink:
I need to check orientation of triangles in received geometry (triangle mesh).
Seems the easiest way would be to set different colours for front and back side of the triangles,
but i have not been able to figure out how.
Prefer to use makie if possible, but not really a requirement. Neat if it works in a notebook.
Ideas, anyone?

Is it a closed mesh? If so, its boundary should be empty. Mis-oriented triangles will show up as extraneous boundaries. MeshCore.jl can help you compute the boundary.

do you mind sharing the triangles(geometry), I could put some color into them :smiley:

1 Like

You can sort-of do this based on the normal vectors with lighting attributes:

fig, ax, p = mesh(
    rand(Point3f0, 30), 
    [3i-j for i in 1:10, j in 0:2], 
    color = :white,
    ambient = Vec3f0(1,0,0),
    diffuse = Vec3f0(-100,0,100)

This will give triangles a red color by default (the Vec3f0’s passed act as multiplier to (red, green, blue)), and a blue color if dot(normal, lightdir) become positive and sufficiently large. So a red backside and a blue front side.

1 Like

@PetrKryslUCSD Yes the meshes are supposed to be closed - but I’m curious how that is supposed to relate to the colouring issue?

@lazarusA Thank you, nice offer but I did have something more general in mind :wink:

@ffreyer How do you mean “sort-of”…?
Seriously, I did expect someone to come up with a solution, but even already being impressed by Julia and Make i did not expect someone to come up with what is essentially a one-liner solution!
That said, when I try with some of my geometries, the colours of the triangles are not as clear-cut as in your example. Even after increasing the size of the diffuse vector five orders of magnitude the result still looks like the image below, which was created with the original “size 100” vector. Turning the box eventually makes the side facing the observer completely blue so the solution works for validating the geometries - but I’m curious why I don’t see the distinct colours of the triangle example.

It is not related directly to the coloring issue. But it is much easier and reliable to check that the mesh is closed
programmatically than it is to check it visually.

I guess that’s a good example of why I said “sort-of”. The solution judges front facing vs back facing based on the direction of normals relative to the light direction, which by default comes from the camera, i.e. the front. The math the shader does is essentially

color = color .* (ambient + diffuse * dot(normal, -lightdirection))

I assume in your case you have a shape with 8 vertices, i.e. 8 positions and 8 normals. The normals probably point diagonally outwards from the corners, not straight in the normal direction of any face/surface. If you render this with a normal color it probably looks kinda weirdly round if this is the case.
If the normals we have in the mesh were always surface normals, the dot product would return a positive number for all visible faces and everything would be blue. But with those weird mixture of three surface normals at each edge, we may get a negative component for some of them and therefore red. The area between vertices has their normals interpolated from the corners, so at some point it flips from one color to the other.

I see your point. But the need was not no “peek inside a crack” to see if the mash was closed, it was to find out whether some of the faces were in fact created with the nodes in the wrong order, actually pointing in the wrong direction. I could have been clearer with that in the OP.

Doh! Yes that makes sense. I just anticipated that without any fancy arguments the mesh sides would be flat. So much goodies included here. But reading your explanation I sort-of :wink: recall reading some post also having problem with normals not being surface normals. So I guess there is (currently) no way to make Makie actually use “flat surface normals”? Somehow that does - at least to me - sound like a less surprising default behaviour, with averaged node normals something you could ask for with a keyword argument.

So I guess there is (currently) no way to make Makie actually use “flat surface normals”?

The way to do that is to do duplicate vertices at hard edges. The rectangle mesh in GeometryBasics does that, for example

Still the same solution: the inconsistently oriented triangles will result in detection of boundaries where there should be none. Reference.

Hmmm, not necessarily, the definition of mesh boundary in (creative) 3D modeling is usually “polygon edges that are used in only one polygon”, regardless of consistent triangle orientation?

Note that I pointed to MeshCore, which would do the processing “outside” of the 3D modeling assumptions.