dphoadley opened this issue on Feb 11, 2010 · 70 posts
dphoadley posted Thu, 11 February 2010 at 3:43 PM
from matmatic.extras import *
class Loom(object):
NumThreads = None
PatternFile = None
PatternThreads = None
PatternNx = None
PatternNy = None
WarpColor = None
WarpColorThreads = None
WeftColor = None
WeftColorThreads = None
Distortion = 1
DistortionFrequency = 1.0
Speckle = .4
FiberLayers = 3
FiberColor = WHITE
FiberColorBlend = .4
FiberBlend = .8
FiberSize = 1
Occlusion = .5
Specular_Value = .1
Highlight_Size = .7
BumpDepth = 0
DisplacementDepth = 0
def init(self, PatternFile=None, PatternThreads=None):
self.PatternFile = PatternFile
self.PatternThreads = PatternThreads
def Generate(self, n = None):
pN = self.PatternThreads
pNx = self.PatternNx
if not pNx:
pNx = pN
pNy = self.PatternNy
if not pNy:
pNy = pNx
if n is None:
n = self.NumThreads
if n is None:
n = pNx
if isinstance(n, int):
n = float(n)
self.n = n
nU = n * U
nV = n * V
if self.Distortion:
f = 10.0 / self.DistortionFrequency / n
i = self.Distortion
nU = (i * FractalSum(f * U, f * V, f * U, 2, 0, .5, .93) + (n - i * .5)) * U
nV = (i * FractalSum(f * U, f * V, f * V, 2, 0, .5, .93) + (n - i * .5)) * V
self.nU = nU
self.nV = nV
delta = .5
pf = self.PatternFile
weave = DecodeWeave(pf, nU, nV, pNx, pNy)
weaveL = DecodeWeave(pf, nU - delta, nV, pNx, pNy)
weaveR = DecodeWeave(pf, nU + delta, nV, pNx, pNy)
weaveU = DecodeWeave(pf, nU, nV + delta, pNx, pNy)
weaveD = DecodeWeave(pf, nU, nV - delta, pNx, pNy)
warpRound = Humps(nU)
weftRound = Humps(nV)
round = Blend(1-self.Occlusion, 1, IF(weave, weftRound, warpRound))
warpDive = IF((1-weave) * Max(weaveU, weaveD), weftRound, 1)
weftDive = IF(weave * (1 - Min(weaveR, weaveL)), warpRound, 1)
dive = Blend(1-self.Occlusion, 1, Bias(IF(weave, weftDive, warpDive), .1))
noiseSeed = .01Floor(IF(weave, nV, nU))
sn = 5
swsf = .4 / n
spiralNoise = 20.0 / sn * FractalSum(swsf * U, swsf * V, noiseSeed, 2, 0, .5, .93)
warpSpiral = Humps(sn * n * (U+.7V) + spiralNoise)
weftSpiral = Humps(sn * n * (1+U-.7*V) + spiralNoise)
spiral = Blend(1-self.Occlusion, 1, IF(weave, weftSpiral, warpSpiral))
bump = dive * round
self.Bump = bump
warpColor = self.WarpColor
warpct = self.WarpColorThreads
if isinstance(warpColor, str):
if warpct is None:
warpct = pNx
s = warpct / n
warpColor = ImageMap(warpColor, U_Scale = s, V_Scale = s)
elif isinstance(warpColor, list) and not isColor(warpColor):
warpColor = ExpandColorList(warpColor)
if warpct is None:
warpct = 1
nc = float(len(warpColor))
warpColor = Interpolate(1.0 / (nc-1) * Floor(1.0/warpct * nU % nc), warpColor)
elif warpColor is None:
warpColor = GRAY6
weftColor = self.WeftColor
weftct = self.WeftColorThreads
if weftColor is None:
weftColor = self.WarpColor
if isinstance(weftColor, str):
if weftct is None:
weftct = warpct
s = weftct / n
weftColor = ImageMap(weftColor, U_Scale = s, V_Scale = s, Texture_Coords = 2)
elif isinstance(weftColor, list) and not isColor(weftColor):
weftColor = ExpandColorList(weftColor)
if weftct is None:
weftct = 1
nc = float(len(weftColor))
weftColor = Interpolate(1.0 / (nc-1) * Floor(1.0/weftct * nV % nc), weftColor)
elif weftColor is None:
weftColor = WHITE
color = Blend(warpColor, weftColor, weave)
if self.Speckle:
f = .03/n
color = color * Blend(1.0-self.Speckle, 1, FractalSum(f * U, f * V, noiseSeed, 4, 0, .6, .93))
self.Color = color
diff = color * bump
if self.FiberLayers:
fibers = FiberLayers(n/self.FiberSize, self.FiberLayers)
diff = Blend(diff, Blend(self.FiberColor, diff, self.FiberColorBlend), self.FiberBlend * fibers)
self.Bump = Max(self.Bump, fibers)
diff = Blend(diff * spiral, diff, Bias(fibers, .2))
bump -= Blend(.2 * spiral, 0, Bias(fibers, .2))
else:
fibers = 0
diff = diff * spiral
bump -= .2 * spiral
self.Fibers = fibers
self.Diffuse_Color = diff
self.Surface = Surface(diff, 1, 1, self.Specular_Value, self.Highlight_Size)
if self.BumpDepth:
self.Surface.Bump = self.BumpDepth * bump
if self.DisplacementDepth:
self.Surface.Displacement = self.DisplacementDepth * bump
return self.Surface
def ExpandColorList(lst):
outlist = []
for x in lst:
if not isColor(x) and (isinstance(x, tuple) or isinstance(x, list)):
n, clr = x
outlist += n * [clr]
else:
outlist.append(x)
return outlist
def Fibers(n):
s = .2 / n
seed = Add(n % .01234 * 100000)
p = FractalSum(s * U, s * V, s * seed, 2, 0, .5, .93)
p = Gain(1 - 10 * Abs(p - .5), .8)
s = s * .8
mask = FractalSum(s * U, s * V, s * seed, 2, 0, .5, 1)
return p * mask
def FiberLayers(n, octaves=6, frequency_gap = .1, layerStrength = .98):
v = None
m = 1.0
for i in xrange(octaves):
nv = m * Bias(Fibers(n), .4)
if v is None:
v = nv
else:
v = Max(v, nv)
n *= (1 + frequency_gap)
m *= layerStrength
return v
def IF(test, a, b): return Blend(b, a, test)
def Humps(inp, offset = 0):
v = Sqrt(Abs(Sin(pi * (inp + offset))))
return v
def DecodeWeave(weavefile, x, y, pNx, pNy):
wou = U - 1.0 / pNx * (Floor(x) + .5)
wov = V - 1.0 / pNy * (Floor(y) + .5)
weave = .5 <= ImageMap(weavefile, 0, 1, 1, wou, wov).asNumber()
return weave