forked from bartvdbraak/blender
1db5b6d283
StrokeVertex.point2d() instead of .getPoint(). It is noted that .point2d() returns a 3-dimensional vector representing a 2D-projected point, with the z component indicating a normalized depth of the original 3D point, whereas .getPoint() returns a plain 2-dimensional vector. This fix should have been done in revision 48510... Also made fix for callers of Stroke.Resample() not calling stroke.UpdateLength().
1345 lines
39 KiB
Python
1345 lines
39 KiB
Python
from freestyle_init import *
|
|
from PredicatesU0D import *
|
|
from PredicatesB1D import *
|
|
from PredicatesU1D import *
|
|
from logical_operators import *
|
|
from ChainingIterators import *
|
|
from random import *
|
|
from math import *
|
|
|
|
## thickness modifiers
|
|
######################
|
|
|
|
class pyDepthDiscontinuityThicknessShader(StrokeShader):
|
|
def __init__(self, min, max):
|
|
StrokeShader.__init__(self)
|
|
self.__min = float(min)
|
|
self.__max = float(max)
|
|
self.__func = ZDiscontinuityF0D()
|
|
def getName(self):
|
|
return "pyDepthDiscontinuityThicknessShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
z_min=0.0
|
|
z_max=1.0
|
|
a = (self.__max - self.__min)/(z_max-z_min)
|
|
b = (self.__min*z_max-self.__max*z_min)/(z_max-z_min)
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
z = self.__func(it.castToInterface0DIterator())
|
|
thickness = a*z+b
|
|
it.getObject().attribute().setThickness(thickness, thickness)
|
|
it.increment()
|
|
|
|
class pyConstantThicknessShader(StrokeShader):
|
|
def __init__(self, thickness):
|
|
StrokeShader.__init__(self)
|
|
self._thickness = thickness
|
|
|
|
def getName(self):
|
|
return "pyConstantThicknessShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
t = self._thickness/2.0
|
|
att.setThickness(t, t)
|
|
it.increment()
|
|
|
|
class pyFXSThicknessShader(StrokeShader):
|
|
def __init__(self, thickness):
|
|
StrokeShader.__init__(self)
|
|
self._thickness = thickness
|
|
|
|
def getName(self):
|
|
return "pyFXSThicknessShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
t = self._thickness/2.0
|
|
att.setThickness(t, t)
|
|
it.increment()
|
|
|
|
class pyFXSVaryingThicknessWithDensityShader(StrokeShader):
|
|
def __init__(self, wsize, threshold_min, threshold_max, thicknessMin, thicknessMax):
|
|
StrokeShader.__init__(self)
|
|
self.wsize= wsize
|
|
self.threshold_min= threshold_min
|
|
self.threshold_max= threshold_max
|
|
self._thicknessMin = thicknessMin
|
|
self._thicknessMax = thicknessMax
|
|
|
|
def getName(self):
|
|
return "pyVaryingThicknessWithDensityShader"
|
|
def shade(self, stroke):
|
|
n = stroke.strokeVerticesSize()
|
|
i = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
func = DensityF0D(self.wsize)
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
toto = it.castToInterface0DIterator()
|
|
c= func(toto)
|
|
if (c < self.threshold_min ):
|
|
c = self.threshold_min
|
|
if (c > self.threshold_max ):
|
|
c = self.threshold_max
|
|
## t = (c - self.threshold_min)/(self.threshold_max - self.threshold_min)*(self._thicknessMax-self._thicknessMin) + self._thicknessMin
|
|
t = (self.threshold_max - c )/(self.threshold_max - self.threshold_min)*(self._thicknessMax-self._thicknessMin) + self._thicknessMin
|
|
att.setThickness(t/2.0, t/2.0)
|
|
i = i+1
|
|
it.increment()
|
|
class pyIncreasingThicknessShader(StrokeShader):
|
|
def __init__(self, thicknessMin, thicknessMax):
|
|
StrokeShader.__init__(self)
|
|
self._thicknessMin = thicknessMin
|
|
self._thicknessMax = thicknessMax
|
|
|
|
def getName(self):
|
|
return "pyIncreasingThicknessShader"
|
|
def shade(self, stroke):
|
|
n = stroke.strokeVerticesSize()
|
|
i = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
c = float(i)/float(n)
|
|
if(i < float(n)/2.0):
|
|
t = (1.0 - c)*self._thicknessMin + c * self._thicknessMax
|
|
else:
|
|
t = (1.0 - c)*self._thicknessMax + c * self._thicknessMin
|
|
att.setThickness(t/2.0, t/2.0)
|
|
i = i+1
|
|
it.increment()
|
|
|
|
class pyConstrainedIncreasingThicknessShader(StrokeShader):
|
|
def __init__(self, thicknessMin, thicknessMax, ratio):
|
|
StrokeShader.__init__(self)
|
|
self._thicknessMin = thicknessMin
|
|
self._thicknessMax = thicknessMax
|
|
self._ratio = ratio
|
|
|
|
def getName(self):
|
|
return "pyConstrainedIncreasingThicknessShader"
|
|
def shade(self, stroke):
|
|
slength = stroke.getLength2D()
|
|
tmp = self._ratio*slength
|
|
maxT = 0.0
|
|
if(tmp < self._thicknessMax):
|
|
maxT = tmp
|
|
else:
|
|
maxT = self._thicknessMax
|
|
n = stroke.strokeVerticesSize()
|
|
i = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
c = float(i)/float(n)
|
|
if(i < float(n)/2.0):
|
|
t = (1.0 - c)*self._thicknessMin + c * maxT
|
|
else:
|
|
t = (1.0 - c)*maxT + c * self._thicknessMin
|
|
att.setThickness(t/2.0, t/2.0)
|
|
if(i == n-1):
|
|
att.setThickness(self._thicknessMin/2.0, self._thicknessMin/2.0)
|
|
i = i+1
|
|
it.increment()
|
|
|
|
class pyDecreasingThicknessShader(StrokeShader):
|
|
def __init__(self, thicknessMax, thicknessMin):
|
|
StrokeShader.__init__(self)
|
|
self._thicknessMin = thicknessMin
|
|
self._thicknessMax = thicknessMax
|
|
|
|
def getName(self):
|
|
return "pyDecreasingThicknessShader"
|
|
def shade(self, stroke):
|
|
l = stroke.getLength2D()
|
|
tMax = self._thicknessMax
|
|
if(self._thicknessMax > 0.33*l):
|
|
tMax = 0.33*l
|
|
tMin = self._thicknessMin
|
|
if(self._thicknessMin > 0.1*l):
|
|
tMin = 0.1*l
|
|
n = stroke.strokeVerticesSize()
|
|
i = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
c = float(i)/float(n)
|
|
t = (1.0 - c)*tMax +c*tMin
|
|
att.setThickness(t/2.0, t/2.0)
|
|
i = i+1
|
|
it.increment()
|
|
|
|
def smoothC( a, exp ):
|
|
c = pow(float(a),exp)*pow(2.0,exp)
|
|
return c
|
|
|
|
class pyNonLinearVaryingThicknessShader(StrokeShader):
|
|
def __init__(self, thicknessExtremity, thicknessMiddle, exponent):
|
|
StrokeShader.__init__(self)
|
|
self._thicknessMin = thicknessMiddle
|
|
self._thicknessMax = thicknessExtremity
|
|
self._exponent = exponent
|
|
|
|
def getName(self):
|
|
return "pyNonLinearVaryingThicknessShader"
|
|
def shade(self, stroke):
|
|
n = stroke.strokeVerticesSize()
|
|
i = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
if(i < float(n)/2.0):
|
|
c = float(i)/float(n)
|
|
else:
|
|
c = float(n-i)/float(n)
|
|
c = smoothC(c, self._exponent)
|
|
t = (1.0 - c)*self._thicknessMax + c * self._thicknessMin
|
|
att.setThickness(t/2.0, t/2.0)
|
|
i = i+1
|
|
it.increment()
|
|
|
|
## Spherical linear interpolation (cos)
|
|
class pySLERPThicknessShader(StrokeShader):
|
|
def __init__(self, thicknessMin, thicknessMax, omega=1.2):
|
|
StrokeShader.__init__(self)
|
|
self._thicknessMin = thicknessMin
|
|
self._thicknessMax = thicknessMax
|
|
self._omega = omega
|
|
|
|
def getName(self):
|
|
return "pySLERPThicknessShader"
|
|
def shade(self, stroke):
|
|
slength = stroke.getLength2D()
|
|
tmp = 0.33*slength
|
|
maxT = self._thicknessMax
|
|
if(tmp < self._thicknessMax):
|
|
maxT = tmp
|
|
|
|
n = stroke.strokeVerticesSize()
|
|
i = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
c = float(i)/float(n)
|
|
if(i < float(n)/2.0):
|
|
t = sin((1-c)*self._omega)/sinh(self._omega)*self._thicknessMin + sin(c*self._omega)/sinh(self._omega) * maxT
|
|
else:
|
|
t = sin((1-c)*self._omega)/sinh(self._omega)*maxT + sin(c*self._omega)/sinh(self._omega) * self._thicknessMin
|
|
att.setThickness(t/2.0, t/2.0)
|
|
i = i+1
|
|
it.increment()
|
|
|
|
class pyTVertexThickenerShader(StrokeShader): ## FIXME
|
|
def __init__(self, a=1.5, n=3):
|
|
StrokeShader.__init__(self)
|
|
self._a = a
|
|
self._n = n
|
|
|
|
def getName(self):
|
|
return "pyTVertexThickenerShader"
|
|
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
predTVertex = pyVertexNatureUP0D(Nature.T_VERTEX)
|
|
while it.isEnd() == 0:
|
|
if(predTVertex(it) == 1):
|
|
it2 = StrokeVertexIterator(it)
|
|
it2.increment()
|
|
if not(it.isBegin() or it2.isEnd()):
|
|
it.increment()
|
|
continue
|
|
n = self._n
|
|
a = self._a
|
|
if(it.isBegin()):
|
|
it3 = StrokeVertexIterator(it)
|
|
count = 0
|
|
while (it3.isEnd() == 0 and count < n):
|
|
att = it3.getObject().attribute()
|
|
tr = att.getThicknessR();
|
|
tl = att.getThicknessL();
|
|
r = (a-1.0)/float(n-1)*(float(n)/float(count+1) - 1) + 1
|
|
#r = (1.0-a)/float(n-1)*count + a
|
|
att.setThickness(r*tr, r*tl)
|
|
it3.increment()
|
|
count = count + 1
|
|
if(it2.isEnd()):
|
|
it4 = StrokeVertexIterator(it)
|
|
count = 0
|
|
while (it4.isBegin() == 0 and count < n):
|
|
att = it4.getObject().attribute()
|
|
tr = att.getThicknessR();
|
|
tl = att.getThicknessL();
|
|
r = (a-1.0)/float(n-1)*(float(n)/float(count+1) - 1) + 1
|
|
#r = (1.0-a)/float(n-1)*count + a
|
|
att.setThickness(r*tr, r*tl)
|
|
it4.decrement()
|
|
count = count + 1
|
|
if ((it4.isBegin() == 1)):
|
|
att = it4.getObject().attribute()
|
|
tr = att.getThicknessR();
|
|
tl = att.getThicknessL();
|
|
r = (a-1.0)/float(n-1)*(float(n)/float(count+1) - 1) + 1
|
|
#r = (1.0-a)/float(n-1)*count + a
|
|
att.setThickness(r*tr, r*tl)
|
|
it.increment()
|
|
|
|
class pyImportance2DThicknessShader(StrokeShader):
|
|
def __init__(self, x, y, w, kmin, kmax):
|
|
StrokeShader.__init__(self)
|
|
self._x = x
|
|
self._y = y
|
|
self._w = float(w)
|
|
self._kmin = float(kmin)
|
|
self._kmax = float(kmax)
|
|
|
|
def getName(self):
|
|
return "pyImportanceThicknessShader"
|
|
def shade(self, stroke):
|
|
origin = Vector([self._x, self._y])
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
v = it.getObject()
|
|
p = Vector([v.getProjectedX(), v.getProjectedY()])
|
|
d = (p-origin).length
|
|
if(d>self._w):
|
|
k = self._kmin
|
|
else:
|
|
k = (self._kmax*(self._w-d) + self._kmin*d)/self._w
|
|
att = v.attribute()
|
|
tr = att.getThicknessR()
|
|
tl = att.getThicknessL()
|
|
att.setThickness(k*tr/2.0, k*tl/2.0)
|
|
it.increment()
|
|
|
|
class pyImportance3DThicknessShader(StrokeShader):
|
|
def __init__(self, x, y, z, w, kmin, kmax):
|
|
StrokeShader.__init__(self)
|
|
self._x = x
|
|
self._y = y
|
|
self._z = z
|
|
self._w = float(w)
|
|
self._kmin = float(kmin)
|
|
self._kmax = float(kmax)
|
|
|
|
def getName(self):
|
|
return "pyImportance3DThicknessShader"
|
|
def shade(self, stroke):
|
|
origin = Vector([self._x, self._y, self._z])
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
v = it.getObject()
|
|
p = Vector([v.getX(), v.getY(), v.getZ()])
|
|
d = (p-origin).length
|
|
if(d>self._w):
|
|
k = self._kmin
|
|
else:
|
|
k = (self._kmax*(self._w-d) + self._kmin*d)/self._w
|
|
att = v.attribute()
|
|
tr = att.getThicknessR()
|
|
tl = att.getThicknessL()
|
|
att.setThickness(k*tr/2.0, k*tl/2.0)
|
|
it.increment()
|
|
|
|
class pyZDependingThicknessShader(StrokeShader):
|
|
def __init__(self, min, max):
|
|
StrokeShader.__init__(self)
|
|
self.__min = min
|
|
self.__max = max
|
|
self.__func = GetProjectedZF0D()
|
|
def getName(self):
|
|
return "pyZDependingThicknessShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
z_min = 1
|
|
z_max = 0
|
|
while it.isEnd() == 0:
|
|
z = self.__func(it.castToInterface0DIterator())
|
|
if z < z_min:
|
|
z_min = z
|
|
if z > z_max:
|
|
z_max = z
|
|
it.increment()
|
|
z_diff = 1 / (z_max - z_min)
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
z = (self.__func(it.castToInterface0DIterator()) - z_min) * z_diff
|
|
thickness = (1 - z) * self.__max + z * self.__min
|
|
it.getObject().attribute().setThickness(thickness, thickness)
|
|
it.increment()
|
|
|
|
|
|
## color modifiers
|
|
##################
|
|
|
|
class pyConstantColorShader(StrokeShader):
|
|
def __init__(self,r,g,b, a = 1):
|
|
StrokeShader.__init__(self)
|
|
self._r = r
|
|
self._g = g
|
|
self._b = b
|
|
self._a = a
|
|
def getName(self):
|
|
return "pyConstantColorShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
att.setColor(self._r, self._g, self._b)
|
|
att.setAlpha(self._a)
|
|
it.increment()
|
|
|
|
#c1->c2
|
|
class pyIncreasingColorShader(StrokeShader):
|
|
def __init__(self,r1,g1,b1,a1, r2,g2,b2,a2):
|
|
StrokeShader.__init__(self)
|
|
self._c1 = [r1,g1,b1,a1]
|
|
self._c2 = [r2,g2,b2,a2]
|
|
def getName(self):
|
|
return "pyIncreasingColorShader"
|
|
def shade(self, stroke):
|
|
n = stroke.strokeVerticesSize() - 1
|
|
inc = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
c = float(inc)/float(n)
|
|
|
|
att.setColor( (1-c)*self._c1[0] + c*self._c2[0],
|
|
(1-c)*self._c1[1] + c*self._c2[1],
|
|
(1-c)*self._c1[2] + c*self._c2[2],)
|
|
att.setAlpha((1-c)*self._c1[3] + c*self._c2[3],)
|
|
inc = inc+1
|
|
it.increment()
|
|
|
|
# c1->c2->c1
|
|
class pyInterpolateColorShader(StrokeShader):
|
|
def __init__(self,r1,g1,b1,a1, r2,g2,b2,a2):
|
|
StrokeShader.__init__(self)
|
|
self._c1 = [r1,g1,b1,a1]
|
|
self._c2 = [r2,g2,b2,a2]
|
|
def getName(self):
|
|
return "pyInterpolateColorShader"
|
|
def shade(self, stroke):
|
|
n = stroke.strokeVerticesSize() - 1
|
|
inc = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
u = float(inc)/float(n)
|
|
c = 1-2*(fabs(u-0.5))
|
|
att.setColor( (1-c)*self._c1[0] + c*self._c2[0],
|
|
(1-c)*self._c1[1] + c*self._c2[1],
|
|
(1-c)*self._c1[2] + c*self._c2[2],)
|
|
att.setAlpha((1-c)*self._c1[3] + c*self._c2[3],)
|
|
inc = inc+1
|
|
it.increment()
|
|
|
|
class pyMaterialColorShader(StrokeShader):
|
|
def __init__(self, threshold=50):
|
|
StrokeShader.__init__(self)
|
|
self._threshold = threshold
|
|
|
|
def getName(self):
|
|
return "pyMaterialColorShader"
|
|
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
func = MaterialF0D()
|
|
xn = 0.312713
|
|
yn = 0.329016
|
|
Yn = 1.0
|
|
un = 4.* xn/ ( -2.*xn + 12.*yn + 3. )
|
|
vn= 9.* yn/ ( -2.*xn + 12.*yn +3. )
|
|
while it.isEnd() == 0:
|
|
toto = it.castToInterface0DIterator()
|
|
mat = func(toto)
|
|
|
|
r = mat.diffuseR()
|
|
g = mat.diffuseG()
|
|
b = mat.diffuseB()
|
|
|
|
X = 0.412453*r + 0.35758 *g + 0.180423*b
|
|
Y = 0.212671*r + 0.71516 *g + 0.072169*b
|
|
Z = 0.019334*r + 0.119193*g + 0.950227*b
|
|
|
|
if((X == 0) and (Y == 0) and (Z == 0)):
|
|
X = 0.01
|
|
Y = 0.01
|
|
Z = 0.01
|
|
u = 4.*X / (X + 15.*Y + 3.*Z)
|
|
v = 9.*Y / (X + 15.*Y + 3.*Z)
|
|
|
|
L= 116. * pow((Y/Yn),(1./3.)) -16
|
|
U = 13. * L * (u - un)
|
|
V = 13. * L * (v - vn)
|
|
|
|
if (L > self._threshold):
|
|
L = L/1.3
|
|
U = U+10
|
|
else:
|
|
L = L +2.5*(100-L)/5.
|
|
U = U/3.0
|
|
V = V/3.0
|
|
u = U / (13. * L) + un
|
|
v = V / (13. * L) + vn
|
|
|
|
Y = Yn * pow( ((L+16.)/116.), 3.)
|
|
X = -9. * Y * u / ((u - 4.)* v - u * v)
|
|
Z = (9. * Y - 15*v*Y - v*X) /( 3. * v)
|
|
|
|
r = 3.240479 * X - 1.53715 * Y - 0.498535 * Z
|
|
g = -0.969256 * X + 1.875991 * Y + 0.041556 * Z
|
|
b = 0.055648 * X - 0.204043 * Y + 1.057311 * Z
|
|
|
|
r = max(0,r)
|
|
g = max(0,g)
|
|
b = max(0,b)
|
|
|
|
att = it.getObject().attribute()
|
|
att.setColor(r, g, b)
|
|
it.increment()
|
|
|
|
class pyRandomColorShader(StrokeShader):
|
|
def getName(self):
|
|
return "pyRandomColorShader"
|
|
def __init__(self, s=1):
|
|
StrokeShader.__init__(self)
|
|
seed(s)
|
|
def shade(self, stroke):
|
|
## pick a random color
|
|
c0 = float(uniform(15,75))/100.0
|
|
c1 = float(uniform(15,75))/100.0
|
|
c2 = float(uniform(15,75))/100.0
|
|
print(c0, c1, c2)
|
|
it = stroke.strokeVerticesBegin()
|
|
while(it.isEnd() == 0):
|
|
it.getObject().attribute().setColor(c0,c1,c2)
|
|
it.increment()
|
|
|
|
class py2DCurvatureColorShader(StrokeShader):
|
|
def getName(self):
|
|
return "py2DCurvatureColorShader"
|
|
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
func = Curvature2DAngleF0D()
|
|
while it.isEnd() == 0:
|
|
toto = it.castToInterface0DIterator()
|
|
sv = it.getObject()
|
|
att = sv.attribute()
|
|
c = func(toto)
|
|
if (c<0):
|
|
print("negative 2D curvature")
|
|
color = 10.0 * c/3.1415
|
|
print(color)
|
|
att.setColor(color,color,color);
|
|
it.increment()
|
|
|
|
class pyTimeColorShader(StrokeShader):
|
|
def __init__(self, step=0.01):
|
|
StrokeShader.__init__(self)
|
|
self._t = 0
|
|
self._step = step
|
|
def shade(self, stroke):
|
|
c = self._t*1.0
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
att = it.getObject().attribute()
|
|
att.setColor(c,c,c)
|
|
it.increment()
|
|
self._t = self._t+self._step
|
|
|
|
## geometry modifiers
|
|
|
|
class pySamplingShader(StrokeShader):
|
|
def __init__(self, sampling):
|
|
StrokeShader.__init__(self)
|
|
self._sampling = sampling
|
|
def getName(self):
|
|
return "pySamplingShader"
|
|
def shade(self, stroke):
|
|
stroke.Resample(float(self._sampling))
|
|
stroke.UpdateLength()
|
|
|
|
class pyBackboneStretcherShader(StrokeShader):
|
|
def __init__(self, l):
|
|
StrokeShader.__init__(self)
|
|
self._l = l
|
|
def getName(self):
|
|
return "pyBackboneStretcherShader"
|
|
def shade(self, stroke):
|
|
it0 = stroke.strokeVerticesBegin()
|
|
it1 = StrokeVertexIterator(it0)
|
|
it1.increment()
|
|
itn = stroke.strokeVerticesEnd()
|
|
itn.decrement()
|
|
itn_1 = StrokeVertexIterator(itn)
|
|
itn_1.decrement()
|
|
v0 = it0.getObject()
|
|
v1 = it1.getObject()
|
|
vn_1 = itn_1.getObject()
|
|
vn = itn.getObject()
|
|
p0 = Vector([v0.getProjectedX(), v0.getProjectedY()])
|
|
pn = Vector([vn.getProjectedX(), vn.getProjectedY()])
|
|
p1 = Vector([v1.getProjectedX(), v1.getProjectedY()])
|
|
pn_1 = Vector([vn_1.getProjectedX(), vn_1.getProjectedY()])
|
|
d1 = p0-p1
|
|
d1.normalize()
|
|
dn = pn-pn_1
|
|
dn.normalize()
|
|
newFirst = p0+d1*float(self._l)
|
|
newLast = pn+dn*float(self._l)
|
|
v0.setPoint(newFirst)
|
|
vn.setPoint(newLast)
|
|
stroke.UpdateLength()
|
|
|
|
class pyLengthDependingBackboneStretcherShader(StrokeShader):
|
|
def __init__(self, l):
|
|
StrokeShader.__init__(self)
|
|
self._l = l
|
|
def getName(self):
|
|
return "pyBackboneStretcherShader"
|
|
def shade(self, stroke):
|
|
l = stroke.getLength2D()
|
|
stretch = self._l*l
|
|
it0 = stroke.strokeVerticesBegin()
|
|
it1 = StrokeVertexIterator(it0)
|
|
it1.increment()
|
|
itn = stroke.strokeVerticesEnd()
|
|
itn.decrement()
|
|
itn_1 = StrokeVertexIterator(itn)
|
|
itn_1.decrement()
|
|
v0 = it0.getObject()
|
|
v1 = it1.getObject()
|
|
vn_1 = itn_1.getObject()
|
|
vn = itn.getObject()
|
|
p0 = Vector([v0.getProjectedX(), v0.getProjectedY()])
|
|
pn = Vector([vn.getProjectedX(), vn.getProjectedY()])
|
|
p1 = Vector([v1.getProjectedX(), v1.getProjectedY()])
|
|
pn_1 = Vector([vn_1.getProjectedX(), vn_1.getProjectedY()])
|
|
d1 = p0-p1
|
|
d1.normalize()
|
|
dn = pn-pn_1
|
|
dn.normalize()
|
|
newFirst = p0+d1*float(stretch)
|
|
newLast = pn+dn*float(stretch)
|
|
v0.setPoint(newFirst)
|
|
vn.setPoint(newLast)
|
|
stroke.UpdateLength()
|
|
|
|
|
|
## Shader to replace a stroke by its corresponding tangent
|
|
class pyGuidingLineShader(StrokeShader):
|
|
def getName(self):
|
|
return "pyGuidingLineShader"
|
|
## shading method
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin() ## get the first vertex
|
|
itlast = stroke.strokeVerticesEnd() ##
|
|
itlast.decrement() ## get the last one
|
|
t = itlast.getObject().getPoint() - it.getObject().getPoint() ## tangent direction
|
|
itmiddle = StrokeVertexIterator(it) ##
|
|
while(itmiddle.getObject().u()<0.5): ## look for the stroke middle vertex
|
|
itmiddle.increment() ##
|
|
it = StrokeVertexIterator(itmiddle)
|
|
it.increment()
|
|
while(it.isEnd() == 0): ## position all the vertices along the tangent for the right part
|
|
it.getObject().setPoint(itmiddle.getObject().getPoint() \
|
|
+t*(it.getObject().u()-itmiddle.getObject().u()))
|
|
it.increment()
|
|
it = StrokeVertexIterator(itmiddle)
|
|
it.decrement()
|
|
while(it.isBegin() == 0): ## position all the vertices along the tangent for the left part
|
|
it.getObject().setPoint(itmiddle.getObject().getPoint() \
|
|
-t*(itmiddle.getObject().u()-it.getObject().u()))
|
|
it.decrement()
|
|
it.getObject().setPoint(itmiddle.getObject().getPoint()-t*(itmiddle.getObject().u())) ## first vertex
|
|
stroke.UpdateLength()
|
|
|
|
|
|
class pyBackboneStretcherNoCuspShader(StrokeShader):
|
|
def __init__(self, l):
|
|
StrokeShader.__init__(self)
|
|
self._l = l
|
|
def getName(self):
|
|
return "pyBackboneStretcherNoCuspShader"
|
|
def shade(self, stroke):
|
|
it0 = stroke.strokeVerticesBegin()
|
|
it1 = StrokeVertexIterator(it0)
|
|
it1.increment()
|
|
itn = stroke.strokeVerticesEnd()
|
|
itn.decrement()
|
|
itn_1 = StrokeVertexIterator(itn)
|
|
itn_1.decrement()
|
|
v0 = it0.getObject()
|
|
v1 = it1.getObject()
|
|
if((v0.getNature() & Nature.CUSP == 0) and (v1.getNature() & Nature.CUSP == 0)):
|
|
p0 = v0.getPoint()
|
|
p1 = v1.getPoint()
|
|
d1 = p0-p1
|
|
d1.normalize()
|
|
newFirst = p0+d1*float(self._l)
|
|
v0.setPoint(newFirst)
|
|
vn_1 = itn_1.getObject()
|
|
vn = itn.getObject()
|
|
if((vn.getNature() & Nature.CUSP == 0) and (vn_1.getNature() & Nature.CUSP == 0)):
|
|
pn = vn.getPoint()
|
|
pn_1 = vn_1.getPoint()
|
|
dn = pn-pn_1
|
|
dn.normalize()
|
|
newLast = pn+dn*float(self._l)
|
|
vn.setPoint(newLast)
|
|
stroke.UpdateLength()
|
|
|
|
normalInfo=Normal2DF0D()
|
|
curvatureInfo=Curvature2DAngleF0D()
|
|
|
|
def edgestopping(x, sigma):
|
|
return exp(- x*x/(2*sigma*sigma))
|
|
|
|
class pyDiffusion2Shader(StrokeShader):
|
|
def __init__(self, lambda1, nbIter):
|
|
StrokeShader.__init__(self)
|
|
self._lambda = lambda1
|
|
self._nbIter = nbIter
|
|
self._normalInfo = Normal2DF0D()
|
|
self._curvatureInfo = Curvature2DAngleF0D()
|
|
def getName(self):
|
|
return "pyDiffusionShader"
|
|
def shade(self, stroke):
|
|
for i in range (1, self._nbIter):
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
v=it.getObject()
|
|
p1 = v.getPoint()
|
|
p2 = self._normalInfo(it.castToInterface0DIterator())*self._lambda*self._curvatureInfo(it.castToInterface0DIterator())
|
|
v.setPoint(p1+p2)
|
|
it.increment()
|
|
stroke.UpdateLength()
|
|
|
|
class pyTipRemoverShader(StrokeShader):
|
|
def __init__(self, l):
|
|
StrokeShader.__init__(self)
|
|
self._l = l
|
|
def getName(self):
|
|
return "pyTipRemoverShader"
|
|
def shade(self, stroke):
|
|
originalSize = stroke.strokeVerticesSize()
|
|
if(originalSize<4):
|
|
return
|
|
verticesToRemove = []
|
|
oldAttributes = []
|
|
it = stroke.strokeVerticesBegin()
|
|
while(it.isEnd() == 0):
|
|
v = it.getObject()
|
|
if((v.curvilinearAbscissa() < self._l) or (v.strokeLength()-v.curvilinearAbscissa() < self._l)):
|
|
verticesToRemove.append(v)
|
|
oldAttributes.append(StrokeAttribute(v.attribute()))
|
|
it.increment()
|
|
if(originalSize-len(verticesToRemove) < 2):
|
|
return
|
|
for sv in verticesToRemove:
|
|
stroke.RemoveVertex(sv)
|
|
stroke.Resample(originalSize)
|
|
if(stroke.strokeVerticesSize() != originalSize):
|
|
print("pyTipRemover: Warning: resampling problem")
|
|
it = stroke.strokeVerticesBegin()
|
|
for a in oldAttributes:
|
|
if(it.isEnd() == 1):
|
|
break
|
|
v = it.getObject()
|
|
v.setAttribute(a)
|
|
it.increment()
|
|
stroke.UpdateLength()
|
|
|
|
class pyTVertexRemoverShader(StrokeShader):
|
|
def getName(self):
|
|
return "pyTVertexRemoverShader"
|
|
def shade(self, stroke):
|
|
if(stroke.strokeVerticesSize() <= 3 ):
|
|
return
|
|
predTVertex = pyVertexNatureUP0D(Nature.T_VERTEX)
|
|
it = stroke.strokeVerticesBegin()
|
|
itlast = stroke.strokeVerticesEnd()
|
|
itlast.decrement()
|
|
if(predTVertex(it) == 1):
|
|
stroke.RemoveVertex(it.getObject())
|
|
if(predTVertex(itlast) == 1):
|
|
stroke.RemoveVertex(itlast.getObject())
|
|
stroke.UpdateLength()
|
|
|
|
class pyExtremitiesOrientationShader(StrokeShader):
|
|
def __init__(self, x1,y1,x2=0,y2=0):
|
|
StrokeShader.__init__(self)
|
|
self._v1 = Vector([x1,y1])
|
|
self._v2 = Vector([x2,y2])
|
|
def getName(self):
|
|
return "pyExtremitiesOrientationShader"
|
|
def shade(self, stroke):
|
|
print(self._v1.x,self._v1.y)
|
|
stroke.setBeginningOrientation(self._v1.x,self._v1.y)
|
|
stroke.setEndingOrientation(self._v2.x,self._v2.y)
|
|
|
|
def getFEdge(it1, it2):
|
|
return it1.getFEdge(it2)
|
|
|
|
class pyHLRShader(StrokeShader):
|
|
def getName(self):
|
|
return "pyHLRShader"
|
|
def shade(self, stroke):
|
|
originalSize = stroke.strokeVerticesSize()
|
|
if(originalSize<4):
|
|
return
|
|
it = stroke.strokeVerticesBegin()
|
|
invisible = 0
|
|
it2 = StrokeVertexIterator(it)
|
|
it2.increment()
|
|
fe = getFEdge(it.getObject(), it2.getObject())
|
|
if(fe.viewedge().qi() != 0):
|
|
invisible = 1
|
|
while(it2.isEnd() == 0):
|
|
v = it.getObject()
|
|
vnext = it2.getObject()
|
|
if(v.getNature() & Nature.VIEW_VERTEX):
|
|
#if(v.getNature() & Nature.T_VERTEX):
|
|
fe = getFEdge(v,vnext)
|
|
qi = fe.viewedge().qi()
|
|
if(qi != 0):
|
|
invisible = 1
|
|
else:
|
|
invisible = 0
|
|
if(invisible == 1):
|
|
v.attribute().setVisible(0)
|
|
it.increment()
|
|
it2.increment()
|
|
|
|
class pyTVertexOrientationShader(StrokeShader):
|
|
def __init__(self):
|
|
StrokeShader.__init__(self)
|
|
self._Get2dDirection = Orientation2DF1D()
|
|
def getName(self):
|
|
return "pyTVertexOrientationShader"
|
|
## finds the TVertex orientation from the TVertex and
|
|
## the previous or next edge
|
|
def findOrientation(self, tv, ve):
|
|
mateVE = tv.mate(ve)
|
|
if((ve.qi() != 0) or (mateVE.qi() != 0)):
|
|
ait = AdjacencyIterator(tv,1,0)
|
|
winner = None
|
|
incoming = 1
|
|
while(ait.isEnd() == 0):
|
|
ave = ait.getObject()
|
|
if((ave.getId() != ve.getId()) and (ave.getId() != mateVE.getId())):
|
|
winner = ait.getObject()
|
|
if(ait.isIncoming() == 0):
|
|
incoming = 0
|
|
break
|
|
ait.increment()
|
|
if(winner != None):
|
|
if(incoming != 0):
|
|
direction = self._Get2dDirection(winner.fedgeB())
|
|
else:
|
|
direction = self._Get2dDirection(winner.fedgeA())
|
|
return direction
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
it2 = StrokeVertexIterator(it)
|
|
it2.increment()
|
|
## case where the first vertex is a TVertex
|
|
v = it.getObject()
|
|
if(v.getNature() & Nature.T_VERTEX):
|
|
tv = v.castToTVertex()
|
|
ve = getFEdge(v, it2.getObject()).viewedge()
|
|
if(tv != None):
|
|
dir = self.findOrientation(tv, ve)
|
|
#print(dir.x, dir.y)
|
|
v.attribute().setAttributeVec2f("orientation", dir)
|
|
while(it2.isEnd() == 0):
|
|
vprevious = it.getObject()
|
|
v = it2.getObject()
|
|
if(v.getNature() & Nature.T_VERTEX):
|
|
tv = v.castToTVertex()
|
|
ve = getFEdge(vprevious, v).viewedge()
|
|
if(tv != None):
|
|
dir = self.findOrientation(tv, ve)
|
|
#print(dir.x, dir.y)
|
|
v.attribute().setAttributeVec2f("orientation", dir)
|
|
it.increment()
|
|
it2.increment()
|
|
## case where the last vertex is a TVertex
|
|
v = it.getObject()
|
|
if(v.getNature() & Nature.T_VERTEX):
|
|
itPrevious = StrokeVertexIterator(it)
|
|
itPrevious.decrement()
|
|
tv = v.castToTVertex()
|
|
ve = getFEdge(itPrevious.getObject(), v).viewedge()
|
|
if(tv != None):
|
|
dir = self.findOrientation(tv, ve)
|
|
#print(dir.x, dir.y)
|
|
v.attribute().setAttributeVec2f("orientation", dir)
|
|
|
|
class pySinusDisplacementShader(StrokeShader):
|
|
def __init__(self, f, a):
|
|
StrokeShader.__init__(self)
|
|
self._f = f
|
|
self._a = a
|
|
self._getNormal = Normal2DF0D()
|
|
|
|
def getName(self):
|
|
return "pySinusDisplacementShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
v = it.getObject()
|
|
#print(self._getNormal.getName())
|
|
n = self._getNormal(it.castToInterface0DIterator())
|
|
p = v.getPoint()
|
|
u = v.u()
|
|
a = self._a*(1-2*(fabs(u-0.5)))
|
|
n = n*a*cos(self._f*u*6.28)
|
|
#print(n.x, n.y)
|
|
v.setPoint(p+n)
|
|
#v.setPoint(v.getPoint()+n*a*cos(f*v.u()))
|
|
it.increment()
|
|
stroke.UpdateLength()
|
|
|
|
class pyPerlinNoise1DShader(StrokeShader):
|
|
def __init__(self, freq = 10, amp = 10, oct = 4, seed = -1):
|
|
StrokeShader.__init__(self)
|
|
self.__noise = Noise(seed)
|
|
self.__freq = freq
|
|
self.__amp = amp
|
|
self.__oct = oct
|
|
def getName(self):
|
|
return "pyPerlinNoise1DShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
v = it.getObject()
|
|
i = v.getProjectedX() + v.getProjectedY()
|
|
nres = self.__noise.turbulence1(i, self.__freq, self.__amp, self.__oct)
|
|
v.setPoint(v.getProjectedX() + nres, v.getProjectedY() + nres)
|
|
it.increment()
|
|
stroke.UpdateLength()
|
|
|
|
class pyPerlinNoise2DShader(StrokeShader):
|
|
def __init__(self, freq = 10, amp = 10, oct = 4, seed = -1):
|
|
StrokeShader.__init__(self)
|
|
self.__noise = Noise(seed)
|
|
self.__freq = freq
|
|
self.__amp = amp
|
|
self.__oct = oct
|
|
def getName(self):
|
|
return "pyPerlinNoise2DShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
v = it.getObject()
|
|
vec = Vector([v.getProjectedX(), v.getProjectedY()])
|
|
nres = self.__noise.turbulence2(vec, self.__freq, self.__amp, self.__oct)
|
|
v.setPoint(v.getProjectedX() + nres, v.getProjectedY() + nres)
|
|
it.increment()
|
|
stroke.UpdateLength()
|
|
|
|
class pyBluePrintCirclesShader(StrokeShader):
|
|
def __init__(self, turns = 1, random_radius = 3, random_center = 5):
|
|
StrokeShader.__init__(self)
|
|
self.__turns = turns
|
|
self.__random_center = random_center
|
|
self.__random_radius = random_radius
|
|
def getName(self):
|
|
return "pyBluePrintCirclesShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
if it.isEnd():
|
|
return
|
|
p_min = it.getObject().getPoint()
|
|
p_max = it.getObject().getPoint()
|
|
while it.isEnd() == 0:
|
|
p = it.getObject().getPoint()
|
|
if (p.x < p_min.x):
|
|
p_min.x = p.x
|
|
if (p.x > p_max.x):
|
|
p_max.x = p.x
|
|
if (p.y < p_min.y):
|
|
p_min.y = p.y
|
|
if (p.y > p_max.y):
|
|
p_max.y = p.y
|
|
it.increment()
|
|
stroke.Resample(32 * self.__turns)
|
|
sv_nb = stroke.strokeVerticesSize()
|
|
# print("min :", p_min.x, p_min.y) # DEBUG
|
|
# print("mean :", p_sum.x, p_sum.y) # DEBUG
|
|
# print("max :", p_max.x, p_max.y) # DEBUG
|
|
# print("----------------------") # DEBUG
|
|
#######################################################
|
|
sv_nb = sv_nb // self.__turns
|
|
center = (p_min + p_max) / 2
|
|
radius = (center.x - p_min.x + center.y - p_min.y) / 2
|
|
p_new = Vector([0, 0])
|
|
#######################################################
|
|
R = self.__random_radius
|
|
C = self.__random_center
|
|
i = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
for j in range(self.__turns):
|
|
prev_radius = radius
|
|
prev_center = center
|
|
radius = radius + randint(-R, R)
|
|
center = center + Vector([randint(-C, C), randint(-C, C)])
|
|
while i < sv_nb and it.isEnd() == 0:
|
|
t = float(i) / float(sv_nb - 1)
|
|
r = prev_radius + (radius - prev_radius) * t
|
|
c = prev_center + (center - prev_center) * t
|
|
p_new.x = c.x + r * cos(2 * pi * t)
|
|
p_new.y = c.y + r * sin(2 * pi * t)
|
|
it.getObject().setPoint(p_new)
|
|
i = i + 1
|
|
it.increment()
|
|
i = 1
|
|
verticesToRemove = []
|
|
while it.isEnd() == 0:
|
|
verticesToRemove.append(it.getObject())
|
|
it.increment()
|
|
for sv in verticesToRemove:
|
|
stroke.RemoveVertex(sv)
|
|
stroke.UpdateLength()
|
|
|
|
class pyBluePrintEllipsesShader(StrokeShader):
|
|
def __init__(self, turns = 1, random_radius = 3, random_center = 5):
|
|
StrokeShader.__init__(self)
|
|
self.__turns = turns
|
|
self.__random_center = random_center
|
|
self.__random_radius = random_radius
|
|
def getName(self):
|
|
return "pyBluePrintEllipsesShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
if it.isEnd():
|
|
return
|
|
p_min = it.getObject().getPoint()
|
|
p_max = it.getObject().getPoint()
|
|
while it.isEnd() == 0:
|
|
p = it.getObject().getPoint()
|
|
if (p.x < p_min.x):
|
|
p_min.x = p.x
|
|
if (p.x > p_max.x):
|
|
p_max.x = p.x
|
|
if (p.y < p_min.y):
|
|
p_min.y = p.y
|
|
if (p.y > p_max.y):
|
|
p_max.y = p.y
|
|
it.increment()
|
|
stroke.Resample(32 * self.__turns)
|
|
sv_nb = stroke.strokeVerticesSize()
|
|
sv_nb = sv_nb // self.__turns
|
|
center = (p_min + p_max) / 2
|
|
radius = center - p_min
|
|
p_new = Vector([0, 0])
|
|
#######################################################
|
|
R = self.__random_radius
|
|
C = self.__random_center
|
|
i = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
for j in range(self.__turns):
|
|
prev_radius = radius
|
|
prev_center = center
|
|
radius = radius + Vector([randint(-R, R), randint(-R, R)])
|
|
center = center + Vector([randint(-C, C), randint(-C, C)])
|
|
while i < sv_nb and it.isEnd() == 0:
|
|
t = float(i) / float(sv_nb - 1)
|
|
r = prev_radius + (radius - prev_radius) * t
|
|
c = prev_center + (center - prev_center) * t
|
|
p_new.x = c.x + r.x * cos(2 * pi * t)
|
|
p_new.y = c.y + r.y * sin(2 * pi * t)
|
|
it.getObject().setPoint(p_new)
|
|
i = i + 1
|
|
it.increment()
|
|
i = 1
|
|
verticesToRemove = []
|
|
while it.isEnd() == 0:
|
|
verticesToRemove.append(it.getObject())
|
|
it.increment()
|
|
for sv in verticesToRemove:
|
|
stroke.RemoveVertex(sv)
|
|
stroke.UpdateLength()
|
|
|
|
|
|
class pyBluePrintSquaresShader(StrokeShader):
|
|
def __init__(self, turns = 1, bb_len = 10, bb_rand = 0):
|
|
StrokeShader.__init__(self)
|
|
self.__turns = turns
|
|
self.__bb_len = bb_len
|
|
self.__bb_rand = bb_rand
|
|
|
|
def getName(self):
|
|
return "pyBluePrintSquaresShader"
|
|
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
if it.isEnd():
|
|
return
|
|
p_min = it.getObject().getPoint()
|
|
p_max = it.getObject().getPoint()
|
|
while it.isEnd() == 0:
|
|
p = it.getObject().getPoint()
|
|
if (p.x < p_min.x):
|
|
p_min.x = p.x
|
|
if (p.x > p_max.x):
|
|
p_max.x = p.x
|
|
if (p.y < p_min.y):
|
|
p_min.y = p.y
|
|
if (p.y > p_max.y):
|
|
p_max.y = p.y
|
|
it.increment()
|
|
stroke.Resample(32 * self.__turns)
|
|
sv_nb = stroke.strokeVerticesSize()
|
|
#######################################################
|
|
sv_nb = sv_nb // self.__turns
|
|
first = sv_nb // 4
|
|
second = 2 * first
|
|
third = 3 * first
|
|
fourth = sv_nb
|
|
p_first = Vector([p_min.x - self.__bb_len, p_min.y])
|
|
p_first_end = Vector([p_max.x + self.__bb_len, p_min.y])
|
|
p_second = Vector([p_max.x, p_min.y - self.__bb_len])
|
|
p_second_end = Vector([p_max.x, p_max.y + self.__bb_len])
|
|
p_third = Vector([p_max.x + self.__bb_len, p_max.y])
|
|
p_third_end = Vector([p_min.x - self.__bb_len, p_max.y])
|
|
p_fourth = Vector([p_min.x, p_max.y + self.__bb_len])
|
|
p_fourth_end = Vector([p_min.x, p_min.y - self.__bb_len])
|
|
#######################################################
|
|
R = self.__bb_rand
|
|
r = self.__bb_rand // 2
|
|
it = stroke.strokeVerticesBegin()
|
|
visible = 1
|
|
for j in range(self.__turns):
|
|
p_first = p_first + Vector([randint(-R, R), randint(-r, r)])
|
|
p_first_end = p_first_end + Vector([randint(-R, R), randint(-r, r)])
|
|
p_second = p_second + Vector([randint(-r, r), randint(-R, R)])
|
|
p_second_end = p_second_end + Vector([randint(-r, r), randint(-R, R)])
|
|
p_third = p_third + Vector([randint(-R, R), randint(-r, r)])
|
|
p_third_end = p_third_end + Vector([randint(-R, R), randint(-r, r)])
|
|
p_fourth = p_fourth + Vector([randint(-r, r), randint(-R, R)])
|
|
p_fourth_end = p_fourth_end + Vector([randint(-r, r), randint(-R, R)])
|
|
vec_first = p_first_end - p_first
|
|
vec_second = p_second_end - p_second
|
|
vec_third = p_third_end - p_third
|
|
vec_fourth = p_fourth_end - p_fourth
|
|
i = 0
|
|
while i < sv_nb and it.isEnd() == 0:
|
|
if i < first:
|
|
p_new = p_first + vec_first * float(i)/float(first - 1)
|
|
if i == first - 1:
|
|
visible = 0
|
|
elif i < second:
|
|
p_new = p_second + vec_second * float(i - first)/float(second - first - 1)
|
|
if i == second - 1:
|
|
visible = 0
|
|
elif i < third:
|
|
p_new = p_third + vec_third * float(i - second)/float(third - second - 1)
|
|
if i == third - 1:
|
|
visible = 0
|
|
else:
|
|
p_new = p_fourth + vec_fourth * float(i - third)/float(fourth - third - 1)
|
|
if i == fourth - 1:
|
|
visible = 0
|
|
if it.getObject() == None:
|
|
i = i + 1
|
|
it.increment()
|
|
if visible == 0:
|
|
visible = 1
|
|
continue
|
|
it.getObject().setPoint(p_new)
|
|
it.getObject().attribute().setVisible(visible)
|
|
if visible == 0:
|
|
visible = 1
|
|
i = i + 1
|
|
it.increment()
|
|
verticesToRemove = []
|
|
while it.isEnd() == 0:
|
|
verticesToRemove.append(it.getObject())
|
|
it.increment()
|
|
for sv in verticesToRemove:
|
|
stroke.RemoveVertex(sv)
|
|
stroke.UpdateLength()
|
|
|
|
|
|
class pyBluePrintDirectedSquaresShader(StrokeShader):
|
|
def __init__(self, turns = 1, bb_len = 10, mult = 1):
|
|
StrokeShader.__init__(self)
|
|
self.__mult = mult
|
|
self.__turns = turns
|
|
self.__bb_len = 1 + float(bb_len) / 100
|
|
def getName(self):
|
|
return "pyBluePrintDirectedSquaresShader"
|
|
def shade(self, stroke):
|
|
stroke.Resample(32 * self.__turns)
|
|
p_mean = Vector([0, 0])
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
p = it.getObject().getPoint()
|
|
p_mean = p_mean + p
|
|
it.increment()
|
|
sv_nb = stroke.strokeVerticesSize()
|
|
p_mean = p_mean / sv_nb
|
|
p_var_xx = 0
|
|
p_var_yy = 0
|
|
p_var_xy = 0
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
p = it.getObject().getPoint()
|
|
p_var_xx = p_var_xx + pow(p.x - p_mean.x, 2)
|
|
p_var_yy = p_var_yy + pow(p.y - p_mean.y, 2)
|
|
p_var_xy = p_var_xy + (p.x - p_mean.x) * (p.y - p_mean.y)
|
|
it.increment()
|
|
p_var_xx = p_var_xx / sv_nb
|
|
p_var_yy = p_var_yy / sv_nb
|
|
p_var_xy = p_var_xy / sv_nb
|
|
## print(p_var_xx, p_var_yy, p_var_xy)
|
|
trace = p_var_xx + p_var_yy
|
|
det = p_var_xx * p_var_yy - p_var_xy * p_var_xy
|
|
sqrt_coeff = sqrt(trace * trace - 4 * det)
|
|
lambda1 = (trace + sqrt_coeff) / 2
|
|
lambda2 = (trace - sqrt_coeff) / 2
|
|
## print(lambda1, lambda2)
|
|
theta = atan(2 * p_var_xy / (p_var_xx - p_var_yy)) / 2
|
|
## print(theta)
|
|
if p_var_yy > p_var_xx:
|
|
e1 = Vector([cos(theta + pi / 2), sin(theta + pi / 2)]) * sqrt(lambda1) * self.__mult
|
|
e2 = Vector([cos(theta + pi), sin(theta + pi)]) * sqrt(lambda2) * self.__mult
|
|
else:
|
|
e1 = Vector([cos(theta), sin(theta)]) * sqrt(lambda1) * self.__mult
|
|
e2 = Vector([cos(theta + pi / 2), sin(theta + pi / 2)]) * sqrt(lambda2) * self.__mult
|
|
#######################################################
|
|
sv_nb = sv_nb // self.__turns
|
|
first = sv_nb // 4
|
|
second = 2 * first
|
|
third = 3 * first
|
|
fourth = sv_nb
|
|
bb_len1 = self.__bb_len
|
|
bb_len2 = 1 + (bb_len1 - 1) * sqrt(lambda1 / lambda2)
|
|
p_first = p_mean - e1 - e2 * bb_len2
|
|
p_second = p_mean - e1 * bb_len1 + e2
|
|
p_third = p_mean + e1 + e2 * bb_len2
|
|
p_fourth = p_mean + e1 * bb_len1 - e2
|
|
vec_first = e2 * bb_len2 * 2
|
|
vec_second = e1 * bb_len1 * 2
|
|
vec_third = vec_first * -1
|
|
vec_fourth = vec_second * -1
|
|
#######################################################
|
|
it = stroke.strokeVerticesBegin()
|
|
visible = 1
|
|
for j in range(self.__turns):
|
|
i = 0
|
|
while i < sv_nb:
|
|
if i < first:
|
|
p_new = p_first + vec_first * float(i)/float(first - 1)
|
|
if i == first - 1:
|
|
visible = 0
|
|
elif i < second:
|
|
p_new = p_second + vec_second * float(i - first)/float(second - first - 1)
|
|
if i == second - 1:
|
|
visible = 0
|
|
elif i < third:
|
|
p_new = p_third + vec_third * float(i - second)/float(third - second - 1)
|
|
if i == third - 1:
|
|
visible = 0
|
|
else:
|
|
p_new = p_fourth + vec_fourth * float(i - third)/float(fourth - third - 1)
|
|
if i == fourth - 1:
|
|
visible = 0
|
|
it.getObject().setPoint(p_new)
|
|
it.getObject().attribute().setVisible(visible)
|
|
if visible == 0:
|
|
visible = 1
|
|
i = i + 1
|
|
it.increment()
|
|
verticesToRemove = []
|
|
while it.isEnd() == 0:
|
|
verticesToRemove.append(it.getObject())
|
|
it.increment()
|
|
for sv in verticesToRemove:
|
|
stroke.RemoveVertex(sv)
|
|
stroke.UpdateLength()
|
|
|
|
class pyModulateAlphaShader(StrokeShader):
|
|
def __init__(self, min = 0, max = 1):
|
|
StrokeShader.__init__(self)
|
|
self.__min = min
|
|
self.__max = max
|
|
def getName(self):
|
|
return "pyModulateAlphaShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
while it.isEnd() == 0:
|
|
alpha = it.getObject().attribute().getAlpha()
|
|
p = it.getObject().getPoint()
|
|
alpha = alpha * p.y / 400
|
|
if alpha < self.__min:
|
|
alpha = self.__min
|
|
elif alpha > self.__max:
|
|
alpha = self.__max
|
|
it.getObject().attribute().setAlpha(alpha)
|
|
it.increment()
|
|
|
|
|
|
## various
|
|
class pyDummyShader(StrokeShader):
|
|
def getName(self):
|
|
return "pyDummyShader"
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
it_end = stroke.strokeVerticesEnd()
|
|
while it.isEnd() == 0:
|
|
toto = it.castToInterface0DIterator()
|
|
att = it.getObject().attribute()
|
|
att.setColor(0.3, 0.4, 0.4)
|
|
att.setThickness(0, 5)
|
|
it.increment()
|
|
|
|
class pyDebugShader(StrokeShader):
|
|
def getName(self):
|
|
return "pyDebugShader"
|
|
|
|
def shade(self, stroke):
|
|
fe = GetSelectedFEdgeCF()
|
|
id1=fe.vertexA().getId()
|
|
id2=fe.vertexB().getId()
|
|
#print(id1.getFirst(), id1.getSecond())
|
|
#print(id2.getFirst(), id2.getSecond())
|
|
it = stroke.strokeVerticesBegin()
|
|
found = 0
|
|
foundfirst = 0
|
|
foundsecond = 0
|
|
while it.isEnd() == 0:
|
|
cp = it.getObject()
|
|
if((cp.A().getId() == id1) or (cp.B().getId() == id1)):
|
|
foundfirst = 1
|
|
if((cp.A().getId() == id2) or (cp.B().getId() == id2)):
|
|
foundsecond = 1
|
|
if((foundfirst != 0) and (foundsecond != 0)):
|
|
found = 1
|
|
break
|
|
it.increment()
|
|
if(found != 0):
|
|
print("The selected Stroke id is: ", stroke.getId().getFirst(), stroke.getId().getSecond())
|