Fix: Add Mesh Extra Objects: Inverted normals of solids when vertex positions are inverted #105123

Merged
Thomas Barlow merged 3 commits from Mysteryem/blender-addons:fix_mesh_extra_objects_solid_inverted_normals into main 2024-01-16 21:38:19 +01:00
Showing only changes of commit 93d3b64772 - Show all commits

View File

@ -51,6 +51,11 @@ def vSum(list):
return reduce(lambda a, b: a + b, list) return reduce(lambda a, b: a + b, list)
# Get a copy of the input faces, but with the normals flipped by reversing the order of the vertex indices of each face.
def flipped_face_normals(faces):
return [list(reversed(vertex_indices)) for vertex_indices in faces]
# creates the 5 platonic solids as a base for the rest # creates the 5 platonic solids as a base for the rest
# plato: should be one of {"4","6","8","12","20"}. decides what solid the # plato: should be one of {"4","6","8","12","20"}. decides what solid the
# outcome will be. # outcome will be.
@ -146,7 +151,8 @@ def createSolid(plato, vtrunc, etrunc, dual, snub):
vInput, fInput = source(dualSource[plato]) vInput, fInput = source(dualSource[plato])
supposedSize = vSum(vInput[i] for i in fInput[0]).length / len(fInput[0]) supposedSize = vSum(vInput[i] for i in fInput[0]).length / len(fInput[0])
vInput = [-i * supposedSize for i in vInput] # mirror it vInput = [-i * supposedSize for i in vInput] # mirror it
return vInput, fInput # Inverting vInput turns the mesh inside-out, so normals need to be flipped.
return vInput, flipped_face_normals(fInput)
return source(plato) return source(plato)
elif 0 < vtrunc <= 0.5: # simple truncation of the source elif 0 < vtrunc <= 0.5: # simple truncation of the source
vInput, fInput = source(plato) vInput, fInput = source(plato)
@ -161,7 +167,8 @@ def createSolid(plato, vtrunc, etrunc, dual, snub):
vInput = [i * supposedSize for i in vInput] vInput = [i * supposedSize for i in vInput]
return vInput, fInput return vInput, fInput
vInput = [-i * supposedSize for i in vInput] vInput = [-i * supposedSize for i in vInput]
return vInput, fInput # Inverting vInput turns the mesh inside-out, so normals need to be flipped.
return vInput, flipped_face_normals(fInput)
# generate connection database # generate connection database
vDict = [{} for i in vInput] vDict = [{} for i in vInput]
@ -269,6 +276,10 @@ def createSolid(plato, vtrunc, etrunc, dual, snub):
if supposedSize and not dual: # this to make the vtrunc > 1 work if supposedSize and not dual: # this to make the vtrunc > 1 work
supposedSize *= len(fvOutput[0]) / vSum(vOutput[i] for i in fvOutput[0]).length supposedSize *= len(fvOutput[0]) / vSum(vOutput[i] for i in fvOutput[0]).length
vOutput = [-i * supposedSize for i in vOutput] vOutput = [-i * supposedSize for i in vOutput]
# Inverting vOutput turns the mesh inside-out, so normals need to be flipped.
flip_normals = True
else:
flip_normals = False
# create new faces by replacing old vert IDs by newly generated verts # create new faces by replacing old vert IDs by newly generated verts
ffOutput = [[] for i in fInput] ffOutput = [[] for i in fInput]
@ -287,7 +298,10 @@ def createSolid(plato, vtrunc, etrunc, dual, snub):
ffOutput[x].append(fvOutput[i][vData[i][3].index(x) - 1]) ffOutput[x].append(fvOutput[i][vData[i][3].index(x) - 1])
if not dual: if not dual:
return vOutput, fvOutput + feOutput + ffOutput fOutput = fvOutput + feOutput + ffOutput
if flip_normals:
fOutput = flipped_face_normals(fOutput)
return vOutput, fOutput
else: else:
# do the same procedure as above, only now on the generated mesh # do the same procedure as above, only now on the generated mesh
# generate connection database # generate connection database