Merekonstruksi sumbu pot dengan satu pecahan melalui vertex normals
Saya berencana untuk melakukan rekonstruksi seluruh pot dari satu pecahan.
Saya sudah memikirkan cara untuk melakukannya, tetapi saya benar-benar tidak tahu bagaimana mewujudkannya dalam kode.
Teori: setiap pecahan memiliki lengkungan tertentu. Tikungan ini berisi dua informasi:
- orientasi pecahan di dalam pot
- diameter pot. Anda dapat dengan mudah melihat ini saat mengaktifkan vertex normals dalam mode edit. Secara teknis dari proses pembuatan gerabah terdapat poros tengah di tengah-tengah setiap pot. Vertex normals melintasi sumbu ini, sehingga Anda dapat melihat sumbu dengan jelas saat menyalakan vertex normals.
Masalah: bagaimana cara saya merekonstruksi sumbu itu melalui skrip? secara matematis itu adalah perpotongan dari simpul normal dengan silinder tipis.
Langkah pertama adalah memilih vertex normals dari seleksi tertentu saja, karena saya tidak memerlukan yang menghadap ke luar ...
Uji Shard
Jawaban
Bukti dari konsep
Selanjutnya untuk berkomentar, telah menambahkan ini sebagai cara untuk membuktikan konsep,
Fistly di sini adalah skrip yang menyalin objek dan mesh Anda ke yang lain, masuk ke mode edit dan mengubahnya menjadi convex hull.
Pilih pecahan dan jalankan
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()
setelah itu bingkai kawat baru dari lambung cembung asli dalam mode edit dengan semua geometri dipilih.
Skrip berikutnya melewati tepi lambung kapal, menemukan titik terdekat pada jala ke titik tengahnya, menggunakan ini untuk membuat lingkaran dari akor seperti yang dijelaskan di sini Bagaimana cara membuat segmen busur / lingkaran yang benar secara matematis?
Untuk memvisualisasikan telah menambahkan sebuah simpul di tengah lingkaran dan dua tepi yang bergabung. Karena data akan disimpan sebagai jari-jari, koordinat pusat, dan normal (sumbu rotasi produk silang yang dinormalisasi dari dua vektor tepi)
Uji skrip, membuat "irisan" lingkaran yang diprediksi untuk setiap tepi yang dipilih. Jalankan dengan jaring lambung cembung dalam mode edit, tepi yang diinginkan dipilih.
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()
Catatan.
Alih-alih memprediksi lingkaran dari titik terdekat ke pusat tepi, bisa berjalan di tepi dan membuat titik sampel untuk dimasuki https://meshlogic.github.io/posts/jupyter/curve-fitting/fitting-a-circle-to-cluster-of-3d-points/ dan https://github.com/ndvanforeest/fit_ellipse seperti yang disarankan oleh @RobinBetts.
Demikian pula dapat menggunakan estimasi lingkaran yang dihasilkan untuk menguji permukaan mesh yang sebenarnya.
Lihatlah hasil normal dari titik terdekat pada mesh.
Persempit pilihan, adakah data historis yang menunjukkan sudut jari-jari atau irisan dalam kisaran tertentu.
Proyek (titik terdekat pada mata jaring) dengan panjang yang sama "subkord" dari tepi ke mata jaring, jika masing-masing memiliki radius dan sudut yang sama akan menjadi pasangan yang cocok. Minimalkan agar paling sesuai.
Lihatlah dimensi kotak pembatas. Jika tepi lebih pendek dari beberapa pecahan dari dimensi bbox minimum, itu mungkin bukan sumbu pot utama. Pertimbangkan untuk mengurangi persentase.
Menghancurkan pembersihan atau menghaluskan jaring pecahan dengan cara tertentu.