import bmesh
import ddg.math.euclidean
import ddg.math.projective as putils
from ddg.datastructures.halfedge.surface_generator import icosphere, cylinder
from ddg.conversion.blender.halfedge import hes_to_bmesh
import numpy as np
import math
############### Generate bmesh functions #######################
#############################################################################
[docs]def from_pydata(verts, edges, faces, bm=None, doubles=False):
"""
Parameters
----------
verts : list(coordinate vector)
edges : list(tuples)
faces : list(tuples)
bm : bmesh (optional, default=None)
doubles : bool (optional, default=False)
Returns
-------
bmesh
"""
if bm is None:
bm = bmesh.new()
else:
bm.clear()
for v in verts:
bm.verts.new(v)
bm.verts.ensure_lookup_table()
if not doubles:
for e in edges:
e = [bm.verts[i] for i in e]
bm.edges.new(e)
for f in faces:
f = [bm.verts[i] for i in f]
bm.faces.new(f)
else:
found = set()
for e in edges:
temp = list(e)
temp.sort()
temp = tuple(temp)
if not temp in found:
e = [bm.verts[i] for i in e]
bm.edges.new(e)
found.add(temp)
found = set()
for f in faces:
temp = list(f)
temp.sort()
temp = tuple(temp)
if not temp in found:
f = [bm.verts[i] for i in f]
bm.faces.new(f)
found.add(temp)
return bm
############### Modify bmesh functions #######################
#############################################################################
[docs]def join(*bmeshes, free=False, bm=None):
"""Join bmeshes.
Parameters
----------
*bmeshes : bmesh
bmeshes to join.
free : bool (optional, default=False)
free joined bmeshes
bm : bmesh (optional, default=None)
bmesh to store joined bmeshes in
Returns
-------
bmesh
bmesh 'containing' all given bmeshes.
"""
if bm is None:
combined = bmesh.new()
else:
combined = bm
combined.clear()
for mesh in bmeshes:
mesh.verts.ensure_lookup_table()
mesh.verts.index_update()
offset = len(combined.verts)
for vert in mesh.verts:
combined.verts.new(vert.co)
combined.verts.index_update()
combined.verts.ensure_lookup_table()
for edge in mesh.edges:
seq = tuple(combined.verts[i.index+offset] for i in edge.verts)
combined.edges.new(seq)
combined.edges.index_update()
for face in mesh.faces:
seq = tuple(combined.verts[i.index+offset] for i in face.verts)
combined.faces.new(seq)
combined.faces.index_update()
if free:
mesh.free()
return combined
[docs]def bisect_plane(bm, normal=np.array((0, 0, 1)), dist=0):
a = np.multiply(dist / np.linalg.norm(normal) ** 2, normal)
result = bmesh.ops.bisect_plane(bm,
dist=0.,
geom=bm.verts[:] + bm.edges[:] + bm.faces[:],
plane_co=a,
plane_no=normal,
clear_inner=False,
clear_outer=True)
[docs]def cut_between_coordinate_planes(bm, axis=0, dist=1., location=np.array((0, 0, 0))):
normal = np.zeros(3)
normal[axis] = 1
bisect_plane(bm, normal=normal, dist=dist + np.inner(location, normal))
bisect_plane(bm, normal=-normal, dist=dist - np.inner(location, normal))
[docs]def cut_bounding_box(bm, distances=np.array((1., 1., 1.)), location=np.array((0, 0, 0))):
for i, dist in enumerate(distances):
if dist is not None:
cut_between_coordinate_planes(bm, axis=i, dist=dist, location=location)