Source code for ddg.datastructures.halfedge.copy

import copy as cpy
import functools

from ddg.datastructures.halfedge import surface

#####################
# copying of surfaces
#####################


[docs]def copy( surf, verts_attr_list=None, edges_attr_list=None, faces_attr_list=None, set_original_vertex_attr=False, ): """ Returns a copy of a half-edge datastructure object, including the attributes on vertices, edges and faces that are stated to be copied. The attributes that shall be copied are handed over in lists for vertices, edges and faces, containing their string names. Parameters ---------- surf : ddg.halfedge.Surface The half-edge data that shall be copied. verts_attr_list : iterable of str (default=None) A list of strings naming the vertex attributes that shall be copied. edges_attr_list : iterable of str (default=None) A list of strings naming the edge attributes that shall be copied. faces_attr_list : iterable of str (default=None) A list of strings naming the face attributes that shall be copied. set_original_vertex_attr : bool (default=False) A Boolean defining whether an attribute that stores the corresponding original vertex (with the name 'original_vertex') shall be added to the vertices of the copy. Returns ------- surf : ddg.halfedge.Surface A copy of the given half-edge data, including the attributes on vertices, edges and faces that were stated. Notes ----- The attributes handed over need to be of a type that implements or allows copy.deepcopy(). """ # surf.validate() if faces_attr_list is None: faces_attr_list = [] if edges_attr_list is None: edges_attr_list = [] if verts_attr_list is None: verts_attr_list = [] s = surface.Surface() edgemap = dict() facemap = dict() vertexmap = dict() if set_original_vertex_attr: s.verts.add_attribute("original_vertex") # copy all attributes that were named in lists as arguments if verts_attr_list: for attr in verts_attr_list: s.verts.add_attribute(attr) if faces_attr_list: for attr in faces_attr_list: s.faces.add_attribute(attr) if edges_attr_list: for attr in edges_attr_list: s.edges.add_attribute(attr) # create egdes, vertices and faces in the copy for e in surf.edges: e_copy = s.edges() # e.edgemap = e_copy edgemap[e] = e_copy for v in surf.verts: v_copy = s.verts() # v.vertexmap = v_copy vertexmap[v] = v_copy # v_copy.edge = v.edge.edgemap v_copy.edge = edgemap.get(v.edge) if set_original_vertex_attr: v_copy.original_vertex = v if verts_attr_list: for attr in verts_attr_list: setattr(v_copy, attr, cpy.deepcopy(getattr(v, attr))) for f in surf.faces: f_copy = s.faces() # f.facemap = f_copy facemap[f] = f_copy # f_copy.edge = f.edge.edgemap f_copy.edge = edgemap.get(f.edge) if faces_attr_list: for attr in faces_attr_list: setattr(f_copy, attr, cpy.deepcopy(getattr(f, attr))) # set references for each new edge for e in surf.edges: e_copy = edgemap.get(e) e_copy.opp = edgemap.get(e.opp) e_copy.nex = edgemap.get(e.nex) e_copy.pre = edgemap.get(e.pre) e_copy.head = vertexmap.get(e.head) if e.face is not None: # e_copy.face = e.face.facemap e_copy.face = facemap.get(e.face) if edges_attr_list: for attr in edges_attr_list: if attr == "crs": setattr(e_copy, attr, cpy.copy(getattr(e, attr))) else: setattr(e_copy, attr, cpy.deepcopy(getattr(e, attr))) return s
[docs]def combinatorial_copy(surf): """ Returns a combinatorial copy of a half-edge datastructure object. Parameters ---------- surf : ddg.halfedge.Surface The half-edge data that shall be copied. Returns ------- surf : ddg.halfedge.Surface A combinatorial copy of the given half-edge data. """ return copy(surf, [], [], [], False)
def _pairwise_union( surf1, surf2, verts_attr_list=None, edges_attr_list=None, faces_attr_list=None ): if edges_attr_list is None: edges_attr_list = [] if verts_attr_list is None: verts_attr_list = [] if faces_attr_list is None: faces_attr_list = [] s = copy( surf1, verts_attr_list=verts_attr_list, edges_attr_list=edges_attr_list, faces_attr_list=faces_attr_list, ) old_verts = list(surf2.verts) old_edges = list(surf2.edges) old_faces = list(surf2.faces) new_verts = [s.verts() for _ in old_verts] new_edges = [s.edges() for _ in old_edges] new_faces = [s.faces() for _ in old_faces] for v_old, v_new in zip(old_verts, new_verts): if v_old.edge is not None: v_new.edge = new_edges[v_old.edge.index] for attr in verts_attr_list: setattr(v_new, attr, cpy.deepcopy(getattr(v_old, attr))) for e_old, e_new in zip(old_edges, new_edges): e_new.opp = new_edges[e_old.opp.index] e_new.nex = new_edges[e_old.nex.index] e_new.pre = new_edges[e_old.pre.index] e_new.head = new_verts[e_old.head.index] if e_old.face is not None: e_new.face = new_faces[e_old.face.index] for attr in edges_attr_list: setattr(e_new, attr, cpy.deepcopy(getattr(e_old, attr))) for f_old, f_new in zip(old_faces, new_faces): if f_old.edge is not None: f_new.edge = new_edges[f_old.edge.index] for attr in faces_attr_list: setattr(f_new, attr, cpy.deepcopy(getattr(f_old, attr))) return s
[docs]def union(*surfaces, verts_attr_list=None, edges_attr_list=None, faces_attr_list=None): """Disjoint union of surfaces as a single, new surface. Parameters ---------- *surfaces : objects of type ddg.halfedge.Surface verts_attr_list, edges_attr_list, faces_attr_list : list of str (default=None) Attributes to be copied. All input surfaces must have the attribute. Just like in copy(), the attribute values must support deepcopy(). Returns ------- surf : ddg.halfedge.Surface See Also -------- ddg.halfedge.copy Notes ----- The result will most likely be disconnected! """ if faces_attr_list is None: faces_attr_list = [] if edges_attr_list is None: edges_attr_list = [] if verts_attr_list is None: verts_attr_list = [] return functools.reduce( functools.partial( _pairwise_union, verts_attr_list=verts_attr_list, edges_attr_list=edges_attr_list, faces_attr_list=faces_attr_list, ), surfaces, surface.Surface(), )