Reconstruction de l'axe du pot avec un fragment via les normales de sommet
Je prévois de faire une reconstruction d'un pot entier à partir d'un fragment de celui-ci.
J'ai déjà pensé à un moyen de le faire, mais je ne sais vraiment pas comment y arriver dans le code.
Théorie: chaque fragment a une certaine inclinaison. Ce coude contient deux informations:
- l'orientation du fragment dans le pot
- le diamètre du pot. Vous pouvez facilement le voir lorsque vous activez les normales de sommet en mode d'édition. Techniquement, à partir du processus de fabrication de la poterie, il y a un axe central au milieu de chaque pot. Les normales de sommet croisent cet axe, de sorte que vous pouvez voir l'axe clairement lorsque vous activez les normales de sommet.
Problème: comment reconstruire cet axe via un script? mathématiquement, c'est l'intersection des normales des sommets avec un cylindre mince.
La première étape serait de sélectionner les normales de sommet à partir d'une certaine sélection uniquement, car je n'ai pas besoin de celle tournée vers l'extérieur ...
Éclat d'essai
Réponses
Preuve de concept
En plus de commenter, nous avons ajouté cela comme un moyen de preuve de concept,
Voici d'abord un script qui copie votre objet et maillage dans un autre, passe en mode édition et le convertit en coque convexe.
Sélectionnez le fragment et exécutez
import bpy
bpy.ops.object.mode_set()
bpy.ops.object.duplicate(linked=False)
dupe = bpy.context.object
dupe.display_type = 'WIRE'
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.convex_hull()
après quoi nouveau fil de fer de la coque convexe de l'original en mode édition avec toute la géométrie sélectionnée.
Le script suivant traverse les bords de la coque, trouve le point le plus proche du maillage sur son point central, les utilise pour créer un cercle à partir de la corde comme décrit ici Comment puis-je créer un segment d'arc / circulaire mathématiquement correct?
Pour visualiser ont ajouté un vert au centre du cercle et les deux arêtes de jonction. Comme les données seraient enregistrées en tant que rayon, coordonnée centrale et normale (axe de rotation le produit croisé normalisé de deux vecteurs d'arête)
Script de test, crée des "coins" de cercle prédits pour chaque arête sélectionnée. Exécuter avec un maillage de coque convexe en mode édition, arêtes d'intérêt sélectionnées.
import bpy
import bmesh
from math import asin, degrees
context = bpy.context
scene = context.scene
ob = context.object
me = ob.data
bm = bmesh.from_edit_mesh(me)
shard = scene.objects.get("3D_Scherbe_Model_50K")
#edges = bm.edges[:] # all edges
edges = [e for e in bm.edges if e.select]
#edges = [e for e in bm.select_history if isinstance(e, bmesh.types.BMEdge)]
for edge in edges:
o = (edge.verts[1].co + edge.verts[0].co) / 2
hit, loc, _, _ = shard.closest_point_on_mesh(o)
if hit:
h = (loc - o).length
if h < 0.1:
print("On surface")
continue
a = edge.calc_length() / 2
r = (a * a + h * h) / (2 * h)
if abs(a / r) > 1:
# math domain error on arcsin
print("N/A")
else:
angle = 2 * asin(a / r)
print(f"{r} {degrees(angle)}")
vc = bm.verts.new(o + r * (o - loc).normalized())
for v in edge.verts:
bm.edges.new((v, vc))
bmesh.update_edit_mesh(me)
me.update()
Remarques.
Au lieu de prédire un cercle du point le plus proche au centre du bord, vous pouvez marcher le bord et créer des points d'échantillonnage dans lesquels se croiser https://meshlogic.github.io/posts/jupyter/curve-fitting/fitting-a-circle-to-cluster-of-3d-points/ et https://github.com/ndvanforeest/fit_ellipse comme suggéré par @RobinBetts.
De même, vous pouvez utiliser l'estimation de cercle générée pour tester par rapport à la surface de maillage réelle.
Regardez la normale renvoyée par le point le plus proche du maillage.
Affinez la sélection, existe-t-il des données historiques suggérant des rayons ou un angle de coin dans une certaine plage.
Projeter (le point le plus proche sur le maillage) des "sous-accords" de longueur égale du bord sur le maillage, si chacun a le même rayon et angle serait une correspondance parfaite. Minimisez pour un meilleur ajustement.
Regardez les dimensions de la boîte englobante. Si une arête est plus courte qu'une fraction de la dimension minimale de la bbox, ce n'est probablement pas le grand axe du pot. Envisagez de raser un certain pourcentage.
Décimer le nettoyage ou lisser le maillage des éclats d'une manière ou d'une autre.