Line styles now have a set of new options for rearranging the stacking order of lines.
This gives artists more control to determine which lines should be drawn on top of others.
Two available sort keys are the distance from camera and curvilinear 2D length.
Since the distance of a line from camera may vary over vertices, another option called
integration type is used to compute the sort key for a line from the values computed at
individual vertices. Available integration types are MEAN, MIN, MAX, FIRST and LAST
(see the tool tips for more detail).
These modifiers were not working properly when they were applied to strokes
whose backbone was already modified by other geometry shaders. This problem
was due to the use of Normal2DF0D that compute 2D vertex normals based on
the underlying FEdges up on which initial stroke geometry is defined. Now vertex
normals are computed on the basis of modified stroke vertices.
A helper function 'stroke_normal' for computing normals of stroke vertices was
added to the 'freestyle.utils' API module.
Additional bug fixes were also done along with the code updates:
* Fix for the use of old Interface1D.pointsBegin() and .pointsEnd() method names
in the definition of pyDensityAnisotropyF1D and pyViewMapGradientNormF1D.
* Fix for wrong data types (int instead of bool) for:
- pyChainSilhouetteGenericIterator constructor and its .orientation property in
modules/freestyle/chainingiterators.py.
- SpatialNoiseShader constructor in styles/external_contour_sketchy.py.
- ChainSilhouetteIterator constructor in styles/multiple_parameterization.py.
Both C- and Python-coded API components were rearranged into logical groups.
New Python modules are packaged as follows:
freestyle - Top-level package
freestyle.types - Classes for core data structues (e.g., view map)
freestyle.chainingiterators - Pre-defined chaining iterators
freestyle.functions - Pre-defined 0D and 1D functions
freestyle.predicates - Pre-defined 0D and 1D predicates
freestyle.shaders - Pre-defined stroke shaders
freestyle.utils - Utility functions
The Python modules are installed in scripts/freestyle/modules. Pre-defined
styles are installed in scripts/freestyle/styles.
To-do: update styles according to the new Freestyle API package structure.
The inner/outer thickness values were separately blended by Multiply, Divide and other binary
operators, which resulted in the wrong thickness values reported in the issue. The operations
must be applied to the sum of the inner and outer thickness values.
Also the Minimum and Maximum operators were not properly implemented (one of the two operands
were ignored by mistake).
Problem report by Light BWK through personal communications, thanks a lot!
Apparently there is something wrong in the way how edges are chained to
create strokes. For some unknown reason, strokes may contain a very small
line segment that proceeds in the opposite direction (e.g., downward
even when adjacent stroke segments proceed upward), resulting in the
reported visual artefact.
This revision is intended to address the reported issue in most cases.
The present solution is not a proper fix of the issue. Another code
update with better understanding of the real cause is due in the future
work.
The reported problem is a visual artefact (extra lines) generated by
ChainingIterators.pySketchyChainingIterator used for sketchy chaining with the Same Object
option disabled in the Parameter Editor mode. The issue is caused by an inconsistency in
the internal data structure (i.e., view map). For now this fatal error condition is addressed
to avoid visually incorrect results. Another fix will follow to address the cause of the
internal inconsistency.
Only the suggested changes that cause backward incompatibility were considered for now.
* Removed pyFXSThicknessShader that is identical with pyConstantThicknessShader.
* Swapped the order of two arguments of the pyDecreasingThicknessShader constructor
in line with other shaders taking the same arguments.
* Made module functions smoothC and get_fedge into methods of relevant shader classes.
* Removed pyExtremitiesOrientationShader that relied on undefined Stroke methods.
The problem was caused by keeping a reference to a Vector object that is
assumed to be unchanged, but actually altered by the geometry modifier.
The same code updates were made to similar code portions to prevent
possible future bugs.
* Fix for wild card import statements (e.g., "from Freestyle import *") was done.
Now import statements are either without using "from" or with all imported names
explicitly listed.
* GNU GPL header blocks were added to Python programs. Additional code clean-up
was also made.
* Removed freestyle_init.py and extra-lines.sml that were no longer used.
* Proper handling of keyword arguments was implemented in Operators and ContextFunctions,
as well as in methods of Interface0D, Interface1D, Iterator, their subclasses, Noise and
IntegrationType.
* Operators' methods and functions in the ContextFunctions module were renamed from
CamelCase to lower cases + underscores. Style modules were updated accordingly.
* Additional code clean-up was also made.
API users no longer need to define them in user-defined Functions, Predicates and StrokeShaders.
Also removed all .getName() and .getExactTypeName() definitions in pre-defined Functions,
Predicates and StrokeShaders subclasses.
Fix for PyGetSetDef and proper handling of keyword arguments were done in
UnaryPredicate0D, UnaryPredicate1D, BinaryPredicate1D, and StrokeShader classes.
Style modules were updated accordingly. Additional code clean-up was also made.
Handling of keyword arguments in Python wrapper class constructors was revised.
This revision is mainly focused on Interface0D, Interface1D, Iterator, and
their subclasses, as well as a few additional view map component classes.
Implementation notes: Because of the extensive use of constructor overloading
in the underlying C++ classes, the corresponding Python wrappers try to parse
arguments through multiple calls of PyArg_ParseTupleAndKeywords() if needed.
The downside of this implementation is that most argument errors result in the
same error message ("invalid argument(s)") without indicating what is wrong.
For now this issue is left for future work.
* Now the instantiation of ViewVertex is prohibited since the underlying
C++ class is an abstract class.
* Removed the .cast_to_interface0diterator() method from CurvePointIterator
and StrokeVertexIterator. Instead the constructor of Interface0DIterator now
accepts the instances of these two iterator classes to construct a nested
Interface0DIterator instance that can be passed to Function0D functor objects.
Specifically, an iterator 'it' is passed to a functor 'func' as follows:
func(Interface0DIterator(it))
instead of:
func(it.cast_to_interface0diterator())
* Boolean arguments of class constructors only accept values of boolean type.
Input values of other types are considered as error.
* Additional code clean-up was made.
Major API updates were made as in part 3 to address code review comments.
This revision focuses on Python wrappers of C++ iterators.
* Most getter/setter methods were reimplemented as attributes using PyGetSetDef.
* 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). The only irregular naming change is the following, to
better indicate the functionality:
- ChainingIterator: getVertex --> next_vertex
* In addition, some code clean-up was done in both C++ and Python. Also duplicated
definitions of predicate classes were removed.
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
The API syntax of FrsMaterial was updated by means of getter/setter properties.
Python style modules (including the Parameter Editor) were updated accordingly.
StrokeAttribute class methods were renamed from camel case to lower case plus underscore.
Also made changes to shaders.pyTVertexOrientationShader that uses the affected methods.
* The API syntax of StrokeVertex and StrokeAttribute was updated by means of getter/setter
properties instead of class methods. Python style modules (including the Parameter Editor
implementation) were updated accordingly.
* Code clean-up was done for a few Python style modules, mostly by removing duplicated
definitions of stroke shaders and fixing indentation.
StrokeVertex.point2d() instead of .getPoint(). It is noted that .point2d()
returns a 3-dimensional vector representing a 2D-projected point, with the z
component indicating a normalized depth of the original 3D point, whereas
.getPoint() returns a plain 2-dimensional vector. This fix should have been
done in revision 48510...
Also made fix for callers of Stroke.Resample() not calling stroke.UpdateLength().
on the console during Freestyle rendering. The debug prints are turned off
by default now. Errors are still printed on the console.
A patch set implementing this functionality was provided by Bastien Montagne.
Many thanks! :)
RNA subtype), since Freestyle internally use angles in radians.
A patch set by Bastien Montagne (many thanks!)
NOTICE FOR BRANCH USERS:
This commit may break line drawing settings of already saved Freestyle files.
All angles are now treated as radians instead of degrees, so collections of
angle values might be necessary in order to recover previous visual results.
Affected properties are:
- Crease Angle in the edge detection options
- Min 2D Angle in the 'Splitting' section of a line style
- Max 2D Angle in the 'Splitting' section of a line style
- 'orientation' parameter of the Calligraphy thickness modifier
- 'angle' parameter of the PerlinNoise1D geometry modifier
- 'angle' parameter of the PerlinNoise2D geometry modifier
- 'angle' parameter of the 2DTransform geometry modifier
when combined with geometry modifiers.
The problem is that users were not able to choose the time when the
dashed line options are applied. Instead, the dashed line options were
applied only before geometry modifiers were employed. Since dashes were
separate strokes, the geometry modifiers were processed dash by dash.
Depending on users' artistic intention, this may or may not lead to
expected stylization results, as reported by octane98 in the
BlenderArtists Freestyle thread on January 3, 2012.
http://blenderartists.org/forum/showthread.php?89986-Freestyle-for-Blender&p=2018592&viewfull=1#post2018592
Now the Strokes tab of the Freestyle Line Style panel has two sets of
dashed line options. One is in the Splitting section of the Strokes tab
and used for splitting strokes by dashed line patterns. The other set
is called "Dashed Line" and used to generate dashed lines based on the
strokes after the geometry modifiers are applied. The two sets of
dashed line options are independent of each other, so that users can
enable one of them as well as both at the same time.
none of the SVertices are within the image boundary but an FEdge intersects with
the image boundary.
The problem was reported by edna through the BA Freestyle thread, with a .blend
file for reproducing the bug. Thanks!