Реконструкция оси горшка с одним осколком через нормали вершин

Aug 16 2020

Планирую сделать реконструкцию целого горшка из одного его осколка.

Я уже придумал, как это сделать, но я действительно не знаю, как это сделать в коде.

Теория: у каждого осколка есть определенный изгиб. Этот изгиб содержит две части информации:

  • ориентация осколка внутри горшка
  • диаметр горшка. В этом легко убедиться, включив нормали вершин в режиме редактирования. Технически, в процессе изготовления керамики в середине каждого горшка есть центральная ось. Нормали вершин пересекают эту ось, поэтому вы можете четко видеть ось при включении нормалей вершин.

Проблема: как мне восстановить эту ось с помощью скрипта? математически это пересечение нормалей вершин с тонким цилиндром.

Первым шагом было бы выбрать нормали вершин только из определенного выделения, так как мне не нужна обращенная наружу ...

Тестовый осколок

Ответы

2 batFINGER Aug 18 2020 at 01:49

Доказательство концепции

Результат на одном выбранном ребре выпуклой оболочки

В дополнение к комментариям, добавили это как способ доказательства концепции,

Во-первых, вот скрипт, который копирует ваш объект и меш в другой, переходит в режим редактирования и преобразует его в выпуклую оболочку.

Выберите осколок и запустите

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

после чего новый каркас выпуклой оболочки оригинала в режиме редактирования со всей выбранной геометрией.

Следующий скрипт проходит через края корпуса, находит ближайшую точку на сетке к его средней точке, использует их для создания круга из хорды, как описано здесь. Как я могу создать математически правильную дугу / круговой сегмент?

Для визуализации добавили вершину в центре круга и два соединяющихся края. Поскольку данные сохраняются как радиус, координата центра и нормаль (ось вращения - нормализованное векторное произведение двух векторов ребер)

Тестовый скрипт создает предсказанные круговые «клинья» для каждой выбранной кромки. Запускаем с выпуклой сеткой корпуса в режиме редактирования, выбирая интересующие края.

Результат на всех краях выпуклой оболочки

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

Заметки.

  • Вместо того, чтобы прогнозировать круг от ближайшей точки к центру края, можно было бы пройти по краю и сделать точки выборки, чтобы https://meshlogic.github.io/posts/jupyter/curve-fitting/fitting-a-circle-to-cluster-of-3d-points/ и https://github.com/ndvanforeest/fit_ellipse как предлагает @RobinBetts.

  • Аналогичным образом можно использовать сгенерированную оценку круга для проверки фактической поверхности сетки.

  • Посмотрите на нормаль, возвращенную из ближайшей точки меша.

  • Сузьте выбор, есть ли исторические данные, которые предлагают радиусы или угол клина в определенном диапазоне.

  • Спроецируйте (ближайшую точку на сетке) «подхорды» края на сетку равной длины, если бы каждый имел одинаковый радиус и угол, было бы идеально. Сверните для наилучшего соответствия.

  • Посмотрите на размеры ограничивающей рамки. Если край короче некоторой доли минимального размера bbox, вероятно, это не главная ось горшка. Подумайте о том, чтобы немного сбрить его.

  • Уничтожение очисткой или сглаживание сетки осколков каким-либо образом.