86 lines
4.0 KiB
Python
86 lines
4.0 KiB
Python
import bpy
|
||
import bmesh
|
||
|
||
mesh_name = "chassis_low"
|
||
output_path = "C:\\Work\\Projects\\space-game001\\blender scripts\\output\\spaceship005.txt"
|
||
|
||
mesh_obj = bpy.data.objects.get(mesh_name)
|
||
|
||
if mesh_obj and mesh_obj.type == 'MESH':
|
||
# Обязательно применяем трансформации, чтобы координаты были актуальными
|
||
# Но для чистоты эксперимента берем mesh data как есть
|
||
|
||
# Работаем с копией меша, чтобы применить триангуляцию (если нужно)
|
||
# и не испортить сцену, но пока используем bmesh напрямую
|
||
bm = bmesh.new()
|
||
bm.from_mesh(mesh_obj.data)
|
||
|
||
# Получаем слой UV
|
||
uv_layer = bm.loops.layers.uv.active
|
||
|
||
# Словарь для хранения уникальных вершин:
|
||
# Ключ: (x, y, z, nx, ny, nz, u, v) -> Значение: новый_индекс
|
||
unique_verts_map = {}
|
||
final_vertices = [] # Список для записи в файл
|
||
final_indices = [] # Список индексов треугольников
|
||
|
||
# Проходим по всем фейсам
|
||
for face in bm.faces:
|
||
face_indices = []
|
||
|
||
# Проходим по углам (loops) фейса
|
||
for loop in face.loops:
|
||
vert = loop.vert
|
||
|
||
# 1. Координаты (округляем для надежности сравнения float)
|
||
co = (round(vert.co.x, 6), round(vert.co.y, 6), round(vert.co.z, 6))
|
||
|
||
# 2. Нормаль (если используете Smooth shading, берите vert.normal, если Flat - face.normal)
|
||
# Для простоты берем нормаль вершины
|
||
no = (round(vert.normal.x, 6), round(vert.normal.y, 6), round(vert.normal.z, 6))
|
||
|
||
# 3. UV координаты
|
||
if uv_layer:
|
||
raw_uv = loop[uv_layer].uv
|
||
uv = (round(raw_uv.x, 6), round(raw_uv.y, 6))
|
||
else:
|
||
uv = (0.0, 0.0)
|
||
|
||
# Собираем уникальный ключ данных вершины
|
||
vert_data_key = (co, no, uv)
|
||
|
||
# Проверяем, есть ли такая комбинация уже
|
||
if vert_data_key in unique_verts_map:
|
||
index = unique_verts_map[vert_data_key]
|
||
else:
|
||
index = len(final_vertices)
|
||
unique_verts_map[vert_data_key] = index
|
||
final_vertices.append(vert_data_key)
|
||
|
||
face_indices.append(index)
|
||
|
||
# Триангуляция "на лету" (если фейс - квадрат, делим на два треугольника)
|
||
# Простейший метод fan (0, 1, 2), (0, 2, 3)...
|
||
for i in range(1, len(face_indices) - 1):
|
||
final_indices.append(face_indices[0])
|
||
final_indices.append(face_indices[i])
|
||
final_indices.append(face_indices[i+1])
|
||
|
||
# --- ЗАПИСЬ В ФАЙЛ ---
|
||
with open(output_path, "w") as file:
|
||
file.write(f"===Vertices (Split by UV/Normal): {len(final_vertices)}\n")
|
||
# Формат строки: ID: X Y Z | NX NY NZ | U V
|
||
for idx, v_data in enumerate(final_vertices):
|
||
co, no, uv = v_data
|
||
file.write(f"V {idx}: Pos({co[0]}, {co[1]}, {co[2]}) Norm({no[0]}, {no[1]}, {no[2]}) UV({uv[0]}, {uv[1]})\n")
|
||
|
||
file.write(f"\n===Triangles (Indices): {len(final_indices) // 3}\n")
|
||
# Записываем тройками
|
||
for i in range(0, len(final_indices), 3):
|
||
file.write(f"Tri: {final_indices[i]} {final_indices[i+1]} {final_indices[i+2]}\n")
|
||
|
||
bm.free()
|
||
print(f"Export done. Original verts: {len(mesh_obj.data.vertices)}, Split verts: {len(final_vertices)}")
|
||
|
||
else:
|
||
print("Mesh not found") |