Source code for cellcomplex.halfedge.halfedge

from cellcomplex.utils.id_generator import IdGenerator


[docs]class HalfEdge: def __init__(self, id, vertex, face, opposite, previous = None, next = None): self.id = id self.vertex = vertex self.face = face self.previous = previous self.next = next self.opposite = opposite def __repr__(self): return 'HalfEdge('+', '.join([k+'='+v for k,v in zip(['id', 'vertex','vertextail' ,'face', 'opposite', 'previous', 'next'], list(map(str,[self.id, self.vertex, self.vertextail(), self.face, self.opposite.id if self.opposite else None, self.previous.id if self.previous else None, self.next.id if self.__next__ else None])))])+')'
[docs] def vertextail(self): if self.opposite: return self.opposite.vertex elif self.previous: return self.previous.vertex return None
[docs]class HalfEdgeMesh: def __init__(self): self._edges = {} self._vertices = {} self._faces = {} self._halfedges = {} self._idgen = IdGenerator() self.verticesproperties = {} self.facesproperties = {} self.edgeproperties = {} self.verticesproperties['position'] = {}
[docs] def vertices(self): return self._vertices.keys()
[docs] def edges(self): return self._edges.keys()
[docs] def faces(self): return self._faces.keys()
[docs] def dart(self, did): return self._edges[did]
[docs] def edge_face(self, eid): # EF edge = self._edges[eid] return (edge.face, edge.opposite.face if edge.opposite else None)
[docs] def edge_vertices(self, eid): # EV edge = self._edges[eid] return (edge.vertex, edge.vertextail())
[docs] def face_edges(self, fid): # FE firstedge = self._faces[fid] if firstedge is None: return yield firstedge currentedge = firstedge while True: currentedge = currentedge.__next__ if (currentedge is None) or (currentedge == firstedge): break yield currentedge
[docs] def vertex_edges(self, vid): # VE return [h.id for h in self._vertices.get(vid,[])]
# firstedge = self._vertices.get(vid) # if firstedge is None: return # yield firstedge.id # currentedge = firstedge # while True: # currentedge = currentedge.next.opposite # if (currentedge is None) or (currentedge == firstedge): # break # yield currentedge.id
[docs] def face_vertices(self, fid): # FV firstedge = self._faces[fid] if firstedge is None: return currentedge = firstedge yield currentedge.vertex while True: currentedge = currentedge.__next__ if (currentedge is None or currentedge == firstedge): break yield currentedge.vertex
[docs] def vertex_faces(self, vid): # VF to be done !!!! return [h.face for h in self._vertices.get(vid,[])]
# firstedge = self._vertices[vid] # if firstedge is None: return # yield firstedge.face # currentedge = firstedge # while True: # currentedge = currentedge.next.opposite # if (currentedge is None) or (currentedge == firstedge): break # yield currentedge.face
[docs] def face_neighbors(self, fid): for currentedge in self.face_edges(fid): yield edge.opposite.face
[docs] def edge_neighbors(self, eid): edge = self._edges[eid] for vertex in (edge.vertex, edge.opposite.vertex): for neid in self.vertex_edges(vertex): if neid != eid: yield neid
[docs] def vertex_neighbors(self, vid): for edge in self.vertex_edges(vid): yield edge.opposite.vertex
[docs] def add_vertex(self, position = None, vid = None): vid = self._idgen.get_id(vid) if position: self.set_position(vid, position) return vid
[docs] def set_position(self, vid, position): self.verticesproperties['position'][vid] = position
[docs] def get_position(self, vid): return self.verticesproperties['position'][vid]
[docs] def add_polygon(self, vids, fid = None): fid = self._idgen.get_id(fid) edges = [] print('add_polygon', vids) for vid1, vid2 in zip(vids,vids[1:]+[vids[0]]): print('add edge', (vid1,vid2), end=' ') for leid in self.vertex_edges(vid1): if self._halfedges[leid].vertextail() == vid2: oppedge = self._edges[leid] break else: oppedge = None eid = self._idgen.get_id() if oppedge is None else -oppedge.id newedge = HalfEdge(eid, vid2, fid, opposite = oppedge) if oppedge: oppedge.opposite = newedge else: self._edges[eid] = newedge self._halfedges[eid] = newedge print('-->', eid) edges.append(newedge) if vid2 not in self._vertices: self._vertices[vid2] = [newedge] else: self._vertices[vid2].append(newedge) for i, edge in enumerate(edges): edge.previous = edges[(i-1)%len(edges)] edge.next = edges[(i+1)%len(edges)] self._faces[fid] = edges[0] return fid
[docs] def topglscene(self): from openalea.plantgl.all import Scene, Shape, FaceSet normalizedpoints = self.verticesproperties['position'].values() normpid = dict([(vid, nid) for nid,vid in enumerate(self.verticesproperties['position'].keys())]) indexlist = [] for fid in self.faces(): index = list(self.face_vertices(fid)) index = [normpid[pid] for pid in index] indexlist.append(index) return Scene([Shape(FaceSet(normalizedpoints, indexlist), id = fid )])
[docs] def print_info(self): print('vertices :') for vid, edges in self._vertices.items(): print(vid, ':', [e.id for e in edges], self.get_position(vid)) print('edges :') for eid, edge in self._edges.items(): print(eid, ':', edge.id, '-->', [edge.id, edge.opposite.id if edge.opposite else None]) print('faces :') for fid, edge in self._faces.items(): print(fid, ':', edge.id, '-->', [h.id for h in self.face_edges(fid)]) print('half edges :') for hid, hedge in self._halfedges.items(): print(hid, ':', hedge)