Age | Commit message (Collapse) | Author |
|
callable(I, T) returns True when I is an object of a type T or
of a subtype of T. Also implemented a measure to avoid an
infinite loop when user-defined predicate and function classes
do not properly overload the __call__ method (including the
cases of directly instantiating the base classes such as
UnaryPredicate0D and BinaryPredicate1D).
|
|
|
|
AdjacencyIterator::isBegin() and AdjacencyIterator::isEnd() always
returned a False value and printed a "not implemented" warning message.
This caused an infinite loop in a few chaining iterators, resulting in
a crash of the program. The origin of the issue seemed to be a fact
that in the C++ layer, the AdjacencyIterator class had not properly
overloaded the definitions of the methods in the Iterator superclass.
The fix here looks okay, although I'm not sure why this inconsistency
was not addressed for a long time.
|
|
Now the following methods in the Freestyle Python API accept
not only Blender.Mathutils.Vector instances but also lists and
tuples having an appropriate number of elements.
FrsNoise::turbulence2()
FrsNoise::turbulence3()
FrsNoise::smoothNoise2()
FrsNoise::smoothNoise3()
SVertex::__init__()
SVertex::setPoint3D()
SVertex::setPoint2D()
SVertex::AddNormal()
FEdgeSharp::setNormalA()
FEdgeSharp::setNormalB()
FEdgeSmooth::setNormal()
CalligraphicShader::__init__()
StrokeAttribute::setAttributeVec2f()
StrokeAttribute::setAttributeVec3f()
StrokeAttribute::setColor()
StrokeVertex::setPoint()
* Added the following converters for the sake of the improvements
mentioned above.
Vec2f_ptr_from_PyObject()
Vec3f_ptr_from_PyObject()
Vec3r_ptr_from_PyObject()
Vec2f_ptr_from_PyList()
Vec3f_ptr_from_PyList()
Vec3r_ptr_from_PyList()
Vec2f_ptr_from_PyTuple()
Vec3f_ptr_from_PyTuple()
Vec3r_ptr_from_PyTuple()
Those converters with the suffixes _PyList and _PyTuple accept
only lists and tuples having an appropriate number of elements,
respectively, while those with the suffix _PyObject accept lists,
tuples, or Blender.Mathutils.Vector instances.
* Fixed a null pointer reference in Interface0D___dealloc__().
* Corrected the names of 3 methods in the FEdgeSmooth class.
|
|
|
|
|
|
blocks in BlenderStrokeRenderer::~BlenderStrokeRenderer().
|
|
in BlenderStrokeRenderer::~BlenderStrokeRenderer().
|
|
|
|
to a specific Python object. The conversion takes place in the following
places.
- Interface0DIterator_getObject (BPy_Interface0DIterator.cpp)
- Director_BPy_BinaryPredicate1D___call__ (Director.cpp)
- Director_BPy_UnaryPredicate1D___call__ (Director.cpp)
- SVertex_viewvertex (BPy_SVertex.cpp)
- BPy_FEdge_from_FEdge (BPy_Convert.cpp)
This is a tentative list and more conversions are expected to be added.
* Added the following two converter functions to BPy_Convert.{cpp,h}:
- BPy_NonTVertex_from_NonTVertex_ptr
- BPy_TVertex_from_TVertex_ptr
|
|
|
|
castToViewVertex method.
|
|
the castToInterface0DIterator method.
|
|
a new file was created or an existing file was loaded.
|
|
|
|
|
|
|
|
positioned at the camera location
|
|
|
|
|
|
Freestyle's pipeline is now fully controllable at the layer level. It can be used:
- in any render layer
- with as many style modules per layer
DETAILS:
Freestyle usage has not changed:
- all the configuration happens in the "Freestyle" render panel, after it is enabled in the "Output" panel with the 'Freestyle' toggle.
- each render layer can choose to render Freestyle strokes by togglingo on 'FrSt' (in the "Render Layers" panel)
- it is fully compatible with compositor nodes
In the "Freestyle" panel, a render layer is selected via the menu list next to the "Render Layer:" label. The options displayed below are those of the currently selected render layer (and are not global to all render layers, as was previously the case).
Style modules are added by pressing the lower button "Add style module". Once added, the following operations are possible:
- deletion (cross)
- reordering (up/down arrows)
- toggling of display (check)
The order of the style modules follows Freestyle's original convention: the modules in the list from top to bottom are respectively the first to the last composited in the render layer. For example, if the module list is "contour" followed by "cartoon", the "cartoon" strokes are rendered on top of the "contour" strokes.
The "Freestyle" panel is constantly synchronized with the "Render Layers" panel: if render layers are added, deleted or toggled off display, Freestyle will take note of the changes.
The current pipeline works as follows:
----------------------------------------------------------------------------------------------
for every scene that is being rendered
if Freestyle is enabled globally
Freestyle is initialized
camera and view settings are transferred from Blender to Freestyle
for every render layer
if: - layer is enabled
- layer enabled Freestyle
- the number of displayed style modules is non-zero
canvas is cleared
geometry is transferred from Blender to Freestyle
settings are fixed for current iteration
view map is calculated
strokes are computed in the canvas (based on view map and style modules)
strokes are rendered in separate Blender scene
scene is composited in current layer
----------------------------------------------------------------------------------------------
A number of changes were made on the codebase:
- the rendering interface between Freestyle and Blender was simplified. The following naming convention was used: functions that are called from within Blender pipeline are prefixed with 'FRS_', while the variables are prefixed with 'freestyle_'
- Freestyle data structures that were put in Blender's render pipeline were removed
- Freestyle cleans up its data structures on Blender exit and shouldn't leak memory
- to ease the configuration in the "Freestyle" panel, a centralized configuration data structure was used and can be easily extended
LIMITATIONS
Even though the current commit is stable and achieves the intended result, it is not as efficient as it could be:
- the canvas and the style modules are at cleared at each layer-level render
- geometry is reloaded at each frame and is duplicated across render layers
This revision clarifies my understanding of the future role of the view map in the compositor. Unfortunately, contrary to what the original proposal said, it is impossible to provide the view map as a render pass because render passes are defined (RE_pipeline.h) as raw floating-point rects. We will have to determine whether or not to extend the notion of render pass to fully integrate the view map in the compositor.
|
|
(tested with gcc version 3.4.5 (mingw-vista special r3), SCons
1.2.0, and Python 2.5.2).
|
|
|
|
True and False but also various other boolean expressions (e.g., 0,
1, and None) are accepted.
|
|
and __call__ methods so that not only True and False but also various
other boolean expressions (e.g., 0, 1, and None) are accepted.
|
|
Now the function results in 0 (radian) if the given Interface0DIterator
object has only 2 vertices, which is not considered an error.
|
|
|
|
|
|
* fixed a bug that was introduced in the last commit.
|
|
|
|
* changed CurvePointIterator::getObject() according to the changes
in revision 19456.
|
|
* Changed BPy_CurvePoint_from_CurvePoint( CurvePoint& cp ) to
BPy_CurvePoint_from_CurvePoint_ptr( CurvePoint *cp ) so that it
retains a CurvePoint pointer instead of a CurvePoint instance.
|
|
|
|
|
|
This will allow style modules to process the underlying color buffer ( AppCanvas::readColorPixels ) and depth buffer ( AppCanvas::readDepthPixels ), as was supported in the original program.
Corrected crash when Freestyle is rendered in "Single" render layer mode (for example, in the compositor)
|
|
compiler warning.
Also made minor changes to make IntegrationType a subclass of the built-in int type.
|
|
Cleaned up comments
|
|
|
|
propagation up to the toplevel error handler in BPY_txt_do_python_Text().
Before these changes were made, the operator() methods of predicates
and functions, for example, returned a value of various types such as
bool, double and Vec2f. These returned values were not capable to
represent an error state in many cases.
Now the operator() methods always return 0 on normal exit and -1 on
error. The original returned values are stored in the "result" member
variables of the predicate/function classes.
This means that if we have a code fragment like below:
UnaryPredicate1D& pred;
Interface1D& inter;
if (pred(inter)) {
/* do something */
}
then we have to rewrite it as follows:
UnaryPredicate1D& pred;
Interface1D& inter;
if (pred(inter) < 0)
return -1; /* an error in pred() is propagated */
if (pred.result) {
/* do something */
}
Suppose that pred is a user-defined predicate in Python, i.e. the predicate
is likely error-prone (especially when debugging the predicate). The first
code fragment shown above prevents the proper error propagation because
the boolean return value of UnaryPredicate1D::operator() cannot inform the
occurrence of an error to the caller; the second code fragment can.
In addition to the operator() methods of predicates and functions, similar
improvements have been made to all other C++ API functions and methods that
are involved in the execution of user-defined Python code snippets. Changes
in the signatures of functions and methods are summarized as follows (note
that all subclasses of listed classes are also subject to the changes).
Old signatures:
virtual void Iterator::increment();
virtual void Iterator::decrement();
virtual void ChainingIterator::init();
virtual ViewEdge * ChainingIterator::traverse(const AdjacencyIterator &it);
static void Operators::select(UnaryPredicate1D& pred);
static void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it,
UnaryPredicate1D& pred, UnaryFunction1D_void& modifier);
static void Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it,
UnaryPredicate1D& pred);
static void Operators::bidirectionalChain(ChainingIterator& it,
UnaryPredicate1D& pred);
static void Operators::bidirectionalChain(ChainingIterator& it);
static void Operators::sequentialSplit(UnaryPredicate0D& startingPred,
UnaryPredicate0D& stoppingPred, float sampling = 0);
static void Operators::sequentialSplit(UnaryPredicate0D& pred, float sampling = 0);
static void Operators::recursiveSplit(UnaryFunction0D<double>& func,
UnaryPredicate1D& pred, float sampling = 0);
static void Operators::recursiveSplit(UnaryFunction0D<double>& func,
UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling = 0);
static void Operators::sort(BinaryPredicate1D& pred);
static void Operators::create(UnaryPredicate1D& pred, vector<StrokeShader*> shaders);
virtual bool UnaryPredicate0D::operator()(Interface0DIterator& it);
virtual bool BinaryPredicate0D::operator()(Interface0D& inter1, Interface0D& inter2);
virtual bool UnaryPredicate1D::operator()(Interface1D& inter);
virtual bool BinaryPredicate1D::operator()(Interface1D& inter1, Interface1D& inter2);
virtual void StrokeShader::shade(Stroke& ioStroke) const;
virtual T UnaryFunction0D::operator()(Interface0DIterator& iter);
virtual T UnaryFunction1D::operator()(Interface1D& inter);
New signatures:
virtual int Iterator::increment();
virtual int Iterator::decrement();
virtual int ChainingIterator::init();
virtual int ChainingIterator::traverse(const AdjacencyIterator &it);
static int Operators::select(UnaryPredicate1D& pred);
static int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it,
UnaryPredicate1D& pred, UnaryFunction1D_void& modifier);
static int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it,
UnaryPredicate1D& pred);
static int Operators::bidirectionalChain(ChainingIterator& it,
UnaryPredicate1D& pred);
static int Operators::bidirectionalChain(ChainingIterator& it);
static int Operators::sequentialSplit(UnaryPredicate0D& startingPred,
UnaryPredicate0D& stoppingPred, float sampling = 0);
static int Operators::sequentialSplit(UnaryPredicate0D& pred, float sampling = 0);
static int Operators::recursiveSplit(UnaryFunction0D<double>& func,
UnaryPredicate1D& pred, float sampling = 0);
static int Operators::recursiveSplit(UnaryFunction0D<double>& func,
UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, float sampling = 0);
static int Operators::sort(BinaryPredicate1D& pred);
static int Operators::create(UnaryPredicate1D& pred, vector<StrokeShader*> shaders);
virtual int UnaryPredicate0D::operator()(Interface0DIterator& it);
virtual int BinaryPredicate0D::operator()(Interface0D& inter1, Interface0D& inter2);
virtual int UnaryPredicate1D::operator()(Interface1D& inter);
virtual int BinaryPredicate1D::operator()(Interface1D& inter1, Interface1D& inter2);
virtual int StrokeShader::shade(Stroke& ioStroke) const;
virtual int UnaryFunction0D::operator()(Interface0DIterator& iter);
virtual int UnaryFunction1D::operator()(Interface1D& inter);
|
|
|
|
|
|
Also exported the Operators.chain() function.
|
|
|
|
|
|
Also changed the type of integration type constants from int to IntegrationType.
|
|
argument.
Now this method accepts 2D coordinates in the following three forms:
a) Python list of 2 real numbers: setPoint([x, y])
b) Blender Vector of 2 elements: setPoint(Vector(x, y))
c) 2 real numbers: setPoint(x, y)
[The log of Revision 19283 had a wrong message...]
|
|
argument.
Now this method accepts 2D coordinates in the following three forms:
a) Python list of 2 real numbers: setPoint([x, y])
b) Blender Vector of 2 elements: setPoint(Vector(x, y))
c) 2 real numbers: setPoint(x, y)
|
|
|
|
Added error handling to prevent crashes even when errors have occurred in user-defined predicates, stroke shaders, and chaining iterators.
|
|
|