[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30820] branches/soc-2008-mxcurioni: * Made the Parameter Editor mode much more functional.
Tamito Kajiyama
rd6t-kjym at asahi-net.or.jp
Wed Jul 28 02:43:46 CEST 2010
Revision: 30820
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30820
Author: kjym3
Date: 2010-07-28 02:43:45 +0200 (Wed, 28 Jul 2010)
Log Message:
-----------
* Made the Parameter Editor mode much more functional. Edge selection
criteria, as well as the color/alpha/thickness Along Stroke modifiers
now work.
* Added more curve blend types. The default is set to "MIX".
Modified Paths:
--------------
branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/parameter_editor.py
branches/soc-2008-mxcurioni/source/blender/blenkernel/intern/linestyle.c
branches/soc-2008-mxcurioni/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
branches/soc-2008-mxcurioni/source/blender/makesdna/DNA_linestyle_types.h
branches/soc-2008-mxcurioni/source/blender/makesrna/intern/rna_linestyle.c
Modified: branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/parameter_editor.py
===================================================================
--- branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/parameter_editor.py 2010-07-28 00:39:12 UTC (rev 30819)
+++ branches/soc-2008-mxcurioni/release/scripts/freestyle/style_modules/parameter_editor.py 2010-07-28 00:43:45 UTC (rev 30820)
@@ -23,20 +23,245 @@
from ChainingIterators import *
from shaders import *
+def blend_curve(blend_type, v1, fac, v2):
+ facm = 1.0 - fac
+ if blend_type == "MIX":
+ v1 = facm * v1 + fac * v2
+ elif blend_type == "ADD":
+ v1 += fac * v2
+ elif blend_type == "MULTIPLY":
+ v1 *= facm + fac * v2;
+ elif blend_type == "SUBTRACT":
+ v1 -= fac * v2
+ elif blend_type == "DIVIDE":
+ if v2 != 0.0:
+ v1 = facm * v1 + fac * v1 / v2
+ elif blend_type == "DIFFERENCE":
+ v1 = facm * v1 + fac * abs(v1 - v2)
+ elif blend_type == "MININUM":
+ tmp = fac * v1
+ if v1 > tmp:
+ v1 = tmp
+ elif blend_type == "MAXIMUM":
+ tmp = fac * v1
+ if v1 < tmp:
+ v1 = tmp
+ else:
+ raise ValueError("unknown curve blend type: " + blend_type)
+ return v1
+
+class ColorAlongStrokeShader(StrokeShader):
+ def __init__(self, blend, influence, ramp):
+ StrokeShader.__init__(self)
+ self.__blend = blend
+ self.__influence = influence
+ self.__ramp = ramp
+ def getName(self):
+ return "ColorAlongStrokeShader"
+ def shade(self, stroke):
+ distance, total = 0.0, stroke.getLength2D()
+ it = stroke.strokeVerticesBegin()
+ while not it.isEnd():
+ sv = it.getObject()
+ p = sv.getPoint()
+ if not it.isBegin():
+ distance += (prev - p).length
+ prev = p
+ t = min(distance / total, 1.0)
+ b = Freestyle.evaluateColorRamp(self.__ramp, t)
+ b = b.xyz # omit alpha
+ a = sv.attribute().getColorRGB()
+ c = Freestyle.blendRamp(self.__blend, a, self.__influence, b)
+ sv.attribute().setColor(c)
+ it.increment()
+
+class AlphaAlongStrokeShader(StrokeShader):
+ def __init__(self, blend, influence, mapping, invert, curve):
+ StrokeShader.__init__(self)
+ self.__blend = blend
+ self.__influence = influence
+ assert mapping in ("LINEAR", "CURVE")
+ self.__mapping = getattr(self, mapping)
+ self.__invert = invert
+ self.__curve = curve
+ def getName(self):
+ return "AlphaAlongStrokeShader"
+ def LINEAR(self, t):
+ if self.__invert:
+ return 1.0 - t
+ return t
+ def CURVE(self, t):
+ return Freestyle.evaluateCurveMappingF(self.__curve, 0, t)
+ def shade(self, stroke):
+ distance, total = 0.0, stroke.getLength2D()
+ it = stroke.strokeVerticesBegin()
+ while not it.isEnd():
+ sv = it.getObject()
+ p = sv.getPoint()
+ if not it.isBegin():
+ distance += (prev - p).length
+ prev = p
+ t = min(distance / total, 1.0)
+ b = self.__mapping(t)
+ a = sv.attribute().getAlpha()
+ c = blend_curve(self.__blend, a, self.__influence, b)
+ sv.attribute().setAlpha(c)
+ it.increment()
+
+class ThicknessAlongStrokeShader(StrokeShader):
+ def __init__(self, blend, influence, mapping, invert, curve, value_min, value_max):
+ StrokeShader.__init__(self)
+ self.__blend = blend
+ self.__influence = influence
+ assert mapping in ("LINEAR", "CURVE")
+ self.__mapping = getattr(self, mapping)
+ self.__invert = invert
+ self.__curve = curve
+ self.__value_min = value_min
+ self.__value_max = value_max
+ def getName(self):
+ return "ThicknessAlongStrokeShader"
+ def LINEAR(self, t):
+ if self.__invert:
+ return 1.0 - t
+ return t
+ def CURVE(self, t):
+ return Freestyle.evaluateCurveMappingF(self.__curve, 0, t)
+ def shade(self, stroke):
+ distance, total = 0.0, stroke.getLength2D()
+ it = stroke.strokeVerticesBegin()
+ while not it.isEnd():
+ sv = it.getObject()
+ p = sv.getPoint()
+ if not it.isBegin():
+ distance += (prev - p).length
+ prev = p
+ t = min(distance / total, 1.0)
+ t = self.__mapping(t)
+ b = self.__value_min + t * (self.__value_max - self.__value_min)
+ a = sv.attribute().getThicknessRL()
+ a = a[0] + a[1]
+ c = blend_curve(self.__blend, a, self.__influence, b)
+ sv.attribute().setThickness(c/2, c/2)
+ it.increment()
+
+class QuantitativeInvisibilityRangeUP1D(UnaryPredicate1D):
+ def __init__(self, qi_start, qi_end):
+ UnaryPredicate1D.__init__(self)
+ self.__getQI = QuantitativeInvisibilityF1D()
+ self.__qi_start = qi_start
+ self.__qi_end = qi_end
+ def getName(self):
+ return "QuantitativeInvisibilityRangeUP1D"
+ def __call__(self, inter):
+ qi = self.__getQI(inter)
+ return self.__qi_start <= qi <= self.__qi_end
+
+def join_unary_predicates(upred_list, bpred):
+ if not upred_list:
+ return TrueUP1D()
+ upred = upred_list[0]
+ for p in upred_list[1:]:
+ upred = bpred(upred, p)
+ return upred
+
def process(layer_name, lineset_name):
scene = Freestyle.getCurrentScene()
layer = scene.render.layers[layer_name]
lineset = layer.freestyle_settings.linesets[lineset_name]
linestyle = lineset.linestyle
+ selection_criteria = []
+ # prepare selection criteria by visibility
+ if lineset.select_by_visibility:
+ if lineset.visibility == "VISIBLE":
+ selection_criteria.append(
+ QuantitativeInvisibilityUP1D(0))
+ elif lineset.visibility == "HIDDEN":
+ selection_criteria.append(
+ NotUP1D(QuantitativeInvisibilityUP1D(0)))
+ elif lineset.visibility == "RANGE":
+ selection_criteria.append(
+ QuantitativeInvisibilityRangeUP1D(lineset.qi_start, lineset.qi_end))
+ # prepare selection criteria by edge types
+ if lineset.select_by_edge_types:
+ edge_type_criteria = []
+ if lineset.edge_type_combination == "OR":
+ flags = Nature.NO_FEATURE
+ if lineset.select_silhouette:
+ flags |= Nature.SILHOUETTE
+ if lineset.select_border:
+ flags |= Nature.BORDER
+ if lineset.select_crease:
+ flags |= Nature.CREASE
+ if lineset.select_ridge:
+ flags |= Nature.RIDGE
+ if lineset.select_valley:
+ flags |= Nature.VALLEY
+ if lineset.select_suggestive_contour:
+ flags |= Nature.SUGGESTIVE_CONTOUR
+ if lineset.select_material_boundary:
+ flags |= Nature.MATERIAL_BOUNDARY
+ if flags != Nature.NO_FEATURE:
+ edge_type_criteria.append(pyNatureUP1D(flags))
+ else:
+ if lineset.select_silhouette:
+ edge_type_criteria.append(pyNatureUP1D(Nature.SILHOUETTE))
+ if lineset.select_border:
+ edge_type_criteria.append(pyNatureUP1D(Nature.BORDER))
+ if lineset.select_crease:
+ edge_type_criteria.append(pyNatureUP1D(Nature.CREASE))
+ if lineset.select_ridge:
+ edge_type_criteria.append(pyNatureUP1D(Nature.RIDGE))
+ if lineset.select_valley:
+ edge_type_criteria.append(pyNatureUP1D(Nature.VALLEY))
+ if lineset.select_suggestive_contour:
+ edge_type_criteria.append(pyNatureUP1D(Nature.SUGGESTIVE_CONTOUR))
+ if lineset.select_material_boundary:
+ edge_type_criteria.append(pyNatureUP1D(Nature.MATERIAL_BOUNDARY))
+ if lineset.select_contour:
+ edge_type_criteria.append(ContourUP1D())
+ if lineset.select_external_contour:
+ edge_type_criteria.append(ExternalContourUP1D())
+ if lineset.edge_type_combination == "OR":
+ upred = join_unary_predicates(edge_type_criteria, OrUP1D)
+ else:
+ upred = join_unary_predicates(edge_type_criteria, AndUP1D)
+ if upred is not None:
+ if lineset.edge_type_negation == "EXCLUSIVE":
+ upred = NotUP1D(upred)
+ selection_criteria.append(upred)
+ # do feature edge selection
+ upred = join_unary_predicates(selection_criteria, AndUP1D)
+ if upred is None:
+ upred = TrueUP1D()
+ Operators.select(upred)
+ # join feature edges
+ Operators.bidirectionalChain(ChainSilhouetteIterator(), NotUP1D(upred)) # FIXME
+ # prepare a list of stroke shaders
color = linestyle.color
-
- upred = QuantitativeInvisibilityUP1D(0)
- Operators.select(upred)
- Operators.bidirectionalChain(ChainSilhouetteIterator(), NotUP1D(upred))
shaders_list = [
SamplingShader(5.0),
ConstantThicknessShader(linestyle.thickness),
- ConstantColorShader(color.r, color.g, color.b, linestyle.alpha)
- ]
+ ConstantColorShader(color.r, color.g, color.b, linestyle.alpha)]
+ for m in linestyle.color_modifiers:
+ if not m.enabled:
+ continue
+ if m.type == "ALONG_STROKE":
+ shaders_list.append(
+ ColorAlongStrokeShader(m.blend, m.influence, m.color_ramp))
+ for m in linestyle.alpha_modifiers:
+ if not m.enabled:
+ continue
+ if m.type == "ALONG_STROKE":
+ shaders_list.append(
+ AlphaAlongStrokeShader(m.blend, m.influence, m.mapping, m.invert, m.curve))
+ for m in linestyle.thickness_modifiers:
+ if not m.enabled:
+ continue
+ if m.type == "ALONG_STROKE":
+ shaders_list.append(
+ ThicknessAlongStrokeShader(m.blend, m.influence, m.mapping, m.invert, m.curve,
+ m.value_min, m.value_max))
+ # create strokes using the shaders list
Operators.create(TrueUP1D(), shaders_list)
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list