Labelling/Colouring edges based on concave convex angle

I am new to Blender and looking for some help.
Given a random scene of 3D shapes (see below), I am looking to label/colour the edges based on the angle between the 2 faces and separate them into 2 groups: concave and convex edges.

I was looking into Freestyle with Python scripting to create custom functions to calculate the angle between faces, but I can’t get the face information for a edge in Freestyle. I also looked at shaders but it doesn’t work perfectly for every random scene.

This seems like a task for geometry nodes… @zeroskilz @Zorro_Weaver @higgsas @SterlingRoth ?

1 Like

Simple solution with geometry nodes:

Remember to use the signed angle on the edge angle node or it won’t work.


Thanks for the help.
I works fine on meshes I make on Blender. However, its not working for my situation for some reason. My scene is from an imported OBJ file and with that scene, these geometry nodes aren’t working. If I change the “Greater Than” node to “Greater Than or Equal to” then it works, but that means its calculating the angle to 0.

I just imported the obj file and used the geometry nodes. Is there anything I need to do before/after importing for it to work?

example.blend (972.9 KB)
4.obj (8.5 KB)

Your imported model has splitted edges. Also some of the face normals are flipped (signed edge angle calculation depends on face normals orientation). In edit mode merge vertices by distance (M) and recalculate normals (Shift+N)


Thanks. I did those things and it seems to be working better but there are still some issues.
Here is another slightly simpler example. I merged the split edges and recalculated the normals. It labels the convex edges well but the concave edge (edge near yellow dot) isn’t getting labeled at all. Using the viewer node, it seems that that edge angle is still 0.

Also, sometimes merging vertices by distance won’t be the best solution for me as it is removing some actual shape defining vertices. Is there a better way to do this in Blender or do I have to implement something programatically?

3.obj (2.8 KB)
3_0.blend (766.8 KB)

Screenshot 2023-03-13 at 5.20.02 PM

Problem is non-manifold edges, you can try to assume that all non-manifold edges is concave with this setup

Try to use lower merge distance


Thanks alot.
Its working alot better now. I have been trying it for some random examples, but, sometimes it seems to be labelling convex (red) edges as concave (blue).

Screenshot 2023-03-13 at 6.49.32 PM
3_0.blend (707.3 KB)

Here is another example. Again, the angle seems convex but its being labelled concave.
Screenshot 2023-03-14 at 11.46.42 AM

ex.blend (729.4 KB)

The issue seems to be an edge angle calculation ambiguity due to non-planar faces. If the corresponding faces on an edge aren’t flat, there’s no way to indefinitely find the angle of that edge. If you cut them into tris, or flatten them, the issue is eliminated.

I’d recommend avoiding distorted faces in your model or triangulating everything first.


When in edit mode you grab a face and it leaves the rest of the mesh in place…
I always use the weld modifier on those…

Thanks for the help. I have some questions to clarify on.

  1. Above I was told that I had to merge vertices by distance and recalculate normals. Is that because when I import an OBJ file, there will be duplicate edges and vertices and we are just removing those?

  2. Regarding the non-planar faces: I create these scenes using a generator program and I am trying to modify it, but I prefer if I can do it in Blender.

  • Are there any other ways to fix it other than cutting them into tris as I don’t want to create additional edges?

  • Where is the flatten option? I don’t see it.

  • In Edit Mode → Mesh → Cleanup, there is a make faces planar option, but it does nothing.

Yes. It depends on the source, but some software will create split edges and double verts. You’ll have to clean them up to get proper results with the edge angle node.

I was referring to Mesh → Cleanup → Make Faces Planar.

It appears I was mistaken before, in this situation, the particular face in question seems to be planar, so flattening it yields no result. However, it’s an n-gon, and the normal calculation of n-gons can be buggy sometimes, because typically, you’re only supposed to use tris and quads if you can.

It looks like there’s just some issue with calculating that particular edge. If you move it just a smidge with vertex slide (press G twice), it fixes the problem.

Thanks. That makes sense.

Here attached is one more examples where this issue occurs. I couldn’t fix it with the vertex slide. Could you please take a look to see if its due to non-planar faces or its since its n-gonal? Also, how do you determine if a face is non-planar in Blender (is there a feature to do so)?
3_0.blend (707.3 KB)

My goal is to eventually take all this and autom
ate this labelling using a python script. So, I need to have a procedure that works with all instances.

From what I can understand, the edge angle calculation can buggy due to non-planar faces or n-gonal faces. I am thinking to automate it is that I select faces with more that 4 vertices and triangulate them. This way I don’t have to triangulate the whole object and only create some new edges. Do you think thats the best way?

Also, since the Edge Angle Node can be buggy, is there any way I can create my own custom edge angle calculation to do the calculation ie. a custom geometry node?

@Zorro_Weaver @higgsas
As mentioned above, I am planning to convert this to a python script so to automate it to work in every situation.

I think triangulating n-gonal faces works to solve the mislabelling issue, but it creates these new edges that I don’t want labeled/coloured. Is there a way to use Geometry Nodes or anything else to exclude/hide edges.

How my program/procedure works:

  1. Merge vertices by distance and recalculate
  2. Find faces with more than 4 vertices, and triangulate them
  3. Use Geometry nodes to calculate convex concave edges (Can I exclude newly created edges from triangulate?)
  4. Hide/Remove newly created edges from triangulate

I can find the newly created edges by comparing the mesh’s edges before and after triangulation. But, I am not sure how to exclude them without effecting the concavity.

Screenshot 2023-03-17 at 11.47.36 AM

The following setup should work:

convexitycolors.blend (686.0 KB)

It essentially does exactly what you described above. First, it triangulates all faces with more than 4 verts. It then captures the edge angle so that it’s preserved when the geometry is modified. Finally, it deletes all edges with near zero angles. Depending on the mesh, you may have to adjust the epsilon value in the equal node to account for edges that have an angle that’s slightly greater or less than 0 after the triangulate.

1 Like

Thanks alot. That makes sense.

One final thing is that this doesn’t fully work for non-manifold edges anymore. The part at the bottom pf the second part should catch and label non-manifold edges as concave. I think its deleting the non-manifold edges as the edge angle is 0 for those edges. So, I added additional nodes so the Delete Geometry ignores these edges. However, it still doesn’t work. But, when I set the edge neighbours to greater than -2, it works for some reason.

Screenshot 2023-03-17 at 2.37.14 PM
Screenshot 2023-03-17 at 1.39.46 PM

manifold.blend (739.3 KB)


Ok I think I figured it out.
The 2nd Edge Neighbours node calculation runs after the Delete Geometry node and takes that as the geometry when calculating the edge neighbours and since some faces are deleted, the calculation is wrong.

I fixed the problem using 2 approaches. I was wondering if one is better than the other in terms of efficiency.

  1. After the Join Geometry node, since all the faces are back, I check the face neighbours and create the material.

  2. I use the Capture Attribute node before the Delete Geometry node to store the edge neighbours data and then access it after.

I want to make sure I am not missing anything and if this makes sense to label non-manifold edges.

I am looking to create a script to select edges based on some visibility conditions.
I want to select edges where only one face (that the edge is connected to) is visible from the camera viewpoint. Then, I want to colour these edges.

I tried using Freestyle and label using silhouettes and contours, but it doesn’t always work and produces some weird results (check below). For some reason, using Freestyle external contour, it labels these inner edges. Hence, I am looking to create a script the definitively colours edges with only 1 visible face.

Is this possible? I feel I can achieve the colouring using Freestyle, but I am not sure how to select the edges based on face visibility.

just spit balling here but I would probably do a bvh overlap test and then cull any edges based on the dot product of the cameras direction vector(or is that a single manifold mesh? Looks like multiple that are overlapping)