Changeset View
Changeset View
Standalone View
Standalone View
release/scripts/freestyle/modules/freestyle/predicates.py
- This file was added.
| # ##### BEGIN GPL LICENSE BLOCK ##### | |||||
| # | |||||
| # This program is free software; you can redistribute it and/or | |||||
| # modify it under the terms of the GNU General Public License | |||||
| # as published by the Free Software Foundation; either version 2 | |||||
| # of the License, or (at your option) any later version. | |||||
| # | |||||
| # This program is distributed in the hope that it will be useful, | |||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| # GNU General Public License for more details. | |||||
| # | |||||
| # You should have received a copy of the GNU General Public License | |||||
| # along with this program; if not, write to the Free Software Foundation, | |||||
| # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||||
| # | |||||
| # ##### END GPL LICENSE BLOCK ##### | |||||
| """ | |||||
| Predicates operating on vertices (0D elements) and polylines (1D | |||||
| elements). Also intended to be a collection of examples for predicate | |||||
| definition in Python | |||||
| """ | |||||
| # module members | |||||
| from _freestyle import ( | |||||
| ContourUP1D, | |||||
| DensityLowerThanUP1D, | |||||
| EqualToChainingTimeStampUP1D, | |||||
| EqualToTimeStampUP1D, | |||||
| ExternalContourUP1D, | |||||
| FalseBP1D, | |||||
| FalseUP0D, | |||||
| FalseUP1D, | |||||
| Length2DBP1D, | |||||
| QuantitativeInvisibilityUP1D, | |||||
| SameShapeIdBP1D, | |||||
| ShapeUP1D, | |||||
| TrueBP1D, | |||||
| TrueUP0D, | |||||
| TrueUP1D, | |||||
| ViewMapGradientNormBP1D, | |||||
| WithinImageBoundaryUP1D, | |||||
| ) | |||||
| # constructs for predicate definition in Python | |||||
| from freestyle.types import ( | |||||
| BinaryPredicate1D, | |||||
| IntegrationType, | |||||
| Nature, | |||||
| TVertex, | |||||
| UnaryPredicate0D, | |||||
| UnaryPredicate1D, | |||||
| ) | |||||
| from freestyle.functions import ( | |||||
| Curvature2DAngleF0D, | |||||
| CurveNatureF1D, | |||||
| DensityF1D, | |||||
| GetCompleteViewMapDensityF1D, | |||||
| GetCurvilinearAbscissaF0D, | |||||
| GetDirectionalViewMapDensityF1D, | |||||
| GetOccludersF1D, | |||||
| GetProjectedZF1D, | |||||
| GetShapeF1D, | |||||
| GetSteerableViewMapDensityF1D, | |||||
| GetZF1D, | |||||
| QuantitativeInvisibilityF0D, | |||||
| ZDiscontinuityF1D, | |||||
| pyCurvilinearLengthF0D, | |||||
| pyDensityAnisotropyF1D, | |||||
| pyViewMapGradientNormF1D, | |||||
| ) | |||||
| import random | |||||
| ## Unary predicates for 0D elements (vertices) | |||||
| ############################################## | |||||
| class pyHigherCurvature2DAngleUP0D(UnaryPredicate0D): | |||||
| def __init__(self,a): | |||||
| UnaryPredicate0D.__init__(self) | |||||
| self._a = a | |||||
| def __call__(self, inter): | |||||
| func = Curvature2DAngleF0D() | |||||
| a = func(inter) | |||||
| return (a > self._a) | |||||
| class pyUEqualsUP0D(UnaryPredicate0D): | |||||
| def __init__(self,u, w): | |||||
| UnaryPredicate0D.__init__(self) | |||||
| self._u = u | |||||
| self._w = w | |||||
| def __call__(self, inter): | |||||
| func = pyCurvilinearLengthF0D() | |||||
| u = func(inter) | |||||
| return (u > (self._u-self._w)) and (u < (self._u+self._w)) | |||||
| class pyVertexNatureUP0D(UnaryPredicate0D): | |||||
| def __init__(self,nature): | |||||
| UnaryPredicate0D.__init__(self) | |||||
| self._nature = nature | |||||
| def __call__(self, inter): | |||||
| v = inter.object | |||||
| return (v.nature & self._nature) != 0 | |||||
| ## check whether an Interface0DIterator | |||||
| ## is a TVertex and is the one that is | |||||
| ## hidden (inferred from the context) | |||||
| class pyBackTVertexUP0D(UnaryPredicate0D): | |||||
| def __init__(self): | |||||
| UnaryPredicate0D.__init__(self) | |||||
| self._getQI = QuantitativeInvisibilityF0D() | |||||
| def __call__(self, iter): | |||||
| if (iter.object.nature & Nature.T_VERTEX) == 0: | |||||
| return False | |||||
| if iter.is_end: | |||||
| return False | |||||
| if self._getQI(iter) != 0: | |||||
| return True | |||||
| return False | |||||
| class pyParameterUP0DGoodOne(UnaryPredicate0D): | |||||
| def __init__(self,pmin,pmax): | |||||
| UnaryPredicate0D.__init__(self) | |||||
| self._m = pmin | |||||
| self._M = pmax | |||||
| def __call__(self, inter): | |||||
| u = inter.u | |||||
| return ((u>=self._m) and (u<=self._M)) | |||||
| class pyParameterUP0D(UnaryPredicate0D): | |||||
| def __init__(self,pmin,pmax): | |||||
| UnaryPredicate0D.__init__(self) | |||||
| self._m = pmin | |||||
| self._M = pmax | |||||
| def __call__(self, inter): | |||||
| func = Curvature2DAngleF0D() | |||||
| c = func(inter) | |||||
| b1 = (c>0.1) | |||||
| u = inter.u | |||||
| b = ((u>=self._m) and (u<=self._M)) | |||||
| return b and b1 | |||||
| ## Unary predicates for 1D elements (curves) | |||||
| ############################################ | |||||
| class AndUP1D(UnaryPredicate1D): | |||||
| def __init__(self, pred1, pred2): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self.__pred1 = pred1 | |||||
| self.__pred2 = pred2 | |||||
| def __call__(self, inter): | |||||
| return self.__pred1(inter) and self.__pred2(inter) | |||||
| class OrUP1D(UnaryPredicate1D): | |||||
| def __init__(self, pred1, pred2): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self.__pred1 = pred1 | |||||
| self.__pred2 = pred2 | |||||
| def __call__(self, inter): | |||||
| return self.__pred1(inter) or self.__pred2(inter) | |||||
| class NotUP1D(UnaryPredicate1D): | |||||
| def __init__(self, pred): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self.__pred = pred | |||||
| def __call__(self, inter): | |||||
| return not self.__pred(inter) | |||||
| class pyNFirstUP1D(UnaryPredicate1D): | |||||
| def __init__(self, n): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self.__n = n | |||||
| self.__count = 0 | |||||
| def __call__(self, inter): | |||||
| self.__count = self.__count + 1 | |||||
| if self.__count <= self.__n: | |||||
| return True | |||||
| return False | |||||
| class pyHigherLengthUP1D(UnaryPredicate1D): | |||||
| def __init__(self,l): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._l = l | |||||
| def __call__(self, inter): | |||||
| return (inter.length_2d > self._l) | |||||
| class pyNatureUP1D(UnaryPredicate1D): | |||||
| def __init__(self,nature): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._nature = nature | |||||
| self._getNature = CurveNatureF1D() | |||||
| def __call__(self, inter): | |||||
| if(self._getNature(inter) & self._nature): | |||||
| return True | |||||
| return False | |||||
| class pyHigherNumberOfTurnsUP1D(UnaryPredicate1D): | |||||
| def __init__(self,n,a): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._n = n | |||||
| self._a = a | |||||
| def __call__(self, inter): | |||||
| count = 0 | |||||
| func = Curvature2DAngleF0D() | |||||
| it = inter.vertices_begin() | |||||
| while not it.is_end: | |||||
| if func(it) > self._a: | |||||
| count = count+1 | |||||
| if count > self._n: | |||||
| return True | |||||
| it.increment() | |||||
| return False | |||||
| class pyDensityUP1D(UnaryPredicate1D): | |||||
| def __init__(self,wsize,threshold, integration = IntegrationType.MEAN, sampling=2.0): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._wsize = wsize | |||||
| self._threshold = threshold | |||||
| self._integration = integration | |||||
| self._func = DensityF1D(self._wsize, self._integration, sampling) | |||||
| def __call__(self, inter): | |||||
| return (self._func(inter) < self._threshold) | |||||
| class pyLowSteerableViewMapDensityUP1D(UnaryPredicate1D): | |||||
| def __init__(self,threshold, level,integration = IntegrationType.MEAN): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._threshold = threshold | |||||
| self._level = level | |||||
| self._integration = integration | |||||
| def __call__(self, inter): | |||||
| func = GetSteerableViewMapDensityF1D(self._level, self._integration) | |||||
| return (func(inter) < self._threshold) | |||||
| class pyLowDirectionalViewMapDensityUP1D(UnaryPredicate1D): | |||||
| def __init__(self,threshold, orientation, level,integration = IntegrationType.MEAN): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._threshold = threshold | |||||
| self._orientation = orientation | |||||
| self._level = level | |||||
| self._integration = integration | |||||
| def __call__(self, inter): | |||||
| func = GetDirectionalViewMapDensityF1D(self._orientation, self._level, self._integration) | |||||
| return (func(inter) < self._threshold) | |||||
| class pyHighSteerableViewMapDensityUP1D(UnaryPredicate1D): | |||||
| def __init__(self,threshold, level,integration = IntegrationType.MEAN): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._threshold = threshold | |||||
| self._level = level | |||||
| self._integration = integration | |||||
| self._func = GetSteerableViewMapDensityF1D(self._level, self._integration) | |||||
| def __call__(self, inter): | |||||
| return (self._func(inter) > self._threshold) | |||||
| class pyHighDirectionalViewMapDensityUP1D(UnaryPredicate1D): | |||||
| def __init__(self,threshold, orientation, level,integration = IntegrationType.MEAN, sampling=2.0): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._threshold = threshold | |||||
| self._orientation = orientation | |||||
| self._level = level | |||||
| self._integration = integration | |||||
| self._sampling = sampling | |||||
| def __call__(self, inter): | |||||
| func = GetDirectionalViewMapDensityF1D(self._orientation, self._level, self._integration, self._sampling) | |||||
| return (func(inter) > self._threshold) | |||||
| class pyHighViewMapDensityUP1D(UnaryPredicate1D): | |||||
| def __init__(self,threshold, level,integration = IntegrationType.MEAN, sampling=2.0): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._threshold = threshold | |||||
| self._level = level | |||||
| self._integration = integration | |||||
| self._sampling = sampling | |||||
| self._func = GetCompleteViewMapDensityF1D(self._level, self._integration, self._sampling) # 2.0 is the smpling | |||||
| def __call__(self, inter): | |||||
| return (self._func(inter) > self._threshold) | |||||
| class pyDensityFunctorUP1D(UnaryPredicate1D): | |||||
| def __init__(self,wsize,threshold, functor, funcmin=0.0, funcmax=1.0, integration = IntegrationType.MEAN): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._wsize = wsize | |||||
| self._threshold = float(threshold) | |||||
| self._functor = functor | |||||
| self._funcmin = float(funcmin) | |||||
| self._funcmax = float(funcmax) | |||||
| self._integration = integration | |||||
| def __call__(self, inter): | |||||
| func = DensityF1D(self._wsize, self._integration) | |||||
| res = self._functor(inter) | |||||
| k = (res-self._funcmin)/(self._funcmax-self._funcmin) | |||||
| return (func(inter) < (self._threshold * k)) | |||||
| class pyZSmallerUP1D(UnaryPredicate1D): | |||||
| def __init__(self,z, integration=IntegrationType.MEAN): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._z = z | |||||
| self._integration = integration | |||||
| def __call__(self, inter): | |||||
| func = GetProjectedZF1D(self._integration) | |||||
| return (func(inter) < self._z) | |||||
| class pyIsOccludedByUP1D(UnaryPredicate1D): | |||||
| def __init__(self,id): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._id = id | |||||
| def __call__(self, inter): | |||||
| func = GetShapeF1D() | |||||
| shapes = func(inter) | |||||
| for s in shapes: | |||||
| if(s.id == self._id): | |||||
| return False | |||||
| it = inter.vertices_begin() | |||||
| itlast = inter.vertices_end() | |||||
| itlast.decrement() | |||||
| v = it.object | |||||
| vlast = itlast.object | |||||
| tvertex = v.viewvertex | |||||
| if type(tvertex) is TVertex: | |||||
| #print("TVertex: [ ", tvertex.id.first, ",", tvertex.id.second," ]") | |||||
| eit = tvertex.edges_begin() | |||||
| while not eit.is_end: | |||||
| ve, incoming = eit.object | |||||
| if ve.id == self._id: | |||||
| return True | |||||
| #print("-------", ve.id.first, "-", ve.id.second) | |||||
| eit.increment() | |||||
| tvertex = vlast.viewvertex | |||||
| if type(tvertex) is TVertex: | |||||
| #print("TVertex: [ ", tvertex.id.first, ",", tvertex.id.second," ]") | |||||
| eit = tvertex.edges_begin() | |||||
| while not eit.is_end: | |||||
| ve, incoming = eit.object | |||||
| if ve.id == self._id: | |||||
| return True | |||||
| #print("-------", ve.id.first, "-", ve.id.second) | |||||
| eit.increment() | |||||
| return False | |||||
| class pyIsInOccludersListUP1D(UnaryPredicate1D): | |||||
| def __init__(self,id): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._id = id | |||||
| def __call__(self, inter): | |||||
| func = GetOccludersF1D() | |||||
| occluders = func(inter) | |||||
| for a in occluders: | |||||
| if a.id == self._id: | |||||
| return True | |||||
| return False | |||||
| class pyIsOccludedByItselfUP1D(UnaryPredicate1D): | |||||
| def __init__(self): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self.__func1 = GetOccludersF1D() | |||||
| self.__func2 = GetShapeF1D() | |||||
| def __call__(self, inter): | |||||
| lst1 = self.__func1(inter) | |||||
| lst2 = self.__func2(inter) | |||||
| for vs1 in lst1: | |||||
| for vs2 in lst2: | |||||
| if vs1.id == vs2.id: | |||||
| return True | |||||
| return False | |||||
| class pyIsOccludedByIdListUP1D(UnaryPredicate1D): | |||||
| def __init__(self, idlist): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._idlist = idlist | |||||
| self.__func1 = GetOccludersF1D() | |||||
| def __call__(self, inter): | |||||
| lst1 = self.__func1(inter) | |||||
| for vs1 in lst1: | |||||
| for _id in self._idlist: | |||||
| if vs1.id == _id: | |||||
| return True | |||||
| return False | |||||
| class pyShapeIdListUP1D(UnaryPredicate1D): | |||||
| def __init__(self,idlist): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._idlist = idlist | |||||
| self._funcs = [] | |||||
| for _id in idlist : | |||||
| self._funcs.append(ShapeUP1D(_id.first, _id.second)) | |||||
| def __call__(self, inter): | |||||
| for func in self._funcs: | |||||
| if func(inter) == 1: | |||||
| return True | |||||
| return False | |||||
| ## deprecated | |||||
| class pyShapeIdUP1D(UnaryPredicate1D): | |||||
| def __init__(self, _id): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._id = _id | |||||
| def __call__(self, inter): | |||||
| func = GetShapeF1D() | |||||
| shapes = func(inter) | |||||
| for a in shapes: | |||||
| if a.id == self._id: | |||||
| return True | |||||
| return False | |||||
| class pyHighDensityAnisotropyUP1D(UnaryPredicate1D): | |||||
| def __init__(self,threshold, level, sampling=2.0): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._l = threshold | |||||
| self.func = pyDensityAnisotropyF1D(level, IntegrationType.MEAN, sampling) | |||||
| def __call__(self, inter): | |||||
| return (self.func(inter) > self._l) | |||||
| class pyHighViewMapGradientNormUP1D(UnaryPredicate1D): | |||||
| def __init__(self,threshold, l, sampling=2.0): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._threshold = threshold | |||||
| self._GetGradient = pyViewMapGradientNormF1D(l, IntegrationType.MEAN) | |||||
| def __call__(self, inter): | |||||
| gn = self._GetGradient(inter) | |||||
| #print(gn) | |||||
| return (gn > self._threshold) | |||||
| class pyDensityVariableSigmaUP1D(UnaryPredicate1D): | |||||
| def __init__(self,functor, sigmaMin,sigmaMax, lmin, lmax, tmin, tmax, integration = IntegrationType.MEAN, sampling=2.0): | |||||
| UnaryPredicate1D.__init__(self) | |||||
| self._functor = functor | |||||
| self._sigmaMin = float(sigmaMin) | |||||
| self._sigmaMax = float(sigmaMax) | |||||
| self._lmin = float(lmin) | |||||
| self._lmax = float(lmax) | |||||
| self._tmin = tmin | |||||
| self._tmax = tmax | |||||
| self._integration = integration | |||||
| self._sampling = sampling | |||||
| def __call__(self, inter): | |||||
| sigma = (self._sigmaMax-self._sigmaMin)/(self._lmax-self._lmin)*(self._functor(inter)-self._lmin) + self._sigmaMin | |||||
| t = (self._tmax-self._tmin)/(self._lmax-self._lmin)*(self._functor(inter)-self._lmin) + self._tmin | |||||
| sigma = max(sigma, self._sigmaMin) | |||||
| self._func = DensityF1D(sigma, self._integration, self._sampling) | |||||
| return (self._func(inter) < t) | |||||
| class pyClosedCurveUP1D(UnaryPredicate1D): | |||||
| def __call__(self, inter): | |||||
| it = inter.vertices_begin() | |||||
| itlast = inter.vertices_end() | |||||
| itlast.decrement() | |||||
| vlast = itlast.object | |||||
| v = it.object | |||||
| #print(v.id.first, v.id.second) | |||||
| #print(vlast.id.first, vlast.id.second) | |||||
| if v.id == vlast.id: | |||||
| return True | |||||
| return False | |||||
| ## Binary predicates for 1D elements (curves) | |||||
| ############################################# | |||||
| class pyZBP1D(BinaryPredicate1D): | |||||
| def __call__(self, i1, i2): | |||||
| func = GetZF1D() | |||||
| return (func(i1) > func(i2)) | |||||
| class pyZDiscontinuityBP1D(BinaryPredicate1D): | |||||
| def __init__(self, iType = IntegrationType.MEAN): | |||||
| BinaryPredicate1D.__init__(self) | |||||
| self._GetZDiscontinuity = ZDiscontinuityF1D(iType) | |||||
| def __call__(self, i1, i2): | |||||
| return (self._GetZDiscontinuity(i1) > self._GetZDiscontinuity(i2)) | |||||
| class pyLengthBP1D(BinaryPredicate1D): | |||||
| def __call__(self, i1, i2): | |||||
| return (i1.length_2d > i2.length_2d) | |||||
| class pySilhouetteFirstBP1D(BinaryPredicate1D): | |||||
| def __call__(self, inter1, inter2): | |||||
| bpred = SameShapeIdBP1D() | |||||
| if (bpred(inter1, inter2) != 1): | |||||
| return False | |||||
| if (inter1.nature & Nature.SILHOUETTE): | |||||
| return (inter2.nature & Nature.SILHOUETTE) != 0 | |||||
| return (inter1.nature == inter2.nature) | |||||
| class pyNatureBP1D(BinaryPredicate1D): | |||||
| def __call__(self, inter1, inter2): | |||||
| return (inter1.nature & inter2.nature) | |||||
| class pyViewMapGradientNormBP1D(BinaryPredicate1D): | |||||
| def __init__(self,l, sampling=2.0): | |||||
| BinaryPredicate1D.__init__(self) | |||||
| self._GetGradient = pyViewMapGradientNormF1D(l, IntegrationType.MEAN) | |||||
| def __call__(self, i1,i2): | |||||
| #print("compare gradient") | |||||
| return (self._GetGradient(i1) > self._GetGradient(i2)) | |||||
| class pyShuffleBP1D(BinaryPredicate1D): | |||||
| def __init__(self): | |||||
| BinaryPredicate1D.__init__(self) | |||||
| random.seed(1) | |||||
| def __call__(self, inter1, inter2): | |||||
| r1 = random.uniform(0,1) | |||||
| r2 = random.uniform(0,1) | |||||
| return (r1<r2) | |||||