general attribute mechanism for combinatorial interface
- add general attribute mechanism
Attributes and enumeration:
- Every class inheriting from Combinatorics HAS TO implement
_generate_vertex_indices, _generate_oriented_edge_indices, _generate_oriented_face_indices, _generate_non_oriented_edge_indices, _generate_non_oriented_face_indices
All cells of this combinatorics class are enumerated by increasing integers. Thus, everything can be implemented using numpy arrays.
Each datastructure inheriting from this class has to implement the functions generating (non) oriented indices. These functions have to return a subscriptable object mapping the actual cells of the datastructures to their index (e.g. a dict or a np.ndarray for EIFS). The oriented/non oriented functions differ, e.g. by mapping edges (i, j) and (j, i) to the same or different index. Note that this is necessary for faces of IndexedFaceSet since one can give them as (i,j, k), (k, i, j), (k,i,j) or with reverse direction.
An instance of a datastructure has to specify on creation if it is oriented or non-oriented. If a datastructure allows combinatoric changes then it needs to update the index generating functions.
The idea of the mechanism of cell attribute setting/deleting/getting can be taken from ddg.IndexedFaceSet
.
Since the cells are enumerated attributes are stored as numpy.ndarrays in self.vertex_attributes etc.
If a datastructure allows combinatoric changes then it needs to update these.
One should implement the basic functionalities for set_vertex_attributes, set_edge_attributes, set_face_attributes
:
-
name
must be string -
values
must be subscriptable, i.e. either it can be a dict or a numpy.ndarray (if vertices match indices) - the functions use the generate_index functions to sort the attributes in the right order for the given cells and then saves the numpy array and {'attr_name': numpy_array} to the self.vertex_attributes
Open:
- When to store indices dicts in self.vertex_indices,... ? As they are generated lazy, one does not know where they will be used first
class Combinatorics(...):
def __init__(self):
# dicts {cell: index}, multiple cells may have same index
self.vertex_indices = None
self.edge_indices = None
self.face_indices = None
self.vertex_attributes = dict() # {'attr_name':[value0, value1, value3, ...], 'attr_name2': ...}
self.edge_attributes = dict()
self.face_attributes = dict()
# generate indices
def _generate_vertex_indices(self):
pass
def _generate_oriented_edge_indices(self):
pass
def _generate_non_oriented_edge_indices(self):
pass
def _generate_oriented_faces_indices(self):
pass
def _generate_non_oriented_face_indices(self):
pass
# adjacency
def adjacent_vertices(self, cell):
...
def adjacent_edges(self, cell):
...
def adjacent_faces(self, cell):
...
# set/get/delete attributes
# values have to be a subsriptable. This can contain only a subset of cells. Cells not given default to None
# If values=None then all cells should be given the default value
def set_vertex_attributes(self, name, values=None, default_value=None):
...
def set_edge_attributes(self, name, values=None, default_value=None):
...
def set_face_attributes(self, name, values=None, default_value=None):
...
def set_vertex_attribute(self, cell, name, value):
self.vertex_attributes[name][self.vertex_indices[cell]] = value
def set_edge_attribute(self, cell, name, value):
self.edge_attributes[name][self.edge_indices[cell]] = value
def set_face_attribute(self, cell, name, value):
self.face_attributes[name][self.face_indices[cell]] = value
# cells have to be None or an iterable. In the latter only attributes of given cells will be returned.
# If None attributes of all cells will be returned.
def get_vertex_attributes(self, name, cells=None):
...
def get_edge_attributes(self, name, cells=None):
...
def get_face_attributes(self, name, cells=None):
...
def get_vertex_attribute(self, name, cell):
...
def get_edge_attribute(self, name, cell):
...
def get_face_attribute(self, name, cell):
...
def delete_vertex_attribute(self, name):
...
def delete_edge_attribute(self, name):
...
def delete_face_attribute(self, name):
...