2

I've been learning hard surface modelling and after a while noticed that some polys of my mesh are darker than others. On closer inspection, it appears that each of these is somehow not a single face but 2 polys taking same exact space and sharing same exact vertices.

Initially, I thought that this happens due to duplicated verts and did Merge By Distance but apparently that's not the case. If I Box Select one of those polys in Wireframe Mode, Blender 2.80 prints Verts: 4, Edges: 4, Faces: 2.

I strongly suspect that doing Fill Holes (Alt+F) did this to me, but I don't understand why.

Any ideas on how to fix this? I surely can pick them manually but would like to know a proper solution which can remove them automagically. Googling yielded nothing but I might've been googling wrong terms.

enter image description here

Harry McKenzie
  • 10,995
  • 8
  • 23
  • 51
Max Yari
  • 131
  • 8
  • Have you tried going to edit mode, selecting all and then mesh > normals > recalculate outside? – Christopher Bennett Jun 23 '20 at 07:37
  • Does this help ? https://blender.stackexchange.com/a/34514/86891 – Gorgious Jun 23 '20 at 07:39
  • @ChristopherBennett those faces are still there, but now shading is all weird (and also resembles a badly drawn penises) http://prntscr.com/t4su94 – Max Yari Jun 23 '20 at 07:39
  • @Gorgious if you mean using F to merge faces - then no, it messes up mesh if used on the whole thing, and does nothing if used on individual pair. – Max Yari Jun 23 '20 at 07:41
  • Recalculate inside then? I'm not sure.... something else must be going on, because that shouldn't happen. When you merge by distance, did you try increasing the value above the default 0.0001m? – Christopher Bennett Jun 23 '20 at 07:50
  • Better yet, any chance you could post your .blend file? I'd be really curious to know what's going on. You can do it here if you like - https://blend-exchange.giantcowfilms.com/ – Christopher Bennett Jun 23 '20 at 07:54
  • @ChristopherBennett same effect. Want to restate that my problem is that there are duplicated faces, like 2 layers of faces in exact same space, but without duplicated verts or edges. I doubt that any operations with normals will remove unwanted faces :( But i guess normals might have been the reason for them appearing in the first place, like screwing up fill holes operation or something – Max Yari Jun 23 '20 at 07:54
  • @ChristopherBennett sure, i haven't thought about posting blend file, a moment. – Max Yari Jun 23 '20 at 07:57
  • Have you tried limited dissolve ? – Gorgious Jun 23 '20 at 08:00
  • @ChristopherBennett added blend file – Max Yari Jun 23 '20 at 08:01
  • @Gorgious yes it actually leaves those intact even if I crank up angle high while messing up all the rest of the mesh :D – Max Yari Jun 23 '20 at 08:02
  • This may be Z-fighting. Remove the obsolete face. – Lukasz-40sth Jun 23 '20 at 09:49
  • I was able to reproduce this issue with https://blender.stackexchange.com/questions/282322/is-having-2-faces-with-4-shared-vertices-a-bug-or-valid-geometry – Harry McKenzie Dec 27 '22 at 06:10

3 Answers3

5

Ok. I got it to work by doing this:

  • Select all > Mesh > Split > Faces by Edges
  • Merge by distance
  • Recalculate outside (just to be safe)

Though I'm still not sure exactly what was going on, there were obviously a great number of duplicate SOMETHING because the merge by distance operation after the edge-split removed 8743 vertices.

I suspect that the fill-holes operation ( on whatever you had selected when you performed it) created faces that were SOMEWHERE? (I give pause here because up until now, I believed it impossible for blender to define 2 faces with the same verts and edges in the same place - if anyone can clarify further, It would be very informative, and I would be very curious to know how this works).

The only way I can conceive of this happening is that there could be 2 faces on top of one another with their normals facing opposite ways, however this theory is negated by the normal's directions themselves as seen in the images below:

Normals1

Normals2

Regardless, the "faces-on-faces" theory still has some merit, because that's the only way I can explain an edge split followed by a merge by distance working the way it did. The only other POSSIBLE thing I can think of is that somehow, some faces got "folded back on themselves", creating the ultimate 180 degree non-manifold plane (sounds weirder the more that I think about it).

Either way, my guess is this is likely the result of a fill-holes operation on to many conjoined faces at once. That's the best I can do. Anyone who knows more about how this type of situation can come about is welcome to explain it further.

Here is an updated .blend with the result of the operations (however they worked)

Christopher Bennett
  • 25,875
  • 2
  • 25
  • 56
  • 1
    While not automagical, it sure is more wholesome for a solution in case the same issue is spread over the mesh. Splitting all faces to then later merge by distance is a nice workaround. But you only need to merge and then recalculate, as faces on top of each other won't affect the merge no matter what direction they face. – Xylvier Jun 23 '20 at 08:22
  • 1
    I played with it some more, it turns out it was even simpler than that - 2 steps. But I agree, the same issue affected the whole mesh in this case. Possibly the result of that curious boolean modifier combined with a fill holes operation? Either way, the merge removed 8743 verts, so something heavy was going on. – Christopher Bennett Jun 23 '20 at 08:24
  • This sounds solid, don't have time to check right now though, will try later today. Thanks for the answer! – Max Yari Jun 23 '20 at 08:26
  • 1
    Simple is good, but in case of automating the solution to make it more magical, i'd include the recalculate outside. Please consider though to explain a bit why you did what you did to make it easier to understand the underlying issue. Gonna remove my answer, so i would be glad to see a bit more details in your answer ;) – Xylvier Jun 23 '20 at 08:30
  • 1
    I would say leave yours. Mine happened to work in this simple case, but more complicated instances would require a more elegant solution. – Christopher Bennett Jun 23 '20 at 08:32
  • Any clue though why this could've potentially happened? Tbh previously I haven't even thought that it's possible for two polys to share all of their vertices. – Max Yari Jun 23 '20 at 08:38
  • 1
    I can only speculate, I updated my answer to include my thoughts. – Christopher Bennett Jun 23 '20 at 08:53
  • 1
    @Xylvier - I know exactly what you're saying when you point out it makes no sense to split, only to merge again right after, but for some very strange reason it works here. I tried merging first, then recalculating the normals, but it gives some very strange results. Try on his blend and see for yourself. For some reason the split is necessary first, and I don't know why - I've never seen anything quite like it. – Christopher Bennett Jun 23 '20 at 09:03
  • 3
    I would definitely call this a bug. As you pointed out the mesh algorithms should not authorize two faces to have the exact same vertices, like how you can't have a face with a hole in it. – Gorgious Jun 23 '20 at 09:07
  • 3
    Agreed. It's very strange - It's something impossible, yet I'm looking right at it. It's either a bug, a miracle, or some kind of paradox that holds the secrets of the universe. – Christopher Bennett Jun 23 '20 at 09:14
  • 1
    Also regarding how it can happen, i tried to create a face where i had one that i first hid, pressing F does not work, but pressing Alt+F (Fill) can create a new face where there already is one. So my guess is that some faces might have been hidden before, looking like holes. Using Fill fixed it, but at the same time the hidden faces were made visible as well, resulting in the problem. – Xylvier Jun 23 '20 at 11:01
  • 1
    @ChristopherBennett Regarding the splitting to then merge, it's a necessity to work around the problem that Blender can't merge faces that share the same vertices. Vertices can be merged, faces not yet (at least not this way) Splitting by edge does generate new vertices for each face, resulting in loose faces with their own vertices that share the same location with the doubles, which then by merging get cleaned up, as those 4 vertices are double, they get removed. Result is one face gone with them as well. Had to rewrite to correct my wording. – Xylvier Jun 23 '20 at 11:15
  • Lmao, I was thinking that me being silly with only a slight chance of this being a genuine bug. Guess it's just 2.80 being a bit raw. Would've tried it on newer version if i knew how exactly i did that. @Xylvier interesting guess regarding filling hidden, I don't remember hiding those faces, but maybe that was some kind of accident. Anyway ChristopherBennett, Xylvier, Gorgious - thanks everyone, that was quite fascinating :D Also there's no Split -> Faces by edges in 2.80, but there's "Edge split" which does the same afaik. It worked and removed 9k (0_0) verts. – Max Yari Jun 24 '20 at 16:04
  • @Gorgious yes it is confirmed bug caused by Limited Dissolve https://developer.blender.org/T70977 – Harry McKenzie Dec 30 '22 at 15:17
  • workaround fix: https://blender.stackexchange.com/a/290949/142292 – Harry McKenzie Apr 18 '23 at 09:27
3

This script is as inefficient as it gets but it did the trick for me.

We iterate over the mesh faces indices in reversed order to prevent the infamous "delete elements from a collection while iterating over it" hair-pulling situation :

Important : you need to be in object mode and have your object selected before running this script

Basically, for each face polygon we iterate over every other face polygon and check if they both share the exact same vertices. If they do, we remove one of these two faces. (Extremely inefficient in large meshes)

import bpy, bmesh

obj = bpy.context.active_object bm = bmesh.new() bm.from_mesh(obj.data)

bm.faces.ensure_lookup_table() faces = bm.faces double_faces = []

for i in range(len(faces) - 1, 0, -1): for j in range(i - 1, -1, -1): if all([vert in faces[i].verts for vert in faces[j].verts]): double_faces.append(i)

for f in double_faces: bm.faces.ensure_lookup_table() faces.remove(faces[f])

bm.to_mesh(obj.data)

Gorgious
  • 30,723
  • 2
  • 44
  • 101
  • 1
    Yes, this does sound quite inefficient if you have thousands of polys to iterate, maybe it can iterate over selected polys instead (which could be a good compromise between full automation and performance)? But anyway it's a legit approach, thanks :) – Max Yari Jun 24 '20 at 16:06
  • execute this in the python console for m in D.meshes: m.validate() then select the object. fixes the issue! thanks to this answer – Harry McKenzie Apr 18 '23 at 09:14
3

Here's the simplest fix by @scurest from this answer. Simply go to the Python Console and execute the following code line:

for m in D.meshes: m.validate()

You need to press Enter twice.

enter image description here

Then select the object in Object Mode to update the view. This instantly fixes all double-faced faces for all meshes.

Harry McKenzie
  • 10,995
  • 8
  • 23
  • 51