Source code for cellcomplex.property_topomesh.topomesh

# -*- python -*-
# -*- coding: utf-8 -*-
#
#       Topomesh : container package
#
#       Copyright or  or Copr. 2006 INRIA - CIRAD - INRA
#
#       File author(s): Jerome Chopard <jerome.chopard@sophia.inria.fr>
#
#       Distributed under the Cecill-C License.
#       See accompanying file LICENSE.txt or copy at
#           http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
#
#       VPlants WebSite : https://gforge.inria.fr/projects/vplants/
#

__doc__="""
This module provide a simple pure python implementation
for a topomesh interface
"""

__license__= "Cecill-C"
__revision__=" $Id$ "

from array import array
from .interface.topomesh import (TopomeshError,InvalidWisp,InvalidDegree,
                                ITopomesh,IWispListMesh,INeighborhoodMesh,IMutableMesh)
from cellcomplex.utils import IdDict

[docs]class StrInvalidWisp (InvalidWisp) : """ exception raised when a wrong wisp id is provided """ def __init__ (self, degree, wid) : InvalidWisp.__init__(self,"wisp %d of degree %d does not exist" % (wid,degree))
[docs]class StrInvalidDegree (InvalidDegree) : """ exception raised when a wrong degree is provided """ def __init__ (self, degree) : InvalidDegree.__init__(self,"degree %d is outside of mesh bounds" % degree)
[docs]class Topomesh (ITopomesh,IWispListMesh,INeighborhoodMesh,IMutableMesh) : """ implementation of a topological mesh """ def __init__ (self, degree, idgenerator = "set") : """ constructor of an empty mesh """ self._degree=degree self._borders = [None] + [IdDict(idgenerator = idgenerator) for i in range(degree)] self._regions = [IdDict(idgenerator = idgenerator)] + [{} for i in range(degree-1)]
[docs] def get_idgenerator_type(self): return self._regions[0].get_generator_type()
[docs] def enable_id_reuse(self, enabled = True): for border in self._borders: if not border is None: border.enable_id_reuse(enabled) self._regions[0].enable_id_reuse(enabled)
[docs] def id_reuse_enabled(self): return self._regions[0].id_reuse_enabled()
######################################################################## # # Mesh concept # ########################################################################
[docs] def degree (self) : return self._degree
degree.__doc__=ITopomesh.degree.__doc__
[docs] def is_valid (self) : return True
is_valid.__doc__=ITopomesh.is_valid.__doc__
[docs] def has_wisp (self, degree, wid) : if degree == 0 : try : return wid in self._regions[0] except IndexError : raise StrInvalidDegree(degree) else : try : return wid in self._borders[degree] except IndexError : raise StrInvalidDegree(degree)
has_wisp.__doc__=ITopomesh.has_wisp.__doc__ def _iter_borders (self, degree, wid) : """Internal function to access borders of an element """ return iter(self._borders[degree][wid]) def _borders_with_offset (self, degree, wids, offset) : if offset==0 : return wids else : ret = set() for wid in wids : ret |= set(self._borders_with_offset(degree-1,self._iter_borders(degree,wid),offset-1)) return iter(ret)
[docs] def borders (self, degree, wid, offset = 1) : if degree - offset < 0 : raise InvalidDegree ("smallest wisps have no borders") return self._borders_with_offset(degree,[wid],offset)
borders.__doc__=ITopomesh.borders.__doc__
[docs] def nb_borders (self, degree, wid) : if degree < 1 : raise InvalidDegree ("smallest wisps have no borders") return len(self._borders[degree][wid])
nb_borders.__doc__=ITopomesh.nb_borders.__doc__ def _iter_regions (self, degree, wid) : """Internal function to access regions of an element """ return iter(self._regions[degree][wid]) def _regions_with_offset (self, degree, wids, offset) : if offset == 0 : return wids else : ret = set() for wid in wids : ret |= set(self._regions_with_offset(degree + 1, self._iter_regions(degree,wid), offset - 1) ) return iter(ret)
[docs] def regions (self, degree, wid, offset = 1) : if (degree + offset) > self.degree() : raise InvalidDegree ("biggest wisps do not separate regions") return self._regions_with_offset(degree,[wid],offset)
regions.__doc__=ITopomesh.regions.__doc__
[docs] def nb_regions (self, degree, wid) : if degree >= self.degree() : raise InvalidDegree ("biggest wisps do not separate regions") return len(self._regions[degree][wid])
nb_regions.__doc__=ITopomesh.nb_regions.__doc__ ######################################################################## # # Wisp list concept # ########################################################################
[docs] def wisps (self, degree) : if degree == 0 : try : return iter(self._regions[degree]) except IndexError : raise StrInvalidDegree(degree) else : try : return iter(self._borders[degree]) except IndexError : raise StrInvalidDegree(degree)
wisps.__doc__=IWispListMesh.wisps.__doc__
[docs] def nb_wisps (self, degree) : if degree == 0 : try : return len(self._regions[degree]) except IndexError : raise StrInvalidDegree(degree) else : try : return len(self._borders[degree]) except IndexError : raise StrInvalidDegree(degree)
nb_wisps.__doc__=IWispListMesh.nb_wisps.__doc__ ######################################################################## # # Neighborhood concept # ########################################################################
[docs] def border_neighbors (self, degree, wid) : for bid in self.borders(degree,wid) : for rid in self.regions(degree-1,bid) : if rid != wid : yield rid
border_neighbors.__doc__=INeighborhoodMesh.border_neighbors.__doc__
[docs] def nb_border_neighbors (self, degree, wid) : return len(list(self.border_neighbors(degree,wid)))
nb_border_neighbors.__doc__=INeighborhoodMesh.nb_border_neighbors.__doc__
[docs] def region_neighbors (self, degree, wid) : for rid in self.regions(degree,wid) : for bid in self.borders(degree+1,rid) : if bid != wid : yield bid
region_neighbors.__doc__=INeighborhoodMesh.region_neighbors.__doc__
[docs] def nb_region_neighbors (self, degree, wid) : return len(list(self.region_neighbors(degree,wid)))
nb_region_neighbors.__doc__=INeighborhoodMesh.nb_region_neighbors.__doc__ ######################################################################## # # Mutable mesh concept # ########################################################################
[docs] def add_wisp (self, degree, wid = None) : if degree > 0 : wid = self._borders[degree].add(array("L"),wid) if degree < self.degree() : self._regions[degree][wid] = array("L") else : wid = self._regions[degree].add(array("L"),wid) return wid
add_wisp.__doc__=IMutableMesh.add_wisp.__doc__
[docs] def remove_wisp (self, degree, wid) : #remove links if degree < self.degree() : for rid in tuple(self.regions(degree,wid) ) : self.unlink(degree+1,rid,wid) if degree > 0 : for bid in tuple(self.borders(degree,wid) ) : self.unlink(degree,wid,bid) #remove element if degree < self.degree() : del self._regions[degree][wid] if degree > 0 : del self._borders[degree][wid]
remove_wisp.__doc__=IMutableMesh.remove_wisp.__doc__ link.__doc__=IMutableMesh.link.__doc__ unlink.__doc__=IMutableMesh.unlink.__doc__