2010-07-26 01:23:27 +00:00
|
|
|
# ##### BEGIN GPL LICENSE BLOCK #####
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU General Public License
|
|
|
|
# as published by the Free Software Foundation; either version 2
|
|
|
|
# of the License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software Foundation,
|
|
|
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
#
|
|
|
|
# ##### END GPL LICENSE BLOCK #####
|
|
|
|
|
2013-03-24 00:53:05 +00:00
|
|
|
# Filename : parameter_editor.py
|
|
|
|
# Authors : Tamito Kajiyama
|
|
|
|
# Date : 26/07/2010
|
|
|
|
# Purpose : Interactive manipulation of stylization parameters
|
|
|
|
|
2013-04-07 11:22:54 +00:00
|
|
|
import freestyle
|
2010-10-10 22:50:32 +00:00
|
|
|
import math
|
2011-09-11 19:57:38 +00:00
|
|
|
import mathutils
|
2011-08-19 14:05:11 +00:00
|
|
|
import time
|
2010-07-26 01:23:27 +00:00
|
|
|
|
2013-02-24 23:43:40 +00:00
|
|
|
from ChainingIterators import pySketchyChainSilhouetteIterator, pySketchyChainingIterator
|
2013-04-07 11:22:54 +00:00
|
|
|
from freestyle import BackboneStretcherShader, BezierCurveShader, BinaryPredicate1D, ChainPredicateIterator, \
|
2013-02-24 23:43:40 +00:00
|
|
|
ChainSilhouetteIterator, ConstantColorShader, ContourUP1D, Curvature2DAngleF0D, ExternalContourUP1D, \
|
|
|
|
FalseBP1D, FalseUP1D, GuidingLinesShader, Interface0DIterator, Nature, Noise, Normal2DF0D, Operators, \
|
|
|
|
PolygonalizationShader, QuantitativeInvisibilityF1D, QuantitativeInvisibilityUP1D, SamplingShader, \
|
|
|
|
SpatialNoiseShader, StrokeAttribute, StrokeShader, TipRemoverShader, TrueBP1D, TrueUP1D, UnaryPredicate0D, \
|
|
|
|
UnaryPredicate1D, VertexOrientation2DF0D, WithinImageBoundaryUP1D
|
|
|
|
from Functions0D import CurveMaterialF0D
|
|
|
|
from PredicatesU1D import pyNatureUP1D
|
|
|
|
from logical_operators import AndUP1D, NotUP1D, OrUP1D
|
|
|
|
from shaders import pyBluePrintCirclesShader, pyBluePrintEllipsesShader, pyBluePrintSquaresShader
|
2010-07-26 01:23:27 +00:00
|
|
|
|
2010-08-01 16:02:34 +00:00
|
|
|
class ColorRampModifier(StrokeShader):
|
2010-07-28 00:43:45 +00:00
|
|
|
def __init__(self, blend, influence, ramp):
|
|
|
|
StrokeShader.__init__(self)
|
|
|
|
self.__blend = blend
|
|
|
|
self.__influence = influence
|
|
|
|
self.__ramp = ramp
|
2010-08-01 16:02:34 +00:00
|
|
|
def evaluate(self, t):
|
2013-04-07 11:22:54 +00:00
|
|
|
col = freestyle.evaluateColorRamp(self.__ramp, t)
|
2010-08-01 16:02:34 +00:00
|
|
|
col = col.xyz # omit alpha
|
|
|
|
return col
|
|
|
|
def blend_ramp(self, a, b):
|
2013-04-07 11:22:54 +00:00
|
|
|
return freestyle.blendRamp(self.__blend, a, self.__influence, b)
|
2010-07-28 00:43:45 +00:00
|
|
|
|
2011-09-11 19:57:38 +00:00
|
|
|
class ScalarBlendModifier(StrokeShader):
|
|
|
|
def __init__(self, blend, influence):
|
2010-07-28 00:43:45 +00:00
|
|
|
StrokeShader.__init__(self)
|
|
|
|
self.__blend = blend
|
|
|
|
self.__influence = influence
|
2011-09-11 19:57:38 +00:00
|
|
|
def blend(self, v1, v2):
|
2010-08-01 16:02:34 +00:00
|
|
|
fac = self.__influence
|
|
|
|
facm = 1.0 - fac
|
2013-04-23 07:06:29 +00:00
|
|
|
if self.__blend == 'MIX':
|
2010-08-01 16:02:34 +00:00
|
|
|
v1 = facm * v1 + fac * v2
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__blend == 'ADD':
|
2010-08-01 16:02:34 +00:00
|
|
|
v1 += fac * v2
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__blend == 'MULTIPLY':
|
2010-08-01 16:02:34 +00:00
|
|
|
v1 *= facm + fac * v2;
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__blend == 'SUBTRACT':
|
2010-08-01 16:02:34 +00:00
|
|
|
v1 -= fac * v2
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__blend == 'DIVIDE':
|
2010-08-01 16:02:34 +00:00
|
|
|
if v2 != 0.0:
|
|
|
|
v1 = facm * v1 + fac * v1 / v2
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__blend == 'DIFFERENCE':
|
2010-08-01 16:02:34 +00:00
|
|
|
v1 = facm * v1 + fac * abs(v1 - v2)
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__blend == 'MININUM':
|
2010-08-01 16:02:34 +00:00
|
|
|
tmp = fac * v1
|
|
|
|
if v1 > tmp:
|
|
|
|
v1 = tmp
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__blend == 'MAXIMUM':
|
2010-08-01 16:02:34 +00:00
|
|
|
tmp = fac * v1
|
|
|
|
if v1 < tmp:
|
|
|
|
v1 = tmp
|
|
|
|
else:
|
|
|
|
raise ValueError("unknown curve blend type: " + self.__blend)
|
|
|
|
return v1
|
|
|
|
|
2011-09-11 19:57:38 +00:00
|
|
|
class CurveMappingModifier(ScalarBlendModifier):
|
|
|
|
def __init__(self, blend, influence, mapping, invert, curve):
|
|
|
|
ScalarBlendModifier.__init__(self, blend, influence)
|
2013-04-23 07:06:29 +00:00
|
|
|
assert mapping in {'LINEAR', 'CURVE'}
|
2011-09-11 19:57:38 +00:00
|
|
|
self.__mapping = getattr(self, mapping)
|
|
|
|
self.__invert = invert
|
|
|
|
self.__curve = curve
|
|
|
|
def LINEAR(self, t):
|
|
|
|
if self.__invert:
|
|
|
|
return 1.0 - t
|
|
|
|
return t
|
|
|
|
def CURVE(self, t):
|
2013-04-07 11:22:54 +00:00
|
|
|
return freestyle.evaluateCurveMappingF(self.__curve, 0, t)
|
2011-09-11 19:57:38 +00:00
|
|
|
def evaluate(self, t):
|
|
|
|
return self.__mapping(t)
|
|
|
|
|
2012-04-07 17:28:09 +00:00
|
|
|
class ThicknessModifierMixIn:
|
|
|
|
def __init__(self):
|
2013-04-07 11:22:54 +00:00
|
|
|
scene = freestyle.getCurrentScene()
|
2013-04-23 07:06:29 +00:00
|
|
|
self.__persp_camera = (scene.camera.data.type == 'PERSP')
|
2012-04-07 17:28:09 +00:00
|
|
|
def set_thickness(self, sv, outer, inner):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
fe = sv.first_svertex.get_fedge(sv.second_svertex)
|
|
|
|
nature = fe.nature
|
2012-04-07 17:28:09 +00:00
|
|
|
if (nature & Nature.BORDER):
|
|
|
|
if self.__persp_camera:
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
point = -sv.point_3d.copy()
|
2012-04-07 17:28:09 +00:00
|
|
|
point.normalize()
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
dir = point.dot(fe.normal_left)
|
2012-04-07 17:28:09 +00:00
|
|
|
else:
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
dir = fe.normal_left.z
|
2012-04-07 17:28:09 +00:00
|
|
|
if dir < 0.0: # the back side is visible
|
|
|
|
outer, inner = inner, outer
|
|
|
|
elif (nature & Nature.SILHOUETTE):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
if fe.is_smooth: # TODO more tests needed
|
2012-04-07 17:28:09 +00:00
|
|
|
outer, inner = inner, outer
|
|
|
|
else:
|
|
|
|
outer = inner = (outer + inner) / 2
|
2013-01-27 20:17:49 +00:00
|
|
|
sv.attribute.thickness = (outer, inner)
|
2012-04-07 17:28:09 +00:00
|
|
|
|
|
|
|
class ThicknessBlenderMixIn(ThicknessModifierMixIn):
|
|
|
|
def __init__(self, position, ratio):
|
|
|
|
ThicknessModifierMixIn.__init__(self)
|
|
|
|
self.__position = position
|
|
|
|
self.__ratio = ratio
|
|
|
|
def blend_thickness(self, outer, inner, v):
|
2013-04-23 07:06:29 +00:00
|
|
|
if self.__position == 'CENTER':
|
2012-04-07 18:16:25 +00:00
|
|
|
outer = self.blend(outer, v / 2)
|
|
|
|
inner = self.blend(inner, v / 2)
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__position == 'INSIDE':
|
2012-04-07 18:16:25 +00:00
|
|
|
outer = self.blend(outer, 0)
|
|
|
|
inner = self.blend(inner, v)
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__position == 'OUTSIDE':
|
2012-04-07 18:16:25 +00:00
|
|
|
outer = self.blend(outer, v)
|
|
|
|
inner = self.blend(inner, 0)
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__position == 'RELATIVE':
|
2012-04-07 18:16:25 +00:00
|
|
|
outer = self.blend(outer, v * self.__ratio)
|
|
|
|
inner = self.blend(inner, v * (1 - self.__ratio))
|
2012-04-07 17:28:09 +00:00
|
|
|
else:
|
|
|
|
raise ValueError("unknown thickness position: " + self.__position)
|
|
|
|
return outer, inner
|
|
|
|
|
|
|
|
class BaseColorShader(ConstantColorShader):
|
2013-02-23 12:17:40 +00:00
|
|
|
pass
|
2012-04-07 17:28:09 +00:00
|
|
|
|
|
|
|
class BaseThicknessShader(StrokeShader, ThicknessModifierMixIn):
|
|
|
|
def __init__(self, thickness, position, ratio):
|
|
|
|
StrokeShader.__init__(self)
|
|
|
|
ThicknessModifierMixIn.__init__(self)
|
2013-04-23 07:06:29 +00:00
|
|
|
if position == 'CENTER':
|
2012-04-07 17:28:09 +00:00
|
|
|
self.__outer = thickness / 2
|
|
|
|
self.__inner = thickness / 2
|
2013-04-23 07:06:29 +00:00
|
|
|
elif position == 'INSIDE':
|
2012-04-07 17:28:09 +00:00
|
|
|
self.__outer = 0
|
|
|
|
self.__inner = thickness
|
2013-04-23 07:06:29 +00:00
|
|
|
elif position == 'OUTSIDE':
|
2012-04-07 17:28:09 +00:00
|
|
|
self.__outer = thickness
|
|
|
|
self.__inner = 0
|
2013-04-23 07:06:29 +00:00
|
|
|
elif position == 'RELATIVE':
|
2012-04-07 17:28:09 +00:00
|
|
|
self.__outer = thickness * ratio
|
|
|
|
self.__inner = thickness * (1 - ratio)
|
|
|
|
else:
|
|
|
|
raise ValueError("unknown thickness position: " + self.position)
|
|
|
|
def shade(self, stroke):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
sv = it.object
|
2012-04-07 17:28:09 +00:00
|
|
|
self.set_thickness(sv, self.__outer, self.__inner)
|
|
|
|
it.increment()
|
|
|
|
|
2010-08-01 16:02:34 +00:00
|
|
|
# Along Stroke modifiers
|
|
|
|
|
|
|
|
def iter_t2d_along_stroke(stroke):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
total = stroke.length_2d
|
2010-08-01 16:02:34 +00:00
|
|
|
distance = 0.0
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-03-03 21:56:36 +00:00
|
|
|
prev = it.object.point
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
p = it.object.point
|
2013-03-03 21:56:36 +00:00
|
|
|
distance += (prev - p).length
|
|
|
|
prev = p.copy() # need a copy because the point can be altered
|
2010-08-01 16:02:34 +00:00
|
|
|
t = min(distance / total, 1.0)
|
|
|
|
yield it, t
|
|
|
|
it.increment()
|
|
|
|
|
|
|
|
class ColorAlongStrokeShader(ColorRampModifier):
|
2010-07-28 00:43:45 +00:00
|
|
|
def shade(self, stroke):
|
2010-08-01 16:02:34 +00:00
|
|
|
for it, t in iter_t2d_along_stroke(stroke):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.color
|
2010-08-01 16:02:34 +00:00
|
|
|
b = self.evaluate(t)
|
2013-01-27 20:17:49 +00:00
|
|
|
sv.attribute.color = self.blend_ramp(a, b)
|
2010-07-28 00:43:45 +00:00
|
|
|
|
2010-08-01 16:02:34 +00:00
|
|
|
class AlphaAlongStrokeShader(CurveMappingModifier):
|
|
|
|
def shade(self, stroke):
|
|
|
|
for it, t in iter_t2d_along_stroke(stroke):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.alpha
|
2010-08-01 16:02:34 +00:00
|
|
|
b = self.evaluate(t)
|
2013-01-27 20:17:49 +00:00
|
|
|
sv.attribute.alpha = self.blend(a, b)
|
2010-08-01 16:02:34 +00:00
|
|
|
|
2012-04-07 17:28:09 +00:00
|
|
|
class ThicknessAlongStrokeShader(ThicknessBlenderMixIn, CurveMappingModifier):
|
|
|
|
def __init__(self, thickness_position, thickness_ratio,
|
|
|
|
blend, influence, mapping, invert, curve, value_min, value_max):
|
|
|
|
ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
|
2010-08-01 16:02:34 +00:00
|
|
|
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
|
2010-07-28 00:43:45 +00:00
|
|
|
self.__value_min = value_min
|
|
|
|
self.__value_max = value_max
|
|
|
|
def shade(self, stroke):
|
2010-08-01 16:02:34 +00:00
|
|
|
for it, t in iter_t2d_along_stroke(stroke):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.thickness
|
2010-08-01 16:02:34 +00:00
|
|
|
b = self.__value_min + self.evaluate(t) * (self.__value_max - self.__value_min)
|
2012-04-07 17:28:09 +00:00
|
|
|
c = self.blend_thickness(a[0], a[1], b)
|
|
|
|
self.set_thickness(sv, c[0], c[1])
|
2010-08-01 16:02:34 +00:00
|
|
|
|
|
|
|
# Distance from Camera modifiers
|
|
|
|
|
|
|
|
def iter_distance_from_camera(stroke, range_min, range_max):
|
|
|
|
normfac = range_max - range_min # normalization factor
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
p = it.object.point_3d # in the camera coordinate
|
2010-08-01 16:02:34 +00:00
|
|
|
distance = p.length
|
|
|
|
if distance < range_min:
|
|
|
|
t = 0.0
|
|
|
|
elif distance > range_max:
|
|
|
|
t = 1.0
|
|
|
|
else:
|
|
|
|
t = (distance - range_min) / normfac
|
|
|
|
yield it, t
|
|
|
|
it.increment()
|
|
|
|
|
|
|
|
class ColorDistanceFromCameraShader(ColorRampModifier):
|
|
|
|
def __init__(self, blend, influence, ramp, range_min, range_max):
|
|
|
|
ColorRampModifier.__init__(self, blend, influence, ramp)
|
|
|
|
self.__range_min = range_min
|
|
|
|
self.__range_max = range_max
|
|
|
|
def shade(self, stroke):
|
|
|
|
for it, t in iter_distance_from_camera(stroke, self.__range_min, self.__range_max):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.color
|
2010-08-01 16:02:34 +00:00
|
|
|
b = self.evaluate(t)
|
2013-01-27 20:17:49 +00:00
|
|
|
sv.attribute.color = self.blend_ramp(a, b)
|
2010-08-01 16:02:34 +00:00
|
|
|
|
|
|
|
class AlphaDistanceFromCameraShader(CurveMappingModifier):
|
|
|
|
def __init__(self, blend, influence, mapping, invert, curve, range_min, range_max):
|
|
|
|
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
|
|
|
|
self.__range_min = range_min
|
|
|
|
self.__range_max = range_max
|
|
|
|
def shade(self, stroke):
|
|
|
|
for it, t in iter_distance_from_camera(stroke, self.__range_min, self.__range_max):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.alpha
|
2010-08-01 16:02:34 +00:00
|
|
|
b = self.evaluate(t)
|
2013-01-27 20:17:49 +00:00
|
|
|
sv.attribute.alpha = self.blend(a, b)
|
2010-08-01 16:02:34 +00:00
|
|
|
|
2012-04-07 17:28:09 +00:00
|
|
|
class ThicknessDistanceFromCameraShader(ThicknessBlenderMixIn, CurveMappingModifier):
|
|
|
|
def __init__(self, thickness_position, thickness_ratio,
|
|
|
|
blend, influence, mapping, invert, curve, range_min, range_max, value_min, value_max):
|
|
|
|
ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
|
2010-08-01 16:02:34 +00:00
|
|
|
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
|
|
|
|
self.__range_min = range_min
|
|
|
|
self.__range_max = range_max
|
|
|
|
self.__value_min = value_min
|
|
|
|
self.__value_max = value_max
|
|
|
|
def shade(self, stroke):
|
|
|
|
for it, t in iter_distance_from_camera(stroke, self.__range_min, self.__range_max):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.thickness
|
2010-08-01 16:02:34 +00:00
|
|
|
b = self.__value_min + self.evaluate(t) * (self.__value_max - self.__value_min)
|
2012-04-07 17:28:09 +00:00
|
|
|
c = self.blend_thickness(a[0], a[1], b)
|
|
|
|
self.set_thickness(sv, c[0], c[1])
|
2010-08-01 16:02:34 +00:00
|
|
|
|
2010-08-01 22:11:57 +00:00
|
|
|
# Distance from Object modifiers
|
|
|
|
|
|
|
|
def iter_distance_from_object(stroke, object, range_min, range_max):
|
2013-04-07 11:22:54 +00:00
|
|
|
scene = freestyle.getCurrentScene()
|
2011-04-12 22:30:18 +00:00
|
|
|
mv = scene.camera.matrix_world.copy() # model-view matrix
|
|
|
|
mv.invert()
|
2011-08-21 00:02:53 +00:00
|
|
|
loc = mv * object.location # loc in the camera coordinate
|
2010-08-01 22:11:57 +00:00
|
|
|
normfac = range_max - range_min # normalization factor
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
p = it.object.point_3d # in the camera coordinate
|
2010-08-01 22:11:57 +00:00
|
|
|
distance = (p - loc).length
|
|
|
|
if distance < range_min:
|
|
|
|
t = 0.0
|
|
|
|
elif distance > range_max:
|
|
|
|
t = 1.0
|
|
|
|
else:
|
|
|
|
t = (distance - range_min) / normfac
|
|
|
|
yield it, t
|
|
|
|
it.increment()
|
|
|
|
|
|
|
|
class ColorDistanceFromObjectShader(ColorRampModifier):
|
|
|
|
def __init__(self, blend, influence, ramp, target, range_min, range_max):
|
|
|
|
ColorRampModifier.__init__(self, blend, influence, ramp)
|
|
|
|
self.__target = target
|
|
|
|
self.__range_min = range_min
|
|
|
|
self.__range_max = range_max
|
|
|
|
def shade(self, stroke):
|
|
|
|
if self.__target is None:
|
|
|
|
return
|
|
|
|
for it, t in iter_distance_from_object(stroke, self.__target, self.__range_min, self.__range_max):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.color
|
2010-08-01 22:11:57 +00:00
|
|
|
b = self.evaluate(t)
|
2013-01-27 20:17:49 +00:00
|
|
|
sv.attribute.color = self.blend_ramp(a, b)
|
2010-08-01 22:11:57 +00:00
|
|
|
|
|
|
|
class AlphaDistanceFromObjectShader(CurveMappingModifier):
|
|
|
|
def __init__(self, blend, influence, mapping, invert, curve, target, range_min, range_max):
|
|
|
|
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
|
|
|
|
self.__target = target
|
|
|
|
self.__range_min = range_min
|
|
|
|
self.__range_max = range_max
|
|
|
|
def shade(self, stroke):
|
|
|
|
if self.__target is None:
|
|
|
|
return
|
|
|
|
for it, t in iter_distance_from_object(stroke, self.__target, self.__range_min, self.__range_max):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.alpha
|
2010-08-01 22:11:57 +00:00
|
|
|
b = self.evaluate(t)
|
2013-01-27 20:17:49 +00:00
|
|
|
sv.attribute.alpha = self.blend(a, b)
|
2010-08-01 22:11:57 +00:00
|
|
|
|
2012-04-07 17:28:09 +00:00
|
|
|
class ThicknessDistanceFromObjectShader(ThicknessBlenderMixIn, CurveMappingModifier):
|
|
|
|
def __init__(self, thickness_position, thickness_ratio,
|
|
|
|
blend, influence, mapping, invert, curve, target, range_min, range_max, value_min, value_max):
|
|
|
|
ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
|
2010-08-01 22:11:57 +00:00
|
|
|
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
|
|
|
|
self.__target = target
|
|
|
|
self.__range_min = range_min
|
|
|
|
self.__range_max = range_max
|
|
|
|
self.__value_min = value_min
|
|
|
|
self.__value_max = value_max
|
|
|
|
def shade(self, stroke):
|
|
|
|
if self.__target is None:
|
|
|
|
return
|
|
|
|
for it, t in iter_distance_from_object(stroke, self.__target, self.__range_min, self.__range_max):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.thickness
|
2010-08-01 22:11:57 +00:00
|
|
|
b = self.__value_min + self.evaluate(t) * (self.__value_max - self.__value_min)
|
2012-04-07 17:28:09 +00:00
|
|
|
c = self.blend_thickness(a[0], a[1], b)
|
|
|
|
self.set_thickness(sv, c[0], c[1])
|
2010-08-01 22:11:57 +00:00
|
|
|
|
2011-07-24 23:29:19 +00:00
|
|
|
# Material modifiers
|
|
|
|
|
2013-04-23 07:06:29 +00:00
|
|
|
def iter_material_color(stroke, material_attribute):
|
Stability improvements for the Face Smoothness option.
The instability considered here is due to a persistent failure of the
getFEdge() method in the Interface0D class and its subclasses in the
presence of smooth FEdges. When the Face Smoothness option is
enabled, the view map is populated with not only sharp FEdges (i.e.,
edges in the original meshes) but also smooth FEdges (i.e., newly
built edges lying on triangular surfaces). The failure of getFEdge()
caused many related issues because the method is widely used in other
predicates and functions that rely on it. The most prominent example
of related user-visible problems is a constant failure of the built-in
MaterialF0D.
The main issue and related problems were addressed as follows:
* A bug in the construction of smooth FEdges was fixed. Individual
smooth FEdges, even when they were detected as a series of smooth
FEdges that constitute one smooth ViewEdge, may have some irregular
geometry in the form of non-uniform OWXFaceLayer::order values. The
OWXFaceLayer::order values were used in an inappropriate way, so that
resulting smooth ViewEdges may have an FEdge between two subsequent
SVertices that were indeed the same SVertex object. This was an
unexpected situation that getFEdge() could not handle.
* Another issue in the construction of smooth FEdges was resolved.
When sharp FEdges are constructed, two SVertices at both ends of an
FEdge are generated only when no SVertex exists in a given 3D position
(this way, the original mesh topology is reconstructed from a bunch of
independent triangles that the BlenderFileLoader class passes to the
view map creation process). This sharing of SVertices was used also
for the generation of SVertices at the two ends of each smooth FEdge,
causing the getFEdge() failure in the presence of smooth FEdges. The
workaround implemented here is to simply suppress the sharing of
generated SVertices when smooth FEdges are created.
* In the Parameter Editor mode, the built-in MaterialF0D was replaced
with a better implementation that works well with Curves and Strokes.
MaterialF0D does not work with these 1D data types.
2011-10-10 19:57:06 +00:00
|
|
|
func = CurveMaterialF0D()
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
2013-02-21 02:57:44 +00:00
|
|
|
material = func(Interface0DIterator(it))
|
2013-04-23 07:06:29 +00:00
|
|
|
if material_attribute == 'DIFF':
|
2013-04-24 00:14:16 +00:00
|
|
|
color = material.diffuse[0:3]
|
2013-04-23 07:06:29 +00:00
|
|
|
elif material_attribute == 'SPEC':
|
2013-04-24 00:14:16 +00:00
|
|
|
color = material.specular[0:3]
|
2011-07-24 23:29:19 +00:00
|
|
|
else:
|
2013-04-23 07:06:29 +00:00
|
|
|
raise ValueError("unexpected material attribute: " + material_attribute)
|
2011-07-24 23:29:19 +00:00
|
|
|
yield it, color
|
|
|
|
it.increment()
|
|
|
|
|
2013-04-23 07:06:29 +00:00
|
|
|
def iter_material_value(stroke, material_attribute):
|
Stability improvements for the Face Smoothness option.
The instability considered here is due to a persistent failure of the
getFEdge() method in the Interface0D class and its subclasses in the
presence of smooth FEdges. When the Face Smoothness option is
enabled, the view map is populated with not only sharp FEdges (i.e.,
edges in the original meshes) but also smooth FEdges (i.e., newly
built edges lying on triangular surfaces). The failure of getFEdge()
caused many related issues because the method is widely used in other
predicates and functions that rely on it. The most prominent example
of related user-visible problems is a constant failure of the built-in
MaterialF0D.
The main issue and related problems were addressed as follows:
* A bug in the construction of smooth FEdges was fixed. Individual
smooth FEdges, even when they were detected as a series of smooth
FEdges that constitute one smooth ViewEdge, may have some irregular
geometry in the form of non-uniform OWXFaceLayer::order values. The
OWXFaceLayer::order values were used in an inappropriate way, so that
resulting smooth ViewEdges may have an FEdge between two subsequent
SVertices that were indeed the same SVertex object. This was an
unexpected situation that getFEdge() could not handle.
* Another issue in the construction of smooth FEdges was resolved.
When sharp FEdges are constructed, two SVertices at both ends of an
FEdge are generated only when no SVertex exists in a given 3D position
(this way, the original mesh topology is reconstructed from a bunch of
independent triangles that the BlenderFileLoader class passes to the
view map creation process). This sharing of SVertices was used also
for the generation of SVertices at the two ends of each smooth FEdge,
causing the getFEdge() failure in the presence of smooth FEdges. The
workaround implemented here is to simply suppress the sharing of
generated SVertices when smooth FEdges are created.
* In the Parameter Editor mode, the built-in MaterialF0D was replaced
with a better implementation that works well with Curves and Strokes.
MaterialF0D does not work with these 1D data types.
2011-10-10 19:57:06 +00:00
|
|
|
func = CurveMaterialF0D()
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
2013-02-21 02:57:44 +00:00
|
|
|
material = func(Interface0DIterator(it))
|
2013-04-23 07:06:29 +00:00
|
|
|
if material_attribute == 'DIFF':
|
2013-04-24 00:14:16 +00:00
|
|
|
r, g, b = material.diffuse[0:3]
|
2011-07-24 23:29:19 +00:00
|
|
|
t = 0.35 * r + 0.45 * r + 0.2 * b
|
2013-04-23 07:06:29 +00:00
|
|
|
elif material_attribute == 'DIFF_R':
|
2013-02-03 17:01:21 +00:00
|
|
|
t = material.diffuse[0]
|
2013-04-23 07:06:29 +00:00
|
|
|
elif material_attribute == 'DIFF_G':
|
2013-02-03 17:01:21 +00:00
|
|
|
t = material.diffuse[1]
|
2013-04-23 07:06:29 +00:00
|
|
|
elif material_attribute == 'DIFF_B':
|
2013-02-03 17:01:21 +00:00
|
|
|
t = material.diffuse[2]
|
2013-04-23 07:06:29 +00:00
|
|
|
elif material_attribute == 'SPEC':
|
2013-04-24 00:14:16 +00:00
|
|
|
r, g, b = material.specular[0:3]
|
2011-07-24 23:29:19 +00:00
|
|
|
t = 0.35 * r + 0.45 * r + 0.2 * b
|
2013-04-23 07:06:29 +00:00
|
|
|
elif material_attribute == 'SPEC_R':
|
2013-02-03 17:01:21 +00:00
|
|
|
t = material.specular[0]
|
2013-04-23 07:06:29 +00:00
|
|
|
elif material_attribute == 'SPEC_G':
|
2013-02-03 17:01:21 +00:00
|
|
|
t = material.specular[1]
|
2013-04-23 07:06:29 +00:00
|
|
|
elif material_attribute == 'SPEC_B':
|
2013-02-03 17:01:21 +00:00
|
|
|
t = material.specular[2]
|
2013-04-23 07:06:29 +00:00
|
|
|
elif material_attribute == 'SPEC_HARDNESS':
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
t = material.shininess
|
2013-04-23 07:06:29 +00:00
|
|
|
elif material_attribute == 'ALPHA':
|
2013-02-03 17:01:21 +00:00
|
|
|
t = material.diffuse[3]
|
2011-07-24 23:29:19 +00:00
|
|
|
else:
|
2013-04-23 07:06:29 +00:00
|
|
|
raise ValueError("unexpected material attribute: " + material_attribute)
|
2011-07-24 23:29:19 +00:00
|
|
|
yield it, t
|
|
|
|
it.increment()
|
|
|
|
|
|
|
|
class ColorMaterialShader(ColorRampModifier):
|
2013-04-23 07:06:29 +00:00
|
|
|
def __init__(self, blend, influence, ramp, material_attribute, use_ramp):
|
2011-07-24 23:29:19 +00:00
|
|
|
ColorRampModifier.__init__(self, blend, influence, ramp)
|
2013-04-23 07:06:29 +00:00
|
|
|
self.__material_attribute = material_attribute
|
2011-07-24 23:29:19 +00:00
|
|
|
self.__use_ramp = use_ramp
|
|
|
|
def shade(self, stroke):
|
2013-04-23 07:06:29 +00:00
|
|
|
if self.__material_attribute in {'DIFF', 'SPEC'} and not self.__use_ramp:
|
|
|
|
for it, b in iter_material_color(stroke, self.__material_attribute):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.color
|
|
|
|
sv.attribute.color = self.blend_ramp(a, b)
|
2011-07-24 23:29:19 +00:00
|
|
|
else:
|
2013-04-23 07:06:29 +00:00
|
|
|
for it, t in iter_material_value(stroke, self.__material_attribute):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.color
|
2011-07-24 23:29:19 +00:00
|
|
|
b = self.evaluate(t)
|
2013-01-27 20:17:49 +00:00
|
|
|
sv.attribute.color = self.blend_ramp(a, b)
|
2011-07-24 23:29:19 +00:00
|
|
|
|
|
|
|
class AlphaMaterialShader(CurveMappingModifier):
|
2013-04-23 07:06:29 +00:00
|
|
|
def __init__(self, blend, influence, mapping, invert, curve, material_attribute):
|
2011-07-24 23:29:19 +00:00
|
|
|
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
|
2013-04-23 07:06:29 +00:00
|
|
|
self.__material_attribute = material_attribute
|
2011-07-24 23:29:19 +00:00
|
|
|
def shade(self, stroke):
|
2013-04-23 07:06:29 +00:00
|
|
|
for it, t in iter_material_value(stroke, self.__material_attribute):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.alpha
|
2011-07-24 23:29:19 +00:00
|
|
|
b = self.evaluate(t)
|
2013-01-27 20:17:49 +00:00
|
|
|
sv.attribute.alpha = self.blend(a, b)
|
2011-07-24 23:29:19 +00:00
|
|
|
|
2012-04-07 17:28:09 +00:00
|
|
|
class ThicknessMaterialShader(ThicknessBlenderMixIn, CurveMappingModifier):
|
|
|
|
def __init__(self, thickness_position, thickness_ratio,
|
2013-04-23 07:06:29 +00:00
|
|
|
blend, influence, mapping, invert, curve, material_attribute, value_min, value_max):
|
2012-04-07 17:28:09 +00:00
|
|
|
ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
|
2011-07-24 23:29:19 +00:00
|
|
|
CurveMappingModifier.__init__(self, blend, influence, mapping, invert, curve)
|
2013-04-23 07:06:29 +00:00
|
|
|
self.__material_attribute = material_attribute
|
2011-07-24 23:29:19 +00:00
|
|
|
self.__value_min = value_min
|
|
|
|
self.__value_max = value_max
|
|
|
|
def shade(self, stroke):
|
2013-04-23 07:06:29 +00:00
|
|
|
for it, t in iter_material_value(stroke, self.__material_attribute):
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.thickness
|
2011-07-24 23:29:19 +00:00
|
|
|
b = self.__value_min + self.evaluate(t) * (self.__value_max - self.__value_min)
|
2012-04-07 17:28:09 +00:00
|
|
|
c = self.blend_thickness(a[0], a[1], b)
|
|
|
|
self.set_thickness(sv, c[0], c[1])
|
2011-09-11 19:57:38 +00:00
|
|
|
|
|
|
|
# Calligraphic thickness modifier
|
|
|
|
|
2012-04-07 17:28:09 +00:00
|
|
|
class CalligraphicThicknessShader(ThicknessBlenderMixIn, ScalarBlendModifier):
|
|
|
|
def __init__(self, thickness_position, thickness_ratio,
|
2013-04-23 07:06:29 +00:00
|
|
|
blend, influence, orientation, thickness_min, thickness_max):
|
2012-04-07 17:28:09 +00:00
|
|
|
ThicknessBlenderMixIn.__init__(self, thickness_position, thickness_ratio)
|
2011-09-11 19:57:38 +00:00
|
|
|
ScalarBlendModifier.__init__(self, blend, influence)
|
2012-12-09 23:19:46 +00:00
|
|
|
self.__orientation = mathutils.Vector((math.cos(orientation), math.sin(orientation)))
|
2013-04-23 07:06:29 +00:00
|
|
|
self.__thickness_min = thickness_min
|
|
|
|
self.__thickness_max = thickness_max
|
2011-09-11 19:57:38 +00:00
|
|
|
def shade(self, stroke):
|
|
|
|
func = VertexOrientation2DF0D()
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
2013-02-21 02:57:44 +00:00
|
|
|
dir = func(Interface0DIterator(it))
|
2011-09-11 19:57:38 +00:00
|
|
|
orthDir = mathutils.Vector((-dir.y, dir.x))
|
|
|
|
orthDir.normalize()
|
|
|
|
fac = abs(orthDir * self.__orientation)
|
2013-02-16 14:21:40 +00:00
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
a = sv.attribute.thickness
|
2013-04-23 07:06:29 +00:00
|
|
|
b = self.__thickness_min + fac * (self.__thickness_max - self.__thickness_min)
|
2011-09-11 19:57:38 +00:00
|
|
|
b = max(b, 0.0)
|
2012-04-07 17:28:09 +00:00
|
|
|
c = self.blend_thickness(a[0], a[1], b)
|
|
|
|
self.set_thickness(sv, c[0], c[1])
|
2011-09-11 19:57:38 +00:00
|
|
|
it.increment()
|
2011-07-24 23:29:19 +00:00
|
|
|
|
2011-08-19 14:05:11 +00:00
|
|
|
# Geometry modifiers
|
|
|
|
|
|
|
|
def iter_distance_along_stroke(stroke):
|
|
|
|
distance = 0.0
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-03-03 21:56:36 +00:00
|
|
|
prev = it.object.point
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
p = it.object.point
|
2013-03-03 21:56:36 +00:00
|
|
|
distance += (prev - p).length
|
|
|
|
prev = p.copy() # need a copy because the point can be altered
|
2011-08-19 14:05:11 +00:00
|
|
|
yield it, distance
|
|
|
|
it.increment()
|
|
|
|
|
|
|
|
class SinusDisplacementShader(StrokeShader):
|
|
|
|
def __init__(self, wavelength, amplitude, phase):
|
|
|
|
StrokeShader.__init__(self)
|
|
|
|
self._wavelength = wavelength
|
|
|
|
self._amplitude = amplitude
|
|
|
|
self._phase = phase / wavelength * 2 * math.pi
|
|
|
|
self._getNormal = Normal2DF0D()
|
|
|
|
def shade(self, stroke):
|
|
|
|
for it, distance in iter_distance_along_stroke(stroke):
|
2013-02-16 14:21:40 +00:00
|
|
|
v = it.object
|
2013-02-21 02:57:44 +00:00
|
|
|
n = self._getNormal(Interface0DIterator(it))
|
2011-08-19 14:05:11 +00:00
|
|
|
n = n * self._amplitude * math.cos(distance / self._wavelength * 2 * math.pi + self._phase)
|
2013-01-27 20:17:49 +00:00
|
|
|
v.point = v.point + n
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
stroke.update_length()
|
2011-08-19 14:05:11 +00:00
|
|
|
|
2011-08-30 00:29:12 +00:00
|
|
|
class PerlinNoise1DShader(StrokeShader):
|
2012-12-09 23:19:46 +00:00
|
|
|
def __init__(self, freq = 10, amp = 10, oct = 4, angle = math.radians(45), seed = -1):
|
2011-08-30 00:29:12 +00:00
|
|
|
StrokeShader.__init__(self)
|
|
|
|
self.__noise = Noise(seed)
|
|
|
|
self.__freq = freq
|
|
|
|
self.__amp = amp
|
|
|
|
self.__oct = oct
|
2013-02-24 23:43:40 +00:00
|
|
|
self.__dir = mathutils.Vector([math.cos(angle), math.sin(angle)])
|
2011-08-30 00:29:12 +00:00
|
|
|
def shade(self, stroke):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
length = stroke.length_2d
|
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
v = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
nres = self.__noise.turbulence1(length * v.u, self.__freq, self.__amp, self.__oct)
|
|
|
|
v.point = v.point + nres * self.__dir
|
2011-08-30 00:29:12 +00:00
|
|
|
it.increment()
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
stroke.update_length()
|
2011-08-30 00:29:12 +00:00
|
|
|
|
|
|
|
class PerlinNoise2DShader(StrokeShader):
|
2012-12-09 23:19:46 +00:00
|
|
|
def __init__(self, freq = 10, amp = 10, oct = 4, angle = math.radians(45), seed = -1):
|
2011-08-30 00:29:12 +00:00
|
|
|
StrokeShader.__init__(self)
|
|
|
|
self.__noise = Noise(seed)
|
|
|
|
self.__freq = freq
|
|
|
|
self.__amp = amp
|
|
|
|
self.__oct = oct
|
2013-02-24 23:43:40 +00:00
|
|
|
self.__dir = mathutils.Vector([math.cos(angle), math.sin(angle)])
|
2011-08-30 00:29:12 +00:00
|
|
|
def shade(self, stroke):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
v = it.object
|
2013-02-24 23:43:40 +00:00
|
|
|
vec = mathutils.Vector([v.projected_x, v.projected_y])
|
2011-08-30 00:29:12 +00:00
|
|
|
nres = self.__noise.turbulence2(vec, self.__freq, self.__amp, self.__oct)
|
2013-01-27 20:17:49 +00:00
|
|
|
v.point = v.point + nres * self.__dir
|
2011-08-30 00:29:12 +00:00
|
|
|
it.increment()
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
stroke.update_length()
|
2011-08-30 00:29:12 +00:00
|
|
|
|
2012-01-04 00:23:34 +00:00
|
|
|
class Offset2DShader(StrokeShader):
|
|
|
|
def __init__(self, start, end, x, y):
|
|
|
|
StrokeShader.__init__(self)
|
|
|
|
self.__start = start
|
|
|
|
self.__end = end
|
2013-02-24 23:43:40 +00:00
|
|
|
self.__xy = mathutils.Vector([x, y])
|
2012-01-04 00:23:34 +00:00
|
|
|
self.__getNormal = Normal2DF0D()
|
|
|
|
def shade(self, stroke):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
v = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
u = v.u
|
2012-01-04 00:23:34 +00:00
|
|
|
a = self.__start + u * (self.__end - self.__start)
|
2013-02-21 02:57:44 +00:00
|
|
|
n = self.__getNormal(Interface0DIterator(it))
|
2012-01-04 00:23:34 +00:00
|
|
|
n = n * a
|
2013-01-27 20:17:49 +00:00
|
|
|
v.point = v.point + n + self.__xy
|
2012-01-04 00:23:34 +00:00
|
|
|
it.increment()
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
stroke.update_length()
|
2012-01-04 00:23:34 +00:00
|
|
|
|
|
|
|
class Transform2DShader(StrokeShader):
|
|
|
|
def __init__(self, pivot, scale_x, scale_y, angle, pivot_u, pivot_x, pivot_y):
|
|
|
|
StrokeShader.__init__(self)
|
|
|
|
self.__pivot = pivot
|
|
|
|
self.__scale_x = scale_x
|
|
|
|
self.__scale_y = scale_y
|
|
|
|
self.__angle = angle
|
|
|
|
self.__pivot_u = pivot_u
|
|
|
|
self.__pivot_x = pivot_x
|
|
|
|
self.__pivot_y = pivot_y
|
|
|
|
def shade(self, stroke):
|
|
|
|
# determine the pivot of scaling and rotation operations
|
2013-04-23 07:06:29 +00:00
|
|
|
if self.__pivot == 'START':
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
pivot = it.object.point
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__pivot == 'END':
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_end()
|
2012-01-04 00:23:34 +00:00
|
|
|
it.decrement()
|
2013-02-16 14:21:40 +00:00
|
|
|
pivot = it.object.point
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__pivot == 'PARAM':
|
2012-01-04 00:23:34 +00:00
|
|
|
p = None
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
2012-01-04 00:23:34 +00:00
|
|
|
prev = p
|
2013-02-16 14:21:40 +00:00
|
|
|
v = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
p = v.point
|
|
|
|
u = v.u
|
2012-01-04 00:23:34 +00:00
|
|
|
if self.__pivot_u < u:
|
|
|
|
break
|
|
|
|
it.increment()
|
|
|
|
if prev is None:
|
|
|
|
pivot = p
|
|
|
|
else:
|
|
|
|
delta = u - self.__pivot_u
|
|
|
|
pivot = p + delta * (prev - p)
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__pivot == 'CENTER':
|
2013-02-24 23:43:40 +00:00
|
|
|
pivot = mathutils.Vector([0.0, 0.0])
|
2012-01-04 00:23:34 +00:00
|
|
|
n = 0
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
p = it.object.point
|
2012-01-04 00:23:34 +00:00
|
|
|
pivot = pivot + p
|
|
|
|
n = n + 1
|
|
|
|
it.increment()
|
|
|
|
pivot.x = pivot.x / n
|
|
|
|
pivot.y = pivot.y / n
|
2013-04-23 07:06:29 +00:00
|
|
|
elif self.__pivot == 'ABSOLUTE':
|
2013-02-24 23:43:40 +00:00
|
|
|
pivot = mathutils.Vector([self.__pivot_x, self.__pivot_y])
|
2012-01-04 00:23:34 +00:00
|
|
|
# apply scaling and rotation operations
|
2012-12-09 23:19:46 +00:00
|
|
|
cos_theta = math.cos(self.__angle)
|
|
|
|
sin_theta = math.sin(self.__angle)
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
v = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
p = v.point
|
2012-01-04 00:23:34 +00:00
|
|
|
p = p - pivot
|
|
|
|
x = p.x * self.__scale_x
|
|
|
|
y = p.y * self.__scale_y
|
|
|
|
p.x = x * cos_theta - y * sin_theta
|
|
|
|
p.y = x * sin_theta + y * cos_theta
|
2013-01-27 20:17:49 +00:00
|
|
|
v.point = p + pivot
|
2012-01-04 00:23:34 +00:00
|
|
|
it.increment()
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
stroke.update_length()
|
2012-01-04 00:23:34 +00:00
|
|
|
|
2010-08-01 16:02:34 +00:00
|
|
|
# Predicates and helper functions
|
2010-07-28 00:43:45 +00:00
|
|
|
|
|
|
|
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 __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:
|
2011-10-27 20:57:14 +00:00
|
|
|
return None
|
2010-07-28 00:43:45 +00:00
|
|
|
upred = upred_list[0]
|
|
|
|
for p in upred_list[1:]:
|
|
|
|
upred = bpred(upred, p)
|
|
|
|
return upred
|
|
|
|
|
2010-12-02 23:50:10 +00:00
|
|
|
class ObjectNamesUP1D(UnaryPredicate1D):
|
|
|
|
def __init__(self, names, negative):
|
|
|
|
UnaryPredicate1D.__init__(self)
|
|
|
|
self._names = names
|
|
|
|
self._negative = negative
|
|
|
|
def __call__(self, viewEdge):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
found = viewEdge.viewshape.name in self._names
|
2010-12-02 23:50:10 +00:00
|
|
|
if self._negative:
|
|
|
|
return not found
|
|
|
|
return found
|
|
|
|
|
2010-10-10 22:50:32 +00:00
|
|
|
# Stroke caps
|
|
|
|
|
|
|
|
def iter_stroke_vertices(stroke):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin()
|
2011-07-02 16:27:52 +00:00
|
|
|
prev_p = None
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
sv = it.object
|
2013-01-27 20:17:49 +00:00
|
|
|
p = sv.point
|
2011-07-02 16:27:52 +00:00
|
|
|
if prev_p is None or (prev_p - p).length > 1e-6:
|
|
|
|
yield sv
|
2013-03-03 21:56:36 +00:00
|
|
|
prev_p = p.copy()
|
2010-10-10 22:50:32 +00:00
|
|
|
it.increment()
|
|
|
|
|
|
|
|
class RoundCapShader(StrokeShader):
|
|
|
|
def round_cap_thickness(self, x):
|
|
|
|
x = max(0.0, min(x, 1.0))
|
|
|
|
return math.sqrt(1.0 - (x ** 2))
|
|
|
|
def shade(self, stroke):
|
|
|
|
# save the location and attribute of stroke vertices
|
|
|
|
buffer = []
|
|
|
|
for sv in iter_stroke_vertices(stroke):
|
2013-02-24 23:43:40 +00:00
|
|
|
buffer.append((mathutils.Vector(sv.point), StrokeAttribute(sv.attribute)))
|
2011-07-03 07:48:19 +00:00
|
|
|
nverts = len(buffer)
|
|
|
|
if nverts < 2:
|
2011-07-02 16:27:52 +00:00
|
|
|
return
|
2010-10-10 22:50:32 +00:00
|
|
|
# calculate the number of additional vertices to form caps
|
2013-01-27 20:17:49 +00:00
|
|
|
R, L = stroke[0].attribute.thickness
|
2010-10-10 22:50:32 +00:00
|
|
|
caplen_beg = (R + L) / 2.0
|
|
|
|
nverts_beg = max(5, int(R + L))
|
2013-01-27 20:17:49 +00:00
|
|
|
R, L = stroke[-1].attribute.thickness
|
2010-10-10 22:50:32 +00:00
|
|
|
caplen_end = (R + L) / 2.0
|
|
|
|
nverts_end = max(5, int(R + L))
|
2011-07-03 07:48:19 +00:00
|
|
|
# adjust the total number of stroke vertices
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
stroke.resample(nverts + nverts_beg + nverts_end)
|
2010-10-10 22:50:32 +00:00
|
|
|
# restore the location and attribute of the original vertices
|
|
|
|
for i in range(nverts):
|
|
|
|
p, attr = buffer[i]
|
2013-01-27 20:17:49 +00:00
|
|
|
stroke[nverts_beg + i].point = p
|
|
|
|
stroke[nverts_beg + i].attribute = attr
|
2010-10-10 22:50:32 +00:00
|
|
|
# reshape the cap at the beginning of the stroke
|
|
|
|
q, attr = buffer[1]
|
|
|
|
p, attr = buffer[0]
|
|
|
|
d = p - q
|
|
|
|
d = d / d.length * caplen_beg
|
|
|
|
n = 1.0 / nverts_beg
|
2013-01-27 20:17:49 +00:00
|
|
|
R, L = attr.thickness
|
2010-10-10 22:50:32 +00:00
|
|
|
for i in range(nverts_beg):
|
|
|
|
t = (nverts_beg - i) * n
|
2013-01-27 20:17:49 +00:00
|
|
|
stroke[i].point = p + d * t
|
2010-10-10 22:50:32 +00:00
|
|
|
r = self.round_cap_thickness((nverts_beg - i + 1) * n)
|
2013-01-27 20:17:49 +00:00
|
|
|
stroke[i].attribute = attr
|
|
|
|
stroke[i].attribute.thickness = (R * r, L * r)
|
2010-10-10 22:50:32 +00:00
|
|
|
# reshape the cap at the end of the stroke
|
|
|
|
q, attr = buffer[-2]
|
|
|
|
p, attr = buffer[-1]
|
|
|
|
d = p - q
|
|
|
|
d = d / d.length * caplen_end
|
|
|
|
n = 1.0 / nverts_end
|
2013-01-27 20:17:49 +00:00
|
|
|
R, L = attr.thickness
|
2010-10-10 22:50:32 +00:00
|
|
|
for i in range(nverts_end):
|
|
|
|
t = (nverts_end - i) * n
|
2013-01-27 20:17:49 +00:00
|
|
|
stroke[-i-1].point = p + d * t
|
2010-10-10 22:50:32 +00:00
|
|
|
r = self.round_cap_thickness((nverts_end - i + 1) * n)
|
2013-01-27 20:17:49 +00:00
|
|
|
stroke[-i-1].attribute = attr
|
|
|
|
stroke[-i-1].attribute.thickness = (R * r, L * r)
|
2012-11-04 23:52:26 +00:00
|
|
|
# update the curvilinear 2D length of each vertex
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
stroke.update_length()
|
2010-10-10 22:50:32 +00:00
|
|
|
|
|
|
|
class SquareCapShader(StrokeShader):
|
|
|
|
def shade(self, stroke):
|
|
|
|
# save the location and attribute of stroke vertices
|
|
|
|
buffer = []
|
|
|
|
for sv in iter_stroke_vertices(stroke):
|
2013-02-24 23:43:40 +00:00
|
|
|
buffer.append((mathutils.Vector(sv.point), StrokeAttribute(sv.attribute)))
|
2011-07-03 07:48:19 +00:00
|
|
|
nverts = len(buffer)
|
|
|
|
if nverts < 2:
|
2011-07-02 16:27:52 +00:00
|
|
|
return
|
2010-10-10 22:50:32 +00:00
|
|
|
# calculate the number of additional vertices to form caps
|
2013-01-27 20:17:49 +00:00
|
|
|
R, L = stroke[0].attribute.thickness
|
2010-10-10 22:50:32 +00:00
|
|
|
caplen_beg = (R + L) / 2.0
|
|
|
|
nverts_beg = 1
|
2013-01-27 20:17:49 +00:00
|
|
|
R, L = stroke[-1].attribute.thickness
|
2010-10-10 22:50:32 +00:00
|
|
|
caplen_end = (R + L) / 2.0
|
|
|
|
nverts_end = 1
|
2011-07-03 07:48:19 +00:00
|
|
|
# adjust the total number of stroke vertices
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
stroke.resample(nverts + nverts_beg + nverts_end)
|
2010-10-10 22:50:32 +00:00
|
|
|
# restore the location and attribute of the original vertices
|
|
|
|
for i in range(nverts):
|
|
|
|
p, attr = buffer[i]
|
2013-01-27 20:17:49 +00:00
|
|
|
stroke[nverts_beg + i].point = p
|
|
|
|
stroke[nverts_beg + i].attribute = attr
|
2010-10-10 22:50:32 +00:00
|
|
|
# reshape the cap at the beginning of the stroke
|
|
|
|
q, attr = buffer[1]
|
|
|
|
p, attr = buffer[0]
|
|
|
|
d = p - q
|
2013-01-27 20:17:49 +00:00
|
|
|
stroke[0].point = p + d / d.length * caplen_beg
|
|
|
|
stroke[0].attribute = attr
|
2010-10-10 22:50:32 +00:00
|
|
|
# reshape the cap at the end of the stroke
|
|
|
|
q, attr = buffer[-2]
|
|
|
|
p, attr = buffer[-1]
|
|
|
|
d = p - q
|
2013-01-27 20:17:49 +00:00
|
|
|
stroke[-1].point = p + d / d.length * caplen_beg
|
|
|
|
stroke[-1].attribute = attr
|
2012-11-04 23:52:26 +00:00
|
|
|
# update the curvilinear 2D length of each vertex
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
stroke.update_length()
|
2010-10-10 22:50:32 +00:00
|
|
|
|
2012-11-04 23:52:26 +00:00
|
|
|
# Split by dashed line pattern
|
2010-10-23 20:42:26 +00:00
|
|
|
|
2012-11-04 23:52:26 +00:00
|
|
|
class SplitPatternStartingUP0D(UnaryPredicate0D):
|
2010-10-23 20:42:26 +00:00
|
|
|
def __init__(self, controller):
|
|
|
|
UnaryPredicate0D.__init__(self)
|
|
|
|
self._controller = controller
|
|
|
|
def __call__(self, inter):
|
|
|
|
return self._controller.start()
|
|
|
|
|
2012-11-04 23:52:26 +00:00
|
|
|
class SplitPatternStoppingUP0D(UnaryPredicate0D):
|
2010-10-23 20:42:26 +00:00
|
|
|
def __init__(self, controller):
|
|
|
|
UnaryPredicate0D.__init__(self)
|
|
|
|
self._controller = controller
|
|
|
|
def __call__(self, inter):
|
|
|
|
return self._controller.stop()
|
|
|
|
|
2012-11-04 23:52:26 +00:00
|
|
|
class SplitPatternController:
|
2010-10-23 20:42:26 +00:00
|
|
|
def __init__(self, pattern, sampling):
|
|
|
|
self.sampling = float(sampling)
|
|
|
|
k = len(pattern) // 2
|
|
|
|
n = k * 2
|
|
|
|
self.start_pos = [pattern[i] + pattern[i+1] for i in range(0, n, 2)]
|
|
|
|
self.stop_pos = [pattern[i] for i in range(0, n, 2)]
|
|
|
|
self.init()
|
|
|
|
def init(self):
|
|
|
|
self.start_len = 0.0
|
|
|
|
self.start_idx = 0
|
|
|
|
self.stop_len = self.sampling
|
|
|
|
self.stop_idx = 0
|
|
|
|
def start(self):
|
|
|
|
self.start_len += self.sampling
|
|
|
|
if abs(self.start_len - self.start_pos[self.start_idx]) < self.sampling / 2.0:
|
|
|
|
self.start_len = 0.0
|
|
|
|
self.start_idx = (self.start_idx + 1) % len(self.start_pos)
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
def stop(self):
|
|
|
|
if self.start_len > 0.0:
|
|
|
|
self.init()
|
|
|
|
self.stop_len += self.sampling
|
|
|
|
if abs(self.stop_len - self.stop_pos[self.stop_idx]) < self.sampling / 2.0:
|
|
|
|
self.stop_len = self.sampling
|
|
|
|
self.stop_idx = (self.stop_idx + 1) % len(self.stop_pos)
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2012-11-04 23:52:26 +00:00
|
|
|
# Dashed line
|
|
|
|
|
|
|
|
class DashedLineShader(StrokeShader):
|
|
|
|
def __init__(self, pattern):
|
|
|
|
StrokeShader.__init__(self)
|
|
|
|
self._pattern = pattern
|
|
|
|
def shade(self, stroke):
|
|
|
|
index = 0 # pattern index
|
|
|
|
start = 0.0 # 2D curvilinear length
|
|
|
|
visible = True
|
|
|
|
sampling = 1.0
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
it = stroke.stroke_vertices_begin(sampling)
|
2013-02-16 14:21:40 +00:00
|
|
|
while not it.is_end:
|
|
|
|
pos = it.t # curvilinear abscissa
|
2012-11-04 23:52:26 +00:00
|
|
|
# The extra 'sampling' term is added below, because the
|
|
|
|
# visibility attribute of the i-th vertex refers to the
|
|
|
|
# visibility of the stroke segment between the i-th and
|
|
|
|
# (i+1)-th vertices.
|
|
|
|
if pos - start + sampling > self._pattern[index]:
|
|
|
|
start = pos
|
|
|
|
index += 1
|
|
|
|
if index == len(self._pattern):
|
|
|
|
index = 0
|
|
|
|
visible = not visible
|
2013-02-16 14:21:40 +00:00
|
|
|
it.object.attribute.visible = visible
|
2012-11-04 23:52:26 +00:00
|
|
|
it.increment()
|
|
|
|
|
2011-01-31 20:57:39 +00:00
|
|
|
# predicates for chaining
|
|
|
|
|
|
|
|
class AngleLargerThanBP1D(BinaryPredicate1D):
|
|
|
|
def __init__(self, angle):
|
|
|
|
BinaryPredicate1D.__init__(self)
|
2012-12-09 23:19:46 +00:00
|
|
|
self._angle = angle
|
2011-01-31 20:57:39 +00:00
|
|
|
def __call__(self, i1, i2):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
sv1a = i1.first_fedge.first_svertex.point_2d
|
|
|
|
sv1b = i1.last_fedge.second_svertex.point_2d
|
|
|
|
sv2a = i2.first_fedge.first_svertex.point_2d
|
|
|
|
sv2b = i2.last_fedge.second_svertex.point_2d
|
2011-01-31 20:57:39 +00:00
|
|
|
if (sv1a - sv2a).length < 1e-6:
|
|
|
|
dir1 = sv1a - sv1b
|
|
|
|
dir2 = sv2b - sv2a
|
|
|
|
elif (sv1b - sv2b).length < 1e-6:
|
|
|
|
dir1 = sv1b - sv1a
|
|
|
|
dir2 = sv2a - sv2b
|
|
|
|
elif (sv1a - sv2b).length < 1e-6:
|
|
|
|
dir1 = sv1a - sv1b
|
|
|
|
dir2 = sv2a - sv2b
|
|
|
|
elif (sv1b - sv2a).length < 1e-6:
|
|
|
|
dir1 = sv1b - sv1a
|
|
|
|
dir2 = sv2b - sv2a
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
denom = dir1.length * dir2.length
|
|
|
|
if denom < 1e-6:
|
|
|
|
return False
|
|
|
|
x = (dir1 * dir2) / denom
|
|
|
|
return math.acos(min(max(x, -1.0), 1.0)) > self._angle
|
|
|
|
|
|
|
|
class AndBP1D(BinaryPredicate1D):
|
|
|
|
def __init__(self, pred1, pred2):
|
|
|
|
BinaryPredicate1D.__init__(self)
|
|
|
|
self.__pred1 = pred1
|
|
|
|
self.__pred2 = pred2
|
|
|
|
def __call__(self, i1, i2):
|
|
|
|
return self.__pred1(i1, i2) and self.__pred2(i1, i2)
|
|
|
|
|
2011-09-18 22:59:51 +00:00
|
|
|
# predicates for selection
|
|
|
|
|
|
|
|
class LengthThresholdUP1D(UnaryPredicate1D):
|
2013-04-23 07:06:29 +00:00
|
|
|
def __init__(self, length_min=None, length_max=None):
|
2011-09-18 22:59:51 +00:00
|
|
|
UnaryPredicate1D.__init__(self)
|
2013-04-23 07:06:29 +00:00
|
|
|
self._length_min = length_min
|
|
|
|
self._length_max = length_max
|
2011-09-18 22:59:51 +00:00
|
|
|
def __call__(self, inter):
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
length = inter.length_2d
|
2013-04-23 07:06:29 +00:00
|
|
|
if self._length_min is not None and length < self._length_min:
|
2011-09-18 22:59:51 +00:00
|
|
|
return False
|
2013-04-23 07:06:29 +00:00
|
|
|
if self._length_max is not None and length > self._length_max:
|
2011-09-18 22:59:51 +00:00
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2011-10-06 02:04:43 +00:00
|
|
|
class FaceMarkBothUP1D(UnaryPredicate1D):
|
|
|
|
def __call__(self, inter): # ViewEdge
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
fe = inter.first_fedge
|
2011-10-06 02:04:43 +00:00
|
|
|
while fe is not None:
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
if fe.is_smooth:
|
|
|
|
if fe.face_mark:
|
2011-10-06 02:04:43 +00:00
|
|
|
return True
|
|
|
|
else:
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
if fe.face_mark_right and fe.face_mark_left:
|
2011-10-06 02:04:43 +00:00
|
|
|
return True
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
fe = fe.next_fedge
|
2011-10-06 02:04:43 +00:00
|
|
|
return False
|
|
|
|
|
|
|
|
class FaceMarkOneUP1D(UnaryPredicate1D):
|
|
|
|
def __call__(self, inter): # ViewEdge
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
fe = inter.first_fedge
|
2011-10-06 02:04:43 +00:00
|
|
|
while fe is not None:
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
if fe.is_smooth:
|
|
|
|
if fe.face_mark:
|
2011-10-06 02:04:43 +00:00
|
|
|
return True
|
|
|
|
else:
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
if fe.face_mark_right or fe.face_mark_left:
|
2011-10-06 02:04:43 +00:00
|
|
|
return True
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
fe = fe.next_fedge
|
2011-10-06 02:04:43 +00:00
|
|
|
return False
|
|
|
|
|
2011-08-13 00:05:25 +00:00
|
|
|
# predicates for splitting
|
|
|
|
|
|
|
|
class MaterialBoundaryUP0D(UnaryPredicate0D):
|
|
|
|
def __call__(self, it):
|
2013-02-16 14:21:40 +00:00
|
|
|
if it.is_begin:
|
2011-08-13 00:05:25 +00:00
|
|
|
return False
|
|
|
|
it_prev = Interface0DIterator(it)
|
|
|
|
it_prev.decrement()
|
2013-02-16 14:21:40 +00:00
|
|
|
v = it.object
|
2011-08-13 00:05:25 +00:00
|
|
|
it.increment()
|
2013-02-16 14:21:40 +00:00
|
|
|
if it.is_end:
|
2011-08-13 00:05:25 +00:00
|
|
|
return False
|
2013-02-16 14:21:40 +00:00
|
|
|
fe = v.get_fedge(it_prev.object)
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
idx1 = fe.material_index if fe.is_smooth else fe.material_index_left
|
2013-02-16 14:21:40 +00:00
|
|
|
fe = v.get_fedge(it.object)
|
Freestyle Python API improvements - part 3.
Major API updates were made to address code review comments.
This revision mostly focuses on Python wrappers of C++ 0D and 1D elements (i.e.,
Interface0D and Interface1D, as well as their subclasses).
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
Vector attributes are now implemented based on mathutils callbacks. Boolean
attributes now only accept boolean values.
* The __getitem__ method was removed and the Sequence protocol was used instead.
* The naming of methods and attributes was fixed to follow the naming conventions
of the Blender Python API (i.e., lower case + underscores for methods and attributes,
and CamelCase for classes). Some naming inconsistency within the Freestyle Python
API was also addressed.
* The Freestyle API had a number of method names including prefix/suffix "A" and
"B", and their meanings were inconsistent (i.e., referring to different things
depending on the classes). The names with these two letters were replaced with
more straightforward names. Also some attribute names were changed so as to indicate
the type of the value (e.g., FEdge.next_fedge instead of FEdge.next_edge) in line
with other names explicitly indicating what the value is (e.g., SVertex.viewvertex).
* In addition, some code clean-up was done in both C++ and Python.
Notes:
In summary, the following irregular naming changes were made through this revision
(those resulting from regular changes of naming conventions are not listed):
- CurvePoint: {A,B} --> {first,second}_svertex
- FEdge: vertex{A,B} --> {first,second}_svertex
- FEdge: {next,previous}Edge --> {next,previous}_fedge
- FEdgeSharp: normal{A,B} --> normal_{right,left}
- FEdgeSharp: {a,b}FaceMark --> face_mark_{right,left}
- FEdgeSharp: {a,b}Material --> material_{right,left}
- FEdgeSharp: {a,b}MaterialIndex --> material_index_{right,left}
- FrsCurve: empty --> is_empty
- FrsCurve: nSegments --> segments_size
- TVertex: mate() --> get_mate()
- ViewEdge: fedge{A,B} --> {first,last}_fedge
- ViewEdge: setaShape, aShape --> occlude
- ViewEdge: {A,B} --> {first,last}_viewvertex
- ViewMap: getScene3dBBox --> scene_bbox
2013-02-14 23:48:34 +00:00
|
|
|
idx2 = fe.material_index if fe.is_smooth else fe.material_index_left
|
2011-08-13 00:05:25 +00:00
|
|
|
return idx1 != idx2
|
|
|
|
|
2011-11-13 20:20:50 +00:00
|
|
|
class Curvature2DAngleThresholdUP0D(UnaryPredicate0D):
|
2013-04-23 07:06:29 +00:00
|
|
|
def __init__(self, angle_min=None, angle_max=None):
|
2011-11-13 20:20:50 +00:00
|
|
|
UnaryPredicate0D.__init__(self)
|
2013-04-23 07:06:29 +00:00
|
|
|
self._angle_min = angle_min
|
|
|
|
self._angle_max = angle_max
|
2011-11-13 20:20:50 +00:00
|
|
|
self._func = Curvature2DAngleF0D()
|
|
|
|
def __call__(self, inter):
|
|
|
|
angle = math.pi - self._func(inter)
|
2013-04-23 07:06:29 +00:00
|
|
|
if self._angle_min is not None and angle < self._angle_min:
|
2011-11-13 20:20:50 +00:00
|
|
|
return True
|
2013-04-23 07:06:29 +00:00
|
|
|
if self._angle_max is not None and angle > self._angle_max:
|
2011-11-13 20:20:50 +00:00
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2011-12-11 23:41:15 +00:00
|
|
|
class Length2DThresholdUP0D(UnaryPredicate0D):
|
|
|
|
def __init__(self, length_limit):
|
|
|
|
UnaryPredicate0D.__init__(self)
|
|
|
|
self._length_limit = length_limit
|
|
|
|
self._t = 0.0
|
|
|
|
def __call__(self, inter):
|
2013-02-16 14:21:40 +00:00
|
|
|
t = inter.t # curvilinear abscissa
|
2011-12-11 23:41:15 +00:00
|
|
|
if t < self._t:
|
|
|
|
self._t = 0.0
|
|
|
|
return False
|
|
|
|
if t - self._t < self._length_limit:
|
|
|
|
return False
|
|
|
|
self._t = t
|
|
|
|
return True
|
|
|
|
|
2011-08-19 14:05:11 +00:00
|
|
|
# Seed for random number generation
|
|
|
|
|
|
|
|
class Seed:
|
|
|
|
def __init__(self):
|
|
|
|
self.t_max = 2 ** 15
|
|
|
|
self.t = int(time.time()) % self.t_max
|
|
|
|
def get(self, seed):
|
|
|
|
if seed < 0:
|
|
|
|
self.t = (self.t + 1) % self.t_max
|
|
|
|
return self.t
|
|
|
|
return seed
|
|
|
|
|
|
|
|
_seed = Seed()
|
|
|
|
|
2010-08-01 16:02:34 +00:00
|
|
|
# main function for parameter processing
|
|
|
|
|
2010-07-26 01:23:27 +00:00
|
|
|
def process(layer_name, lineset_name):
|
2013-04-07 11:22:54 +00:00
|
|
|
scene = freestyle.getCurrentScene()
|
2010-07-26 01:23:27 +00:00
|
|
|
layer = scene.render.layers[layer_name]
|
|
|
|
lineset = layer.freestyle_settings.linesets[lineset_name]
|
|
|
|
linestyle = lineset.linestyle
|
|
|
|
|
2010-07-28 00:43:45 +00:00
|
|
|
selection_criteria = []
|
|
|
|
# prepare selection criteria by visibility
|
|
|
|
if lineset.select_by_visibility:
|
2013-04-23 07:06:29 +00:00
|
|
|
if lineset.visibility == 'VISIBLE':
|
2010-07-28 00:43:45 +00:00
|
|
|
selection_criteria.append(
|
|
|
|
QuantitativeInvisibilityUP1D(0))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif lineset.visibility == 'HIDDEN':
|
2010-07-28 00:43:45 +00:00
|
|
|
selection_criteria.append(
|
|
|
|
NotUP1D(QuantitativeInvisibilityUP1D(0)))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif lineset.visibility == 'RANGE':
|
2010-07-28 00:43:45 +00:00
|
|
|
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 = []
|
2011-10-27 20:57:14 +00:00
|
|
|
if lineset.select_silhouette:
|
|
|
|
upred = pyNatureUP1D(Nature.SILHOUETTE)
|
|
|
|
edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_silhouette else upred)
|
|
|
|
if lineset.select_border:
|
|
|
|
upred = pyNatureUP1D(Nature.BORDER)
|
|
|
|
edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_border else upred)
|
|
|
|
if lineset.select_crease:
|
|
|
|
upred = pyNatureUP1D(Nature.CREASE)
|
|
|
|
edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_crease else upred)
|
2012-02-05 12:50:01 +00:00
|
|
|
if lineset.select_ridge_valley:
|
2011-10-27 20:57:14 +00:00
|
|
|
upred = pyNatureUP1D(Nature.RIDGE)
|
2012-02-05 12:50:01 +00:00
|
|
|
edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_ridge_valley else upred)
|
2011-10-27 20:57:14 +00:00
|
|
|
if lineset.select_suggestive_contour:
|
|
|
|
upred = pyNatureUP1D(Nature.SUGGESTIVE_CONTOUR)
|
|
|
|
edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_suggestive_contour else upred)
|
|
|
|
if lineset.select_material_boundary:
|
|
|
|
upred = pyNatureUP1D(Nature.MATERIAL_BOUNDARY)
|
|
|
|
edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_material_boundary else upred)
|
|
|
|
if lineset.select_edge_mark:
|
|
|
|
upred = pyNatureUP1D(Nature.EDGE_MARK)
|
|
|
|
edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_edge_mark else upred)
|
2010-07-28 00:43:45 +00:00
|
|
|
if lineset.select_contour:
|
2011-10-27 20:57:14 +00:00
|
|
|
upred = ContourUP1D()
|
|
|
|
edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_contour else upred)
|
2010-07-28 00:43:45 +00:00
|
|
|
if lineset.select_external_contour:
|
2011-10-27 20:57:14 +00:00
|
|
|
upred = ExternalContourUP1D()
|
|
|
|
edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_external_contour else upred)
|
2013-04-23 07:06:29 +00:00
|
|
|
if lineset.edge_type_combination == 'OR':
|
2010-07-28 00:43:45 +00:00
|
|
|
upred = join_unary_predicates(edge_type_criteria, OrUP1D)
|
|
|
|
else:
|
|
|
|
upred = join_unary_predicates(edge_type_criteria, AndUP1D)
|
|
|
|
if upred is not None:
|
2013-04-23 07:06:29 +00:00
|
|
|
if lineset.edge_type_negation == 'EXCLUSIVE':
|
2010-07-28 00:43:45 +00:00
|
|
|
upred = NotUP1D(upred)
|
|
|
|
selection_criteria.append(upred)
|
2011-10-06 02:04:43 +00:00
|
|
|
# prepare selection criteria by face marks
|
|
|
|
if lineset.select_by_face_marks:
|
2013-04-23 07:06:29 +00:00
|
|
|
if lineset.face_mark_condition == 'BOTH':
|
2011-10-06 02:04:43 +00:00
|
|
|
upred = FaceMarkBothUP1D()
|
|
|
|
else:
|
|
|
|
upred = FaceMarkOneUP1D()
|
2013-04-23 07:06:29 +00:00
|
|
|
if lineset.face_mark_negation == 'EXCLUSIVE':
|
2011-10-06 02:04:43 +00:00
|
|
|
upred = NotUP1D(upred)
|
|
|
|
selection_criteria.append(upred)
|
2010-12-02 23:50:10 +00:00
|
|
|
# prepare selection criteria by group of objects
|
|
|
|
if lineset.select_by_group:
|
2012-05-04 00:37:06 +00:00
|
|
|
if lineset.group is not None:
|
2010-12-02 23:50:10 +00:00
|
|
|
names = dict((ob.name, True) for ob in lineset.group.objects)
|
|
|
|
upred = ObjectNamesUP1D(names, lineset.group_negation == 'EXCLUSIVE')
|
|
|
|
selection_criteria.append(upred)
|
2010-12-03 23:17:49 +00:00
|
|
|
# prepare selection criteria by image border
|
|
|
|
if lineset.select_by_image_border:
|
2013-03-15 00:30:20 +00:00
|
|
|
fac = scene.render.resolution_percentage / 100.0
|
|
|
|
w = scene.render.resolution_x * fac
|
|
|
|
h = scene.render.resolution_y * fac
|
2010-12-03 23:17:49 +00:00
|
|
|
if scene.render.use_border:
|
|
|
|
xmin = scene.render.border_min_x * w
|
|
|
|
xmax = scene.render.border_max_x * w
|
|
|
|
ymin = scene.render.border_min_y * h
|
|
|
|
ymax = scene.render.border_max_y * h
|
|
|
|
else:
|
|
|
|
xmin, xmax = 0.0, float(w)
|
|
|
|
ymin, ymax = 0.0, float(h)
|
2012-05-28 23:53:28 +00:00
|
|
|
upred = WithinImageBoundaryUP1D(xmin, ymin, xmax, ymax)
|
2010-12-03 23:17:49 +00:00
|
|
|
selection_criteria.append(upred)
|
2011-09-18 22:59:51 +00:00
|
|
|
# select feature edges
|
2010-07-28 00:43:45 +00:00
|
|
|
upred = join_unary_predicates(selection_criteria, AndUP1D)
|
|
|
|
if upred is None:
|
|
|
|
upred = TrueUP1D()
|
2010-07-26 01:23:27 +00:00
|
|
|
Operators.select(upred)
|
2011-09-18 22:59:51 +00:00
|
|
|
# join feature edges to form chains
|
2011-10-25 23:24:59 +00:00
|
|
|
if linestyle.use_chaining:
|
2013-04-23 07:06:29 +00:00
|
|
|
if linestyle.chaining == 'PLAIN':
|
|
|
|
if linestyle.use_same_object:
|
2013-02-24 02:39:38 +00:00
|
|
|
Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred))
|
2011-10-25 23:24:59 +00:00
|
|
|
else:
|
2013-02-24 02:39:38 +00:00
|
|
|
Operators.bidirectional_chain(ChainPredicateIterator(upred, TrueBP1D()), NotUP1D(upred))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif linestyle.chaining == 'SKETCHY':
|
|
|
|
if linestyle.use_same_object:
|
2013-02-24 02:39:38 +00:00
|
|
|
Operators.bidirectional_chain(pySketchyChainSilhouetteIterator(linestyle.rounds))
|
2011-10-25 23:24:59 +00:00
|
|
|
else:
|
2013-02-24 02:39:38 +00:00
|
|
|
Operators.bidirectional_chain(pySketchyChainingIterator(linestyle.rounds))
|
2011-12-11 23:41:15 +00:00
|
|
|
else:
|
|
|
|
Operators.chain(ChainPredicateIterator(FalseUP1D(), FalseBP1D()), NotUP1D(upred))
|
2011-09-18 22:59:51 +00:00
|
|
|
# split chains
|
|
|
|
if linestyle.material_boundary:
|
2013-02-24 02:39:38 +00:00
|
|
|
Operators.sequential_split(MaterialBoundaryUP0D())
|
2013-04-23 07:06:29 +00:00
|
|
|
if linestyle.use_angle_min or linestyle.use_angle_max:
|
|
|
|
angle_min = linestyle.angle_min if linestyle.use_angle_min else None
|
|
|
|
angle_max = linestyle.angle_max if linestyle.use_angle_max else None
|
|
|
|
Operators.sequential_split(Curvature2DAngleThresholdUP0D(angle_min, angle_max))
|
2011-12-11 23:41:15 +00:00
|
|
|
if linestyle.use_split_length:
|
2013-02-24 02:39:38 +00:00
|
|
|
Operators.sequential_split(Length2DThresholdUP0D(linestyle.split_length), 1.0)
|
2012-11-04 23:52:26 +00:00
|
|
|
if linestyle.use_split_pattern:
|
|
|
|
pattern = []
|
|
|
|
if linestyle.split_dash1 > 0 and linestyle.split_gap1 > 0:
|
|
|
|
pattern.append(linestyle.split_dash1)
|
|
|
|
pattern.append(linestyle.split_gap1)
|
|
|
|
if linestyle.split_dash2 > 0 and linestyle.split_gap2 > 0:
|
|
|
|
pattern.append(linestyle.split_dash2)
|
|
|
|
pattern.append(linestyle.split_gap2)
|
|
|
|
if linestyle.split_dash3 > 0 and linestyle.split_gap3 > 0:
|
|
|
|
pattern.append(linestyle.split_dash3)
|
|
|
|
pattern.append(linestyle.split_gap3)
|
|
|
|
if len(pattern) > 0:
|
|
|
|
sampling = 1.0
|
|
|
|
controller = SplitPatternController(pattern, sampling)
|
2013-02-24 02:39:38 +00:00
|
|
|
Operators.sequential_split(SplitPatternStartingUP0D(controller),
|
|
|
|
SplitPatternStoppingUP0D(controller),
|
|
|
|
sampling)
|
2011-09-18 22:59:51 +00:00
|
|
|
# select chains
|
2013-04-23 07:06:29 +00:00
|
|
|
if linestyle.use_length_min or linestyle.use_length_max:
|
|
|
|
length_min = linestyle.length_min if linestyle.use_length_min else None
|
|
|
|
length_max = linestyle.length_max if linestyle.use_length_max else None
|
|
|
|
Operators.select(LengthThresholdUP1D(length_min, length_max))
|
2010-07-28 00:43:45 +00:00
|
|
|
# prepare a list of stroke shaders
|
2011-08-19 14:05:11 +00:00
|
|
|
shaders_list = []
|
|
|
|
for m in linestyle.geometry_modifiers:
|
|
|
|
if not m.use:
|
|
|
|
continue
|
2013-04-23 07:06:29 +00:00
|
|
|
if m.type == 'SAMPLING':
|
2011-08-19 14:05:11 +00:00
|
|
|
shaders_list.append(SamplingShader(
|
|
|
|
m.sampling))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'BEZIER_CURVE':
|
2011-08-19 14:05:11 +00:00
|
|
|
shaders_list.append(BezierCurveShader(
|
|
|
|
m.error))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'SINUS_DISPLACEMENT':
|
2011-08-19 14:05:11 +00:00
|
|
|
shaders_list.append(SinusDisplacementShader(
|
|
|
|
m.wavelength, m.amplitude, m.phase))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'SPATIAL_NOISE':
|
2011-08-19 14:05:11 +00:00
|
|
|
shaders_list.append(SpatialNoiseShader(
|
2013-04-23 07:06:29 +00:00
|
|
|
m.amplitude, m.scale, m.octaves, m.smooth, m.use_pure_random))
|
|
|
|
elif m.type == 'PERLIN_NOISE_1D':
|
2011-08-30 00:29:12 +00:00
|
|
|
shaders_list.append(PerlinNoise1DShader(
|
|
|
|
m.frequency, m.amplitude, m.octaves, m.angle, _seed.get(m.seed)))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'PERLIN_NOISE_2D':
|
2011-08-30 00:29:12 +00:00
|
|
|
shaders_list.append(PerlinNoise2DShader(
|
|
|
|
m.frequency, m.amplitude, m.octaves, m.angle, _seed.get(m.seed)))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'BACKBONE_STRETCHER':
|
2011-08-19 14:05:11 +00:00
|
|
|
shaders_list.append(BackboneStretcherShader(
|
2011-11-11 20:35:03 +00:00
|
|
|
m.backbone_length))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'TIP_REMOVER':
|
2011-08-19 14:05:11 +00:00
|
|
|
shaders_list.append(TipRemoverShader(
|
|
|
|
m.tip_length))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'POLYGONIZATION':
|
2011-11-01 09:47:41 +00:00
|
|
|
shaders_list.append(PolygonalizationShader(
|
|
|
|
m.error))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'GUIDING_LINES':
|
2011-11-01 09:47:41 +00:00
|
|
|
shaders_list.append(GuidingLinesShader(
|
|
|
|
m.offset))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'BLUEPRINT':
|
|
|
|
if m.shape == 'CIRCLES':
|
2011-11-11 20:35:03 +00:00
|
|
|
shaders_list.append(pyBluePrintCirclesShader(
|
|
|
|
m.rounds, m.random_radius, m.random_center))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.shape == 'ELLIPSES':
|
2011-11-11 20:35:03 +00:00
|
|
|
shaders_list.append(pyBluePrintEllipsesShader(
|
|
|
|
m.rounds, m.random_radius, m.random_center))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.shape == 'SQUARES':
|
2011-11-11 20:35:03 +00:00
|
|
|
shaders_list.append(pyBluePrintSquaresShader(
|
|
|
|
m.rounds, m.backbone_length, m.random_backbone))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == '2D_OFFSET':
|
2012-01-04 00:23:34 +00:00
|
|
|
shaders_list.append(Offset2DShader(
|
|
|
|
m.start, m.end, m.x, m.y))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == '2D_TRANSFORM':
|
2012-01-04 00:23:34 +00:00
|
|
|
shaders_list.append(Transform2DShader(
|
|
|
|
m.pivot, m.scale_x, m.scale_y, m.angle, m.pivot_u, m.pivot_x, m.pivot_y))
|
2010-07-28 00:43:45 +00:00
|
|
|
color = linestyle.color
|
2013-04-23 07:06:29 +00:00
|
|
|
if (not linestyle.use_chaining) or (linestyle.chaining == 'PLAIN' and linestyle.use_same_object):
|
2012-04-08 22:21:48 +00:00
|
|
|
thickness_position = linestyle.thickness_position
|
|
|
|
else:
|
2013-04-23 07:06:29 +00:00
|
|
|
thickness_position = 'CENTER'
|
2013-01-03 23:27:20 +00:00
|
|
|
import bpy
|
|
|
|
if bpy.app.debug_freestyle:
|
2013-04-23 07:06:29 +00:00
|
|
|
print("Warning: Thickness position options are applied when chaining is disabled\n"
|
|
|
|
" or the Plain chaining is used with the Same Object option enabled.")
|
2012-04-07 17:28:09 +00:00
|
|
|
shaders_list.append(BaseColorShader(color.r, color.g, color.b, linestyle.alpha))
|
2012-04-08 22:21:48 +00:00
|
|
|
shaders_list.append(BaseThicknessShader(linestyle.thickness, thickness_position,
|
2012-04-07 17:28:09 +00:00
|
|
|
linestyle.thickness_ratio))
|
2010-07-28 00:43:45 +00:00
|
|
|
for m in linestyle.color_modifiers:
|
2010-10-10 23:34:27 +00:00
|
|
|
if not m.use:
|
2010-07-28 00:43:45 +00:00
|
|
|
continue
|
2013-04-23 07:06:29 +00:00
|
|
|
if m.type == 'ALONG_STROKE':
|
2010-08-01 16:02:34 +00:00
|
|
|
shaders_list.append(ColorAlongStrokeShader(
|
|
|
|
m.blend, m.influence, m.color_ramp))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'DISTANCE_FROM_CAMERA':
|
2010-08-01 16:02:34 +00:00
|
|
|
shaders_list.append(ColorDistanceFromCameraShader(
|
|
|
|
m.blend, m.influence, m.color_ramp,
|
|
|
|
m.range_min, m.range_max))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'DISTANCE_FROM_OBJECT':
|
2010-08-01 22:11:57 +00:00
|
|
|
shaders_list.append(ColorDistanceFromObjectShader(
|
|
|
|
m.blend, m.influence, m.color_ramp, m.target,
|
|
|
|
m.range_min, m.range_max))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'MATERIAL':
|
2011-07-24 23:29:19 +00:00
|
|
|
shaders_list.append(ColorMaterialShader(
|
2013-04-23 07:06:29 +00:00
|
|
|
m.blend, m.influence, m.color_ramp, m.material_attribute,
|
2011-07-24 23:29:19 +00:00
|
|
|
m.use_ramp))
|
2010-07-28 00:43:45 +00:00
|
|
|
for m in linestyle.alpha_modifiers:
|
2010-10-10 23:34:27 +00:00
|
|
|
if not m.use:
|
2010-07-28 00:43:45 +00:00
|
|
|
continue
|
2013-04-23 07:06:29 +00:00
|
|
|
if m.type == 'ALONG_STROKE':
|
2010-08-01 16:02:34 +00:00
|
|
|
shaders_list.append(AlphaAlongStrokeShader(
|
|
|
|
m.blend, m.influence, m.mapping, m.invert, m.curve))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'DISTANCE_FROM_CAMERA':
|
2010-08-01 16:02:34 +00:00
|
|
|
shaders_list.append(AlphaDistanceFromCameraShader(
|
|
|
|
m.blend, m.influence, m.mapping, m.invert, m.curve,
|
|
|
|
m.range_min, m.range_max))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'DISTANCE_FROM_OBJECT':
|
2010-08-01 22:11:57 +00:00
|
|
|
shaders_list.append(AlphaDistanceFromObjectShader(
|
|
|
|
m.blend, m.influence, m.mapping, m.invert, m.curve, m.target,
|
|
|
|
m.range_min, m.range_max))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'MATERIAL':
|
2011-07-24 23:29:19 +00:00
|
|
|
shaders_list.append(AlphaMaterialShader(
|
|
|
|
m.blend, m.influence, m.mapping, m.invert, m.curve,
|
2013-04-23 07:06:29 +00:00
|
|
|
m.material_attribute))
|
2010-07-28 00:43:45 +00:00
|
|
|
for m in linestyle.thickness_modifiers:
|
2010-10-10 23:34:27 +00:00
|
|
|
if not m.use:
|
2010-07-28 00:43:45 +00:00
|
|
|
continue
|
2013-04-23 07:06:29 +00:00
|
|
|
if m.type == 'ALONG_STROKE':
|
2010-08-01 16:02:34 +00:00
|
|
|
shaders_list.append(ThicknessAlongStrokeShader(
|
2012-04-08 22:21:48 +00:00
|
|
|
thickness_position, linestyle.thickness_ratio,
|
2010-08-01 16:02:34 +00:00
|
|
|
m.blend, m.influence, m.mapping, m.invert, m.curve,
|
|
|
|
m.value_min, m.value_max))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'DISTANCE_FROM_CAMERA':
|
2010-08-01 16:02:34 +00:00
|
|
|
shaders_list.append(ThicknessDistanceFromCameraShader(
|
2012-04-08 22:21:48 +00:00
|
|
|
thickness_position, linestyle.thickness_ratio,
|
2010-08-01 16:02:34 +00:00
|
|
|
m.blend, m.influence, m.mapping, m.invert, m.curve,
|
|
|
|
m.range_min, m.range_max, m.value_min, m.value_max))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'DISTANCE_FROM_OBJECT':
|
2010-08-01 22:11:57 +00:00
|
|
|
shaders_list.append(ThicknessDistanceFromObjectShader(
|
2012-04-08 22:21:48 +00:00
|
|
|
thickness_position, linestyle.thickness_ratio,
|
2010-08-01 22:11:57 +00:00
|
|
|
m.blend, m.influence, m.mapping, m.invert, m.curve, m.target,
|
|
|
|
m.range_min, m.range_max, m.value_min, m.value_max))
|
2013-04-23 07:06:29 +00:00
|
|
|
elif m.type == 'MATERIAL':
|
2011-07-24 23:29:19 +00:00
|
|
|
shaders_list.append(ThicknessMaterialShader(
|
2012-04-08 22:21:48 +00:00
|
|
|
thickness_position, linestyle.thickness_ratio,
|
2011-07-24 23:29:19 +00:00
|
|
|
m.blend, m.influence, m.mapping, m.invert, m.curve,
|
2013-04-23 07:06:29 +00:00
|
|
|
m.material_attribute, m.value_min, m.value_max))
|
|
|
|
elif m.type == 'CALLIGRAPHY':
|
2011-09-11 19:57:38 +00:00
|
|
|
shaders_list.append(CalligraphicThicknessShader(
|
2012-04-08 22:21:48 +00:00
|
|
|
thickness_position, linestyle.thickness_ratio,
|
2011-09-11 19:57:38 +00:00
|
|
|
m.blend, m.influence,
|
2013-04-23 07:06:29 +00:00
|
|
|
m.orientation, m.thickness_min, m.thickness_max))
|
|
|
|
if linestyle.caps == 'ROUND':
|
2011-08-22 12:42:56 +00:00
|
|
|
shaders_list.append(RoundCapShader())
|
2013-04-23 07:06:29 +00:00
|
|
|
elif linestyle.caps == 'SQUARE':
|
2011-08-22 12:42:56 +00:00
|
|
|
shaders_list.append(SquareCapShader())
|
2012-11-04 23:52:26 +00:00
|
|
|
if linestyle.use_dashed_line:
|
|
|
|
pattern = []
|
|
|
|
if linestyle.dash1 > 0 and linestyle.gap1 > 0:
|
|
|
|
pattern.append(linestyle.dash1)
|
|
|
|
pattern.append(linestyle.gap1)
|
|
|
|
if linestyle.dash2 > 0 and linestyle.gap2 > 0:
|
|
|
|
pattern.append(linestyle.dash2)
|
|
|
|
pattern.append(linestyle.gap2)
|
|
|
|
if linestyle.dash3 > 0 and linestyle.gap3 > 0:
|
|
|
|
pattern.append(linestyle.dash3)
|
|
|
|
pattern.append(linestyle.gap3)
|
|
|
|
if len(pattern) > 0:
|
|
|
|
shaders_list.append(DashedLineShader(pattern))
|
2010-07-28 00:43:45 +00:00
|
|
|
# create strokes using the shaders list
|
2010-07-26 01:23:27 +00:00
|
|
|
Operators.create(TrueUP1D(), shaders_list)
|