2025-12-01

This commit is contained in:
2026-03-17 14:58:51 -06:00
parent 183e865f8b
commit 4b82b57113
6846 changed files with 954887 additions and 162606 deletions
@@ -0,0 +1,41 @@
import bmesh
def bisect_on_axes(bm: bmesh.types.BMesh, xaxis: bool, yaxis: bool, zaxis: bool):
"""Bisect once for each axis specified"""
if xaxis:
bmesh.ops.bisect_plane(
bm,
geom=[v for v in bm.verts] + [e for e in bm.edges] + [f for f in bm.faces],
dist=0.0001,
plane_co=(0, 0, 0),
plane_no=(1, 0, 0),
use_snap_center=False,
clear_outer=False,
clear_inner=True # Remove geometry on negative side of plane
)
if yaxis:
bmesh.ops.bisect_plane(
bm,
geom=[v for v in bm.verts] + [e for e in bm.edges] + [f for f in bm.faces],
dist=0.0001,
plane_co=(0, 0, 0),
plane_no=(0, 1, 0),
use_snap_center=False,
clear_outer=False,
clear_inner=True # Remove geometry on negative side of plane
)
if zaxis:
bmesh.ops.bisect_plane(
bm,
geom=[v for v in bm.verts] + [e for e in bm.edges] + [f for f in bm.faces],
dist=0.0001,
plane_co=(0, 0, 0),
plane_no=(0, 0, 1),
use_snap_center=False,
clear_outer=False,
clear_inner=True # Remove geometry on negative side of plane
)
@@ -0,0 +1,64 @@
import bmesh
def export_sharp_features(bm: bmesh.types.BMesh, sharp_filepath: str, sharp_angle: float=35) -> int:
"""Export edges marked sharp, boundary, and seams as sharp features as OBJ format"""
sharp_edges = []
bm.edges.index_update()
bm.edges.ensure_lookup_table()
for edge in bm.edges:
if edge.is_wire:
continue
if not edge.smooth:
convexity = 1 if edge.is_convex else 0
face = edge.link_faces[0]
face_index = face.index
for ei, e in enumerate(face.edges):
if e.index == edge.index:
edge_index = ei
break
sharp_edges.append(f"{convexity},{face_index},{edge_index}")
num_sharp_features = len(sharp_edges)
with open(sharp_filepath, 'w') as f:
f.write(f"{num_sharp_features}\n")
for edge in sharp_edges:
f.write(f"{edge}\n")
f.close()
return num_sharp_features
def export_mesh(bm: bmesh.types.BMesh, mesh_filepath: str) -> None:
"""Export mesh as OBJ format"""
verts = []
vert_normals = []
faces = []
for v in bm.verts:
verts.append(f"v {v.co.x:.6f} {v.co.y:.6f} {v.co.z:.6f}")
for fid, f in enumerate(bm.faces):
# NOTE: Blender will export per face normals if flat-shaded, per face per loop normals if smooth-shaded
vert_normals.append(f"vn {f.normal.x:.4f} {f.normal.y:.4f} {f.normal.z:.4f}")
face_verts = []
for v in f.verts:
# NOTE: OBJ indices start at 1
face_verts.append(f"{v.index + 1}//{fid + 1}")
faces.append(f"f {' '.join(face_verts)}")
with open(mesh_filepath, 'w') as f:
f.write("# OBJ file\n")
f.write('\n'.join(verts))
f.write('\n')
f.write('\n'.join(vert_normals))
f.write('\n')
f.write('\n'.join(faces))
f.write('\n')
f.close()
@@ -0,0 +1,33 @@
import bpy
import os
def import_mesh(mesh_filepath: str) -> bpy.types.Mesh:
if not os.path.isfile(mesh_filepath):
raise Exception(f"File does not exist at {mesh_filepath}")
with open(mesh_filepath, 'r') as f:
lines = f.read().splitlines()
f.close()
verts = []
edges = []
faces = []
for line in lines:
tokens = line.split(' ')
element = tokens[0]
if element == 'v':
verts.append(tuple([float(coord) for coord in tokens[1:]]))
elif element == 'f':
# NOTE: OBJ indices start at 1
faces.append(tuple([int(vertex_id) - 1 for vertex_id in tokens[1:]]))
else:
continue
new_mesh = bpy.data.meshes.new('Mesh')
new_mesh.from_pydata(verts, edges, faces)
new_mesh.update()
return new_mesh