
StrokeAttribute class methods were renamed from camel case to lower case plus underscore. Also made changes to shaders.pyTVertexOrientationShader that uses the affected methods.
1335 lines
39 KiB
Python
1335 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.thickness = (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:
|
|
t = self._thickness/2.0
|
|
it.getObject().attribute.thickness = (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:
|
|
t = self._thickness/2.0
|
|
it.getObject().attribute.thickness = (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:
|
|
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
|
|
it.getObject().attribute.thickness = (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:
|
|
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
|
|
it.getObject().attribute.thickness = (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.thickness = (t/2.0, t/2.0)
|
|
if(i == n-1):
|
|
att.thickness = (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:
|
|
c = float(i)/float(n)
|
|
t = (1.0 - c)*tMax +c*tMin
|
|
it.getObject().attribute.thickness = (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:
|
|
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
|
|
it.getObject().attribute.thickness = (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:
|
|
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
|
|
it.getObject().attribute.thickness = (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, tl) = att.thickness
|
|
r = (a-1.0)/float(n-1)*(float(n)/float(count+1) - 1) + 1
|
|
#r = (1.0-a)/float(n-1)*count + a
|
|
att.thickness = (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, tl) = att.thickness
|
|
r = (a-1.0)/float(n-1)*(float(n)/float(count+1) - 1) + 1
|
|
#r = (1.0-a)/float(n-1)*count + a
|
|
att.thickness = (r*tr, r*tl)
|
|
it4.decrement()
|
|
count = count + 1
|
|
if ((it4.isBegin() == 1)):
|
|
att = it4.getObject().attribute
|
|
(tr, tl) = att.thickness
|
|
r = (a-1.0)/float(n-1)*(float(n)/float(count+1) - 1) + 1
|
|
#r = (1.0-a)/float(n-1)*count + a
|
|
att.thickness = (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, tl) = att.thickness
|
|
att.thickness = (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, tl) = att.thickness
|
|
att.thickness = (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.thickness = (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.color = (self._r, self._g, self._b)
|
|
att.alpha = 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.color = ((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.alpha = (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.color = ((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.alpha = (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)
|
|
|
|
it.getObject().attribute.color = (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.color = (c0,c1,c2)
|
|
it.increment()
|
|
|
|
class py2DCurvatureColorShader(StrokeShader):
|
|
def getName(self):
|
|
return "py2DCurvatureColorShader"
|
|
|
|
def shade(self, stroke):
|
|
it = stroke.strokeVerticesBegin()
|
|
func = Curvature2DAngleF0D()
|
|
while it.isEnd() == 0:
|
|
c = func(it.castToInterface0DIterator())
|
|
if c < 0:
|
|
print("negative 2D curvature")
|
|
color = 10.0 * c/3.1415
|
|
it.getObject().attribute.color = (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:
|
|
it.getObject().attribute.color = (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.point = newFirst
|
|
vn.point = 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.point = newFirst
|
|
vn.point = 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().point - it.getObject().point ## 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().point = itmiddle.getObject().point \
|
|
+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().point = itmiddle.getObject().point \
|
|
-t*(itmiddle.getObject().u-it.getObject().u)
|
|
it.decrement()
|
|
it.getObject().point = itmiddle.getObject().point-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.point
|
|
p1 = v1.point
|
|
d1 = p0-p1
|
|
d1.normalize()
|
|
newFirst = p0+d1*float(self._l)
|
|
v0.point = newFirst
|
|
vn_1 = itn_1.getObject()
|
|
vn = itn.getObject()
|
|
if((vn.getNature() & Nature.CUSP == 0) and (vn_1.getNature() & Nature.CUSP == 0)):
|
|
pn = vn.point
|
|
pn_1 = vn_1.point
|
|
dn = pn-pn_1
|
|
dn.normalize()
|
|
newLast = pn+dn*float(self._l)
|
|
vn.point = newLast
|
|
stroke.UpdateLength()
|
|
|
|
class pyDiffusion2Shader(StrokeShader):
|
|
"""This shader iteratively adds an offset to the position of each
|
|
stroke vertex in the direction perpendicular to the stroke direction
|
|
at the point. The offset is scaled by the 2D curvature (i.e., how
|
|
quickly the stroke curve is) at the point."""
|
|
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.point
|
|
p2 = self._normalInfo(it.castToInterface0DIterator())*self._lambda*self._curvatureInfo(it.castToInterface0DIterator())
|
|
v.point = 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.curvilinear_abscissa < self._l) or (v.stroke_length-v.curvilinear_abscissa < 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.UpdateLength()
|
|
stroke.Resample(originalSize)
|
|
if(stroke.strokeVerticesSize() != originalSize):
|
|
print("pyTipRemover: Warning: resampling problem")
|
|
it = stroke.strokeVerticesBegin()
|
|
for a in oldAttributes:
|
|
if(it.isEnd() == 1):
|
|
break
|
|
it.getObject().attribute = 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.visible = False
|
|
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 = True
|
|
while not ait.isEnd():
|
|
ave = ait.getObject()
|
|
if ave.getId() != ve.getId() and ave.getId() != mateVE.getId():
|
|
winner = ait.getObject()
|
|
if not ait.isIncoming():
|
|
incoming = False
|
|
break
|
|
ait.increment()
|
|
if winner is not None:
|
|
if not incoming:
|
|
direction = self._Get2dDirection(winner.fedgeB())
|
|
else:
|
|
direction = self._Get2dDirection(winner.fedgeA())
|
|
return direction
|
|
return None
|
|
def castToTVertex(self, cp):
|
|
if cp.t2d() == 0.0:
|
|
return cp.A().viewvertex()
|
|
elif cp.t2d() == 1.0:
|
|
return cp.B().viewvertex()
|
|
return None
|
|
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 = self.castToTVertex(v)
|
|
if tv is not None:
|
|
ve = getFEdge(v, it2.getObject()).viewedge()
|
|
dir = self.findOrientation(tv, ve)
|
|
if dir is not None:
|
|
#print(dir.x, dir.y)
|
|
v.attribute.set_attribute_vec2("orientation", dir)
|
|
while(it2.isEnd() == 0):
|
|
vprevious = it.getObject()
|
|
v = it2.getObject()
|
|
if(v.getNature() & Nature.T_VERTEX):
|
|
tv = self.castToTVertex(v)
|
|
if tv is not None:
|
|
ve = getFEdge(vprevious, v).viewedge()
|
|
dir = self.findOrientation(tv, ve)
|
|
if dir is not None:
|
|
#print(dir.x, dir.y)
|
|
v.attribute.set_attribute_vec2("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 = self.castToTVertex(v)
|
|
if tv is not None:
|
|
ve = getFEdge(itPrevious.getObject(), v).viewedge()
|
|
dir = self.findOrientation(tv, ve)
|
|
if dir is not None:
|
|
#print(dir.x, dir.y)
|
|
v.attribute.set_attribute_vec2("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.point
|
|
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.point = p+n
|
|
#v.point = v.point+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.point = (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.point = (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 = Vector(it.getObject().point)
|
|
p_max = Vector(it.getObject().point)
|
|
while it.isEnd() == 0:
|
|
p = it.getObject().point
|
|
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().point = 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 = Vector(it.getObject().point)
|
|
p_max = Vector(it.getObject().point)
|
|
while it.isEnd() == 0:
|
|
p = it.getObject().point
|
|
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().point = 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 = Vector(it.getObject().point)
|
|
p_max = Vector(it.getObject().point)
|
|
while it.isEnd() == 0:
|
|
p = it.getObject().point
|
|
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().point = p_new
|
|
it.getObject().attribute.visible = 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().point
|
|
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().point
|
|
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().point = p_new
|
|
it.getObject().attribute.visible = 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.alpha
|
|
p = it.getObject().point
|
|
alpha = alpha * p.y / 400
|
|
if alpha < self.__min:
|
|
alpha = self.__min
|
|
elif alpha > self.__max:
|
|
alpha = self.__max
|
|
it.getObject().attribute.alpha = 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.color = (0.3, 0.4, 0.4)
|
|
att.thickness = (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())
|