Tái tạo trục của nồi với một mảnh thông qua các tiêu chuẩn đỉnh
Tôi đang lên kế hoạch tái tạo lại toàn bộ cái nồi từ một mảnh của nó.
Tôi đã nghĩ ra cách để làm điều đó, nhưng tôi thực sự không biết làm thế nào để biến nó thành hiện thực trong mã.
Lý thuyết: mọi mảnh vỡ đều có một phần uốn cong nhất định đối với nó. Phần uốn cong này chứa hai thông tin:
- hướng của mảnh trong chậu
- đường kính của chậu. Bạn có thể dễ dàng nhận thấy điều này khi bật tiêu chuẩn đỉnh trong chế độ chỉnh sửa. Về mặt kỹ thuật, từ quá trình làm gốm, giữa mỗi chiếc bình đều có một trục tâm. Các chuẩn đỉnh cắt qua trục này, vì vậy bạn có thể nhìn thấy trục rõ ràng khi bật chuẩn đỉnh.
Vấn đề: làm cách nào để tạo lại trục đó thông qua tập lệnh? về mặt toán học, nó là giao điểm của các chuẩn đỉnh với một hình trụ mỏng.
Bước một sẽ là chỉ chọn các điểm chuẩn của đỉnh từ một lựa chọn nhất định, vì tôi không cần cái hướng ra ngoài ...
Thử nghiệm Shard
Trả lời
Bằng chứng của khái niệm
Thêm vào đó để nhận xét, đã thêm điều này như một cách nào đó để chứng minh khái niệm,
Fistly ở đây là một tập lệnh sao chép đối tượng và lưới của bạn sang một đối tượng khác, chuyển sang chế độ chỉnh sửa và chuyển đổi nó thành một vỏ lồi.
Chọn phân đoạn và chạy
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()
sau đó khung dây mới của vỏ lồi của bản gốc ở chế độ chỉnh sửa với tất cả hình học được chọn.
Tập lệnh tiếp theo đi qua các cạnh của thân tàu, tìm điểm gần nhất trên lưới với điểm giữa của nó, sử dụng chúng để tạo một vòng tròn từ hợp âm như được mô tả ở đây Làm cách nào để tạo một đoạn cung / tròn chính xác về mặt toán học?
Để hình dung, đã thêm một vert ở tâm vòng tròn và hai cạnh nối. Vì dữ liệu sẽ lưu dưới dạng bán kính, tọa độ tâm và pháp tuyến (trục quay tích chéo chuẩn hóa của hai vectơ cạnh)
Tập lệnh thử nghiệm, tạo "nêm" vòng tròn dự đoán cho mỗi cạnh đã chọn. Chạy với lưới vỏ lồi ở chế độ chỉnh sửa, các cạnh quan tâm được chọn.
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()
Ghi chú.
Thay vì dự đoán một vòng tròn từ điểm gần nhất đến tâm cạnh, có thể đi bộ cạnh và tạo các điểm mẫu để thu thập https://meshlogic.github.io/posts/jupyter/curve-fitting/fitting-a-circle-to-cluster-of-3d-points/ và https://github.com/ndvanforeest/fit_ellipse theo đề xuất của @RobinBetts.
Tương tự, có thể sử dụng ước tính vòng tròn được tạo để kiểm tra so với bề mặt lưới thực tế.
Nhìn vào điểm bình thường được trả về từ điểm gần nhất trên lưới.
Thu hẹp lựa chọn, có dữ liệu lịch sử gợi ý bán kính hoặc góc nêm trong một phạm vi nhất định.
Dự án (điểm gần nhất trên lưới) có chiều dài bằng nhau "các dây đàn con" của cạnh lên lưới, nếu mỗi chiếc có cùng bán kính và góc sẽ là một kết hợp hoàn hảo. Giảm thiểu để phù hợp nhất.
Nhìn vào kích thước hộp giới hạn. Nếu một cạnh ngắn hơn một số phần nhỏ của kích thước bbox tối thiểu thì nó có thể không phải là trục nồi chính. Cân nhắc cạo bớt một số phần trăm.
Làm sạch hoặc làm mịn lưới mảnh vỡ theo một cách nào đó.