Source code for ddg.conversion.blender.halfedge

import bmesh
import bpy
import numpy as np

import ddg
import ddg.math.euclidean
from ddg.blender.mesh import duplicate_by_transformation_matrices, from_bmesh


[docs]def hes_to_bmesh(hes, co_attr="co", bpy_data=None): """ Converts a given half-edge surface into a bmesh. The returned bmesh can then be used for handing over the surface to Blender. Parameters ---------- hes : ddg.halfedge.Surface The half-edge surface that shall be converted to a bmesh. co_attr : coordinate attribute The type of coordinates that will be taken for conversion. bpy_data : bmesh (optional, default=None) When given, bmesh to save the data into. Returns ------- bmesh The bmesh corresponding to the input half-edge surface. """ if bpy_data is None: hes_bmesh = bmesh.new() else: hes_bmesh = bpy_data hes_bmesh.clear() co = getattr(hes.verts, co_attr) # create vertices # by adding new vertices to the bmesh for _ in range(len(hes.verts)): hes_bmesh.verts.new() # and handing over the coordinates hes_bmesh.verts.ensure_lookup_table() tmp_dict = dict() # for rebuilding the faces: save the correspondence of # the bmesh-vertex and its corresponding hes-vertex-id for i, v in enumerate(hes.verts): hes_bmesh.verts[i].co = co[v] tmp_dict[id(v)] = hes_bmesh.verts[i] # create faces for f in hes.faces: face_verts = list(ddg.halfedge.face_vertices(f)) hes_bmesh.faces.new([tmp_dict[id(v)] for v in face_verts]) # catch edges not belonging to a face for e in ddg.halfedge.single_edges(hes): if e.face is None and e.opp.face is None: hes_bmesh.edges.new([tmp_dict[id(e.opp.head)], tmp_dict[id(e.head)]]) return hes_bmesh
[docs]def face_objects( heobj, bobj, collection=None, location_attr="co", rotation_attr=None, scale_attr=None, material_attr=None, ): """ places a Blender object at every face of the given half-edge object. Parameters ---------- see vertex_object. Returns ------- vobjs: list list of Blender objects placed at each face of given half-edge object. Notes ----- Half-edge face's does not natively store a location attribute this must be calculated and added as an attribute before hand. """ faces = heobj.faces transformations = [] material = [] for f in faces: co_obj = np.array(list(getattr(f, location_attr)) + [1]) translation_mat = np.concatenate([np.eye(4, 3), co_obj.reshape(-1, 1)], axis=1) if rotation_attr is not None: rot_obj = getattr(f, rotation_attr) scale_obj = getattr(f, scale_attr) translation_mat = translation_mat @ rot_obj @ scale_obj transformations.append(translation_mat) if material_attr is not None: material.append(getattr(f, material_attr)) if len(material) == 0: material = None vobjs = duplicate_by_transformation_matrices( bobj, transformations, collection, material ) return vobjs
[docs]def hes_to_mesh(hes, name="Halfedge mesh", co_attr="co"): hes_bmesh = hes_to_bmesh(hes, co_attr=co_attr) return from_bmesh(hes_bmesh, name, free=True)
[docs]def hes_to_blender_object( hes, name="Halfedge object", co_attr="co", parent=None, matrix=np.eye(4) ): hes_mesh = hes_to_mesh(hes, name=name, co_attr=co_attr) obj = bpy.data.objects.new(name, hes_mesh) obj.parent = parent obj.matrix_local = matrix bpy.context.scene.collection.objects.link(obj) return obj