Hi,
my progress stopped understanding the rhino behavoir as i’m unable to remove normals from a mesh i have exploded into single faces.
In the example file the explode is done on the left with a commercial plugin that creates mesh faces without normals. If i make a mesh offset i get perfect quad elements.
My own script always creates a normal on the face the leads to intersecting quad elements.
is there a way to remove this normal?
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
import scriptcontext as sc
import Rhino
import scriptcontext
import math
import os
def unweld_all_faces(mesh_id):
# Netz aus der Rhino-Dokumentation abrufen
mesh = rs.coercemesh(mesh_id)
if not mesh:
print("Kein Netz gefunden.")
return
# Das Netz explodieren (d.h. in einzelne Faces zerlegen)
exploded_meshes = []
for face_index in range(mesh.Faces.Count):
# Extrahiere jede Face als einzelnes Netz
single_face_mesh = Rhino.Geometry.Mesh()
# Hole die Eckpunkte der aktuellen Face
face = mesh.Faces[face_index]
vertices = [mesh.Vertices[face.A], mesh.Vertices[face.B], mesh.Vertices[face.C], mesh.Vertices[face.D]]
# Füge die Vertices zum neuen Netz hinzu
for vertex in vertices:
single_face_mesh.Vertices.Add(vertex)
# Füge die Face zum neuen Netz hinzu (unabhängig von der Anzahl der Punkte)
if face.IsQuad:
single_face_mesh.Faces.AddFace(0, 1, 2, 3) # Quad Face
else:
single_face_mesh.Faces.AddFace(0, 1, 2) # Triangular Face
#Normals, Texturen, Farben usw. können hier auch übertragen werden, falls nötig
#single_face_mesh.Normals.ComputeNormals()
#single_face_mesh.Compact()
# Füge das explodierte Netz zur Liste hinzu
exploded_meshes.append(single_face_mesh)
# Lösche das ursprüngliche Netz
rs.DeleteObject(mesh_id)
# Füge die explodierten Netze zur Rhino-Dokumentation hinzu
for single_mesh in exploded_meshes:
sc.doc.Objects.AddMesh(single_mesh)
sc.doc.Views.Redraw()
print(f"{len(exploded_meshes)} Faces erfolgreich unwelded und explodiert.")
mesh = rs.GetObject("getmesh")
unweld_all_faces(mesh)
It looks to me like what you need is not so much to remove normals, but rather to have matching normals at the shared vertices.
Instead of exploding the mesh at the start, you can iterate through the faces, get their 4 vertex indices and then use the vertex normals at these indices when creating your offset.
import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
def unweld_all_faces(mesh_id):
# Netz aus der Rhino-Dokumentation abrufen
mesh = rs.coercemesh(mesh_id)
if not mesh:
print("Kein Netz gefunden.")
return
# Das Netz explodieren (d.h. in einzelne Faces zerlegen)
exploded_meshes = []
for face_index in range(mesh.Faces.Count):
# Extrahiere jede Face als einzelnes Netz
single_face_mesh = Rhino.Geometry.Mesh()
# Hole die Eckpunkte der aktuellen Face
face = mesh.Faces[face_index]
vertices = [mesh.Vertices[face.A], mesh.Vertices[face.B], mesh.Vertices[face.C]]
# Füge die Vertices zum neuen Netz hinzu und kopiere die Normalen
for i, vertex in enumerate(vertices):
single_face_mesh.Vertices.Add(vertex)
# Kopiere die Normalen der Vertices
normal = mesh.Normals[face[i]] # Hole die Normalen des entsprechenden Vertex
single_face_mesh.Normals.Add(normal)
# Füge die Face zum neuen Netz hinzu
if face.IsQuad:
single_face_mesh.Vertices.Add(mesh.Vertices[face.D]) # Füge den vierten Vertex bei Quad hinzu
single_face_mesh.Normals.Add(mesh.Normals[face.D]) # Füge den vierten Vertex Normal hinzu
single_face_mesh.Faces.AddFace(0, 1, 2, 3) # Quad Face
else:
single_face_mesh.Faces.AddFace(0, 1, 2) # Triangular Face
# Komprimiere das Netz
single_face_mesh.Compact()
# Füge das explodierte Netz zur Liste hinzu
exploded_meshes.append(single_face_mesh)
# Lösche das ursprüngliche Netz
rs.DeleteObject(mesh_id)
# Füge die explodierten Netze zur Rhino-Dokumentation hinzu
for single_mesh in exploded_meshes:
sc.doc.Objects.AddMesh(single_mesh)
sc.doc.Views.Redraw()
print(f"{len(exploded_meshes)} Faces erfolgreich unwelded und explodiert.")
def main():
# Benutzer wählt ein Netz aus
mesh_id = rs.GetObject("Bitte das Netz auswählen", rs.filter.mesh)
if mesh_id:
unweld_all_faces(mesh_id)
else:
print("Kein Netz ausgewählt.")
# Skript ausführen
main()