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!
The new options enable a better control on the position of stroke thickness with
respect to stroke backbone geometry. Three predefined positions are:
* center: thickness is evenly split to the left and right side of the stroke geometry.
* inside: strokes are drawn within object boundary.
* outside: strokes are drawn outside the object boundary.
Another option called "relative" allows users to specify the relative position by a
number between 0 (inside) and 1 (outside).
The thickness position options are applied only to strokes of the edge types SILHOUETTE
and BORDER, since these are the only edge types defined in terms of object boundary.
Strokes of other edge types are always using the "center" option.
* Added a new chain splitting option for dividing chains into pieces having
a given curvilinear 2D length.
* Rearranged the UI controls of chain splitting options according to the
actual order of processing.
* Made changes for converting each view edge into a chain in the case of
not using chaining.
relative to the stroke length (i.e., the number of noise displacement
values was the same for strokes of different lengths). This resulted
in very noisy short strokes and much less noisy long strokes. Now the
noise frequency is relative to the distance from the starting point of
a stroke. That is, two strokes of the same length will be distorted
by the same number of noise displacement values, whereas longer strokes
will have more noise displacement values along stroke.
Problem report by JO5EF through the BA Freestyle thread, thank you!
that produces a blueprint using circular, elliptic, and square contour strokes.
Related changes and bug fixes were made as follows:
* The randomness in radius and center has been transformed into optional
parameters of the pyBluePrintCirclesShader and pyBluePrintEllipsesShader.
Also a new optional parameter to control the randomness of backbone
stretching has been added to the pyBluePrintSquaresShader.
* A bug in the pyBluePrintSquaresShader that invisible stroke vertices at
corners of rectangular contour strokes were not properly drawn. The problem
was due to the changes of the / operator between Python 2.x to 3.x. Even
when the two operands of the division operator are integers, Python 3.x
gives a floating-point number when the quotient is not an integer. The fix
was just to replace the / operator by the // operator for integer division.
* An unpleasant discontinuity in circular and elliptical contour strokes
was fixed.
* The length parameter of the Backbone Stretcher geometry modifier has been
renamed to `backbone_length' in line with the parameter of the same name in
the pyBluePrintSquaresShader.
modifications of stroke vertices.
* Fix for a bug in pyBluePrintCirclesShader that did not check the end of
iteration over stroke vertices.
* Fix for stroke vertex removal during iteration over stroke vertices in
pyBluePrintCirclesShader, pyBluePrintEllipsesShader, pyBluePrintSquaresShader,
and pyBluePrintDirectedSquaresShader.
* Stroke::Resample(int nPoints) was not properly working when a wrong
value was returned from Stroke::getLength2D(), resulting in repeated
warning messages "Warning: incorrect points number" during stroke
rendering. The main cause was that stroke geometry shaders did not
update the two-dimensional (2D) length (also referred to as curvilinear
abscissa) after they modified the 2D points of stroke vertices. Now
all stroke geometry shaders make explicit calls for Stroke::UpdateLength()
that has been introduced for recomputing the 2D length. Many thanks to
Josef who reported the problem together with sample .blend files for
reproducing the issue.
* Missing Python wrapper of Stroke::getLength2D() was added.