Source code for ddg.halfedge._copy

import copy as cpy
import functools

from ddg.halfedge._surface import Surface

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


[docs]def copy( surf, verts_attr_list=None, edges_attr_list=None, faces_attr_list=None, original_vertex_attr=None, original_edge_attr=None, original_face_attr=None, ): """ Returns a copy of a halfedge 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. original_vertex_attr : str (default=None) Defining whether an attribute that stores the corresponding original vertex shall be added to the vertices of the copy. Default is None, if a string is given this becomes the name of the new attribute. original_edge_attr : str (default=None) Defining whether an attribute that stores the corresponding original edge shall be added to the edges of the copy. Default is None, if a string is given this becomes the name of the new attribute. original_face_attr : str (default=None) Defining whether an attribute that stores the corresponding original face shall be added to the faces of the copy. Default is None, if a string is given this becomes the name of the new attribute. Returns ------- surf : ddg.halfedge.Surface A copy of the given halfedge 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(). See Also -------- ddg.halfedge.combinatorial_copy """ # 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() edgemap = dict() facemap = dict() vertexmap = dict() # 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) # set original cell attributes if original_vertex_attr is not None: ova = s.verts.add_attribute(original_vertex_attr) if original_edge_attr is not None: oea = s.edges.add_attribute(original_edge_attr) if original_face_attr is not None: ofa = s.faces.add_attribute(original_face_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 original_vertex_attr is not None: ova[v_copy] = 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 original_face_attr is not None: ofa[f_copy] = f 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 original_edge_attr is not None: oea[e_copy] = e if edges_attr_list: for attr in edges_attr_list: setattr(e_copy, attr, cpy.deepcopy(getattr(e, attr))) return s
[docs]def combinatorial_copy(surf): """ Returns a combinatorial copy of a halfedge datastructure object. The halfedge object is copied, the combinatorics of the copy are the same as of the original halfedge object. No (manually generated) cell attributes are copied or set. Parameters ---------- surf : ddg.halfedge.Surface The halfedge data that shall be copied. Returns ------- surf : ddg.halfedge.Surface A combinatorial copy of the given halfedge data. See Also -------- ddg.halfedge.copy """ return copy(surf, [], [], [])
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(), )