Reconstrucción del eje de la olla con un fragmento a través de normales de vértice

Aug 16 2020

Estoy planeando hacer una reconstrucción de una olla completa a partir de un fragmento.

Ya he pensado en una forma de hacerlo, pero realmente no sé cómo hacerlo en código.

Teoría: cada fragmento tiene una cierta curvatura. Esta curva contiene dos piezas de información:

  • la orientación del fragmento dentro de la olla
  • el diámetro de la olla. Puede ver esto fácilmente al activar las normales de vértice en el modo de edición. Técnicamente, desde el proceso de elaboración de la cerámica, hay un eje central en el medio de cada vasija. Las normales de vértice cruzan este eje, por lo que puede ver el eje con claridad al activar las normales de vértice.

Problema: ¿cómo reconstruyo ese eje a través de un script? matemáticamente es la intersección de las normales del vértice con un cilindro delgado.

El primer paso sería seleccionar las normales de vértice de una selección determinada solamente, ya que no necesito la que mira hacia afuera ...

Fragmento de prueba

Respuestas

2 batFINGER Aug 18 2020 at 01:49

Prueba de concepto

Resultado en un solo borde seleccionado del casco convexo

Además de comentar, he agregado esto como una forma de prueba de concepto,

En primer lugar, aquí hay un script que copia su objeto y malla a otro, entra en modo de edición y lo convierte en un casco convexo.

Seleccione el fragmento y ejecute

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()

después de lo cual nuevo marco de alambre del casco convexo del original en modo de edición con toda la geometría seleccionada.

La siguiente secuencia de comandos atraviesa los bordes del casco, encuentra el punto más cercano en la malla a su punto medio, los usa para crear un círculo a partir de una cuerda como se describe aquí. ¿Cómo puedo crear un segmento circular / arco matemáticamente correcto?

Para visualizar se ha agregado un vértice en el centro del círculo y los dos bordes de unión. Como los datos se guardarían como radio, coordenada central y normal (eje de rotación, el producto cruzado normalizado de dos vectores de borde)

Prueba de secuencia de comandos, crea "cuñas" de círculo predichas para cada borde seleccionado. Ejecutar con malla de casco convexa en modo de edición, bordes de interés seleccionados.

Resultado en todos los bordes del casco convexo

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()

Notas.

  • En lugar de predecir un círculo desde el punto más cercano al centro del borde, podría caminar por el borde y hacer puntos de muestra para contraer https://meshlogic.github.io/posts/jupyter/curve-fitting/fitting-a-circle-to-cluster-of-3d-points/ y https://github.com/ndvanforeest/fit_ellipse como lo sugiere @RobinBetts.

  • De manera similar, podría usar la estimación del círculo generado para probar contra la superficie de malla real.

  • Mire el retorno normal del punto más cercano en la malla.

  • Reduzca la selección, ¿hay datos históricos que sugieran radios o ángulos de cuña dentro de un cierto rango?

  • Proyecte (punto más cercano en la malla) "subcadenas" de igual longitud de borde sobre malla, si cada uno tiene el mismo radio y ángulo, sería una combinación perfecta. Minimizar para un mejor ajuste.

  • Mira las dimensiones del cuadro delimitador. Si un borde es más corto que una fracción de la dimensión mínima de bbox, probablemente no sea el eje principal del bote. Considere recortar algún porcentaje.

  • Diezmar la limpieza o alisar la malla de fragmentos de alguna manera.