forked from bartvdbraak/blender
Merged changes in the trunk up to revision 53280.
This commit is contained in:
commit
40449b1994
@ -1787,33 +1787,57 @@ print_info() {
|
||||
INFO ""
|
||||
INFO "If you're using CMake add this to your configuration flags:"
|
||||
|
||||
_buildargs=""
|
||||
|
||||
if $ALL_STATIC; then
|
||||
INFO " -D WITH_STATIC_LIBS=ON"
|
||||
_1="-D WITH_STATIC_LIBS=ON"
|
||||
INFO " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
fi
|
||||
|
||||
if [ -d $INST/boost ]; then
|
||||
INFO " -D BOOST_ROOT=$INST/boost"
|
||||
INFO " -D Boost_NO_SYSTEM_PATHS=ON"
|
||||
_1="-D BOOST_ROOT=$INST/boost"
|
||||
_2="-D Boost_NO_SYSTEM_PATHS=ON"
|
||||
INFO " $_1"
|
||||
INFO " $_2"
|
||||
_buildargs="$_buildargs $_1 $_2"
|
||||
elif $ALL_STATIC; then
|
||||
INFO " -D Boost_USE_ICU=ON"
|
||||
_1="-D Boost_USE_ICU=ON"
|
||||
INFO " $_1"
|
||||
_buildargs="$_buildargs $_1"
|
||||
fi
|
||||
|
||||
if [ -d $INST/osl -a $WITH_OSL == true ]; then
|
||||
INFO " -D CYCLES_OSL=$INST/osl"
|
||||
INFO " -D WITH_CYCLES_OSL=ON"
|
||||
INFO " -D LLVM_VERSION=$LLVM_VERSION_FOUND"
|
||||
_1="-D CYCLES_OSL=$INST/osl"
|
||||
_2="-D WITH_CYCLES_OSL=ON"
|
||||
_3="-D LLVM_VERSION=$LLVM_VERSION_FOUND"
|
||||
INFO " $_1"
|
||||
INFO " $_2"
|
||||
INFO " $_3"
|
||||
_buildargs="$_buildargs $_1 $_2 $_3"
|
||||
if [ -d $INST/llvm ]; then
|
||||
INFO " -D LLVM_DIRECTORY=$INST/llvm"
|
||||
INFO " -D LLVM_STATIC=ON"
|
||||
_1="-D LLVM_DIRECTORY=$INST/llvm"
|
||||
_2="-D LLVM_STATIC=ON"
|
||||
INFO " $_1"
|
||||
INFO " $_2"
|
||||
_buildargs="$_buildargs $_1 $_2"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d $INST/ffmpeg ]; then
|
||||
INFO " -D WITH_CODEC_FFMPEG=ON"
|
||||
INFO " -D FFMPEG=$INST/ffmpeg"
|
||||
INFO " -D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;rt;`print_info_ffmpeglink`'"
|
||||
_1="-D WITH_CODEC_FFMPEG=ON"
|
||||
_2="-D FFMPEG=$INST/ffmpeg"
|
||||
_3="-D FFMPEG_LIBRARIES='avformat;avcodec;avutil;avdevice;swscale;rt;`print_info_ffmpeglink`'"
|
||||
INFO " $_1"
|
||||
INFO " $_2"
|
||||
INFO " $_3"
|
||||
_buildargs="$_buildargs $_1 $_2 $_3"
|
||||
fi
|
||||
|
||||
INFO ""
|
||||
INFO "Or even simpler, just run (in your build dir):"
|
||||
INFO " make -j$THREADS BUILD_CMAKE_ARGS=\"$_buildargs\""
|
||||
|
||||
INFO ""
|
||||
INFO "If you're using SCons add this to your user-config:"
|
||||
|
||||
@ -1832,6 +1856,7 @@ print_info() {
|
||||
|
||||
if [ -d $INST/boost ]; then
|
||||
INFO "BF_BOOST = '$INST/boost'"
|
||||
INFO "WITH_BF_BOOST = True"
|
||||
fi
|
||||
|
||||
if [ -d $INST/ffmpeg ]; then
|
||||
|
@ -103,7 +103,7 @@ WITH_BF_FFTW3 = True
|
||||
WITH_BF_STATICFFTW3 = True
|
||||
|
||||
# JACK
|
||||
WITH_BF_JACK = True
|
||||
WITH_BF_JACK = False
|
||||
WITH_BF_STATICJACK = True
|
||||
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
|
||||
|
||||
|
@ -103,7 +103,7 @@ WITH_BF_FFTW3 = True
|
||||
WITH_BF_STATICFFTW3 = True
|
||||
|
||||
# JACK
|
||||
WITH_BF_JACK = True
|
||||
WITH_BF_JACK = False
|
||||
WITH_BF_STATICJACK = True
|
||||
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
|
||||
|
||||
|
@ -92,7 +92,7 @@ WITH_BF_FFTW3 = True
|
||||
WITH_BF_STATICFFTW3 = True
|
||||
|
||||
# JACK
|
||||
WITH_BF_JACK = True
|
||||
WITH_BF_JACK = False
|
||||
|
||||
# Cycles
|
||||
WITH_BF_CYCLES = True
|
||||
|
@ -92,7 +92,7 @@ WITH_BF_FFTW3 = True
|
||||
WITH_BF_STATICFFTW3 = True
|
||||
|
||||
# JACK
|
||||
WITH_BF_JACK = True
|
||||
WITH_BF_JACK = False
|
||||
|
||||
# Cycles
|
||||
WITH_BF_CYCLES = True
|
||||
|
@ -103,7 +103,7 @@ BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBP
|
||||
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
|
||||
|
||||
# JACK
|
||||
WITH_BF_JACK = True
|
||||
WITH_BF_JACK = False
|
||||
WITH_BF_STATICJACK = True
|
||||
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
|
||||
|
||||
|
@ -103,7 +103,7 @@ BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBP
|
||||
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
|
||||
|
||||
# JACK
|
||||
WITH_BF_JACK = True
|
||||
WITH_BF_JACK = False
|
||||
WITH_BF_STATICJACK = True
|
||||
BF_JACK_LIB_STATIC = '${BF_ZLIB}/lib/libjack.a'
|
||||
|
||||
|
@ -98,7 +98,7 @@ BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBP
|
||||
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
|
||||
|
||||
# JACK
|
||||
WITH_BF_JACK = True
|
||||
WITH_BF_JACK = False
|
||||
|
||||
# Motion Tracking
|
||||
WITH_BF_LIBMV = False
|
||||
|
@ -98,7 +98,7 @@ BF_BOOST_LIB_STATIC = '${BF_BOOST_LIBPATH}/libboost_filesystem.a ${BF_BOOST_LIBP
|
||||
BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
|
||||
|
||||
# JACK
|
||||
WITH_BF_JACK = True
|
||||
WITH_BF_JACK = False
|
||||
|
||||
# Motion Tracking
|
||||
WITH_BF_LIBMV = False
|
||||
|
@ -47,10 +47,10 @@ def get_version():
|
||||
|
||||
if (ver_base is not None) and (ver_char is not None) and (ver_cycle is not None):
|
||||
# eg '2.56a-beta'
|
||||
if ver_cycle:
|
||||
if ver_cycle != "release":
|
||||
ver_display = "%s%s-%s" % (ver_base, ver_char, ver_cycle)
|
||||
else:
|
||||
ver_display = "%s%s" % (ver_base, ver_char) # assume release
|
||||
ver_display = "%s%s" % (ver_base, ver_char)
|
||||
|
||||
return ver_base, ver_display, ver_cycle
|
||||
|
||||
|
@ -125,6 +125,10 @@ Variables
|
||||
|
||||
The current mouse wrapped in an :class:`~bge.types.SCA_PythonMouse` object.
|
||||
|
||||
.. data:: joysticks
|
||||
|
||||
A list of attached joysticks. The list size it he maximum number of supported joysticks. If no joystick is available for a given slot, the slot is set to None.
|
||||
|
||||
*****************
|
||||
General functions
|
||||
*****************
|
||||
@ -172,7 +176,7 @@ General functions
|
||||
|
||||
Restarts the current game by reloading the .blend file (the last saved version, not what is currently running).
|
||||
|
||||
.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False, load_scripts=True)
|
||||
.. function:: LibLoad(blend, type, data, load_actions=False, verbose=False, load_scripts=True, async=False)
|
||||
|
||||
Converts the all of the datablocks of the given type from the given blend.
|
||||
|
||||
@ -187,7 +191,13 @@ General functions
|
||||
:arg verbose: Whether or not to print debugging information (e.g., "SceneName: Scene")
|
||||
:type verbose: bool
|
||||
:arg load_scripts: Whether or not to load text datablocks as well (can be disabled for some extra security)
|
||||
:type load_scripts: bool
|
||||
:type load_scripts: bool
|
||||
:arg async: Whether or not to do the loading asynchronously (in another thread). Only the "Scene" type is currently supported for this feature.
|
||||
:type async: bool
|
||||
|
||||
:rtype: :class:`bge.types.KX_LibLoadStatus`
|
||||
|
||||
.. note:: Asynchronously loaded libraries will not be available immediately after LibLoad() returns. Use the returned KX_LibLoadStatus to figure out when the libraries are ready.
|
||||
|
||||
.. function:: LibNew(name, type, data)
|
||||
|
||||
|
@ -141,6 +141,74 @@ Types
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. class:: SCA_PythonJoystick(PyObjectPlus)
|
||||
|
||||
A Python interface to a joystick.
|
||||
|
||||
.. attribute:: name
|
||||
|
||||
The name assigned to the joystick by the operating system. (read-only)
|
||||
|
||||
:type: string
|
||||
|
||||
.. attribute:: activeButtons
|
||||
|
||||
A list of active button values. (read-only)
|
||||
|
||||
:type: list
|
||||
|
||||
.. attribute:: axisValues
|
||||
|
||||
The state of the joysticks axis as a list of values :data:`numAxis` long. (read-only).
|
||||
|
||||
:type: list of ints.
|
||||
|
||||
Each specifying the value of an axis between -1.0 and 1.0 depending on how far the axis is pushed, 0 for nothing.
|
||||
The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls.
|
||||
|
||||
* left:[-1.0, 0.0, ...]
|
||||
* right:[1.0, 0.0, ...]
|
||||
* up:[0.0, -1.0, ...]
|
||||
* down:[0.0, 1.0, ...]
|
||||
|
||||
.. attribute:: hatValues
|
||||
|
||||
The state of the joysticks hats as a list of values :data:`numHats` long. (read-only).
|
||||
|
||||
:type: list of ints
|
||||
|
||||
Each specifying the direction of the hat from 1 to 12, 0 when inactive.
|
||||
|
||||
Hat directions are as follows...
|
||||
|
||||
* 0:None
|
||||
* 1:Up
|
||||
* 2:Right
|
||||
* 4:Down
|
||||
* 8:Left
|
||||
* 3:Up - Right
|
||||
* 6:Down - Right
|
||||
* 12:Down - Left
|
||||
* 9:Up - Left
|
||||
|
||||
.. attribute:: numAxis
|
||||
|
||||
The number of axes for the joystick at this index. (read-only).
|
||||
|
||||
:type: integer
|
||||
|
||||
.. attribute:: numButtons
|
||||
|
||||
The number of buttons for the joystick at this index. (read-only).
|
||||
|
||||
:type: integer
|
||||
|
||||
.. attribute:: numHats
|
||||
|
||||
The number of hats for the joystick at this index. (read-only).
|
||||
|
||||
:type: integer
|
||||
|
||||
.. class:: SCA_IObject(CValue)
|
||||
|
||||
This class has no python functions
|
||||
@ -1861,6 +1929,44 @@ Types
|
||||
|
||||
:type: boolean
|
||||
|
||||
.. class:: KX_LibLoadStatus(PyObjectPlus)
|
||||
|
||||
An object providing information about a LibLoad() operation.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Print a message when an async LibLoad is done
|
||||
import bge
|
||||
|
||||
def finished_cb(status):
|
||||
print("Library (%s) loaded in %.2fms." % (status.libraryName, status.timeTaken))
|
||||
|
||||
bge.logic.LibLoad('myblend.blend', 'Scene', async=True).onFinish = finished_cb
|
||||
|
||||
.. attribute:: onFinish
|
||||
|
||||
A callback that gets called when the lib load is done.
|
||||
|
||||
:type: callable
|
||||
|
||||
.. attribute:: progress
|
||||
|
||||
The current progress of the lib load as a normalized value from 0.0 to 1.0.
|
||||
|
||||
:type: float
|
||||
|
||||
.. attribute:: libraryName
|
||||
|
||||
The name of the library being loaded (the first argument to LibLoad).
|
||||
|
||||
:type: string
|
||||
|
||||
.. attribute:: timeTaken
|
||||
|
||||
The amount of time, in seconds, the lib load took (0 until the operation is complete).
|
||||
|
||||
:type: float
|
||||
|
||||
.. class:: KX_LightObject(KX_GameObject)
|
||||
|
||||
A Light object.
|
||||
@ -3977,7 +4083,7 @@ Types
|
||||
|
||||
:type: list of ints.
|
||||
|
||||
Each spesifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing.
|
||||
Each specifying the value of an axis between -32767 and 32767 depending on how far the axis is pushed, 0 for nothing.
|
||||
The first 2 values are used by most joysticks and gamepads for directional control. 3rd and 4th values are only on some joysticks and can be used for arbitary controls.
|
||||
|
||||
* left:[-32767, 0, ...]
|
||||
@ -4001,7 +4107,7 @@ Types
|
||||
|
||||
:type: list of ints
|
||||
|
||||
Each spesifying the direction of the hat from 1 to 12, 0 when inactive.
|
||||
Each specifying the direction of the hat from 1 to 12, 0 when inactive.
|
||||
|
||||
Hat directions are as follows...
|
||||
|
||||
|
4
extern/libmv/CMakeLists.txt
vendored
4
extern/libmv/CMakeLists.txt
vendored
@ -47,9 +47,9 @@ set(SRC
|
||||
libmv/multiview/conditioning.cc
|
||||
libmv/multiview/euclidean_resection.cc
|
||||
libmv/multiview/fundamental.cc
|
||||
libmv/multiview/homography.cc
|
||||
libmv/multiview/projection.cc
|
||||
libmv/multiview/triangulation.cc
|
||||
libmv/multiview/homography.cc
|
||||
libmv/numeric/numeric.cc
|
||||
libmv/numeric/poly.cc
|
||||
libmv/simple_pipeline/bundle.cc
|
||||
@ -71,8 +71,8 @@ set(SRC
|
||||
libmv/tracking/lmicklt_region_tracker.cc
|
||||
libmv/tracking/pyramid_region_tracker.cc
|
||||
libmv/tracking/retrack_region_tracker.cc
|
||||
libmv/tracking/trklt_region_tracker.cc
|
||||
libmv/tracking/track_region.cc
|
||||
libmv/tracking/trklt_region_tracker.cc
|
||||
|
||||
third_party/fast/fast_10.c
|
||||
third_party/fast/fast_11.c
|
||||
|
800
extern/libmv/ChangeLog
vendored
800
extern/libmv/ChangeLog
vendored
@ -1,3 +1,487 @@
|
||||
commit cfabdfe48df2add3d1f30cf4370efd0b31990ab0
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 20 05:46:53 2012 +0600
|
||||
|
||||
Assorted fixes for keyframe selection:
|
||||
|
||||
- Biggest error was in cost functors used for F and H refirement,
|
||||
they were just wrong.
|
||||
|
||||
- Use natural logarithms, since it's actually makes sense from
|
||||
math papers point of view and error is somewhere else.
|
||||
|
||||
- Disabled rho for GRIC, for now use non-clamped error for tests.
|
||||
|
||||
- Made SymmetricEpipolarDistance returning non-squared distance
|
||||
Keyframe selection is currently the only used of this function
|
||||
and it seems using non-squared distance makes much more sense.
|
||||
|
||||
Also would think to append suffix "Squared" to functions which
|
||||
returns squared distances.
|
||||
|
||||
- Removed templated version of SymmetricEpipolarDistance, since
|
||||
it's not needed actually.
|
||||
|
||||
This is actually even worse working than previous implementation,
|
||||
but commit it needed for further review.
|
||||
|
||||
commit 35d8c57626ad74818f155e6e5960c663ea84e032
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 20 03:00:40 2012 +0600
|
||||
|
||||
Euclidean resection cost function didn't use correct constructor
|
||||
|
||||
It was storing a reference to initial rotation passed by value,
|
||||
leading to pointer being pointing to a stack variable, leading to
|
||||
wrong memory access in residuals computing.
|
||||
|
||||
Apparently was visible in optimized builds only with inline
|
||||
substitution allowed.
|
||||
|
||||
commit 0798d3162bb49cee7e1c423ceccbca1326ad5650
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 20 02:50:52 2012 +0600
|
||||
|
||||
Automatic keyframe selection based on Pollefeys's criteria
|
||||
|
||||
This commit implements automatic keyframe selection algorithm
|
||||
based on Pollefeys's criteria (F-GRIC is smaller than H-GRIC
|
||||
and correspondence ratio is more then 90%).
|
||||
|
||||
It is implemented as a part of simple pipeline and returns
|
||||
vector of keyframe images for a given Tracks structure.
|
||||
|
||||
For simple pipeline reconstruction two best keyframes are
|
||||
expected to be selected from all detected candidates.
|
||||
Criteria for this selection could be reprojection error of
|
||||
solution from two candidate keyfames.
|
||||
|
||||
Unfortunately, it's not fully workable yet, hopefully would
|
||||
be fixed soon.
|
||||
|
||||
commit e943985552f0598ae122252876f305d72c25c2f9
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 6 17:47:11 2012 +0600
|
||||
|
||||
Camera Tracking: allow fallback to reprojection resection
|
||||
by user demand
|
||||
|
||||
This fixes some "regressions" introduced in previous commit
|
||||
which lead to much worse solution in some cases. Now it's
|
||||
possible to bring old behavior back.
|
||||
|
||||
Perhaps it's more like temporal solution for time being smarter
|
||||
solution is found. But finding such a solution isn't so fast,
|
||||
so let's bring manual control over reprojection usage.
|
||||
|
||||
But anyway, imo it's now nice to have a structure which could
|
||||
be used to pass different settings to the solver.
|
||||
|
||||
commit 5a23d01dd531d1e0798298d17ba42a3397effb82
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu Sep 20 18:55:44 2012 +0000
|
||||
|
||||
Make Euclidean resection "always" succeed.
|
||||
|
||||
The Euclidean resection code had a magical constant, 1e-3, used to
|
||||
compare the results of solving an equation. This failure detection
|
||||
was well-intended, trying to prevent poor solutions from getting
|
||||
made without notifying the caller. Unfortunately in practice, this
|
||||
threshold is too conservative. Furthermore, it is not clear the
|
||||
threshold should exist at all; the purpose of the Euclidean
|
||||
resection is to come up with the best solution it can; other
|
||||
methods (e.g. reprojection error) should be used to compare
|
||||
whether the method succeeded.
|
||||
|
||||
This commit changes the Euclidean EPnP code to always succeed,
|
||||
causing the previous fallback to projective resection to never
|
||||
run. In most cases, this will result in better reconstructions.
|
||||
|
||||
This should, in most cases, fix the dreaded "flipping" problem.
|
||||
|
||||
commit 57dad861d2a7f9d058c6d8edde1a2d51d7225a51
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu Sep 20 02:27:34 2012 +0000
|
||||
|
||||
Fix variable naming in the planar tracker.
|
||||
|
||||
commit e9392fd3b46f5668662935696e7d9afac3390ca4
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu Sep 20 02:10:33 2012 +0000
|
||||
|
||||
Add smarter tolerance checking in the planar tracker.
|
||||
|
||||
The planar tracker uses Ceres for the refinement stage. During
|
||||
refinement, Ceres iteratively updates the parameters with the
|
||||
latest best guess. If the change in the parameters falls below a
|
||||
threshold, Ceres will abort successfully ("converged").
|
||||
|
||||
For the case of pure translation tracking, the parameters are
|
||||
exactly the two pixel shifts (dx, dy), and measuring the change in
|
||||
these parameters gives a meaningful termination criterion.
|
||||
However, for all the other parameterizations like affine, where
|
||||
the parameterization involves affine parameters that have no
|
||||
physical interpretation, Ceres is left with no way to terminate
|
||||
the solver early. With the existing code, often many iterations
|
||||
are run long after Ceres has found a solution sufficiently
|
||||
accurate for all tracking needs. No one needs tracking with
|
||||
a quadrillionth of a pixel accuracy; that time is wasted.
|
||||
|
||||
This patch extends the existing iteration callback that is passed
|
||||
in to Ceres to check if the pattern has fallen out of the search
|
||||
window, to also check if the optimizer has made a tiny step. In
|
||||
particular, if the maximum shift of any patch corner between two
|
||||
successful optimizer steps is less than a threshold (currently
|
||||
0.005 pixels), the track is declared successful and tracking
|
||||
is terminated.
|
||||
|
||||
This leads to dramatic speed increases in some cases, with little
|
||||
to no loss in track quality. This is especially apparent when
|
||||
tracking patches with affine or perspective motion models. For
|
||||
example, on some tracking cases I tried, the iterations Ceres took
|
||||
went from 50 to 3.
|
||||
|
||||
commit 36729c19bf90cb767e9adb96ba7dd48a5ace2be1
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Wed Sep 19 22:25:02 2012 +0000
|
||||
|
||||
Detect too-small planar tracking patches.
|
||||
|
||||
The planar tracker did not detect very skinny patches which have
|
||||
effectively zero area and are untrackable. This adds detection and
|
||||
rejection of patterns with zero area. This fixes a crash found by
|
||||
during Mango production.
|
||||
|
||||
commit 5cf2bae255a5a0f2e36ea0516670782cb88b589d
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 6 17:33:53 2012 +0600
|
||||
|
||||
Real fix for previous commit from Keir. He's comment;
|
||||
|
||||
Cleanup for when trackers fall out of the search window.
|
||||
|
||||
Sergey originally left a TODO() here, but his fix is the correct
|
||||
one. I removed the TODO and fixed some comment issues.
|
||||
|
||||
commit a11533918720e5b43dc1e95895db0eb36c8c06aa
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 6 17:31:16 2012 +0600
|
||||
|
||||
Fix crash when tracking in planar motion model (and maybe some other)
|
||||
|
||||
It was an Abort() caused by check for solver result not equal to USER_ABORT.
|
||||
|
||||
In some cases solver returns USER_ABORT due to BoundaryCheckingCallback
|
||||
detects coordinates does not belong to image.
|
||||
|
||||
Somehow this callback wasn't called in previous version of Ceres and
|
||||
in the same case marker was jumping. Now when the callback is called
|
||||
it seems we could simply return failure of tracking without aborting
|
||||
Blender.
|
||||
|
||||
Probably this is in fact some issue somewhere else, would double
|
||||
check with Keir about this.
|
||||
|
||||
commit 4be2306bcc664b259aaf7068b9f32ab60124a509
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 6 17:29:39 2012 +0600
|
||||
|
||||
Resolved some compilation warnings (missed prototypes)
|
||||
|
||||
In some cases it was missed include of header file, in some other
|
||||
cases symbol could be static.
|
||||
|
||||
commit bef729ba5c12683d13584d2a728b8b6506b7ca90
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 6 17:27:17 2012 +0600
|
||||
|
||||
Code cleanup: silence some -Wnarrowing warnings from C++11
|
||||
|
||||
commit add1415d896818367087c784a3013dd8f1bb2095
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 6 17:25:18 2012 +0600
|
||||
|
||||
Changes to SamplePlanarPatch to support mask input and
|
||||
added output for pattern center.
|
||||
|
||||
commit daa354c0735b954b0cd7725626e9a3d67416d46b
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Sat Jun 9 19:22:39 2012 +0000
|
||||
|
||||
Change libmv's bilinear sampling to assume the same
|
||||
pixel conventions as Blender. This fixes the preview
|
||||
widget in Blender, and should make tracking slightly
|
||||
more accurate.
|
||||
|
||||
commit 99b6222873fbfbe248316316956720376a58f438
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Sat Jun 9 18:58:51 2012 +0000
|
||||
|
||||
Add new warp regularization scheme for planar tracking.
|
||||
|
||||
This adds a new term to the tracking cost function that
|
||||
restricts how much the optimizer can warp the patch (as
|
||||
opposed to merely adjusting the translation). This should
|
||||
reduce the "jumpiness" that is sometimes seen when doing
|
||||
non-"Loc" tracks.
|
||||
|
||||
It is disabled in this commit; a subsequent commit will add
|
||||
controls to the tracking dialog for this.
|
||||
|
||||
commit a1c5a70badd11cba0470700bad2eac2b2bd30c86
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Sat Jun 9 06:55:21 2012 +0000
|
||||
|
||||
Planar tracker polish.
|
||||
|
||||
- Fixes the correlation checking code that was broken in the
|
||||
previous commit. The bug was a transpose error.
|
||||
- Fixes a memory leak of the warp functor, found by Sameer.
|
||||
- Various cleanups done at Sameer's suggestion.
|
||||
|
||||
Thanks to Sameer Agarwal for a code review.
|
||||
|
||||
commit 2cb784caa854a77cdd43620ab133f26b87ed0d83
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri Jun 8 17:42:17 2012 +0000
|
||||
|
||||
Make planar tracking much faster.
|
||||
|
||||
- This makes planar tracking around 2-3x or more faster than
|
||||
before, by rearranging how the sampling is done.
|
||||
Previously, the source patch was sampled repeatedly on
|
||||
every optimizer iteration; this was done for
|
||||
implementation speed, but was wasteful in computation.
|
||||
|
||||
- This also contains some additions to Ceres to help
|
||||
deailing with mixed numeric / automatic differentation. In
|
||||
particular, there is now a "Chain::Rule" operator that
|
||||
facilitates calling a function that takes Jet arguments,
|
||||
yet does numeric derivatives internally. This is used to
|
||||
mix the numeric differentation of the images with the warp
|
||||
parameters, passed as jets by Ceres to the warp functor.
|
||||
|
||||
There is also a new "JetOps" object for doing operations
|
||||
on types which may or may not be jets, such as scaling
|
||||
the derivative part only, or extracting the scalar part
|
||||
of a jet.
|
||||
|
||||
This patche is aimed at Ceres upstream.
|
||||
|
||||
- A new function for sampling a patch is now part of the
|
||||
track_region.h API; this will get used to make the preview
|
||||
widget properly show what is getting tracked. Currently
|
||||
the preview widget does not handle perspective tracks.
|
||||
|
||||
Known issues:
|
||||
|
||||
This patch introduces a bug such that the "Minimum
|
||||
Correlation" flag does not work; if it is enabled, tracking
|
||||
aborts immediately. The workaround for now is to disable the
|
||||
correlation checking, and examine your tracks carefully. A
|
||||
fix will get added shortly.
|
||||
|
||||
commit 81d028f13738ebe2304287dfce90e91bc782e2cf
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri May 18 20:04:43 2012 +0000
|
||||
|
||||
Remove an unnecessary template<> line in libmv. Convert debug logs to LG.
|
||||
|
||||
commit 238aaba241ef99995d254aadc974db719da04b96
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri May 18 12:05:10 2012 +0000
|
||||
|
||||
Support normalization in the tracking prepass
|
||||
|
||||
The last tracker commit added normalized tracking. This makes
|
||||
tracking patches undergoing uniform illumination change easier.
|
||||
However, the prepass which computes a quick translation-only
|
||||
estimate of the warp did not take this into account. This commit
|
||||
fixes that.
|
||||
|
||||
This works reasonably well but in some examples the brute
|
||||
initialization fails. I suspect this is due to the warped template
|
||||
estimate in the current frame being too different from the
|
||||
original, so there are multiple peaks in the normalized-SAD
|
||||
correlation function.
|
||||
|
||||
The solution is to use the previous frame for the brute
|
||||
initialization and the keyframe for refinement, but that requires
|
||||
architecture changes.
|
||||
|
||||
commit 981ca4f6a679cd9ac3d086eae3cd946ce72ca8a5
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri May 18 02:12:47 2012 +0000
|
||||
|
||||
Add light-normalized tracking to the planar tracker
|
||||
|
||||
This commit adds the ability to normalize patterns by their
|
||||
average value while tracking, to make them invariant to global
|
||||
illumination changes.
|
||||
|
||||
To see this in action, check out the "Lobby" scene from Hollywood
|
||||
VFX. If you track the markers that are shadowed by the actress,
|
||||
previously they would not track. With the scale adaption on, the
|
||||
tracker would shrink the area to compensate for the changed
|
||||
illumination, losing the track. With "Normalize" turned on, the
|
||||
patch is correctly tracked and scale is maintained.
|
||||
|
||||
A remaining problem is that only the Ceres cost function is
|
||||
updated to handle the normalization. The brute translation search
|
||||
does not take this into account. Perhaps "Prepass" (see below)
|
||||
should get disabled if normalization is enabled until I fix the
|
||||
prepass to normalize as well.
|
||||
|
||||
There are a few other changes:
|
||||
|
||||
- Bail out of the sampling loop early if the mask is zero; this
|
||||
saves expensive samples of the image derivatives.
|
||||
|
||||
- Fix a bug where the mask was ignored when sampling in the cost
|
||||
functor.
|
||||
|
||||
commit e9384b15fb2a6a5b81346d5758fa136f0911e945
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu May 17 23:53:32 2012 +0000
|
||||
|
||||
Implement support for affine tracking in the planar tracker; cleanups.
|
||||
|
||||
commit 021d41eed8b4ce6a4e37786ccd357ed5dc83a13f
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu May 17 21:26:06 2012 +0000
|
||||
|
||||
For the planar tracker, initialize the warp from the four correspondences
|
||||
after brute force translation search.
|
||||
|
||||
commit 003d1bf6145cfd30938b35f6e10d43708dbf916c
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 6 16:56:01 2012 +0600
|
||||
|
||||
Correction to region tracker options initialization.
|
||||
|
||||
Based on patch from Keir to Blender:
|
||||
https://svn.blender.org/svnroot/bf-blender/branches/soc-2011-tomato@46743
|
||||
|
||||
commit 6af47b218cfdf5219f0ebb3cb95459817cf9abf2
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Thu May 17 02:31:52 2012 +0000
|
||||
|
||||
Add new planar tracker features and use the new planar API
|
||||
|
||||
This commit removes the use of the legacy RegionTracker API from
|
||||
Blender, and replaces it with the new TrackRegion API. This also
|
||||
adds several features to the planar tracker in libmv:
|
||||
|
||||
- Do a brute-force initialization of tracking similar to "Hybrid"
|
||||
mode in the stable release, but using all floats. This is slower
|
||||
but more accurate. It is still necessary to evaluate if the
|
||||
performance loss is worth it. In particular, this change is
|
||||
necessary to support high bit depth imagery.
|
||||
|
||||
- Add support for masks over the search window. This is a step
|
||||
towards supporting user-defined tracker masks. The tracker masks
|
||||
will make it easy for users to make a mask for e.g. a ball.
|
||||
|
||||
- Add Pearson product moment correlation coefficient checking (aka
|
||||
"Correlation" in the UI. This causes tracking failure if the
|
||||
tracked patch is not linearly related to the template.
|
||||
|
||||
- Add support for warping a few points in addition to the supplied
|
||||
points. This is useful because the tracking code deliberately
|
||||
does not expose the underlying warp representation. Instead,
|
||||
warps are specified in an aparametric way via the correspondences.
|
||||
|
||||
- Remove the "num_samples_xy" concept and replace it with
|
||||
automatic determination of the number of samples. This makes the
|
||||
API easier for users.
|
||||
|
||||
- Fix various bugs in the parameterizations.
|
||||
|
||||
There remains a bug with subpixel precision tracking when in
|
||||
"keyframe" mode; this will get fixed shortly.
|
||||
|
||||
commit 16a46db104468cec80bd31ca9d5f8bffbe3e003e
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Mon May 14 12:15:38 2012 +0000
|
||||
|
||||
"Efficient Second-order Minimization" for the planar tracker
|
||||
|
||||
This implements the "Efficient Second-order Minimization"
|
||||
scheme, as supported by the existing translation tracker.
|
||||
This increases the amount of per-iteration work, but
|
||||
decreases the number of iterations required to converge and
|
||||
also increases the size of the basin of attraction for the
|
||||
optimization.
|
||||
|
||||
commit 23243b1b1f3e1ab3ef862b47bca06ee876ac2cf4
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Sun May 13 23:08:56 2012 +0000
|
||||
|
||||
Add a planar tracking implementation to libmv
|
||||
|
||||
This adds a new planar tracking implementation to libmv. The
|
||||
tracker is based on Ceres[1], the new nonlinear minimizer that
|
||||
myself and Sameer released from Google as open source. Since
|
||||
the motion model is more involved, the interface is
|
||||
different than the RegionTracker interface used previously
|
||||
in Blender.
|
||||
|
||||
The ESM tracker, also known as the KLT tracker in the UI, is
|
||||
temporarily changed to use the new Ceres-based planar
|
||||
tracker in translation-only mode. Currently it is a bit
|
||||
slower than ESM and also doesn't have all the bells and
|
||||
whistles implemented. Those will come soon. Longer term,
|
||||
both trackers will remain since Ceres is unlikely to be as
|
||||
fast as ESM for pure translation solving, due to its
|
||||
generality.
|
||||
|
||||
The next step is to implement a new tracking UI. The current
|
||||
UI assumes a translational motion model; the new one must
|
||||
support arbitrary perspective transforms of the pattern
|
||||
regions.
|
||||
|
||||
[1] http://code.google.com/p/ceres-solver
|
||||
|
||||
commit 52be92b53eb4decb1a316690b162196f227cc441
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Thu Dec 6 16:06:08 2012 +0600
|
||||
|
||||
Initial Ceres integration
|
||||
|
||||
Currently only put sources to src/third_party/ceres and made sure they're
|
||||
not giving compilation issues.
|
||||
|
||||
Used Ceres upstream version 1.3.0.
|
||||
|
||||
Needed to make some modifications to it's CMakeLists.txt also to glog and
|
||||
fglags. They're described in README.libmv of this libraries.
|
||||
|
||||
Basically:
|
||||
|
||||
- Added -fPIC to glog/gflags, so shared ceres library could be linked
|
||||
statically against this libraries.
|
||||
|
||||
- Tweaked Ceres's build rules to use needed libraries from libmv's
|
||||
third_party folder.
|
||||
|
||||
commit b13f9d13122e091cb85855c2094386ccdef6e5a4
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Wed Dec 5 19:05:34 2012 +0600
|
||||
|
||||
Update Eigen to version 3.1.2
|
||||
|
||||
Mainly because of lots of warnings generating by gcc-4.7 which are
|
||||
resolved in newer eigen version.
|
||||
|
||||
commit 1f0dd94e8e37d3fe2df89282ec16a6a685fdde0b
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri May 25 16:36:44 2012 +0600
|
||||
|
||||
- Added avutil to qt-tracker linking when building with FFmpeg support.
|
||||
On some platforms it seems to be required
|
||||
- Synchronized QT Creator project for qt-tracker with changes in sources,
|
||||
so no it might be compiled from QT Creator.
|
||||
|
||||
commit b813dbe3f46bbbc7e73ac791d4665622e4fc7ba5
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Wed May 9 19:01:10 2012 +0600
|
||||
@ -238,319 +722,3 @@ Date: Fri Feb 17 20:08:01 2012 +0600
|
||||
SAD tracker now can deal with pattern size any size,
|
||||
Very quick implementation came from Blender before Hybrid tracker was added.
|
||||
Better to be replaced with brute tracker.
|
||||
|
||||
commit d547c9cfe37d5d3397d33c8b0e58471e1e1c1634
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 20:03:52 2012 +0600
|
||||
|
||||
Just convert end of lines to unix style.
|
||||
|
||||
commit eb73ddbaec5b9e1ad30331bbf858a6ebc266c4aa
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 20:02:20 2012 +0600
|
||||
|
||||
Made some function static. Resolves possible linking issues when building with MinGW.
|
||||
|
||||
commit 2930681fafd86e4f4a958054b1db8bfff29623d1
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 19:59:45 2012 +0600
|
||||
|
||||
Missed this in commit with improvements in camera intrinsics.
|
||||
|
||||
commit 8d31bc767019b05c5bf8c9f309f9545b3428afa1
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 19:57:51 2012 +0600
|
||||
|
||||
Another step of syncing codebase with Blender.
|
||||
Mainly fixes for freebsd/osx compilation and aligned memory allocation.
|
||||
|
||||
commit 3214a2df5bfd98021f25d0f1a626a86318bb245f
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 19:48:02 2012 +0600
|
||||
|
||||
Support compilation on FreeBSD platform
|
||||
|
||||
commit 0e5abe96f543687ccfb3a923ec639cb8f45d54f8
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 19:44:18 2012 +0600
|
||||
|
||||
Implementation of basic system for progress reporting into callee stuff
|
||||
|
||||
Implemented by using simple callbacks classes which are getting invoked from
|
||||
places where lots of calculation happens, so applications which are using
|
||||
libmv may display nice progress bar.
|
||||
|
||||
commit c5e18fe35464618055e0e9761be8d22fae56db49
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri Feb 17 19:25:45 2012 +0600
|
||||
|
||||
Add support for detecting tracking failure in the ESM tracker component of
|
||||
libmv. Since both KLT and Hybrid rely on ESM underneath, KLT and Hybrid now
|
||||
have a minimum correlation setting to match. With this fix, track failures
|
||||
should get detected quicker, with the issue that sometimes the tracker will
|
||||
give up too easily. That is fixable by reducing the required correlation (in
|
||||
the track properties).
|
||||
|
||||
commit ea0fed736ecdcc8c020227aeef8ef4cd3be5e63d
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri Feb 17 19:23:50 2012 +0600
|
||||
|
||||
Add a new hybrid region tracker for motion tracking to libmv, and
|
||||
add it as an option (under "Hybrid") in the tracking settings. The
|
||||
region tracker is a combination of brute force tracking for coarse
|
||||
alignment, then refinement with the ESM/KLT algorithm already in
|
||||
libmv that gives excellent subpixel precision (typically 1/50'th
|
||||
of a pixel)
|
||||
|
||||
This also adds a new "brute force" region tracker which does a
|
||||
brute force search through every pixel position in the destination
|
||||
for the pattern in the first frame. It leverages SSE if available,
|
||||
similar to the SAD tracker, to do this quickly. Currently it does
|
||||
some unnecessary conversions to/from floating point that will get
|
||||
fixed later.
|
||||
|
||||
The hybrid tracker glues the two trackers (brute & ESM) together
|
||||
to get an overall better tracker. The algorithm is simple:
|
||||
|
||||
1. Track from frame 1 to frame 2 with the brute force tracker.
|
||||
This tries every possible pixel position for the pattern from
|
||||
frame 1 in frame 2. The position with the smallest
|
||||
sum-of-absolute-differences is chosen. By definition, this
|
||||
position is only accurate up to 1 pixel or so.
|
||||
2. Using the result from 1, initialize a track with ESM. This does
|
||||
a least-squares fit with subpixel precision.
|
||||
3. If the ESM shift was more than 2 pixels, report failure.
|
||||
4. If the ESM track shifted less than 2 pixels, then the track is
|
||||
good and we're done. The rationale here is that if the
|
||||
refinement stage shifts more than 1 pixel, then the brute force
|
||||
result likely found some random position that's not a good fit.
|
||||
|
||||
commit a07fff8431621c01d81ae52595d8dd91a295a776
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri Feb 17 19:19:58 2012 +0600
|
||||
|
||||
Assorted camera tracker improvements
|
||||
|
||||
- Add support for refining the camera's intrinsic parameters
|
||||
during a solve. Currently, refining supports only the following
|
||||
combinations of intrinsic parameters:
|
||||
|
||||
f
|
||||
f, cx, cy
|
||||
f, cx, cy, k1, k2
|
||||
f, k1
|
||||
f, k1, k2
|
||||
|
||||
This is not the same as autocalibration, since the user must
|
||||
still make a reasonable initial guess about the focal length and
|
||||
other parameters, whereas true autocalibration would eliminate
|
||||
the need for the user specify intrinsic parameters at all.
|
||||
|
||||
However, the solver works well with only rough guesses for the
|
||||
focal length, so perhaps full autocalibation is not that
|
||||
important.
|
||||
|
||||
Adding support for the last two combinations, (f, k1) and (f,
|
||||
k1, k2) required changes to the library libmv depends on for
|
||||
bundle adjustment, SSBA. These changes should get ported
|
||||
upstream not just to libmv but to SSBA as well.
|
||||
|
||||
- Improved the region of convergence for bundle adjustment by
|
||||
increasing the number of Levenberg-Marquardt iterations from 50
|
||||
to 500. This way, the solver is able to crawl out of the bad
|
||||
local minima it gets stuck in when changing from, for example,
|
||||
bundling k1 and k2 to just k1 and resetting k2 to 0.
|
||||
|
||||
- Add several new region tracker implementations. A region tracker
|
||||
is a libmv concept, which refers to tracking a template image
|
||||
pattern through frames. The impact to end users is that tracking
|
||||
should "just work better". I am reserving a more detailed
|
||||
writeup, and maybe a paper, for later.
|
||||
|
||||
- Other libmv tweaks, such as detecting that a tracker is headed
|
||||
outside of the image bounds.
|
||||
|
||||
This includes several changes made directly to the libmv extern
|
||||
code rather expecting to get those changes through normal libmv
|
||||
channels, because I, the libmv BDFL, decided it was faster to work
|
||||
on libmv directly in Blender, then later reverse-port the libmv
|
||||
changes from Blender back into libmv trunk. The interesting part
|
||||
is that I added a full Levenberg-Marquardt loop to the region
|
||||
tracking code, which should lead to a more stable solutions. I
|
||||
also added a hacky implementation of "Efficient Second-Order
|
||||
Minimization" for tracking, which works nicely. A more detailed
|
||||
quantitative evaluation will follow.
|
||||
|
||||
commit 0bf66c009d5022eacfc473d247884a73ffeefa8f
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 19:13:49 2012 +0600
|
||||
|
||||
Rest of compilation fix with FAST library.
|
||||
|
||||
commit 71b578ca2ba34c528363c514cd1fcc85791d01f3
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri Feb 17 19:00:28 2012 +0600
|
||||
|
||||
Improve the KLT tracking behaviour and UI
|
||||
|
||||
- Remove the overly-conservative use of libmv's re-track tracker. The re-track
|
||||
tracker would take a normal tracker such as TRKLT or KLT or pyramid KLT, and
|
||||
track from frame 1 to 2, then back from the position found in 2 back to 1.
|
||||
Then, when the reverse-track doesn't match the original track with high
|
||||
precision, the track is considered "failed". This is a good approach for
|
||||
fully automatic reconstruction, but is too conservative for supervised
|
||||
tracking.
|
||||
|
||||
The retrack-tracker will return when fully automatic tracking is added.
|
||||
|
||||
- Always solve for (dx, dy) in the TRKLT loop even if the linear system is
|
||||
ill-conditioned. The client (Blender in this case) can still use the solved
|
||||
position, even though it is less reliable.
|
||||
|
||||
commit 7d8a8762f2bc2e36f95b0b6f4fb4ca996f9f0db7
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 18:46:24 2012 +0600
|
||||
|
||||
Changes in camera intrinsics distortion/undistortion:
|
||||
|
||||
- Distortion/undistortion of scaled images wasn't happening right,
|
||||
because camera intrinsics are calibrated on an original frame which
|
||||
has got some particular resolution and trying to apply this model on
|
||||
an image with another resolution gives totally wrong result.
|
||||
This is needed to be able to do post-prccessing of render, running
|
||||
distortion on a scene which might be rendered with higher resolution
|
||||
than footage itself and then be scaled down.
|
||||
- Fixed incorrect calculation/applying of precomputed grid when
|
||||
distortion is high high enough and produces pixel offset higher
|
||||
than 127 pixels. This might be still not very distorted image,
|
||||
but if it's a 4K footage "normal" camera will easily give such
|
||||
a distortion.
|
||||
- Added support of overscan distortion/undistortion.
|
||||
|
||||
commit ed080785d63bb8e3a13dde51a2dc94fe59b059bb
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 18:38:51 2012 +0600
|
||||
|
||||
Fast headers now can be included from C++ sources.
|
||||
Was needed to make it working fine when bundling in Blender but might also
|
||||
be needed to bundle into another applications.
|
||||
|
||||
commit 5f5a7aa46a2d87b96c8098dfc8682f4d01b5cd40
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 18:36:16 2012 +0600
|
||||
|
||||
Bring back FAST detector which seems to be working much nicer than Morravec.
|
||||
Both of them are available in API.
|
||||
|
||||
commit 2cab13c18216fb684b270cec077f7300262584af
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 18:27:36 2012 +0600
|
||||
|
||||
Revert "Make CameraIntrinsics (and thus Qt tracker) compilable without linking libmv."
|
||||
|
||||
This reverts commit 81613ee0cc94b315f333c9632b18b95d426aad05.
|
||||
|
||||
That commit made inverting intrinsics totally unworkable, so reverted this and
|
||||
made needed tweaks to qt-tracker project file to make it compilable (was needed
|
||||
to make it linking together with glog).
|
||||
|
||||
Conflicts:
|
||||
|
||||
src/ui/tracker/tracker.cc
|
||||
src/ui/tracker/tracker.pro
|
||||
|
||||
commit ec46cae041401b17afb4fe4d9c9343d10797090f
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 17:59:55 2012 +0600
|
||||
|
||||
Fix compilation error using official MinGW
|
||||
|
||||
commit 6fbc370e922c47cfa35381662b6c439f4891ed74
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 17:38:20 2012 +0600
|
||||
|
||||
Fix compilation error with MSVC 2010 which is more picky for "missed" STL headers
|
||||
|
||||
commit be9e6b63691d83b551a085f0766878bd84220767
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 17:36:18 2012 +0600
|
||||
|
||||
Fix compilation with MSVC where snprintf function is declared as unsafe and _snprintf should be used instead.
|
||||
|
||||
Better to switch to own implementation will ensure string is correctly NULL-terminated.
|
||||
|
||||
commit 1847d9e414ed763cd80668775d7d9f79575fc8ca
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 17:34:45 2012 +0600
|
||||
|
||||
Fix compilation error on OSX caused by incorrect access to ucontext
|
||||
|
||||
commit 90579b6ffad07672172a1c240499615b30b25549
|
||||
Merge: b9aac30 531c79b
|
||||
Author: Sergey Sharybin <sergey.vfx@gmail.com>
|
||||
Date: Fri Feb 17 18:32:52 2012 +0600
|
||||
|
||||
Merge remote-tracking branch 'Matthias-Fauconneau/master' into devel
|
||||
|
||||
Conflicts:
|
||||
src/libmv/tracking/CMakeLists.txt
|
||||
|
||||
commit b9aac30a9ca6bc8362c09a0e191040964f7c6de2
|
||||
Merge: 198894e 6969e1a
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Sat Nov 5 17:38:30 2011 -0700
|
||||
|
||||
Merge pull request #3 from nathanwiegand/master
|
||||
|
||||
Just a few tiny cleanups
|
||||
|
||||
commit 6969e1a9534291a982749baa5a3672c97bfa506d
|
||||
Author: Nathan Wiegand <nathanwiegand@gmail.com>
|
||||
Date: Sat Nov 5 14:26:54 2011 -0700
|
||||
|
||||
I've added cleaned up a few style issues here an there. Also, I've updated the CMakeLists.txt file so that it can build the image_io library. Note, it's only been tested on OSX 10.6
|
||||
|
||||
commit 4763f851299050140757bfaa069107a0cf639e56
|
||||
Author: Nathan Wiegand <nathanwiegand@gmail.com>
|
||||
Date: Fri Nov 4 23:59:08 2011 -0700
|
||||
|
||||
Removed a superfulous comment
|
||||
|
||||
commit a44577c0162e273681e4a9a3cc5f5b37d4315b67
|
||||
Author: Nathan Wiegand <nathanwiegand@gmail.com>
|
||||
Date: Fri Nov 4 23:55:52 2011 -0700
|
||||
|
||||
Removed a duplicate entry for an author.
|
||||
|
||||
commit 198894e4c4f51c2c1784ad7c02eb45d2d1ada9bc
|
||||
Merge: c4c67db 6e797d6
|
||||
Author: Keir Mierle <mierle@gmail.com>
|
||||
Date: Fri Nov 4 21:47:05 2011 -0700
|
||||
|
||||
Merge pull request #2 from nathanwiegand/master
|
||||
|
||||
CMake changes for OSX
|
||||
|
||||
commit 6e797d678c4c19f6a9e21657d66183f412cc995b
|
||||
Author: Nathan Wiegand <nathanwiegand@gmail.com>
|
||||
Date: Fri Nov 4 21:43:28 2011 -0700
|
||||
|
||||
Uncomment the GUI part of the CMake file
|
||||
|
||||
commit 33ef88a33860345d8906f3c9dd22d8dbce3df53e
|
||||
Author: Nathan Wiegand <nathanwiegand@gmail.com>
|
||||
Date: Fri Nov 4 21:31:22 2011 -0700
|
||||
|
||||
Fixed build error on OSX by adding 'glog' to the dependencies in the tracker CMake
|
||||
|
||||
commit 531c79bf95fddaaa70707d1abcd4fdafda16bbf0
|
||||
Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
|
||||
Date: Sat Aug 20 00:00:42 2011 +0200
|
||||
|
||||
Display warped pattern in marker preview.
|
||||
|
||||
commit bb5c27e671b6f8eb56ddf490f0795d59bede591b
|
||||
Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
|
||||
Date: Fri Aug 19 18:37:48 2011 +0200
|
||||
|
||||
Fix CMake build.
|
||||
|
13
extern/libmv/bundle.sh
vendored
13
extern/libmv/bundle.sh
vendored
@ -136,19 +136,6 @@ set(INC_SYS
|
||||
\${ZLIB_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
|
||||
# XXX - FIXME
|
||||
# this is a momentary hack to find unwind.h in 10.6.sdk
|
||||
if(APPLE)
|
||||
if(\${CMAKE_OSX_DEPLOYMENT_TARGET} STREQUAL "10.6")
|
||||
list(APPEND INC_SYS
|
||||
\${CMAKE_OSX_SYSROOT}/Developer/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin10/4.2.1/include
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
# XXX - END
|
||||
|
||||
|
||||
set(SRC
|
||||
libmv-capi.cpp
|
||||
${sources}
|
||||
|
5
extern/libmv/files.txt
vendored
5
extern/libmv/files.txt
vendored
@ -17,6 +17,9 @@ libmv/multiview/euclidean_resection.cc
|
||||
libmv/multiview/euclidean_resection.h
|
||||
libmv/multiview/fundamental.cc
|
||||
libmv/multiview/fundamental.h
|
||||
libmv/multiview/homography.cc
|
||||
libmv/multiview/homography.h
|
||||
libmv/multiview/homography_parameterization.h
|
||||
libmv/multiview/nviewtriangulation.h
|
||||
libmv/multiview/projection.cc
|
||||
libmv/multiview/projection.h
|
||||
@ -69,6 +72,8 @@ libmv/tracking/pyramid_region_tracker.h
|
||||
libmv/tracking/region_tracker.h
|
||||
libmv/tracking/retrack_region_tracker.cc
|
||||
libmv/tracking/retrack_region_tracker.h
|
||||
libmv/tracking/track_region.cc
|
||||
libmv/tracking/track_region.h
|
||||
libmv/tracking/trklt_region_tracker.cc
|
||||
libmv/tracking/trklt_region_tracker.h
|
||||
third_party/fast/fast_10.c
|
||||
|
4
extern/libmv/libmv/multiview/fundamental.cc
vendored
4
extern/libmv/libmv/multiview/fundamental.cc
vendored
@ -254,8 +254,8 @@ double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2) {
|
||||
Vec3 Ft_y = F.transpose() * y;
|
||||
double y_F_x = y.dot(F_x);
|
||||
|
||||
return Square(y_F_x) * ( 1 / F_x.head<2>().squaredNorm()
|
||||
+ 1 / Ft_y.head<2>().squaredNorm());
|
||||
return y_F_x * ( 1 / F_x.head<2>().norm()
|
||||
+ 1 / Ft_y.head<2>().norm());
|
||||
}
|
||||
|
||||
// HZ 9.6 pag 257 (formula 9.12)
|
||||
|
@ -31,22 +31,6 @@
|
||||
namespace libmv {
|
||||
namespace {
|
||||
|
||||
void CoordinatesForMarkersInImage(const vector<Marker> &markers,
|
||||
int image,
|
||||
Mat *coordinates) {
|
||||
vector<Vec2> coords;
|
||||
for (int i = 0; i < markers.size(); ++i) {
|
||||
const Marker &marker = markers[i];
|
||||
if (markers[i].image == image) {
|
||||
coords.push_back(Vec2(marker.x, marker.y));
|
||||
}
|
||||
}
|
||||
coordinates->resize(2, coords.size());
|
||||
for (int i = 0; i < coords.size(); i++) {
|
||||
coordinates->col(i) = coords[i];
|
||||
}
|
||||
}
|
||||
|
||||
void GetImagesInMarkers(const vector<Marker> &markers,
|
||||
int *image1, int *image2) {
|
||||
if (markers.size() < 2) {
|
||||
|
26
extern/libmv/libmv/simple_pipeline/tracks.cc
vendored
26
extern/libmv/libmv/simple_pipeline/tracks.cc
vendored
@ -72,6 +72,16 @@ vector<Marker> Tracks::MarkersForTrack(int track) const {
|
||||
return markers;
|
||||
}
|
||||
|
||||
vector<Marker> Tracks::MarkersInBothImages(int image1, int image2) const {
|
||||
vector<Marker> markers;
|
||||
for (int i = 0; i < markers_.size(); ++i) {
|
||||
int image = markers_[i].image;
|
||||
if (image == image1 || image == image2)
|
||||
markers.push_back(markers_[i]);
|
||||
}
|
||||
return markers;
|
||||
}
|
||||
|
||||
vector<Marker> Tracks::MarkersForTracksInBothImages(int image1, int image2) const {
|
||||
std::vector<int> image1_tracks;
|
||||
std::vector<int> image2_tracks;
|
||||
@ -156,4 +166,20 @@ int Tracks::NumMarkers() const {
|
||||
return markers_.size();
|
||||
}
|
||||
|
||||
void CoordinatesForMarkersInImage(const vector<Marker> &markers,
|
||||
int image,
|
||||
Mat *coordinates) {
|
||||
vector<Vec2> coords;
|
||||
for (int i = 0; i < markers.size(); ++i) {
|
||||
const Marker &marker = markers[i];
|
||||
if (markers[i].image == image) {
|
||||
coords.push_back(Vec2(marker.x, marker.y));
|
||||
}
|
||||
}
|
||||
coordinates->resize(2, coords.size());
|
||||
for (int i = 0; i < coords.size(); i++) {
|
||||
coordinates->col(i) = coords[i];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace libmv
|
||||
|
8
extern/libmv/libmv/simple_pipeline/tracks.h
vendored
8
extern/libmv/libmv/simple_pipeline/tracks.h
vendored
@ -22,6 +22,7 @@
|
||||
#define LIBMV_SIMPLE_PIPELINE_TRACKS_H_
|
||||
|
||||
#include "libmv/base/vector.h"
|
||||
#include "libmv/numeric/numeric.h"
|
||||
|
||||
namespace libmv {
|
||||
|
||||
@ -84,6 +85,9 @@ class Tracks {
|
||||
/// Returns all the markers visible in \a image.
|
||||
vector<Marker> MarkersInImage(int image) const;
|
||||
|
||||
/// Returns all the markers visible in \a image1 and \a image2.
|
||||
vector<Marker> MarkersInBothImages(int image1, int image2) const;
|
||||
|
||||
/*!
|
||||
Returns the markers in \a image1 and \a image2 which have a common track.
|
||||
|
||||
@ -114,6 +118,10 @@ class Tracks {
|
||||
vector<Marker> markers_;
|
||||
};
|
||||
|
||||
void CoordinatesForMarkersInImage(const vector<Marker> &markers,
|
||||
int image,
|
||||
Mat *coordinates);
|
||||
|
||||
} // namespace libmv
|
||||
|
||||
#endif // LIBMV_SIMPLE_PIPELINE_MARKERS_H_
|
||||
|
2
extern/libmv/third_party/gflags/README.libmv
vendored
2
extern/libmv/third_party/gflags/README.libmv
vendored
@ -11,4 +11,6 @@ Local modifications:
|
||||
- Added a poor-man's version of upstream's port.cc/h to make gflags compile on
|
||||
windows. This isn't sufficient but is a stopgap for now.
|
||||
|
||||
- Added -fPIC flag, so shared libraries from Ceres could be linked against static glog
|
||||
|
||||
TODO(keir): Import and use gflags for Windows from upstream.
|
||||
|
1
extern/libmv/third_party/glog/README.libmv
vendored
1
extern/libmv/third_party/glog/README.libmv
vendored
@ -22,3 +22,4 @@ Upgrading Notes
|
||||
* Do not define va_copy for MinGW platforms (it's already defined there).
|
||||
* Patch localtime_r to be working fine with MinGW, disable strerror_r for MinGW because
|
||||
of lack of needed functions.
|
||||
* Added -fPIC flag, so shared libraries from Ceres could be linked against static glog
|
||||
|
@ -68,7 +68,7 @@ if(WITH_CYCLES_BLENDER)
|
||||
add_subdirectory(blender)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_TEST)
|
||||
if(WITH_CYCLES_TEST OR WITH_CYCLES_NETWORK)
|
||||
add_subdirectory(app)
|
||||
endif()
|
||||
|
||||
|
@ -23,7 +23,9 @@
|
||||
#include "util_args.h"
|
||||
#include "util_foreach.h"
|
||||
#include "util_path.h"
|
||||
#include "util_stats.h"
|
||||
#include "util_string.h"
|
||||
#include "util_task.h"
|
||||
|
||||
using namespace ccl;
|
||||
|
||||
@ -32,29 +34,29 @@ int main(int argc, const char **argv)
|
||||
path_init();
|
||||
|
||||
/* device types */
|
||||
string devices = "";
|
||||
string devicelist = "";
|
||||
string devicename = "cpu";
|
||||
bool list = false;
|
||||
|
||||
vector<DeviceType>& types = Device::available_types();
|
||||
|
||||
foreach(DeviceType type, types) {
|
||||
if(devices != "")
|
||||
devices += ", ";
|
||||
if(devicelist != "")
|
||||
devicelist += ", ";
|
||||
|
||||
devices += Device::string_from_type(type);
|
||||
devicelist += Device::string_from_type(type);
|
||||
}
|
||||
|
||||
/* parse options */
|
||||
ArgParse ap;
|
||||
|
||||
ap.options ("Usage: cycles_server [options]",
|
||||
"--device %s", &devicename, ("Devices to use: " + devices).c_str(),
|
||||
"--device %s", &devicename, ("Devices to use: " + devicelist).c_str(),
|
||||
"--list-devices", &list, "List information about all available devices",
|
||||
NULL);
|
||||
|
||||
if(ap.parse(argc, argv) < 0) {
|
||||
fprintf(stderr, "%s\n", ap.error_message().c_str());
|
||||
fprintf(stderr, "%s\n", ap.geterror().c_str());
|
||||
ap.usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -84,13 +86,18 @@ int main(int argc, const char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
TaskScheduler::init();
|
||||
|
||||
while(1) {
|
||||
Device *device = Device::create(device_info);
|
||||
printf("Cycles Server with device: %s\n", device->description().c_str());
|
||||
Stats stats;
|
||||
Device *device = Device::create(device_info, stats);
|
||||
printf("Cycles Server with device: %s\n", device->info.description.c_str());
|
||||
device->server_run();
|
||||
delete device;
|
||||
}
|
||||
|
||||
TaskScheduler::exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -331,7 +331,13 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
|
||||
/* device default CPU */
|
||||
params.device = devices[0];
|
||||
|
||||
if(RNA_enum_get(&cscene, "device") != 0) {
|
||||
if(RNA_enum_get(&cscene, "device") == 2) {
|
||||
/* find network device */
|
||||
foreach(DeviceInfo& info, devices)
|
||||
if(info.type == DEVICE_NETWORK)
|
||||
params.device = info;
|
||||
}
|
||||
else if(RNA_enum_get(&cscene, "device") == 1) {
|
||||
/* find GPU device with given id */
|
||||
PointerRNA systemptr = b_userpref.system().ptr;
|
||||
PropertyRNA *deviceprop = RNA_struct_find_property(&systemptr, "compute_device");
|
||||
|
@ -31,6 +31,8 @@ class NetworkDevice : public Device
|
||||
public:
|
||||
boost::asio::io_service io_service;
|
||||
tcp::socket socket;
|
||||
device_ptr mem_counter;
|
||||
DeviceTask the_task; /* todo: handle multiple tasks */
|
||||
|
||||
NetworkDevice(Stats &stats, const char *address)
|
||||
: Device(stats), socket(io_service)
|
||||
@ -49,75 +51,72 @@ public:
|
||||
socket.close();
|
||||
socket.connect(*endpoint_iterator++, error);
|
||||
}
|
||||
|
||||
if(error)
|
||||
throw boost::system::system_error(error);
|
||||
|
||||
mem_counter = 0;
|
||||
}
|
||||
|
||||
~NetworkDevice()
|
||||
{
|
||||
RPCSend snd(socket, "stop");
|
||||
snd.write();
|
||||
}
|
||||
|
||||
void mem_alloc(device_memory& mem, MemoryType type)
|
||||
{
|
||||
#if 0
|
||||
mem.device_pointer = ++mem_counter;
|
||||
|
||||
RPCSend snd(socket, "mem_alloc");
|
||||
|
||||
snd.archive & size & type;
|
||||
snd.add(mem);
|
||||
snd.add(type);
|
||||
snd.write();
|
||||
|
||||
RPCReceive rcv(socket);
|
||||
|
||||
device_ptr mem;
|
||||
*rcv.archive & mem;
|
||||
|
||||
return mem;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mem_copy_to(device_memory& mem)
|
||||
{
|
||||
#if 0
|
||||
RPCSend snd(socket, "mem_copy_to");
|
||||
|
||||
snd.archive & mem & size;
|
||||
snd.add(mem);
|
||||
snd.write();
|
||||
snd.write_buffer(host, size);
|
||||
#endif
|
||||
snd.write_buffer((void*)mem.data_pointer, mem.memory_size());
|
||||
}
|
||||
|
||||
void mem_copy_from(device_memory& mem, int y, int w, int h, int elem)
|
||||
{
|
||||
#if 0
|
||||
RPCSend snd(socket, "mem_copy_from");
|
||||
|
||||
snd.archive & mem & offset & size;
|
||||
snd.add(mem);
|
||||
snd.add(y);
|
||||
snd.add(w);
|
||||
snd.add(h);
|
||||
snd.add(elem);
|
||||
snd.write();
|
||||
|
||||
RPCReceive rcv(socket);
|
||||
rcv.read_buffer(host, size);
|
||||
#endif
|
||||
rcv.read_buffer((void*)mem.data_pointer, mem.memory_size());
|
||||
}
|
||||
|
||||
void mem_zero(device_memory& mem)
|
||||
{
|
||||
#if 0
|
||||
RPCSend snd(socket, "mem_zero");
|
||||
|
||||
snd.archive & mem & size;
|
||||
snd.add(mem);
|
||||
snd.write();
|
||||
#endif
|
||||
}
|
||||
|
||||
void mem_free(device_memory& mem)
|
||||
{
|
||||
#if 0
|
||||
if(mem) {
|
||||
if(mem.device_pointer) {
|
||||
RPCSend snd(socket, "mem_free");
|
||||
|
||||
snd.archive & mem;
|
||||
snd.add(mem);
|
||||
snd.write();
|
||||
|
||||
mem.device_pointer = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void const_copy_to(const char *name, void *host, size_t size)
|
||||
@ -126,79 +125,107 @@ public:
|
||||
|
||||
string name_string(name);
|
||||
|
||||
snd.archive & name_string & size;
|
||||
snd.add(name_string);
|
||||
snd.add(size);
|
||||
snd.write();
|
||||
snd.write_buffer(host, size);
|
||||
}
|
||||
|
||||
void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
|
||||
{
|
||||
#if 0
|
||||
mem.device_pointer = ++mem_counter;
|
||||
|
||||
RPCSend snd(socket, "tex_alloc");
|
||||
|
||||
string name_string(name);
|
||||
|
||||
snd.archive & name_string & width & height & datatype & components & interpolation;
|
||||
snd.add(name_string);
|
||||
snd.add(mem);
|
||||
snd.add(interpolation);
|
||||
snd.add(periodic);
|
||||
snd.write();
|
||||
|
||||
size_t size = width*height*components*datatype_size(datatype);
|
||||
snd.write_buffer(host, size);
|
||||
|
||||
RPCReceive rcv(socket);
|
||||
|
||||
device_ptr mem;
|
||||
*rcv.archive & mem;
|
||||
|
||||
return mem;
|
||||
#endif
|
||||
snd.write_buffer((void*)mem.data_pointer, mem.memory_size());
|
||||
}
|
||||
|
||||
void tex_free(device_memory& mem)
|
||||
{
|
||||
#if 0
|
||||
if(mem) {
|
||||
if(mem.device_pointer) {
|
||||
RPCSend snd(socket, "tex_free");
|
||||
|
||||
snd.archive & mem;
|
||||
snd.add(mem);
|
||||
snd.write();
|
||||
|
||||
mem.device_pointer = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void path_trace(int x, int y, int w, int h, device_ptr buffer, device_ptr rng_state, int sample)
|
||||
{
|
||||
#if 0
|
||||
RPCSend snd(socket, "path_trace");
|
||||
|
||||
snd.archive & x & y & w & h & buffer & rng_state & sample;
|
||||
snd.write();
|
||||
#endif
|
||||
}
|
||||
|
||||
void tonemap(int x, int y, int w, int h, device_ptr rgba, device_ptr buffer, int sample, int resolution)
|
||||
{
|
||||
#if 0
|
||||
RPCSend snd(socket, "tonemap");
|
||||
|
||||
snd.archive & x & y & w & h & rgba & buffer & sample & resolution;
|
||||
snd.write();
|
||||
#endif
|
||||
}
|
||||
|
||||
void task_add(DeviceTask& task)
|
||||
{
|
||||
if(task.type == DeviceTask::TONEMAP)
|
||||
tonemap(task.x, task.y, task.w, task.h, task.rgba, task.buffer, task.sample, task.resolution);
|
||||
else if(task.type == DeviceTask::PATH_TRACE)
|
||||
path_trace(task.x, task.y, task.w, task.h, task.buffer, task.rng_state, task.sample);
|
||||
the_task = task;
|
||||
|
||||
RPCSend snd(socket, "task_add");
|
||||
snd.add(task);
|
||||
snd.write();
|
||||
}
|
||||
|
||||
void task_wait()
|
||||
{
|
||||
RPCSend snd(socket, "task_wait");
|
||||
snd.write();
|
||||
|
||||
list<RenderTile> the_tiles;
|
||||
|
||||
/* todo: run this threaded for connecting to multiple clients */
|
||||
for(;;) {
|
||||
RPCReceive rcv(socket);
|
||||
RenderTile tile;
|
||||
|
||||
if(rcv.name == "acquire_tile") {
|
||||
/* todo: watch out for recursive calls! */
|
||||
if(the_task.acquire_tile(this, tile)) { /* write return as bool */
|
||||
the_tiles.push_back(tile);
|
||||
|
||||
RPCSend snd(socket, "acquire_tile");
|
||||
snd.add(tile);
|
||||
snd.write();
|
||||
}
|
||||
else {
|
||||
RPCSend snd(socket, "acquire_tile_none");
|
||||
snd.write();
|
||||
}
|
||||
}
|
||||
else if(rcv.name == "release_tile") {
|
||||
rcv.read(tile);
|
||||
|
||||
for(list<RenderTile>::iterator it = the_tiles.begin(); it != the_tiles.end(); it++) {
|
||||
if(tile.x == it->x && tile.y == it->y && tile.start_sample == it->start_sample) {
|
||||
tile.buffers = it->buffers;
|
||||
the_tiles.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(tile.buffers != NULL);
|
||||
|
||||
the_task.release_tile(tile);
|
||||
|
||||
RPCSend snd(socket, "release_tile");
|
||||
snd.write();
|
||||
}
|
||||
else if(rcv.name == "task_wait_done")
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void task_cancel()
|
||||
{
|
||||
RPCSend snd(socket, "task_cancel");
|
||||
snd.write();
|
||||
}
|
||||
|
||||
bool support_advanced_shading()
|
||||
{
|
||||
return true; /* todo: get this info from device */
|
||||
}
|
||||
};
|
||||
|
||||
@ -219,16 +246,285 @@ void device_network_info(vector<DeviceInfo>& devices)
|
||||
devices.push_back(info);
|
||||
}
|
||||
|
||||
class DeviceServer {
|
||||
public:
|
||||
DeviceServer(Device *device_, tcp::socket& socket_)
|
||||
: device(device_), socket(socket_)
|
||||
{
|
||||
}
|
||||
|
||||
void listen()
|
||||
{
|
||||
/* receive remote function calls */
|
||||
for(;;) {
|
||||
RPCReceive rcv(socket);
|
||||
|
||||
if(rcv.name == "stop")
|
||||
break;
|
||||
|
||||
process(rcv);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
void process(RPCReceive& rcv)
|
||||
{
|
||||
// fprintf(stderr, "receive process %s\n", rcv.name.c_str());
|
||||
|
||||
if(rcv.name == "mem_alloc") {
|
||||
MemoryType type;
|
||||
network_device_memory mem;
|
||||
device_ptr remote_pointer;
|
||||
|
||||
rcv.read(mem);
|
||||
rcv.read(type);
|
||||
|
||||
/* todo: CPU needs mem.data_pointer */
|
||||
|
||||
remote_pointer = mem.device_pointer;
|
||||
|
||||
mem_data[remote_pointer] = vector<uint8_t>();
|
||||
mem_data[remote_pointer].resize(mem.memory_size());
|
||||
if(mem.memory_size())
|
||||
mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
|
||||
else
|
||||
mem.data_pointer = 0;
|
||||
|
||||
device->mem_alloc(mem, type);
|
||||
|
||||
ptr_map[remote_pointer] = mem.device_pointer;
|
||||
ptr_imap[mem.device_pointer] = remote_pointer;
|
||||
}
|
||||
else if(rcv.name == "mem_copy_to") {
|
||||
network_device_memory mem;
|
||||
|
||||
rcv.read(mem);
|
||||
|
||||
device_ptr remote_pointer = mem.device_pointer;
|
||||
mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
|
||||
|
||||
rcv.read_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
|
||||
|
||||
mem.device_pointer = ptr_map[remote_pointer];
|
||||
|
||||
device->mem_copy_to(mem);
|
||||
}
|
||||
else if(rcv.name == "mem_copy_from") {
|
||||
network_device_memory mem;
|
||||
int y, w, h, elem;
|
||||
|
||||
rcv.read(mem);
|
||||
rcv.read(y);
|
||||
rcv.read(w);
|
||||
rcv.read(h);
|
||||
rcv.read(elem);
|
||||
|
||||
device_ptr remote_pointer = mem.device_pointer;
|
||||
mem.device_pointer = ptr_map[remote_pointer];
|
||||
mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
|
||||
|
||||
device->mem_copy_from(mem, y, w, h, elem);
|
||||
|
||||
RPCSend snd(socket);
|
||||
snd.write();
|
||||
snd.write_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
|
||||
}
|
||||
else if(rcv.name == "mem_zero") {
|
||||
network_device_memory mem;
|
||||
|
||||
rcv.read(mem);
|
||||
device_ptr remote_pointer = mem.device_pointer;
|
||||
mem.device_pointer = ptr_map[mem.device_pointer];
|
||||
mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
|
||||
|
||||
device->mem_zero(mem);
|
||||
}
|
||||
else if(rcv.name == "mem_free") {
|
||||
network_device_memory mem;
|
||||
device_ptr remote_pointer;
|
||||
|
||||
rcv.read(mem);
|
||||
|
||||
remote_pointer = mem.device_pointer;
|
||||
mem.device_pointer = ptr_map[mem.device_pointer];
|
||||
ptr_map.erase(remote_pointer);
|
||||
ptr_imap.erase(mem.device_pointer);
|
||||
mem_data.erase(remote_pointer);
|
||||
|
||||
device->mem_free(mem);
|
||||
}
|
||||
else if(rcv.name == "const_copy_to") {
|
||||
string name_string;
|
||||
size_t size;
|
||||
|
||||
rcv.read(name_string);
|
||||
rcv.read(size);
|
||||
|
||||
vector<char> host_vector(size);
|
||||
rcv.read_buffer(&host_vector[0], size);
|
||||
|
||||
device->const_copy_to(name_string.c_str(), &host_vector[0], size);
|
||||
}
|
||||
else if(rcv.name == "tex_alloc") {
|
||||
network_device_memory mem;
|
||||
string name;
|
||||
bool interpolation;
|
||||
bool periodic;
|
||||
device_ptr remote_pointer;
|
||||
|
||||
rcv.read(name);
|
||||
rcv.read(mem);
|
||||
rcv.read(interpolation);
|
||||
rcv.read(periodic);
|
||||
|
||||
remote_pointer = mem.device_pointer;
|
||||
|
||||
mem_data[remote_pointer] = vector<uint8_t>();
|
||||
mem_data[remote_pointer].resize(mem.memory_size());
|
||||
if(mem.memory_size())
|
||||
mem.data_pointer = (device_ptr)&(mem_data[remote_pointer][0]);
|
||||
else
|
||||
mem.data_pointer = 0;
|
||||
|
||||
rcv.read_buffer((uint8_t*)mem.data_pointer, mem.memory_size());
|
||||
|
||||
device->tex_alloc(name.c_str(), mem, interpolation, periodic);
|
||||
|
||||
ptr_map[remote_pointer] = mem.device_pointer;
|
||||
ptr_imap[mem.device_pointer] = remote_pointer;
|
||||
}
|
||||
else if(rcv.name == "tex_free") {
|
||||
network_device_memory mem;
|
||||
device_ptr remote_pointer;
|
||||
|
||||
rcv.read(mem);
|
||||
|
||||
remote_pointer = mem.device_pointer;
|
||||
mem.device_pointer = ptr_map[mem.device_pointer];
|
||||
ptr_map.erase(remote_pointer);
|
||||
ptr_map.erase(mem.device_pointer);
|
||||
mem_data.erase(remote_pointer);
|
||||
|
||||
device->tex_free(mem);
|
||||
}
|
||||
else if(rcv.name == "task_add") {
|
||||
DeviceTask task;
|
||||
|
||||
rcv.read(task);
|
||||
|
||||
if(task.buffer) task.buffer = ptr_map[task.buffer];
|
||||
if(task.rgba) task.rgba = ptr_map[task.rgba];
|
||||
if(task.shader_input) task.shader_input = ptr_map[task.shader_input];
|
||||
if(task.shader_output) task.shader_output = ptr_map[task.shader_output];
|
||||
|
||||
task.acquire_tile = function_bind(&DeviceServer::task_acquire_tile, this, _1, _2);
|
||||
task.release_tile = function_bind(&DeviceServer::task_release_tile, this, _1);
|
||||
task.update_progress_sample = function_bind(&DeviceServer::task_update_progress_sample, this);
|
||||
task.update_tile_sample = function_bind(&DeviceServer::task_update_tile_sample, this, _1);
|
||||
task.get_cancel = function_bind(&DeviceServer::task_get_cancel, this);
|
||||
|
||||
device->task_add(task);
|
||||
}
|
||||
else if(rcv.name == "task_wait") {
|
||||
device->task_wait();
|
||||
|
||||
RPCSend snd(socket, "task_wait_done");
|
||||
snd.write();
|
||||
}
|
||||
else if(rcv.name == "task_cancel") {
|
||||
device->task_cancel();
|
||||
}
|
||||
}
|
||||
|
||||
bool task_acquire_tile(Device *device, RenderTile& tile)
|
||||
{
|
||||
thread_scoped_lock acquire_lock(acquire_mutex);
|
||||
|
||||
bool result = false;
|
||||
|
||||
RPCSend snd(socket, "acquire_tile");
|
||||
snd.write();
|
||||
|
||||
while(1) {
|
||||
RPCReceive rcv(socket);
|
||||
|
||||
if(rcv.name == "acquire_tile") {
|
||||
rcv.read(tile);
|
||||
|
||||
if(tile.buffer) tile.buffer = ptr_map[tile.buffer];
|
||||
if(tile.rng_state) tile.rng_state = ptr_map[tile.rng_state];
|
||||
if(tile.rgba) tile.rgba = ptr_map[tile.rgba];
|
||||
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
else if(rcv.name == "acquire_tile_none")
|
||||
break;
|
||||
else
|
||||
process(rcv);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void task_update_progress_sample()
|
||||
{
|
||||
; /* skip */
|
||||
}
|
||||
|
||||
void task_update_tile_sample(RenderTile&)
|
||||
{
|
||||
; /* skip */
|
||||
}
|
||||
|
||||
void task_release_tile(RenderTile& tile)
|
||||
{
|
||||
thread_scoped_lock acquire_lock(acquire_mutex);
|
||||
|
||||
if(tile.buffer) tile.buffer = ptr_imap[tile.buffer];
|
||||
if(tile.rng_state) tile.rng_state = ptr_imap[tile.rng_state];
|
||||
if(tile.rgba) tile.rgba = ptr_imap[tile.rgba];
|
||||
|
||||
RPCSend snd(socket, "release_tile");
|
||||
snd.add(tile);
|
||||
snd.write();
|
||||
|
||||
while(1) {
|
||||
RPCReceive rcv(socket);
|
||||
|
||||
if(rcv.name == "release_tile")
|
||||
break;
|
||||
else
|
||||
process(rcv);
|
||||
}
|
||||
}
|
||||
|
||||
bool task_get_cancel()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* properties */
|
||||
Device *device;
|
||||
tcp::socket& socket;
|
||||
|
||||
/* mapping of remote to local pointer */
|
||||
map<device_ptr, device_ptr> ptr_map;
|
||||
map<device_ptr, device_ptr> ptr_imap;
|
||||
map<device_ptr, vector<uint8_t> > mem_data;
|
||||
|
||||
thread_mutex acquire_mutex;
|
||||
|
||||
/* todo: free memory and device (osl) on network error */
|
||||
};
|
||||
|
||||
void Device::server_run()
|
||||
{
|
||||
try
|
||||
{
|
||||
try {
|
||||
/* starts thread that responds to discovery requests */
|
||||
ServerDiscovery discovery;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
||||
for(;;) {
|
||||
/* accept connection */
|
||||
boost::asio::io_service io_service;
|
||||
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVER_PORT));
|
||||
@ -236,145 +532,17 @@ void Device::server_run()
|
||||
tcp::socket socket(io_service);
|
||||
acceptor.accept(socket);
|
||||
|
||||
/* receive remote function calls */
|
||||
for(;;) {
|
||||
RPCReceive rcv(socket);
|
||||
string remote_address = socket.remote_endpoint().address().to_string();
|
||||
printf("Connected to remote client at: %s\n", remote_address.c_str());
|
||||
|
||||
if(rcv.name == "description") {
|
||||
string desc = description();
|
||||
DeviceServer server(this, socket);
|
||||
server.listen();
|
||||
|
||||
RPCSend snd(socket);
|
||||
snd.archive & desc;
|
||||
snd.write();
|
||||
}
|
||||
else if(rcv.name == "mem_alloc") {
|
||||
#if 0
|
||||
MemoryType type;
|
||||
size_t size;
|
||||
device_ptr mem;
|
||||
|
||||
*rcv.archive & size & type;
|
||||
mem = mem_alloc(size, type);
|
||||
|
||||
RPCSend snd(socket);
|
||||
snd.archive & mem;
|
||||
snd.write();
|
||||
#endif
|
||||
}
|
||||
else if(rcv.name == "mem_copy_to") {
|
||||
#if 0
|
||||
device_ptr mem;
|
||||
size_t size;
|
||||
|
||||
*rcv.archive & mem & size;
|
||||
|
||||
vector<char> host_vector(size);
|
||||
rcv.read_buffer(&host_vector[0], size);
|
||||
|
||||
mem_copy_to(mem, &host_vector[0], size);
|
||||
#endif
|
||||
}
|
||||
else if(rcv.name == "mem_copy_from") {
|
||||
#if 0
|
||||
device_ptr mem;
|
||||
size_t offset, size;
|
||||
|
||||
*rcv.archive & mem & offset & size;
|
||||
|
||||
vector<char> host_vector(size);
|
||||
|
||||
mem_copy_from(&host_vector[0], mem, offset, size);
|
||||
|
||||
RPCSend snd(socket);
|
||||
snd.write();
|
||||
snd.write_buffer(&host_vector[0], size);
|
||||
#endif
|
||||
}
|
||||
else if(rcv.name == "mem_zero") {
|
||||
#if 0
|
||||
device_ptr mem;
|
||||
size_t size;
|
||||
|
||||
*rcv.archive & mem & size;
|
||||
mem_zero(mem, size);
|
||||
#endif
|
||||
}
|
||||
else if(rcv.name == "mem_free") {
|
||||
#if 0
|
||||
device_ptr mem;
|
||||
|
||||
*rcv.archive & mem;
|
||||
mem_free(mem);
|
||||
#endif
|
||||
}
|
||||
else if(rcv.name == "const_copy_to") {
|
||||
string name_string;
|
||||
size_t size;
|
||||
|
||||
*rcv.archive & name_string & size;
|
||||
|
||||
vector<char> host_vector(size);
|
||||
rcv.read_buffer(&host_vector[0], size);
|
||||
|
||||
const_copy_to(name_string.c_str(), &host_vector[0], size);
|
||||
}
|
||||
else if(rcv.name == "tex_alloc") {
|
||||
#if 0
|
||||
string name_string;
|
||||
DataType datatype;
|
||||
device_ptr mem;
|
||||
size_t width, height;
|
||||
int components;
|
||||
bool interpolation;
|
||||
|
||||
*rcv.archive & name_string & width & height & datatype & components & interpolation;
|
||||
|
||||
size_t size = width*height*components*datatype_size(datatype);
|
||||
|
||||
vector<char> host_vector(size);
|
||||
rcv.read_buffer(&host_vector[0], size);
|
||||
|
||||
mem = tex_alloc(name_string.c_str(), &host_vector[0], width, height, datatype, components, interpolation);
|
||||
|
||||
RPCSend snd(socket);
|
||||
snd.archive & mem;
|
||||
snd.write();
|
||||
#endif
|
||||
}
|
||||
else if(rcv.name == "tex_free") {
|
||||
#if 0
|
||||
device_ptr mem;
|
||||
|
||||
*rcv.archive & mem;
|
||||
tex_free(mem);
|
||||
#endif
|
||||
}
|
||||
else if(rcv.name == "path_trace") {
|
||||
#if 0
|
||||
device_ptr buffer, rng_state;
|
||||
int x, y, w, h;
|
||||
int sample;
|
||||
|
||||
*rcv.archive & x & y & w & h & buffer & rng_state & sample;
|
||||
path_trace(x, y, w, h, buffer, rng_state, sample);
|
||||
#endif
|
||||
}
|
||||
else if(rcv.name == "tonemap") {
|
||||
#if 0
|
||||
device_ptr rgba, buffer;
|
||||
int x, y, w, h;
|
||||
int sample, resolution;
|
||||
|
||||
*rcv.archive & x & y & w & h & rgba & buffer & sample & resolution;
|
||||
tonemap(x, y, w, h, rgba, buffer, sample, resolution);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
printf("Disconnected.\n");
|
||||
}
|
||||
}
|
||||
catch(exception& e)
|
||||
{
|
||||
cerr << "Network server exception: " << e.what() << endl;
|
||||
catch(exception& e) {
|
||||
fprintf(stderr, "Network server exception: %s\n", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,15 +31,17 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "buffers.h"
|
||||
|
||||
#include "util_foreach.h"
|
||||
#include "util_list.h"
|
||||
#include "util_map.h"
|
||||
#include "util_string.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using std::cout;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::hex;
|
||||
using std::setw;
|
||||
using std::exception;
|
||||
@ -51,13 +53,63 @@ static const int DISCOVER_PORT = 5121;
|
||||
static const string DISCOVER_REQUEST_MSG = "REQUEST_RENDER_SERVER_IP";
|
||||
static const string DISCOVER_REPLY_MSG = "REPLY_RENDER_SERVER_IP";
|
||||
|
||||
typedef struct RPCSend {
|
||||
/* Serialization of device memory */
|
||||
|
||||
class network_device_memory : public device_memory
|
||||
{
|
||||
public:
|
||||
network_device_memory() {}
|
||||
~network_device_memory() { device_pointer = 0; };
|
||||
|
||||
vector<char> local_data;
|
||||
};
|
||||
|
||||
/* Remote procedure call Send */
|
||||
|
||||
class RPCSend {
|
||||
public:
|
||||
RPCSend(tcp::socket& socket_, const string& name_ = "")
|
||||
: name(name_), socket(socket_), archive(archive_stream)
|
||||
: name(name_), socket(socket_), archive(archive_stream), sent(false)
|
||||
{
|
||||
archive & name_;
|
||||
}
|
||||
|
||||
~RPCSend()
|
||||
{
|
||||
if(!sent)
|
||||
fprintf(stderr, "Error: RPC %s not sent\n", name.c_str());
|
||||
}
|
||||
|
||||
void add(const device_memory& mem)
|
||||
{
|
||||
archive & mem.data_type & mem.data_elements & mem.data_size;
|
||||
archive & mem.data_width & mem.data_height & mem.device_pointer;
|
||||
}
|
||||
|
||||
template<typename T> void add(const T& data)
|
||||
{
|
||||
archive & data;
|
||||
}
|
||||
|
||||
void add(const DeviceTask& task)
|
||||
{
|
||||
int type = (int)task.type;
|
||||
|
||||
archive & type & task.x & task.y & task.w & task.h;
|
||||
archive & task.rgba & task.buffer & task.sample & task.num_samples;
|
||||
archive & task.resolution & task.offset & task.stride;
|
||||
archive & task.shader_input & task.shader_output & task.shader_eval_type;
|
||||
archive & task.shader_x & task.shader_w;
|
||||
}
|
||||
|
||||
void add(const RenderTile& tile)
|
||||
{
|
||||
archive & tile.x & tile.y & tile.w & tile.h;
|
||||
archive & tile.start_sample & tile.num_samples & tile.sample;
|
||||
archive & tile.resolution & tile.offset & tile.stride;
|
||||
archive & tile.buffer & tile.rng_state & tile.rgba;
|
||||
}
|
||||
|
||||
void write()
|
||||
{
|
||||
boost::system::error_code error;
|
||||
@ -84,6 +136,8 @@ typedef struct RPCSend {
|
||||
|
||||
if(error.value())
|
||||
cout << "Network send error: " << error.message() << "\n";
|
||||
|
||||
sent = true;
|
||||
}
|
||||
|
||||
void write_buffer(void *buffer, size_t size)
|
||||
@ -98,13 +152,18 @@ typedef struct RPCSend {
|
||||
cout << "Network send error: " << error.message() << "\n";
|
||||
}
|
||||
|
||||
protected:
|
||||
string name;
|
||||
tcp::socket& socket;
|
||||
ostringstream archive_stream;
|
||||
boost::archive::text_oarchive archive;
|
||||
} RPCSend;
|
||||
bool sent;
|
||||
};
|
||||
|
||||
typedef struct RPCReceive {
|
||||
/* Remote procedure call Receive */
|
||||
|
||||
class RPCReceive {
|
||||
public:
|
||||
RPCReceive(tcp::socket& socket_)
|
||||
: socket(socket_), archive_stream(NULL), archive(NULL)
|
||||
{
|
||||
@ -151,6 +210,19 @@ typedef struct RPCReceive {
|
||||
delete archive_stream;
|
||||
}
|
||||
|
||||
void read(network_device_memory& mem)
|
||||
{
|
||||
*archive & mem.data_type & mem.data_elements & mem.data_size;
|
||||
*archive & mem.data_width & mem.data_height & mem.device_pointer;
|
||||
|
||||
mem.data_pointer = 0;
|
||||
}
|
||||
|
||||
template<typename T> void read(T& data)
|
||||
{
|
||||
*archive & data;
|
||||
}
|
||||
|
||||
void read_buffer(void *buffer, size_t size)
|
||||
{
|
||||
size_t len = boost::asio::read(socket, boost::asio::buffer(buffer, size));
|
||||
@ -159,12 +231,39 @@ typedef struct RPCReceive {
|
||||
cout << "Network receive error: buffer size doesn't match expected size\n";
|
||||
}
|
||||
|
||||
void read(DeviceTask& task)
|
||||
{
|
||||
int type;
|
||||
|
||||
*archive & type & task.x & task.y & task.w & task.h;
|
||||
*archive & task.rgba & task.buffer & task.sample & task.num_samples;
|
||||
*archive & task.resolution & task.offset & task.stride;
|
||||
*archive & task.shader_input & task.shader_output & task.shader_eval_type;
|
||||
*archive & task.shader_x & task.shader_w;
|
||||
|
||||
task.type = (DeviceTask::Type)type;
|
||||
}
|
||||
|
||||
void read(RenderTile& tile)
|
||||
{
|
||||
*archive & tile.x & tile.y & tile.w & tile.h;
|
||||
*archive & tile.start_sample & tile.num_samples & tile.sample;
|
||||
*archive & tile.resolution & tile.offset & tile.stride;
|
||||
*archive & tile.buffer & tile.rng_state & tile.rgba;
|
||||
|
||||
tile.buffers = NULL;
|
||||
}
|
||||
|
||||
string name;
|
||||
|
||||
protected:
|
||||
tcp::socket& socket;
|
||||
string archive_str;
|
||||
istringstream *archive_stream;
|
||||
boost::archive::text_iarchive *archive;
|
||||
} RPCReceive;
|
||||
};
|
||||
|
||||
/* Server auto discovery */
|
||||
|
||||
class ServerDiscovery {
|
||||
public:
|
||||
|
@ -55,6 +55,7 @@ set(SRC_CLOSURE_HEADERS
|
||||
closure/bsdf_phong_ramp.h
|
||||
closure/bsdf_reflection.h
|
||||
closure/bsdf_refraction.h
|
||||
closure/bsdf_toon.h
|
||||
closure/bsdf_transparent.h
|
||||
closure/bsdf_util.h
|
||||
closure/bsdf_ward.h
|
||||
|
206
intern/cycles/kernel/closure/bsdf_toon.h
Normal file
206
intern/cycles/kernel/closure/bsdf_toon.h
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Adapted from Open Shading Language with this license:
|
||||
*
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011, Blender Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Sony Pictures Imageworks nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __BSDF_TOON_H__
|
||||
#define __BSDF_TOON_H__
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* DIFFUSE TOON */
|
||||
|
||||
__device int bsdf_diffuse_toon_setup(ShaderClosure *sc)
|
||||
{
|
||||
sc->type = CLOSURE_BSDF_DIFFUSE_TOON_ID;
|
||||
sc->data0 = clamp(sc->data0, 0.0f, 1.0f);
|
||||
sc->data1 = clamp(sc->data1, 0.0f, 1.0f);
|
||||
|
||||
return SD_BSDF|SD_BSDF_HAS_EVAL;
|
||||
}
|
||||
|
||||
__device void bsdf_diffuse_toon_blur(ShaderClosure *sc, float roughness)
|
||||
{
|
||||
}
|
||||
|
||||
__device float3 bsdf_toon_get_intensity(float max_angle, float smooth, float angle)
|
||||
{
|
||||
float is;
|
||||
|
||||
if(angle < max_angle)
|
||||
is = 1.0f;
|
||||
else if(angle < (max_angle + smooth) && smooth != 0.0f)
|
||||
is = (1.0f - (angle - max_angle)/smooth);
|
||||
else
|
||||
is = 0.0f;
|
||||
|
||||
return make_float3(is, is, is);
|
||||
}
|
||||
|
||||
__device float bsdf_toon_get_sample_angle(float max_angle, float smooth)
|
||||
{
|
||||
return fminf(max_angle + smooth, M_PI_2_F);
|
||||
}
|
||||
|
||||
__device float3 bsdf_diffuse_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
|
||||
{
|
||||
float max_angle = sc->data0*M_PI_2_F;
|
||||
float smooth = sc->data1*M_PI_2_F;
|
||||
float angle = safe_acosf(fmaxf(dot(sc->N, omega_in), 0.0f));
|
||||
|
||||
float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
|
||||
|
||||
if(eval.x > 0.0f) {
|
||||
float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
|
||||
|
||||
*pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
|
||||
return *pdf * eval;
|
||||
}
|
||||
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
__device float3 bsdf_diffuse_toon_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
|
||||
{
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
__device int bsdf_diffuse_toon_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
|
||||
{
|
||||
float max_angle = sc->data0*M_PI_2_F;
|
||||
float smooth = sc->data1*M_PI_2_F;
|
||||
float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
|
||||
float angle = sample_angle*randu;
|
||||
|
||||
if(sample_angle > 0.0f) {
|
||||
sample_uniform_cone(sc->N, sample_angle, randu, randv, omega_in, pdf);
|
||||
|
||||
if(dot(Ng, *omega_in) > 0.0f) {
|
||||
*eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
// TODO: find a better approximation for the bounce
|
||||
*domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx;
|
||||
*domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*pdf = 0.0f;
|
||||
}
|
||||
|
||||
return LABEL_REFLECT | LABEL_DIFFUSE;
|
||||
|
||||
}
|
||||
|
||||
/* SPECULAR TOON */
|
||||
|
||||
__device int bsdf_specular_toon_setup(ShaderClosure *sc)
|
||||
{
|
||||
sc->type = CLOSURE_BSDF_SPECULAR_TOON_ID;
|
||||
sc->data0 = clamp(sc->data0, 0.0f, 1.0f);
|
||||
sc->data1 = clamp(sc->data1, 0.0f, 1.0f);
|
||||
|
||||
return SD_BSDF|SD_BSDF_HAS_EVAL;
|
||||
}
|
||||
|
||||
__device void bsdf_specular_toon_blur(ShaderClosure *sc, float roughness)
|
||||
{
|
||||
}
|
||||
|
||||
__device float3 bsdf_specular_toon_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
|
||||
{
|
||||
float max_angle = sc->data0*M_PI_2_F;
|
||||
float smooth = sc->data1*M_PI_2_F;
|
||||
float cosNI = dot(sc->N, omega_in);
|
||||
float cosNO = dot(sc->N, I);
|
||||
|
||||
if(cosNI > 0 && cosNO > 0) {
|
||||
/* reflect the view vector */
|
||||
float3 R = (2 * cosNO) * sc->N - I;
|
||||
float cosRI = dot(R, omega_in);
|
||||
|
||||
float angle = safe_acosf(fmaxf(cosRI, 0.0f));
|
||||
|
||||
float3 eval = bsdf_toon_get_intensity(max_angle, smooth, angle);
|
||||
float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
|
||||
|
||||
*pdf = 0.5f * M_1_PI_F / (1.0f - cosf(sample_angle));
|
||||
return *pdf * eval;
|
||||
}
|
||||
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
__device float3 bsdf_specular_toon_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
|
||||
{
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
__device int bsdf_specular_toon_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
|
||||
{
|
||||
float max_angle = sc->data0*M_PI_2_F;
|
||||
float smooth = sc->data1*M_PI_2_F;
|
||||
float cosNO = dot(sc->N, I);
|
||||
|
||||
if(cosNO > 0) {
|
||||
/* reflect the view vector */
|
||||
float3 R = (2 * cosNO) * sc->N - I;
|
||||
|
||||
float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth);
|
||||
float angle = sample_angle*randu;
|
||||
|
||||
sample_uniform_cone(R, sample_angle, randu, randv, omega_in, pdf);
|
||||
|
||||
if(dot(Ng, *omega_in) > 0.0f) {
|
||||
float cosNI = dot(sc->N, *omega_in);
|
||||
|
||||
/* make sure the direction we chose is still in the right hemisphere */
|
||||
if(cosNI > 0) {
|
||||
*eval = *pdf * bsdf_toon_get_intensity(max_angle, smooth, angle);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
*domega_in_dx = (2 * dot(sc->N, dIdx)) * sc->N - dIdx;
|
||||
*domega_in_dy = (2 * dot(sc->N, dIdy)) * sc->N - dIdy;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
*pdf = 0.0f;
|
||||
}
|
||||
else
|
||||
*pdf = 0.0f;
|
||||
}
|
||||
|
||||
return LABEL_GLOSSY | LABEL_REFLECT;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __BSDF_TOON_H__ */
|
||||
|
@ -37,6 +37,7 @@
|
||||
#define __global
|
||||
#define __shared __shared__
|
||||
#define __constant
|
||||
#define __may_alias
|
||||
|
||||
/* No assert supported for CUDA */
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#define __device
|
||||
#define __device_inline __device
|
||||
#define __device_noinline __device __noinline
|
||||
#define __may_alias
|
||||
|
||||
/* no assert in opencl */
|
||||
#define kernel_assert(cond)
|
||||
|
@ -105,6 +105,22 @@ __device_inline void sample_uniform_hemisphere(const float3 N,
|
||||
*pdf = 0.5f * M_1_PI_F;
|
||||
}
|
||||
|
||||
__device_inline void sample_uniform_cone(const float3 N, float angle,
|
||||
float randu, float randv,
|
||||
float3 *omega_in, float *pdf)
|
||||
{
|
||||
float z = cosf(angle*randu);
|
||||
float r = sqrtf(max(0.0f, 1.0f - z*z));
|
||||
float phi = 2.0f * M_PI_F * randv;
|
||||
float x = r * cosf(phi);
|
||||
float y = r * sinf(phi);
|
||||
|
||||
float3 T, B;
|
||||
make_orthonormals (N, &T, &B);
|
||||
*omega_in = x * T + y * B + z * N;
|
||||
*pdf = 0.5f * M_1_PI_F / (1.0f - cosf(angle));
|
||||
}
|
||||
|
||||
__device float3 sample_uniform_sphere(float u1, float u2)
|
||||
{
|
||||
float z = 1.0f - 2.0f*u1;
|
||||
|
@ -20,11 +20,16 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
enum ObjectTransform {
|
||||
OBJECT_TRANSFORM = 0,
|
||||
OBJECT_INVERSE_TRANSFORM = 3,
|
||||
OBJECT_PROPERTIES = 6,
|
||||
OBJECT_TRANSFORM_MOTION_PRE = 8,
|
||||
OBJECT_TRANSFORM_MOTION_POST = 12,
|
||||
OBJECT_DUPLI = 16
|
||||
OBJECT_TRANSFORM_MOTION_PRE = 0,
|
||||
OBJECT_INVERSE_TRANSFORM = 4,
|
||||
OBJECT_TRANSFORM_MOTION_POST = 4,
|
||||
OBJECT_PROPERTIES = 8,
|
||||
OBJECT_DUPLI = 9
|
||||
};
|
||||
|
||||
enum ObjectVectorTransform {
|
||||
OBJECT_VECTOR_MOTION_PRE = 0,
|
||||
OBJECT_VECTOR_MOTION_POST = 3
|
||||
};
|
||||
|
||||
__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
|
||||
@ -40,6 +45,19 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object,
|
||||
return tfm;
|
||||
}
|
||||
|
||||
__device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type)
|
||||
{
|
||||
int offset = object*OBJECT_VECTOR_SIZE + (int)type;
|
||||
|
||||
Transform tfm;
|
||||
tfm.x = kernel_tex_fetch(__objects_vector, offset + 0);
|
||||
tfm.y = kernel_tex_fetch(__objects_vector, offset + 1);
|
||||
tfm.z = kernel_tex_fetch(__objects_vector, offset + 2);
|
||||
tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
||||
#ifdef __OBJECT_MOTION__
|
||||
__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
|
||||
{
|
||||
|
@ -34,6 +34,7 @@ KERNEL_TEX(uint, texture_uint, __object_node)
|
||||
|
||||
/* objects */
|
||||
KERNEL_TEX(float4, texture_float4, __objects)
|
||||
KERNEL_TEX(float4, texture_float4, __objects_vector)
|
||||
|
||||
/* triangles */
|
||||
KERNEL_TEX(float4, texture_float4, __tri_normal)
|
||||
|
@ -209,10 +209,10 @@ __device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd)
|
||||
* transformation was set match the world/object space of motion_pre/post */
|
||||
Transform tfm;
|
||||
|
||||
tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_PRE);
|
||||
tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_PRE);
|
||||
motion_pre = transform_point(&tfm, motion_pre);
|
||||
|
||||
tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_POST);
|
||||
tfm = object_fetch_vector_transform(kg, sd->object, OBJECT_VECTOR_MOTION_POST);
|
||||
motion_post = transform_point(&tfm, motion_post);
|
||||
|
||||
float3 P;
|
||||
|
@ -29,7 +29,8 @@
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* constants */
|
||||
#define OBJECT_SIZE 18
|
||||
#define OBJECT_SIZE 11
|
||||
#define OBJECT_VECTOR_SIZE 6
|
||||
#define LIGHT_SIZE 4
|
||||
#define FILTER_TABLE_SIZE 256
|
||||
#define RAMP_TABLE_SIZE 256
|
||||
|
@ -16,6 +16,7 @@ set(SRC
|
||||
background.cpp
|
||||
bsdf_diffuse_ramp.cpp
|
||||
bsdf_phong_ramp.cpp
|
||||
bsdf_toon.cpp
|
||||
emissive.cpp
|
||||
osl_closures.cpp
|
||||
osl_services.cpp
|
||||
|
179
intern/cycles/kernel/osl/bsdf_toon.cpp
Normal file
179
intern/cycles/kernel/osl/bsdf_toon.cpp
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Adapted from Open Shading Language with this license:
|
||||
*
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011, Blender Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of Sony Pictures Imageworks nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "osl_closures.h"
|
||||
|
||||
#include "kernel_types.h"
|
||||
#include "kernel_montecarlo.h"
|
||||
#include "closure/bsdf_toon.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
/* DIFFUSE TOON */
|
||||
|
||||
class DiffuseToonClosure : public CBSDFClosure {
|
||||
public:
|
||||
DiffuseToonClosure() : CBSDFClosure(LABEL_DIFFUSE) {}
|
||||
|
||||
size_t memsize() const { return sizeof(*this); }
|
||||
const char *name() const { return "diffuse_toon"; }
|
||||
|
||||
void setup()
|
||||
{
|
||||
sc.prim = this;
|
||||
m_shaderdata_flag = bsdf_diffuse_toon_setup(&sc);
|
||||
}
|
||||
|
||||
bool mergeable(const ClosurePrimitive *other) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void blur(float roughness)
|
||||
{
|
||||
bsdf_diffuse_toon_blur(&sc, roughness);
|
||||
}
|
||||
|
||||
void print_on(std::ostream &out) const
|
||||
{
|
||||
out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))";
|
||||
}
|
||||
|
||||
float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
|
||||
{
|
||||
return bsdf_diffuse_toon_eval_reflect(&sc, omega_out, omega_in, &pdf);
|
||||
}
|
||||
|
||||
float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const
|
||||
{
|
||||
return bsdf_diffuse_toon_eval_transmit(&sc, omega_out, omega_in, &pdf);
|
||||
}
|
||||
|
||||
int sample(const float3 &Ng,
|
||||
const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
|
||||
float randu, float randv,
|
||||
float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
|
||||
float &pdf, float3 &eval) const
|
||||
{
|
||||
return bsdf_diffuse_toon_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy,
|
||||
randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf);
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_bsdf_diffuse_toon_params()
|
||||
{
|
||||
static ClosureParam params[] = {
|
||||
CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(DiffuseToonClosure, sc.data0),
|
||||
CLOSURE_FLOAT_PARAM(DiffuseToonClosure, sc.data1),
|
||||
CLOSURE_STRING_KEYPARAM("label"),
|
||||
CLOSURE_FINISH_PARAM(DiffuseToonClosure)
|
||||
};
|
||||
return params;
|
||||
}
|
||||
|
||||
CLOSURE_PREPARE(closure_bsdf_diffuse_toon_prepare, DiffuseToonClosure)
|
||||
|
||||
/* SPECULAR TOON */
|
||||
|
||||
class SpecularToonClosure : public CBSDFClosure {
|
||||
public:
|
||||
SpecularToonClosure() : CBSDFClosure(LABEL_GLOSSY) {}
|
||||
|
||||
size_t memsize() const { return sizeof(*this); }
|
||||
const char *name() const { return "specular_toon"; }
|
||||
|
||||
void setup()
|
||||
{
|
||||
sc.prim = this;
|
||||
m_shaderdata_flag = bsdf_specular_toon_setup(&sc);
|
||||
}
|
||||
|
||||
bool mergeable(const ClosurePrimitive *other) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void blur(float roughness)
|
||||
{
|
||||
bsdf_specular_toon_blur(&sc, roughness);
|
||||
}
|
||||
|
||||
void print_on(std::ostream &out) const
|
||||
{
|
||||
out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))";
|
||||
}
|
||||
|
||||
float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
|
||||
{
|
||||
return bsdf_specular_toon_eval_reflect(&sc, omega_out, omega_in, &pdf);
|
||||
}
|
||||
|
||||
float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const
|
||||
{
|
||||
return bsdf_specular_toon_eval_transmit(&sc, omega_out, omega_in, &pdf);
|
||||
}
|
||||
|
||||
int sample(const float3 &Ng,
|
||||
const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
|
||||
float randu, float randv,
|
||||
float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
|
||||
float &pdf, float3 &eval) const
|
||||
{
|
||||
return bsdf_specular_toon_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy,
|
||||
randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf);
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_bsdf_specular_toon_params()
|
||||
{
|
||||
static ClosureParam params[] = {
|
||||
CLOSURE_FLOAT3_PARAM(SpecularToonClosure, sc.N),
|
||||
CLOSURE_FLOAT_PARAM(SpecularToonClosure, sc.data0),
|
||||
CLOSURE_FLOAT_PARAM(SpecularToonClosure, sc.data1),
|
||||
CLOSURE_STRING_KEYPARAM("label"),
|
||||
CLOSURE_FINISH_PARAM(SpecularToonClosure)
|
||||
};
|
||||
return params;
|
||||
}
|
||||
|
||||
CLOSURE_PREPARE(closure_bsdf_specular_toon_prepare, SpecularToonClosure)
|
||||
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -48,7 +48,6 @@
|
||||
#include "closure/bsdf_diffuse.h"
|
||||
#include "closure/bsdf_microfacet.h"
|
||||
#include "closure/bsdf_oren_nayar.h"
|
||||
#include "closure/bsdf_phong_ramp.h"
|
||||
#include "closure/bsdf_reflection.h"
|
||||
#include "closure/bsdf_refraction.h"
|
||||
#include "closure/bsdf_transparent.h"
|
||||
@ -194,10 +193,14 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
|
||||
closure_holdout_params(), closure_holdout_prepare);
|
||||
register_closure(ss, "ambient_occlusion", id++,
|
||||
closure_ambient_occlusion_params(), closure_ambient_occlusion_prepare);
|
||||
register_closure(ss, "phong_ramp", id++,
|
||||
closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
|
||||
register_closure(ss, "diffuse_ramp", id++,
|
||||
closure_bsdf_diffuse_ramp_params(), closure_bsdf_diffuse_ramp_prepare);
|
||||
register_closure(ss, "phong_ramp", id++,
|
||||
closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
|
||||
register_closure(ss, "diffuse_toon", id++,
|
||||
closure_bsdf_diffuse_toon_params(), closure_bsdf_diffuse_toon_prepare);
|
||||
register_closure(ss, "specular_toon", id++,
|
||||
closure_bsdf_specular_toon_params(), closure_bsdf_specular_toon_prepare);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@ -47,15 +47,19 @@ OSL::ClosureParam *closure_emission_params();
|
||||
OSL::ClosureParam *closure_background_params();
|
||||
OSL::ClosureParam *closure_holdout_params();
|
||||
OSL::ClosureParam *closure_ambient_occlusion_params();
|
||||
OSL::ClosureParam *closure_bsdf_phong_ramp_params();
|
||||
OSL::ClosureParam *closure_bsdf_diffuse_ramp_params();
|
||||
OSL::ClosureParam *closure_bsdf_phong_ramp_params();
|
||||
OSL::ClosureParam *closure_bsdf_diffuse_toon_params();
|
||||
OSL::ClosureParam *closure_bsdf_specular_toon_params();
|
||||
|
||||
void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_background_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_holdout_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_ambient_occlusion_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_diffuse_toon_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_specular_toon_prepare(OSL::RendererServices *, int id, void *data);
|
||||
|
||||
enum {
|
||||
AmbientOcclusion = 100
|
||||
|
@ -634,11 +634,10 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
|
||||
{
|
||||
KernelGlobals *kg = kernel_globals;
|
||||
ShaderData *sd = (ShaderData *)renderstate;
|
||||
int object = sd->object;
|
||||
int tri = sd->prim;
|
||||
int object, tri;
|
||||
|
||||
/* lookup of attribute on another object */
|
||||
if (object_name != u_empty) {
|
||||
if (object_name != u_empty || sd == NULL) {
|
||||
OSLGlobals::ObjectNameMap::iterator it = kg->osl->object_name_map.find(object_name);
|
||||
|
||||
if (it == kg->osl->object_name_map.end())
|
||||
@ -647,8 +646,12 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
|
||||
object = it->second;
|
||||
tri = ~0;
|
||||
}
|
||||
else if (object == ~0) {
|
||||
return get_background_attribute(kg, sd, name, type, derivatives, val);
|
||||
else {
|
||||
object = sd->object;
|
||||
tri = sd->prim;
|
||||
|
||||
if (object == ~0)
|
||||
return get_background_attribute(kg, sd, name, type, derivatives, val);
|
||||
}
|
||||
|
||||
/* find attribute on object */
|
||||
|
@ -161,7 +161,6 @@ vector cross (vector a, vector b) BUILTIN;
|
||||
float dot (vector a, vector b) BUILTIN;
|
||||
float length (vector v) BUILTIN;
|
||||
float distance (point a, point b) BUILTIN;
|
||||
float distance (point a, point b, point q) BUILTIN;
|
||||
normal normalize (normal v) BUILTIN;
|
||||
vector normalize (vector v) BUILTIN;
|
||||
vector faceforward (vector N, vector I, vector Nref) BUILTIN;
|
||||
@ -433,8 +432,10 @@ string concat (string a, string b, string c, string d, string e, string f) {
|
||||
|
||||
closure color diffuse(normal N) BUILTIN;
|
||||
closure color oren_nayar(normal N, float sigma) BUILTIN;
|
||||
closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
|
||||
closure color diffuse_ramp(normal N, color colors[8]) BUILTIN;
|
||||
closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
|
||||
closure color diffuse_toon(normal N, float size, float smooth) BUILTIN;
|
||||
closure color specular_toon(normal N, float size, float smooth) BUILTIN;
|
||||
closure color translucent(normal N) BUILTIN;
|
||||
closure color reflection(normal N) BUILTIN;
|
||||
closure color refraction(normal N, float eta) BUILTIN;
|
||||
|
@ -18,73 +18,6 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
__device float safe_asinf(float a)
|
||||
{
|
||||
if(a <= -1.0f)
|
||||
return -M_PI_2_F;
|
||||
else if(a >= 1.0f)
|
||||
return M_PI_2_F;
|
||||
|
||||
return asinf(a);
|
||||
}
|
||||
|
||||
__device float safe_acosf(float a)
|
||||
{
|
||||
if(a <= -1.0f)
|
||||
return M_PI_F;
|
||||
else if(a >= 1.0f)
|
||||
return 0.0f;
|
||||
|
||||
return acosf(a);
|
||||
}
|
||||
|
||||
__device float compatible_powf(float x, float y)
|
||||
{
|
||||
/* GPU pow doesn't accept negative x, do manual checks here */
|
||||
if(x < 0.0f) {
|
||||
if(fmod(-y, 2.0f) == 0.0f)
|
||||
return powf(-x, y);
|
||||
else
|
||||
return -powf(-x, y);
|
||||
}
|
||||
else if(x == 0.0f)
|
||||
return 0.0f;
|
||||
|
||||
return powf(x, y);
|
||||
}
|
||||
|
||||
__device float safe_powf(float a, float b)
|
||||
{
|
||||
if(b == 0.0f)
|
||||
return 1.0f;
|
||||
if(a == 0.0f)
|
||||
return 0.0f;
|
||||
if(a < 0.0f && b != (int)b)
|
||||
return 0.0f;
|
||||
|
||||
return compatible_powf(a, b);
|
||||
}
|
||||
|
||||
__device float safe_logf(float a, float b)
|
||||
{
|
||||
if(a < 0.0f || b < 0.0f)
|
||||
return 0.0f;
|
||||
|
||||
return logf(a)/logf(b);
|
||||
}
|
||||
|
||||
__device float safe_divide(float a, float b)
|
||||
{
|
||||
float result;
|
||||
|
||||
if(b == 0.0f)
|
||||
result = 0.0f;
|
||||
else
|
||||
result = a/b;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
__device float svm_math(NodeMath type, float Fac1, float Fac2)
|
||||
{
|
||||
float Fac;
|
||||
|
@ -314,6 +314,7 @@ typedef enum ClosureType {
|
||||
CLOSURE_BSDF_DIFFUSE_ID,
|
||||
CLOSURE_BSDF_OREN_NAYAR_ID,
|
||||
CLOSURE_BSDF_DIFFUSE_RAMP_ID,
|
||||
CLOSURE_BSDF_DIFFUSE_TOON_ID,
|
||||
|
||||
CLOSURE_BSDF_GLOSSY_ID,
|
||||
CLOSURE_BSDF_REFLECTION_ID,
|
||||
@ -323,6 +324,7 @@ typedef enum ClosureType {
|
||||
CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
|
||||
CLOSURE_BSDF_WESTIN_SHEEN_ID,
|
||||
CLOSURE_BSDF_PHONG_RAMP_ID,
|
||||
CLOSURE_BSDF_SPECULAR_TOON_ID,
|
||||
|
||||
CLOSURE_BSDF_TRANSMISSION_ID,
|
||||
CLOSURE_BSDF_TRANSLUCENT_ID,
|
||||
|
@ -150,12 +150,17 @@ ObjectManager::~ObjectManager()
|
||||
|
||||
void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, uint *object_flag, Progress& progress)
|
||||
{
|
||||
float4 *objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
|
||||
float4 *objects;
|
||||
float4 *objects_vector = NULL;
|
||||
int i = 0;
|
||||
map<Mesh*, float> surface_area_map;
|
||||
Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
|
||||
bool have_motion = false;
|
||||
|
||||
objects = dscene->objects.resize(OBJECT_SIZE*scene->objects.size());
|
||||
if(need_motion == Scene::MOTION_PASS)
|
||||
objects_vector = dscene->objects_vector.resize(OBJECT_VECTOR_SIZE*scene->objects.size());
|
||||
|
||||
foreach(Object *ob, scene->objects) {
|
||||
Mesh *mesh = ob->mesh;
|
||||
uint flag = 0;
|
||||
@ -205,8 +210,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
||||
int offset = i*OBJECT_SIZE;
|
||||
|
||||
memcpy(&objects[offset], &tfm, sizeof(float4)*3);
|
||||
memcpy(&objects[offset+3], &itfm, sizeof(float4)*3);
|
||||
objects[offset+6] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id));
|
||||
memcpy(&objects[offset+4], &itfm, sizeof(float4)*3);
|
||||
objects[offset+8] = make_float4(surface_area, pass_id, random_number, __int_as_float(ob->particle_id));
|
||||
|
||||
if(need_motion == Scene::MOTION_PASS) {
|
||||
/* motion transformations, is world/object space depending if mesh
|
||||
@ -220,8 +225,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
||||
if(!mesh->attributes.find(ATTR_STD_MOTION_POST))
|
||||
mtfm_post = mtfm_post * itfm;
|
||||
|
||||
memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
|
||||
memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4);
|
||||
memcpy(&objects_vector[i*OBJECT_VECTOR_SIZE+0], &mtfm_pre, sizeof(float4)*3);
|
||||
memcpy(&objects_vector[i*OBJECT_VECTOR_SIZE+3], &mtfm_post, sizeof(float4)*3);
|
||||
}
|
||||
#ifdef __OBJECT_MOTION__
|
||||
else if(need_motion == Scene::MOTION_BLUR) {
|
||||
@ -230,20 +235,16 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
||||
DecompMotionTransform decomp;
|
||||
|
||||
transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
|
||||
memcpy(&objects[offset+8], &decomp, sizeof(float4)*8);
|
||||
memcpy(&objects[offset], &decomp, sizeof(float4)*8);
|
||||
flag |= SD_OBJECT_MOTION;
|
||||
have_motion = true;
|
||||
}
|
||||
else {
|
||||
float4 no_motion = make_float4(FLT_MAX);
|
||||
memcpy(&objects[offset+8], &no_motion, sizeof(float4)*8);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* dupli object coords */
|
||||
objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
|
||||
objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
|
||||
objects[offset+9] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
|
||||
objects[offset+10] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
|
||||
|
||||
/* object flag */
|
||||
if(ob->use_holdout)
|
||||
@ -256,6 +257,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
|
||||
}
|
||||
|
||||
device->tex_alloc("__objects", dscene->objects);
|
||||
if(need_motion == Scene::MOTION_PASS)
|
||||
device->tex_alloc("__objects_vector", dscene->objects_vector);
|
||||
|
||||
dscene->data.bvh.have_motion = have_motion;
|
||||
}
|
||||
@ -297,6 +300,9 @@ void ObjectManager::device_free(Device *device, DeviceScene *dscene)
|
||||
device->tex_free(dscene->objects);
|
||||
dscene->objects.clear();
|
||||
|
||||
device->tex_free(dscene->objects_vector);
|
||||
dscene->objects_vector.clear();
|
||||
|
||||
device->tex_free(dscene->object_flag);
|
||||
dscene->object_flag.clear();
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ public:
|
||||
|
||||
/* objects */
|
||||
device_vector<float4> objects;
|
||||
device_vector<float4> objects_vector;
|
||||
|
||||
/* attributes */
|
||||
device_vector<uint4> attributes_map;
|
||||
|
@ -394,10 +394,10 @@ bool cuLibraryInit()
|
||||
string cuCompilerPath()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const char *defaultpath = "C:/CUDA/bin";
|
||||
const char *defaultpaths[] = {"C:/CUDA/bin", NULL};
|
||||
const char *executable = "nvcc.exe";
|
||||
#else
|
||||
const char *defaultpath = "/usr/local/cuda/bin";
|
||||
const char *defaultpaths[] = {"/Developer/NVIDIA/CUDA-4.2/bin", "/usr/local/cuda-4.2/bin", "/usr/local/cuda/bin", NULL};
|
||||
const char *executable = "nvcc";
|
||||
#endif
|
||||
|
||||
@ -405,13 +405,17 @@ string cuCompilerPath()
|
||||
|
||||
string nvcc;
|
||||
|
||||
if(binpath)
|
||||
if(binpath) {
|
||||
nvcc = path_join(binpath, executable);
|
||||
else
|
||||
nvcc = path_join(defaultpath, executable);
|
||||
if(path_exists(nvcc))
|
||||
return nvcc;
|
||||
}
|
||||
|
||||
if(path_exists(nvcc))
|
||||
return nvcc;
|
||||
for(int i = 0; defaultpaths[i]; i++) {
|
||||
nvcc = path_join(defaultpaths[i], executable);
|
||||
if(path_exists(nvcc))
|
||||
return nvcc;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ CCL_NAMESPACE_END
|
||||
|
||||
#define CUDA_VERSION 3020
|
||||
|
||||
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
|
||||
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) || defined(__LP64__)
|
||||
typedef unsigned long long CUdeviceptr;
|
||||
#else
|
||||
typedef unsigned int CUdeviceptr;
|
||||
|
@ -1092,6 +1092,75 @@ __device_inline float3 rotate_around_axis(float3 p, float3 axis, float angle)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* NaN-safe math ops */
|
||||
|
||||
__device float safe_asinf(float a)
|
||||
{
|
||||
if(a <= -1.0f)
|
||||
return -M_PI_2_F;
|
||||
else if(a >= 1.0f)
|
||||
return M_PI_2_F;
|
||||
|
||||
return asinf(a);
|
||||
}
|
||||
|
||||
__device float safe_acosf(float a)
|
||||
{
|
||||
if(a <= -1.0f)
|
||||
return M_PI_F;
|
||||
else if(a >= 1.0f)
|
||||
return 0.0f;
|
||||
|
||||
return acosf(a);
|
||||
}
|
||||
|
||||
__device float compatible_powf(float x, float y)
|
||||
{
|
||||
/* GPU pow doesn't accept negative x, do manual checks here */
|
||||
if(x < 0.0f) {
|
||||
if(fmod(-y, 2.0f) == 0.0f)
|
||||
return powf(-x, y);
|
||||
else
|
||||
return -powf(-x, y);
|
||||
}
|
||||
else if(x == 0.0f)
|
||||
return 0.0f;
|
||||
|
||||
return powf(x, y);
|
||||
}
|
||||
|
||||
__device float safe_powf(float a, float b)
|
||||
{
|
||||
if(b == 0.0f)
|
||||
return 1.0f;
|
||||
if(a == 0.0f)
|
||||
return 0.0f;
|
||||
if(a < 0.0f && b != (int)b)
|
||||
return 0.0f;
|
||||
|
||||
return compatible_powf(a, b);
|
||||
}
|
||||
|
||||
__device float safe_logf(float a, float b)
|
||||
{
|
||||
if(a < 0.0f || b < 0.0f)
|
||||
return 0.0f;
|
||||
|
||||
return logf(a)/logf(b);
|
||||
}
|
||||
|
||||
__device float safe_divide(float a, float b)
|
||||
{
|
||||
float result;
|
||||
|
||||
if(b == 0.0f)
|
||||
result = 0.0f;
|
||||
else
|
||||
result = a/b;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __UTIL_MATH_H__ */
|
||||
|
@ -45,7 +45,7 @@ typedef struct Transform {
|
||||
*
|
||||
* For the DecompMotionTransform we drop scale from pre/post. */
|
||||
|
||||
typedef struct MotionTransform {
|
||||
typedef struct __may_alias MotionTransform {
|
||||
Transform pre;
|
||||
Transform mid;
|
||||
Transform post;
|
||||
|
@ -39,12 +39,14 @@
|
||||
#if defined(_WIN32) && !defined(FREE_WINDOWS)
|
||||
#define __device_inline static __forceinline
|
||||
#define __align(...) __declspec(align(__VA_ARGS__))
|
||||
#define __may_alias
|
||||
#else
|
||||
#define __device_inline static inline __attribute__((always_inline))
|
||||
#ifndef FREE_WINDOWS64
|
||||
#define __forceinline inline __attribute__((always_inline))
|
||||
#endif
|
||||
#define __align(...) __attribute__((aligned(__VA_ARGS__)))
|
||||
#define __may_alias __attribute__((__may_alias__))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -296,8 +296,6 @@ protected:
|
||||
/** Multitouch trackpad availability */
|
||||
bool m_hasMultiTouchTrackpad;
|
||||
|
||||
/** Multitouch gesture in progress, useful to distinguish trackpad from mouse scroll events */
|
||||
bool m_isGestureInProgress;
|
||||
};
|
||||
|
||||
#endif // __GHOST_SYSTEMCOCOA_H__
|
||||
|
@ -551,7 +551,6 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
|
||||
char *rstring = NULL;
|
||||
|
||||
m_modifierMask =0;
|
||||
m_isGestureInProgress = false;
|
||||
m_cursorDelta_x=0;
|
||||
m_cursorDelta_y=0;
|
||||
m_outsideLoopEventProcessed = false;
|
||||
@ -1580,8 +1579,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
||||
|
||||
case NSScrollWheel:
|
||||
{
|
||||
/* Send trackpad event if inside a trackpad gesture, send wheel event otherwise */
|
||||
if (!m_hasMultiTouchTrackpad || !m_isGestureInProgress) {
|
||||
if (!m_hasMultiTouchTrackpad) {
|
||||
GHOST_TInt32 delta;
|
||||
|
||||
double deltaF = [event deltaY];
|
||||
@ -1641,12 +1639,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
||||
pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventRotate, x, y,
|
||||
-[event rotation] * 5.0, 0));
|
||||
}
|
||||
case NSEventTypeBeginGesture:
|
||||
m_isGestureInProgress = true;
|
||||
break;
|
||||
case NSEventTypeEndGesture:
|
||||
m_isGestureInProgress = false;
|
||||
break;
|
||||
default:
|
||||
return GHOST_kFailure;
|
||||
break;
|
||||
|
@ -67,13 +67,13 @@ extern "C" {
|
||||
}
|
||||
|
||||
- (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa;
|
||||
- (void)windowWillClose:(NSNotification *)notification;
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification;
|
||||
- (void)windowDidResignKey:(NSNotification *)notification;
|
||||
- (void)windowDidExpose:(NSNotification *)notification;
|
||||
- (void)windowDidResize:(NSNotification *)notification;
|
||||
- (void)windowDidMove:(NSNotification *)notification;
|
||||
- (void)windowWillMove:(NSNotification *)notification;
|
||||
- (BOOL)windowShouldClose:(id)sender;
|
||||
@end
|
||||
|
||||
@implementation CocoaWindowDelegate : NSObject
|
||||
@ -83,11 +83,6 @@ extern "C" {
|
||||
associatedWindow = winCocoa;
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification *)notification
|
||||
{
|
||||
systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow);
|
||||
}
|
||||
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification
|
||||
{
|
||||
systemCocoa->handleWindowEvent(GHOST_kEventWindowActivate, associatedWindow);
|
||||
@ -132,6 +127,14 @@ extern "C" {
|
||||
wm_draw_update(ghostC);
|
||||
}*/
|
||||
}
|
||||
|
||||
- (BOOL)windowShouldClose:(id)sender;
|
||||
{
|
||||
//Let Blender close the window rather than closing immediately
|
||||
systemCocoa->handleWindowEvent(GHOST_kEventWindowClose, associatedWindow);
|
||||
return false;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark NSWindow subclass
|
||||
@ -571,8 +574,6 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
|
||||
[m_window setContentView:m_openGLView];
|
||||
[m_window setInitialFirstResponder:m_openGLView];
|
||||
|
||||
[m_window setReleasedWhenClosed:NO]; //To avoid bad pointer exception in case of user closing the window
|
||||
|
||||
[m_window makeKeyAndOrderFront:nil];
|
||||
|
||||
setDrawingContextType(type);
|
||||
@ -616,11 +617,6 @@ GHOST_WindowCocoa::~GHOST_WindowCocoa()
|
||||
[m_openGLView release];
|
||||
|
||||
if (m_window) {
|
||||
// previously we called [m_window release], but on 10.8 this does not
|
||||
// remove the window from [NSApp orderedWindows] and perhaps other
|
||||
// places, leading to crashes. so instead we set setReleasedWhenClosed
|
||||
// back to YES right before closing
|
||||
[m_window setReleasedWhenClosed:YES];
|
||||
[m_window close];
|
||||
}
|
||||
|
||||
@ -955,7 +951,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
|
||||
//Copy current window parameters
|
||||
[tmpWindow setTitle:[m_window title]];
|
||||
[tmpWindow setRepresentedFilename:[m_window representedFilename]];
|
||||
[tmpWindow setReleasedWhenClosed:NO];
|
||||
[tmpWindow setAcceptsMouseMovedEvents:YES];
|
||||
[tmpWindow setDelegate:[m_window delegate]];
|
||||
[tmpWindow setSystemAndWindowCocoa:[m_window systemCocoa] windowCocoa:this];
|
||||
@ -1013,7 +1008,6 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
|
||||
//Copy current window parameters
|
||||
[tmpWindow setTitle:[m_window title]];
|
||||
[tmpWindow setRepresentedFilename:[m_window representedFilename]];
|
||||
[tmpWindow setReleasedWhenClosed:NO];
|
||||
[tmpWindow setAcceptsMouseMovedEvents:YES];
|
||||
[tmpWindow setDelegate:[m_window delegate]];
|
||||
[tmpWindow setSystemAndWindowCocoa:[m_window systemCocoa] windowCocoa:this];
|
||||
|
@ -1,4 +1,5 @@
|
||||
#!/bin/sh
|
||||
# This script updates icons from the SVG file
|
||||
|
||||
inkscape blender_icons.svg --without-gui --export-png=blender_icons.png
|
||||
inkscape blender_icons.svg --export-dpi=90 --without-gui --export-png=blender_icons16.png
|
||||
inkscape blender_icons.svg --export-dpi=180 --without-gui --export-png=blender_icons32.png
|
||||
|
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 4.5 MiB After Width: | Height: | Size: 3.9 MiB |
Binary file not shown.
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 225 KiB |
Binary file not shown.
Before Width: | Height: | Size: 539 KiB After Width: | Height: | Size: 562 KiB |
@ -29,7 +29,7 @@ __all__ = (
|
||||
)
|
||||
|
||||
import bpy as _bpy
|
||||
|
||||
_user_preferences = _bpy.context.user_preferences
|
||||
|
||||
error_duplicates = False
|
||||
error_encoding = False
|
||||
@ -201,7 +201,7 @@ def check(module_name):
|
||||
:rtype: tuple of booleans
|
||||
"""
|
||||
import sys
|
||||
loaded_default = module_name in _bpy.context.user_preferences.addons
|
||||
loaded_default = module_name in _user_preferences.addons
|
||||
|
||||
mod = sys.modules.get(module_name)
|
||||
loaded_state = mod and getattr(mod, "__addon_enabled__", Ellipsis)
|
||||
@ -232,6 +232,7 @@ def enable(module_name, default_set=True, persistent=False):
|
||||
|
||||
import os
|
||||
import sys
|
||||
from bpy_restrict_state import RestrictBlend
|
||||
|
||||
def handle_error():
|
||||
import traceback
|
||||
@ -259,34 +260,38 @@ def enable(module_name, default_set=True, persistent=False):
|
||||
# Split registering up into 3 steps so we can undo
|
||||
# if it fails par way through.
|
||||
|
||||
# 1) try import
|
||||
try:
|
||||
mod = __import__(module_name)
|
||||
mod.__time__ = os.path.getmtime(mod.__file__)
|
||||
mod.__addon_enabled__ = False
|
||||
except:
|
||||
handle_error()
|
||||
return None
|
||||
# disable the context, using the context at all is
|
||||
# really bad while loading an addon, don't do it!
|
||||
with RestrictBlend():
|
||||
|
||||
# 2) try register collected modules
|
||||
# removed, addons need to handle own registration now.
|
||||
# 1) try import
|
||||
try:
|
||||
mod = __import__(module_name)
|
||||
mod.__time__ = os.path.getmtime(mod.__file__)
|
||||
mod.__addon_enabled__ = False
|
||||
except:
|
||||
handle_error()
|
||||
return None
|
||||
|
||||
# 3) try run the modules register function
|
||||
try:
|
||||
mod.register()
|
||||
except:
|
||||
print("Exception in module register(): %r" %
|
||||
getattr(mod, "__file__", module_name))
|
||||
handle_error()
|
||||
del sys.modules[module_name]
|
||||
return None
|
||||
# 2) try register collected modules
|
||||
# removed, addons need to handle own registration now.
|
||||
|
||||
# 3) try run the modules register function
|
||||
try:
|
||||
mod.register()
|
||||
except:
|
||||
print("Exception in module register(): %r" %
|
||||
getattr(mod, "__file__", module_name))
|
||||
handle_error()
|
||||
del sys.modules[module_name]
|
||||
return None
|
||||
|
||||
# * OK loaded successfully! *
|
||||
if default_set:
|
||||
# just in case its enabled already
|
||||
ext = _bpy.context.user_preferences.addons.get(module_name)
|
||||
ext = _user_preferences.addons.get(module_name)
|
||||
if not ext:
|
||||
ext = _bpy.context.user_preferences.addons.new()
|
||||
ext = _user_preferences.addons.new()
|
||||
ext.module = module_name
|
||||
|
||||
mod.__addon_enabled__ = True
|
||||
@ -327,7 +332,7 @@ def disable(module_name, default_set=True):
|
||||
(module_name, "disabled" if mod is None else "loaded"))
|
||||
|
||||
# could be in more then once, unlikely but better do this just in case.
|
||||
addons = _bpy.context.user_preferences.addons
|
||||
addons = _user_preferences.addons
|
||||
|
||||
if default_set:
|
||||
while module_name in addons:
|
||||
|
@ -57,6 +57,7 @@ import sys as _sys
|
||||
|
||||
import addon_utils as _addon_utils
|
||||
|
||||
_user_preferences = _bpy.context.user_preferences
|
||||
_script_module_dirs = "startup", "modules"
|
||||
|
||||
|
||||
@ -132,8 +133,6 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
|
||||
"""
|
||||
use_time = _bpy.app.debug_python
|
||||
|
||||
prefs = _bpy.context.user_preferences
|
||||
|
||||
if use_time:
|
||||
import time
|
||||
t_main = time.time()
|
||||
@ -150,7 +149,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
|
||||
# to reload. note that they will only actually reload of the
|
||||
# modification time changes. This `won't` work for packages so...
|
||||
# its not perfect.
|
||||
for module_name in [ext.module for ext in prefs.addons]:
|
||||
for module_name in [ext.module for ext in _user_preferences.addons]:
|
||||
_addon_utils.disable(module_name, default_set=False)
|
||||
|
||||
def register_module_call(mod):
|
||||
@ -218,24 +217,27 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
|
||||
|
||||
del _global_loaded_modules[:]
|
||||
|
||||
for base_path in script_paths():
|
||||
for path_subdir in _script_module_dirs:
|
||||
path = _os.path.join(base_path, path_subdir)
|
||||
if _os.path.isdir(path):
|
||||
_sys_path_ensure(path)
|
||||
from bpy_restrict_state import RestrictBlend
|
||||
|
||||
# only add this to sys.modules, don't run
|
||||
if path_subdir == "modules":
|
||||
continue
|
||||
with RestrictBlend():
|
||||
for base_path in script_paths():
|
||||
for path_subdir in _script_module_dirs:
|
||||
path = _os.path.join(base_path, path_subdir)
|
||||
if _os.path.isdir(path):
|
||||
_sys_path_ensure(path)
|
||||
|
||||
for mod in modules_from_path(path, loaded_modules):
|
||||
test_register(mod)
|
||||
# only add this to sys.modules, don't run
|
||||
if path_subdir == "modules":
|
||||
continue
|
||||
|
||||
for mod in modules_from_path(path, loaded_modules):
|
||||
test_register(mod)
|
||||
|
||||
# deal with addons separately
|
||||
_addon_utils.reset_all(reload_scripts)
|
||||
|
||||
# run the active integration preset
|
||||
filepath = preset_find(prefs.inputs.active_keyconfig, "keyconfig")
|
||||
filepath = preset_find(_user_preferences.inputs.active_keyconfig, "keyconfig")
|
||||
|
||||
if filepath:
|
||||
keyconfig_set(filepath)
|
||||
@ -264,7 +266,7 @@ def script_path_user():
|
||||
|
||||
def script_path_pref():
|
||||
"""returns the user preference or None"""
|
||||
path = _bpy.context.user_preferences.filepaths.script_directory
|
||||
path = _user_preferences.filepaths.script_directory
|
||||
return _os.path.normpath(path) if path else None
|
||||
|
||||
|
||||
|
57
release/scripts/modules/bpy_restrict_state.py
Normal file
57
release/scripts/modules/bpy_restrict_state.py
Normal file
@ -0,0 +1,57 @@
|
||||
# ##### 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 #####
|
||||
|
||||
# <pep8-80 compliant>
|
||||
|
||||
"""
|
||||
This module contains RestrictBlend context manager.
|
||||
"""
|
||||
|
||||
__all__ = (
|
||||
"RestrictBlend",
|
||||
)
|
||||
|
||||
import bpy as _bpy
|
||||
|
||||
class _RestrictContext():
|
||||
__slots__ = ()
|
||||
_real_data = _bpy.data
|
||||
@property
|
||||
def window_manager(self):
|
||||
return self._real_data.window_managers[0]
|
||||
|
||||
|
||||
class _RestrictData():
|
||||
__slots__ = ()
|
||||
|
||||
|
||||
_context_restrict = _RestrictContext()
|
||||
_data_restrict = _RestrictData()
|
||||
|
||||
|
||||
class RestrictBlend():
|
||||
__slots__ = ("context", "data")
|
||||
def __enter__(self):
|
||||
self.data = _bpy.data
|
||||
self.context = _bpy.context
|
||||
_bpy.data = _data_restrict
|
||||
_bpy.context = _context_restrict
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
_bpy.data = self.data
|
||||
_bpy.context = self.context
|
@ -484,6 +484,15 @@ class Text(bpy_types.ID):
|
||||
if cont.type == 'PYTHON']
|
||||
)
|
||||
|
||||
class NodeSocket(StructRNA): # , metaclass=RNAMeta
|
||||
__slots__ = ()
|
||||
|
||||
@property
|
||||
def links(self):
|
||||
"""List of node links from or to this socket"""
|
||||
return tuple(link for link in self.id_data.links if link.from_socket == self or link.to_socket == self)
|
||||
|
||||
|
||||
# values are module: [(cls, path, line), ...]
|
||||
TypeMap = {}
|
||||
|
||||
|
@ -170,6 +170,8 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
|
||||
if ob and pchan:
|
||||
col.label(text="Bone Group:")
|
||||
col.prop_search(pchan, "bone_group", ob.pose, "bone_groups", text="")
|
||||
col.label(text="Object Children:")
|
||||
col.prop(bone, "use_relative_parent")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Parent:")
|
||||
@ -181,11 +183,11 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
|
||||
sub = col.column()
|
||||
sub.active = (bone.parent is not None)
|
||||
sub.prop(bone, "use_connect")
|
||||
sub.prop(bone, "use_inherit_rotation", text="Inherit Rotation")
|
||||
sub.prop(bone, "use_inherit_scale", text="Inherit Scale")
|
||||
sub.prop(bone, "use_inherit_rotation")
|
||||
sub.prop(bone, "use_inherit_scale")
|
||||
sub = col.column()
|
||||
sub.active = (not bone.parent or not bone.use_connect)
|
||||
sub.prop(bone, "use_local_location", text="Local Location")
|
||||
sub.prop(bone, "use_local_location")
|
||||
|
||||
|
||||
class BONE_PT_display(BoneButtonsPanel, Panel):
|
||||
|
@ -1,4 +1,5 @@
|
||||
# ##### 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
|
||||
@ -544,7 +545,7 @@ class RENDER_PT_bake(RenderButtonsPanel, Panel):
|
||||
if rd.bake_type == 'AO':
|
||||
col = split.column()
|
||||
col.prop(rd, "bake_bias")
|
||||
col.prop(rd, "bake_rays_number")
|
||||
col.prop(rd, "bake_samples")
|
||||
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
@ -66,6 +66,7 @@ class TEXT_HT_header(Header):
|
||||
row.operator("text.run_script")
|
||||
|
||||
row = layout.row()
|
||||
row.active = text.name.endswith(".py")
|
||||
row.prop(text, "use_module")
|
||||
|
||||
row = layout.row()
|
||||
|
@ -686,6 +686,28 @@ class USERPREF_PT_theme(Panel):
|
||||
col.separator()
|
||||
|
||||
ui = theme.user_interface
|
||||
|
||||
col.label("Menu Shadow:")
|
||||
|
||||
row = col.row()
|
||||
|
||||
subsplit = row.split(percentage=0.95)
|
||||
|
||||
padding = subsplit.split(percentage=0.15)
|
||||
colsub = padding.column()
|
||||
colsub = padding.column()
|
||||
colsub.row().prop(ui, "menu_shadow_fac")
|
||||
|
||||
subsplit = row.split(percentage=0.85)
|
||||
|
||||
padding = subsplit.split(percentage=0.15)
|
||||
colsub = padding.column()
|
||||
colsub = padding.column()
|
||||
colsub.row().prop(ui, "menu_shadow_width")
|
||||
|
||||
col.separator()
|
||||
col.separator()
|
||||
|
||||
col.label("Icons:")
|
||||
|
||||
row = col.row()
|
||||
|
@ -971,6 +971,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel):
|
||||
col.operator("object.vertex_group_transfer_weight", text="Transfer Weights")
|
||||
col.operator("object.vertex_group_limit_total", text="Limit Total")
|
||||
col.operator("object.vertex_group_fix", text="Fix Deforms")
|
||||
col.operator("paint.weight_gradient")
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel):
|
||||
|
@ -2,7 +2,7 @@ bl_info = {
|
||||
"name": "New Object",
|
||||
"author": "Your Name Here",
|
||||
"version": (1, 0),
|
||||
"blender": (2, 5, 5),
|
||||
"blender": (2, 65, 0),
|
||||
"location": "View3D > Add > Mesh > New Object",
|
||||
"description": "Adds a new Mesh Object",
|
||||
"warning": "",
|
||||
|
@ -42,20 +42,22 @@ class ModalDrawOperator(bpy.types.Operator):
|
||||
self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
|
||||
|
||||
elif event.type == 'LEFTMOUSE':
|
||||
context.region.callback_remove(self._handle)
|
||||
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
|
||||
return {'FINISHED'}
|
||||
|
||||
elif event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||
context.region.callback_remove(self._handle)
|
||||
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
|
||||
return {'CANCELLED'}
|
||||
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
if context.area.type == 'VIEW_3D':
|
||||
# the arguments we pass the the callback
|
||||
args = (self, context)
|
||||
# Add the region OpenGL drawing callback
|
||||
# draw in view space with 'POST_VIEW' and 'PRE_VIEW'
|
||||
self._handle = context.region.callback_add(draw_callback_px, (self, context), 'POST_PIXEL')
|
||||
self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
|
||||
|
||||
self.mouse_path = []
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
||||
#ifdef __BIG_ENDIAN__
|
||||
|
||||
/* copied from BLI_endian_switch_inline.h */
|
||||
static void invert(int *num)
|
||||
static void invert(int *val)
|
||||
{
|
||||
int tval = *val;
|
||||
*val = ((tval >> 24)) |
|
||||
|
@ -50,7 +50,7 @@ extern "C" {
|
||||
|
||||
/* used by packaging tools */
|
||||
/* can be left blank, otherwise a,b,c... etc with no quotes */
|
||||
#define BLENDER_VERSION_CHAR
|
||||
#define BLENDER_VERSION_CHAR a
|
||||
/* alpha/beta/rc/release, docs use this */
|
||||
#define BLENDER_VERSION_CYCLE alpha
|
||||
|
||||
|
@ -185,6 +185,7 @@ enum {
|
||||
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member);
|
||||
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type);
|
||||
ListBase CTX_data_collection_get(const bContext *C, const char *member);
|
||||
ListBase CTX_data_dir_get_ex(const bContext *C, const short use_store, const short use_rna, const short use_all);
|
||||
ListBase CTX_data_dir_get(const bContext *C);
|
||||
int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb, short *r_type);
|
||||
|
||||
|
@ -114,7 +114,7 @@ typedef struct Global {
|
||||
#define G_BACKBUFSEL (1 << 4)
|
||||
#define G_PICKSEL (1 << 5)
|
||||
|
||||
/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_MASK) */
|
||||
/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_FACE_SEL) */
|
||||
|
||||
#define G_SCRIPT_AUTOEXEC (1 << 13)
|
||||
#define G_SCRIPT_OVERRIDE_PREF (1 << 14) /* when this flag is set ignore the userprefs */
|
||||
|
@ -123,6 +123,17 @@ void BKE_mesh_flush_hidden_from_verts(const struct MVert *mvert,
|
||||
struct MEdge *medge, int totedge,
|
||||
struct MPoly *mpoly, int totpoly);
|
||||
|
||||
void BKE_mesh_flush_select_from_polys_ex(struct MVert *mvert, const int totvert,
|
||||
struct MLoop *mloop,
|
||||
struct MEdge *medge, const int totedge,
|
||||
const struct MPoly *mpoly, const int totpoly);
|
||||
void BKE_mesh_flush_select_from_polys(struct Mesh *me);
|
||||
void BKE_mesh_flush_select_from_verts_ex(const struct MVert *mvert, const int totvert,
|
||||
struct MLoop *mloop,
|
||||
struct MEdge *medge, const int totedge,
|
||||
struct MPoly *mpoly, const int totpoly);
|
||||
void BKE_mesh_flush_select_from_verts(struct Mesh *me);
|
||||
|
||||
void BKE_mesh_unlink(struct Mesh *me);
|
||||
void BKE_mesh_free(struct Mesh *me, int unlink);
|
||||
struct Mesh *BKE_mesh_add(const char *name);
|
||||
@ -132,7 +143,7 @@ void mesh_update_customdata_pointers(struct Mesh *me, const short do_ensure_tess
|
||||
void BKE_mesh_make_local(struct Mesh *me);
|
||||
void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]);
|
||||
void BKE_mesh_texspace_calc(struct Mesh *me);
|
||||
float *BKE_mesh_orco_verts_get(struct Object *ob);
|
||||
float (*BKE_mesh_orco_verts_get(struct Object *ob))[3];
|
||||
void BKE_mesh_orco_verts_transform(struct Mesh *me, float (*orco)[3], int totvert, int invert);
|
||||
int test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex, int nr);
|
||||
struct Mesh *BKE_mesh_from_object(struct Object *ob);
|
||||
@ -152,7 +163,7 @@ void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase,
|
||||
int **orco_index_ptr);
|
||||
void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob);
|
||||
void free_dverts(struct MDeformVert *dvert, int totvert);
|
||||
void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */
|
||||
void copy_dverts(struct MDeformVert *dst, const struct MDeformVert *src, int totvert);
|
||||
void BKE_mesh_delete_material_index(struct Mesh *me, short index);
|
||||
void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
|
||||
void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
|
||||
|
@ -857,30 +857,27 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob,
|
||||
return dm;
|
||||
}
|
||||
|
||||
static float *get_editbmesh_orco_verts(BMEditMesh *em)
|
||||
static float (*get_editbmesh_orco_verts(BMEditMesh *em))[3]
|
||||
{
|
||||
BMIter iter;
|
||||
BMVert *eve;
|
||||
float *orco;
|
||||
int a, totvert;
|
||||
float (*orco)[3];
|
||||
int i;
|
||||
|
||||
/* these may not really be the orco's, but it's only for preview.
|
||||
* could be solver better once, but isn't simple */
|
||||
|
||||
totvert = em->bm->totvert;
|
||||
|
||||
orco = MEM_mallocN(sizeof(float) * 3 * totvert, "BMEditMesh Orco");
|
||||
orco = MEM_mallocN(sizeof(float) * 3 * em->bm->totvert, "BMEditMesh Orco");
|
||||
|
||||
eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
|
||||
for (a = 0; eve; eve = BM_iter_step(&iter), a += 3) {
|
||||
copy_v3_v3(orco + a, eve->co);
|
||||
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
|
||||
copy_v3_v3(orco[i], eve->co);
|
||||
}
|
||||
|
||||
return orco;
|
||||
}
|
||||
|
||||
/* orco custom data layer */
|
||||
static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free)
|
||||
static float (*get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free))[3]
|
||||
{
|
||||
*free = 0;
|
||||
|
||||
@ -889,9 +886,9 @@ static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free
|
||||
*free = 1;
|
||||
|
||||
if (em)
|
||||
return (float(*)[3])get_editbmesh_orco_verts(em);
|
||||
return get_editbmesh_orco_verts(em);
|
||||
else
|
||||
return (float(*)[3])BKE_mesh_orco_verts_get(ob);
|
||||
return BKE_mesh_orco_verts_get(ob);
|
||||
}
|
||||
else if (layer == CD_CLOTH_ORCO) {
|
||||
/* apply shape key for cloth, this should really be solved
|
||||
@ -1815,17 +1812,18 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
|
||||
BLI_linklist_free((LinkNode *)datamasks, NULL);
|
||||
}
|
||||
|
||||
float (*editbmesh_get_vertex_cos(BMEditMesh * em, int *numVerts_r))[3]
|
||||
float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *numVerts_r))[3]
|
||||
{
|
||||
int i, numVerts = *numVerts_r = em->bm->totvert;
|
||||
float (*cos)[3];
|
||||
BMIter iter;
|
||||
BMVert *eve;
|
||||
float (*cos)[3];
|
||||
int i;
|
||||
|
||||
cos = MEM_mallocN(sizeof(float) * 3 * numVerts, "vertexcos");
|
||||
*numVerts_r = em->bm->totvert;
|
||||
|
||||
eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
|
||||
for (i = 0; eve; eve = BM_iter_step(&iter), i++) {
|
||||
cos = MEM_mallocN(sizeof(float) * 3 * em->bm->totvert, "vertexcos");
|
||||
|
||||
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
|
||||
copy_v3_v3(cos[i], eve->co);
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/blenlib/intern/bpath.c
|
||||
/** \file blender/blenkernel/intern/bpath.c
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
|
@ -1875,7 +1875,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
|
||||
bm->totface);
|
||||
|
||||
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
|
||||
BMIter iter, liter;
|
||||
BMIter iter;
|
||||
BMVert *eve;
|
||||
BMEdge *eed;
|
||||
BMFace *efa;
|
||||
@ -1913,7 +1913,7 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
|
||||
CD_CALLOC, dm->numLoopData);
|
||||
CustomData_merge(&bm->pdata, &dm->polyData, mask,
|
||||
CD_CALLOC, dm->numPolyData);
|
||||
|
||||
|
||||
/* add tessellation mface layers */
|
||||
if (use_tessface) {
|
||||
CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em_tottri);
|
||||
@ -2002,7 +2002,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
|
||||
j = 0;
|
||||
efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
|
||||
for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) {
|
||||
BMLoop *l;
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
MPoly *mp = &mpoly[i];
|
||||
|
||||
BM_elem_index_set(efa, i); /* set_inline */
|
||||
@ -2011,15 +2012,16 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
|
||||
mp->flag = BM_face_flag_to_mflag(efa);
|
||||
mp->loopstart = j;
|
||||
mp->mat_nr = efa->mat_nr;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
mloop->v = BM_elem_index_get(l->v);
|
||||
mloop->e = BM_elem_index_get(l->e);
|
||||
CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
|
||||
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
|
||||
do {
|
||||
mloop->v = BM_elem_index_get(l_iter->v);
|
||||
mloop->e = BM_elem_index_get(l_iter->e);
|
||||
CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l_iter->head.data, j);
|
||||
|
||||
j++;
|
||||
mloop++;
|
||||
}
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
|
||||
CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
|
||||
|
||||
|
@ -427,11 +427,11 @@ int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListB
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void data_dir_add(ListBase *lb, const char *member)
|
||||
static void data_dir_add(ListBase *lb, const char *member, const short use_all)
|
||||
{
|
||||
LinkData *link;
|
||||
|
||||
if (strcmp(member, "scene") == 0) /* exception */
|
||||
if ((use_all == FALSE) && strcmp(member, "scene") == 0) /* exception */
|
||||
return;
|
||||
|
||||
if (BLI_findstring(lb, member, offsetof(LinkData, data)))
|
||||
@ -442,7 +442,13 @@ static void data_dir_add(ListBase *lb, const char *member)
|
||||
BLI_addtail(lb, link);
|
||||
}
|
||||
|
||||
ListBase CTX_data_dir_get(const bContext *C)
|
||||
/**
|
||||
* \param C Context
|
||||
* \param use_store Use 'C->wm.store'
|
||||
* \param use_rna Use Include the properties from 'RNA_Context'
|
||||
* \param use_all Don't skip values (currently only "scene")
|
||||
*/
|
||||
ListBase CTX_data_dir_get_ex(const bContext *C, const short use_store, const short use_rna, const short use_all)
|
||||
{
|
||||
bContextDataResult result;
|
||||
ListBase lb;
|
||||
@ -453,11 +459,33 @@ ListBase CTX_data_dir_get(const bContext *C)
|
||||
|
||||
memset(&lb, 0, sizeof(lb));
|
||||
|
||||
if (C->wm.store) {
|
||||
if (use_rna) {
|
||||
char name[256], *nameptr;
|
||||
int namelen;
|
||||
|
||||
PropertyRNA *iterprop;
|
||||
PointerRNA ctx_ptr;
|
||||
RNA_pointer_create(NULL, &RNA_Context, (void *)C, &ctx_ptr);
|
||||
|
||||
iterprop = RNA_struct_iterator_property(ctx_ptr.type);
|
||||
|
||||
RNA_PROP_BEGIN (&ctx_ptr, itemptr, iterprop)
|
||||
{
|
||||
nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
|
||||
data_dir_add(&lb, name, use_all);
|
||||
if (nameptr) {
|
||||
if (name != nameptr) {
|
||||
MEM_freeN(nameptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
RNA_PROP_END;
|
||||
}
|
||||
if (use_store && C->wm.store) {
|
||||
bContextStoreEntry *entry;
|
||||
|
||||
for (entry = C->wm.store->entries.first; entry; entry = entry->next)
|
||||
data_dir_add(&lb, entry->name);
|
||||
data_dir_add(&lb, entry->name, use_all);
|
||||
}
|
||||
if ((ar = CTX_wm_region(C)) && ar->type && ar->type->context) {
|
||||
memset(&result, 0, sizeof(result));
|
||||
@ -465,7 +493,7 @@ ListBase CTX_data_dir_get(const bContext *C)
|
||||
|
||||
if (result.dir)
|
||||
for (a = 0; result.dir[a]; a++)
|
||||
data_dir_add(&lb, result.dir[a]);
|
||||
data_dir_add(&lb, result.dir[a], use_all);
|
||||
}
|
||||
if ((sa = CTX_wm_area(C)) && sa->type && sa->type->context) {
|
||||
memset(&result, 0, sizeof(result));
|
||||
@ -473,7 +501,7 @@ ListBase CTX_data_dir_get(const bContext *C)
|
||||
|
||||
if (result.dir)
|
||||
for (a = 0; result.dir[a]; a++)
|
||||
data_dir_add(&lb, result.dir[a]);
|
||||
data_dir_add(&lb, result.dir[a], use_all);
|
||||
}
|
||||
if ((sc = CTX_wm_screen(C)) && sc->context) {
|
||||
bContextDataCallback cb = sc->context;
|
||||
@ -482,12 +510,17 @@ ListBase CTX_data_dir_get(const bContext *C)
|
||||
|
||||
if (result.dir)
|
||||
for (a = 0; result.dir[a]; a++)
|
||||
data_dir_add(&lb, result.dir[a]);
|
||||
data_dir_add(&lb, result.dir[a], use_all);
|
||||
}
|
||||
|
||||
return lb;
|
||||
}
|
||||
|
||||
ListBase CTX_data_dir_get(const bContext *C)
|
||||
{
|
||||
return CTX_data_dir_get_ex(C, TRUE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
int CTX_data_equals(const char *member, const char *str)
|
||||
{
|
||||
return (strcmp(member, str) == 0);
|
||||
|
@ -687,7 +687,7 @@ static void boundInsert(Bounds3D *b, float point[3])
|
||||
static float getSurfaceDimension(PaintSurfaceData *sData)
|
||||
{
|
||||
Bounds3D *mb = &sData->bData->mesh_bounds;
|
||||
return MAX3((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
|
||||
return max_fff((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
|
||||
}
|
||||
|
||||
static void freeGrid(PaintSurfaceData *data)
|
||||
@ -754,14 +754,14 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface)
|
||||
/* get dimensions */
|
||||
sub_v3_v3v3(dim, grid->grid_bounds.max, grid->grid_bounds.min);
|
||||
copy_v3_v3(td, dim);
|
||||
min_dim = MAX3(td[0], td[1], td[2]) / 1000.f;
|
||||
min_dim = max_fff(td[0], td[1], td[2]) / 1000.f;
|
||||
|
||||
/* deactivate zero axises */
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (td[i] < min_dim) { td[i] = 1.0f; axis -= 1; }
|
||||
}
|
||||
|
||||
if (axis == 0 || MAX3(td[0], td[1], td[2]) < 0.0001f) {
|
||||
if (axis == 0 || max_fff(td[0], td[1], td[2]) < 0.0001f) {
|
||||
MEM_freeN(grid_bounds);
|
||||
MEM_freeN(bData->grid);
|
||||
bData->grid = NULL;
|
||||
@ -4260,7 +4260,7 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s
|
||||
if (surface->effect & MOD_DPAINT_EFFECT_DO_SHRINK)
|
||||
shrink_speed = surface->shrink_speed;
|
||||
|
||||
fastest_effect = MAX3(spread_speed, shrink_speed, average_force);
|
||||
fastest_effect = max_fff(spread_speed, shrink_speed, average_force);
|
||||
avg_dist = bData->average_dist * CANVAS_REL_SIZE / getSurfaceDimension(sData);
|
||||
|
||||
steps = (int)ceil(1.5f * EFF_MOVEMENT_PER_FRAME * fastest_effect / avg_dist * timescale);
|
||||
@ -4444,8 +4444,7 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal
|
||||
float dt, min_dist, damp_factor;
|
||||
float wave_speed = surface->wave_speed;
|
||||
double average_dist = 0.0f;
|
||||
Bounds3D *mb = &sData->bData->mesh_bounds;
|
||||
float canvas_size = MAX3((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
|
||||
const float canvas_size = getSurfaceDimension(sData);
|
||||
float wave_scale = CANVAS_REL_SIZE / canvas_size;
|
||||
|
||||
/* allocate memory */
|
||||
|
@ -115,10 +115,10 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
|
||||
BMesh *bm = em->bm;
|
||||
BMLoop *(*looptris)[3] = NULL;
|
||||
BLI_array_declare(looptris);
|
||||
BMIter iter, liter;
|
||||
BMIter iter;
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
int i = 0, j;
|
||||
int i = 0;
|
||||
|
||||
ScanFillContext sf_ctx;
|
||||
|
||||
@ -161,16 +161,29 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
|
||||
/* no need to ensure the loop order, we know its ok */
|
||||
|
||||
else if (efa->len == 3) {
|
||||
#if 0
|
||||
int j;
|
||||
BLI_array_grow_one(looptris);
|
||||
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
|
||||
looptris[i][j] = l;
|
||||
}
|
||||
i += 1;
|
||||
#else
|
||||
/* more cryptic but faster */
|
||||
BLI_array_grow_one(looptris);
|
||||
{
|
||||
BMLoop **l_ptr = looptris[i++];
|
||||
l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa);
|
||||
l_ptr[1] = l = l->next;
|
||||
l_ptr[2] = l->next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (efa->len == 4) {
|
||||
#if 0
|
||||
BMLoop *ltmp[4];
|
||||
int j;
|
||||
BLI_array_grow_items(looptris, 2);
|
||||
|
||||
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
|
||||
ltmp[j] = l;
|
||||
}
|
||||
@ -184,11 +197,27 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
|
||||
looptris[i][1] = ltmp[2];
|
||||
looptris[i][2] = ltmp[3];
|
||||
i += 1;
|
||||
#else
|
||||
/* more cryptic but faster */
|
||||
BLI_array_grow_items(looptris, 2);
|
||||
{
|
||||
BMLoop **l_ptr_a = looptris[i++];
|
||||
BMLoop **l_ptr_b = looptris[i++];
|
||||
(l_ptr_a[0] = l_ptr_b[0] = l = BM_FACE_FIRST_LOOP(efa));
|
||||
(l_ptr_a[1] = l = l->next);
|
||||
(l_ptr_a[2] = l_ptr_b[1] = l = l->next);
|
||||
( l_ptr_b[2] = l->next);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* USE_TESSFACE_SPEEDUP */
|
||||
|
||||
else {
|
||||
int j;
|
||||
BMLoop *l_iter;
|
||||
BMLoop *l_first;
|
||||
|
||||
ScanFillVert *sf_vert, *sf_vert_last = NULL, *sf_vert_first = NULL;
|
||||
/* ScanFillEdge *e; */ /* UNUSED */
|
||||
ScanFillFace *sf_tri;
|
||||
@ -197,20 +226,25 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *em)
|
||||
BLI_scanfill_begin(&sf_ctx);
|
||||
|
||||
/* scanfill time */
|
||||
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
|
||||
/*mark order */
|
||||
BM_elem_index_set(l, j); /* set_loop */
|
||||
|
||||
sf_vert = BLI_scanfill_vert_add(&sf_ctx, l->v->co);
|
||||
sf_vert->tmp.p = l;
|
||||
j = 0;
|
||||
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
|
||||
do {
|
||||
sf_vert = BLI_scanfill_vert_add(&sf_ctx, l_iter->v->co);
|
||||
sf_vert->tmp.p = l_iter;
|
||||
|
||||
if (sf_vert_last) {
|
||||
/* e = */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert);
|
||||
}
|
||||
|
||||
sf_vert_last = sf_vert;
|
||||
if (sf_vert_first == NULL) sf_vert_first = sf_vert;
|
||||
}
|
||||
if (sf_vert_first == NULL) {
|
||||
sf_vert_first = sf_vert;
|
||||
}
|
||||
|
||||
/*mark order */
|
||||
BM_elem_index_set(l_iter, j++); /* set_loop */
|
||||
|
||||
} while ((l_iter = l_iter->next) != l_first);
|
||||
|
||||
/* complete the loop */
|
||||
BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
|
||||
|
@ -500,8 +500,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
|
||||
BLI_assert(bezt_last != NULL);
|
||||
|
||||
if (include_handles) {
|
||||
xminv = MIN3(xminv, bezt_first->vec[0][0], bezt_first->vec[1][0]);
|
||||
xmaxv = MAX3(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]);
|
||||
xminv = min_fff(xminv, bezt_first->vec[0][0], bezt_first->vec[1][0]);
|
||||
xmaxv = max_fff(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]);
|
||||
}
|
||||
else {
|
||||
xminv = min_ff(xminv, bezt_first->vec[1][0]);
|
||||
@ -517,8 +517,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
|
||||
for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
|
||||
if ((do_sel_only == FALSE) || BEZSELECTED(bezt)) {
|
||||
if (include_handles) {
|
||||
yminv = MIN4(yminv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
|
||||
ymaxv = MAX4(ymaxv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
|
||||
yminv = min_ffff(yminv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
|
||||
ymaxv = max_ffff(ymaxv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
|
||||
}
|
||||
else {
|
||||
yminv = min_ff(yminv, bezt->vec[1][1]);
|
||||
|
@ -188,7 +188,7 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, int setactive)
|
||||
|
||||
/* make this one the active one */
|
||||
if (setactive)
|
||||
gpencil_layer_setactive(gpd, gpl);
|
||||
gpencil_layer_setactive(gpd, gpl);
|
||||
|
||||
/* return layer */
|
||||
return gpl;
|
||||
|
@ -937,7 +937,7 @@ int BKE_imtype_to_ftype(const char imtype)
|
||||
return RADHDR;
|
||||
#endif
|
||||
else if (imtype == R_IMF_IMTYPE_PNG)
|
||||
return PNG;
|
||||
return PNG | 90;
|
||||
#ifdef WITH_DDS
|
||||
else if (imtype == R_IMF_IMTYPE_DDS)
|
||||
return DDS;
|
||||
|
@ -158,8 +158,10 @@ void id_lib_extern(ID *id)
|
||||
/* ensure we have a real user */
|
||||
void id_us_ensure_real(ID *id)
|
||||
{
|
||||
if (ID_REAL_USERS(id) <= 0) {
|
||||
id->us = MAX2(id->us, 0) + 1;
|
||||
if (id) {
|
||||
if (ID_REAL_USERS(id) <= 0) {
|
||||
id->us = MAX2(id->us, 0) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1514,7 +1514,7 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
|
||||
float in_v /*, out_v*/;
|
||||
float workp[3];
|
||||
float dvec[3];
|
||||
float tmp_v, workp_v, max_len, len, nx, ny, nz, MAXN;
|
||||
float tmp_v, workp_v, max_len, nx, ny, nz, max_dim;
|
||||
|
||||
calc_mballco(ml, in);
|
||||
in_v = mbproc->function(in[0], in[1], in[2]);
|
||||
@ -1573,17 +1573,17 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
|
||||
ny = abs((out[1] - in[1]) / mbproc->size);
|
||||
nz = abs((out[2] - in[2]) / mbproc->size);
|
||||
|
||||
MAXN = MAX3(nx, ny, nz);
|
||||
if (MAXN != 0.0f) {
|
||||
dvec[0] = (out[0] - in[0]) / MAXN;
|
||||
dvec[1] = (out[1] - in[1]) / MAXN;
|
||||
dvec[2] = (out[2] - in[2]) / MAXN;
|
||||
max_dim = max_fff(nx, ny, nz);
|
||||
if (max_dim != 0.0f) {
|
||||
float len = 0.0f;
|
||||
|
||||
dvec[0] = (out[0] - in[0]) / max_dim;
|
||||
dvec[1] = (out[1] - in[1]) / max_dim;
|
||||
dvec[2] = (out[2] - in[2]) / max_dim;
|
||||
|
||||
len = 0.0;
|
||||
while (len <= max_len) {
|
||||
workp[0] += dvec[0];
|
||||
workp[1] += dvec[1];
|
||||
workp[2] += dvec[2];
|
||||
add_v3_v3(workp, dvec);
|
||||
|
||||
/* compute value of implicite function */
|
||||
tmp_v = mbproc->function(workp[0], workp[1], workp[2]);
|
||||
/* add cube to the stack, when value of implicite function crosses zero value */
|
||||
|
@ -430,7 +430,7 @@ void BKE_mesh_free(Mesh *me, int unlink)
|
||||
if (me->edit_btmesh) MEM_freeN(me->edit_btmesh);
|
||||
}
|
||||
|
||||
void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount)
|
||||
void copy_dverts(MDeformVert *dst, const MDeformVert *src, int copycount)
|
||||
{
|
||||
/* Assumes dst is already set up */
|
||||
int i;
|
||||
@ -442,7 +442,7 @@ void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount)
|
||||
|
||||
for (i = 0; i < copycount; i++) {
|
||||
if (src[i].dw) {
|
||||
dst[i].dw = MEM_callocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
|
||||
dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight");
|
||||
memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight);
|
||||
}
|
||||
}
|
||||
@ -731,7 +731,7 @@ void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_rot[3], float r_siz
|
||||
if (r_size) copy_v3_v3(r_size, me->size);
|
||||
}
|
||||
|
||||
float *BKE_mesh_orco_verts_get(Object *ob)
|
||||
float (*BKE_mesh_orco_verts_get(Object *ob))[3]
|
||||
{
|
||||
Mesh *me = ob->data;
|
||||
MVert *mvert = NULL;
|
||||
@ -748,7 +748,7 @@ float *BKE_mesh_orco_verts_get(Object *ob)
|
||||
copy_v3_v3(vcos[a], mvert->co);
|
||||
}
|
||||
|
||||
return (float *)vcos;
|
||||
return vcos;
|
||||
}
|
||||
|
||||
void BKE_mesh_orco_verts_transform(Mesh *me, float (*orco)[3], int totvert, int invert)
|
||||
@ -3107,6 +3107,107 @@ void BKE_mesh_flush_hidden_from_verts(const MVert *mvert,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* simple poly -> vert/edge selection.
|
||||
*/
|
||||
void BKE_mesh_flush_select_from_polys_ex(MVert *mvert, const int totvert,
|
||||
MLoop *mloop,
|
||||
MEdge *medge, const int totedge,
|
||||
const MPoly *mpoly, const int totpoly)
|
||||
{
|
||||
MVert *mv;
|
||||
MEdge *med;
|
||||
const MPoly *mp;
|
||||
int i;
|
||||
|
||||
i = totvert;
|
||||
for (mv = mvert; i--; mv++) {
|
||||
mv->flag &= ~SELECT;
|
||||
}
|
||||
|
||||
i = totedge;
|
||||
for (med = medge; i--; med++) {
|
||||
med->flag &= ~SELECT;
|
||||
}
|
||||
|
||||
i = totpoly;
|
||||
for (mp = mpoly; i--; mp++) {
|
||||
/* assume if its selected its not hidden and none of its verts/edges are hidden
|
||||
* (a common assumption)*/
|
||||
if (mp->flag & ME_FACE_SEL) {
|
||||
MLoop *ml;
|
||||
int j;
|
||||
j = mp->totloop;
|
||||
for (ml = &mloop[mp->loopstart]; j--; ml++) {
|
||||
mvert[ml->v].flag |= SELECT;
|
||||
medge[ml->e].flag |= SELECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void BKE_mesh_flush_select_from_polys(Mesh *me)
|
||||
{
|
||||
BKE_mesh_flush_select_from_polys_ex(me->mvert, me->totvert,
|
||||
me->mloop,
|
||||
me->medge, me->totedge,
|
||||
me->mpoly, me->totpoly);
|
||||
}
|
||||
|
||||
void BKE_mesh_flush_select_from_verts_ex(const MVert *mvert, const int UNUSED(totvert),
|
||||
MLoop *mloop,
|
||||
MEdge *medge, const int totedge,
|
||||
MPoly *mpoly, const int totpoly)
|
||||
{
|
||||
MEdge *med;
|
||||
MPoly *mp;
|
||||
int i;
|
||||
|
||||
/* edges */
|
||||
i = totedge;
|
||||
for (med = medge; i--; med++) {
|
||||
if ((med->flag & ME_HIDE) == 0) {
|
||||
if ((mvert[med->v1].flag & SELECT) && (mvert[med->v2].flag & SELECT)) {
|
||||
med->flag |= SELECT;
|
||||
}
|
||||
else {
|
||||
med->flag &= ~SELECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* polys */
|
||||
i = totpoly;
|
||||
for (mp = mpoly; i--; mp++) {
|
||||
if ((mp->flag & ME_HIDE) == 0) {
|
||||
int ok = TRUE;
|
||||
MLoop *ml;
|
||||
int j;
|
||||
j = mp->totloop;
|
||||
for (ml = &mloop[mp->loopstart]; j--; ml++) {
|
||||
if ((mvert[ml->v].flag & SELECT) == 0) {
|
||||
ok = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
mp->flag |= ME_FACE_SEL;
|
||||
}
|
||||
else {
|
||||
mp->flag &= ~ME_FACE_SEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void BKE_mesh_flush_select_from_verts(Mesh *me)
|
||||
{
|
||||
BKE_mesh_flush_select_from_verts_ex(me->mvert, me->totvert,
|
||||
me->mloop,
|
||||
me->medge, me->totedge,
|
||||
me->mpoly, me->totpoly);
|
||||
}
|
||||
|
||||
|
||||
/* basic vertex data functions */
|
||||
int BKE_mesh_minmax(Mesh *me, float r_min[3], float r_max[3])
|
||||
{
|
||||
|
@ -2162,6 +2162,24 @@ void nodeRegisterType(bNodeTreeType *ttype, bNodeType *ntype)
|
||||
|
||||
if (found == NULL)
|
||||
BLI_addtail(typelist, ntype);
|
||||
|
||||
/* Associate the RNA struct type with the bNodeType.
|
||||
* Dynamically registered nodes will create an RNA type at runtime
|
||||
* and call RNA_struct_blender_type_set, so this only needs to be done for old RNA types
|
||||
* created in makesrna, which can not be associated to a bNodeType immediately,
|
||||
* since bNodeTypes are registered afterward ...
|
||||
*/
|
||||
#define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
|
||||
if (ID == ntype->type) { \
|
||||
StructRNA *srna = RNA_struct_find(STRINGIFY_ARG(Category##StructName)); \
|
||||
BLI_assert(srna != NULL); \
|
||||
RNA_struct_blender_type_set(srna, ntype); \
|
||||
}
|
||||
|
||||
/* XXX hack, this file will be moved to the nodes folder in customnodes branch,
|
||||
* then this stupid include path is not needed any more.
|
||||
*/
|
||||
#include "intern/rna_nodetree_types.h"
|
||||
}
|
||||
|
||||
static void registerCompositNodes(bNodeTreeType *ttype)
|
||||
|
@ -1853,12 +1853,19 @@ static void ob_parbone(Object *ob, Object *par, float mat[4][4])
|
||||
}
|
||||
|
||||
/* get bone transform */
|
||||
copy_m4_m4(mat, pchan->pose_mat);
|
||||
if (pchan->bone->flag & BONE_RELATIVE_PARENTING) {
|
||||
/* the new option uses the root - expected bahaviour, but differs from old... */
|
||||
/* XXX check on version patching? */
|
||||
copy_m4_m4(mat, pchan->chan_mat);
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(mat, pchan->pose_mat);
|
||||
|
||||
/* but for backwards compatibility, the child has to move to the tail */
|
||||
copy_v3_v3(vec, mat[1]);
|
||||
mul_v3_fl(vec, pchan->bone->length);
|
||||
add_v3_v3(mat[3], vec);
|
||||
/* but for backwards compatibility, the child has to move to the tail */
|
||||
copy_v3_v3(vec, mat[1]);
|
||||
mul_v3_fl(vec, pchan->bone->length);
|
||||
add_v3_v3(mat[3], vec);
|
||||
}
|
||||
}
|
||||
|
||||
static void give_parvert(Object *par, int nr, float vec[3])
|
||||
@ -1936,7 +1943,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
|
||||
}
|
||||
else if (ELEM(par->type, OB_CURVE, OB_SURF)) {
|
||||
Curve *cu = par->data;
|
||||
ListBase *nurb = BKE_curve_nurbs_get(cu);;
|
||||
ListBase *nurb = BKE_curve_nurbs_get(cu);
|
||||
|
||||
BKE_nurbList_index_get_co(nurb, nr, vec);
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ int paint_facesel_test(Object *ob)
|
||||
return ( (ob != NULL) &&
|
||||
(ob->type == OB_MESH) &&
|
||||
(ob->data != NULL) &&
|
||||
(((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_MASK) &&
|
||||
(((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) &&
|
||||
(ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
|
||||
);
|
||||
}
|
||||
@ -165,7 +165,7 @@ int paint_vertsel_test(Object *ob)
|
||||
return ( (ob != NULL) &&
|
||||
(ob->type == OB_MESH) &&
|
||||
(ob->data != NULL) &&
|
||||
(((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) &&
|
||||
(((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) &&
|
||||
(ob->mode & OB_MODE_WEIGHT_PAINT)
|
||||
);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/blenlib/intern/pbvh.c
|
||||
/** \file blender/blenkernel/intern/pbvh.c
|
||||
* \ingroup bli
|
||||
*/
|
||||
|
||||
|
@ -446,7 +446,8 @@ static Scene *scene_add(Main *bmain, const char *name)
|
||||
sce->r.bake_osa = 5;
|
||||
sce->r.bake_flag = R_BAKE_CLEAR;
|
||||
sce->r.bake_normal_space = R_BAKE_SPACE_TANGENT;
|
||||
sce->r.bake_rays_number = 256;
|
||||
sce->r.bake_samples = 256;
|
||||
sce->r.bake_biasdist = 0.001;
|
||||
sce->r.scemode = R_DOCOMP | R_DOSEQ | R_EXTENSION;
|
||||
sce->r.stamp = R_STAMP_TIME | R_STAMP_FRAME | R_STAMP_DATE | R_STAMP_CAMERA | R_STAMP_SCENE | R_STAMP_FILENAME | R_STAMP_RENDERTIME;
|
||||
sce->r.stamp_font_id = 12;
|
||||
|
@ -593,8 +593,8 @@ void BKE_sequence_calc(Scene *scene, Sequence *seq)
|
||||
/* XXX These resets should not be necessary, but users used to be able to
|
||||
* edit effect's length, leading to strange results. See [#29190] */
|
||||
seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
|
||||
seq->start = seq->startdisp = MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
|
||||
seq->enddisp = MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
|
||||
seq->start = seq->startdisp = max_iii(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
|
||||
seq->enddisp = min_iii(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
|
||||
/* we cant help if strips don't overlap, it wont give useful results.
|
||||
* but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
|
||||
if (seq->enddisp < seq->startdisp) {
|
||||
|
@ -170,7 +170,7 @@ void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int
|
||||
|
||||
if (free_old && sds->fluid)
|
||||
smoke_free(sds->fluid);
|
||||
if (!MIN3(res[0], res[1], res[2])) {
|
||||
if (!min_iii(res[0], res[1], res[2])) {
|
||||
sds->fluid = NULL;
|
||||
return;
|
||||
}
|
||||
@ -191,7 +191,7 @@ void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[
|
||||
|
||||
if (free_old && sds->wt)
|
||||
smoke_turbulence_free(sds->wt);
|
||||
if (!MIN3(res[0], res[1], res[2])) {
|
||||
if (!min_iii(res[0], res[1], res[2])) {
|
||||
sds->wt = NULL;
|
||||
return;
|
||||
}
|
||||
|
@ -1097,12 +1097,12 @@ static int sb_detect_face_pointCached(float face_v1[3], float face_v2[3], float
|
||||
float facedist, outerfacethickness, tune = 10.f;
|
||||
int a, deflected=0;
|
||||
|
||||
aabbmin[0] = MIN3(face_v1[0], face_v2[0], face_v3[0]);
|
||||
aabbmin[1] = MIN3(face_v1[1], face_v2[1], face_v3[1]);
|
||||
aabbmin[2] = MIN3(face_v1[2], face_v2[2], face_v3[2]);
|
||||
aabbmax[0] = MAX3(face_v1[0], face_v2[0], face_v3[0]);
|
||||
aabbmax[1] = MAX3(face_v1[1], face_v2[1], face_v3[1]);
|
||||
aabbmax[2] = MAX3(face_v1[2], face_v2[2], face_v3[2]);
|
||||
aabbmin[0] = min_fff(face_v1[0], face_v2[0], face_v3[0]);
|
||||
aabbmin[1] = min_fff(face_v1[1], face_v2[1], face_v3[1]);
|
||||
aabbmin[2] = min_fff(face_v1[2], face_v2[2], face_v3[2]);
|
||||
aabbmax[0] = max_fff(face_v1[0], face_v2[0], face_v3[0]);
|
||||
aabbmax[1] = max_fff(face_v1[1], face_v2[1], face_v3[1]);
|
||||
aabbmax[2] = max_fff(face_v1[2], face_v2[2], face_v3[2]);
|
||||
|
||||
/* calculate face normal once again SIGH */
|
||||
sub_v3_v3v3(edge1, face_v1, face_v2);
|
||||
@ -1196,12 +1196,12 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
|
||||
float t, tune = 10.0f;
|
||||
int a, deflected=0;
|
||||
|
||||
aabbmin[0] = MIN3(face_v1[0], face_v2[0], face_v3[0]);
|
||||
aabbmin[1] = MIN3(face_v1[1], face_v2[1], face_v3[1]);
|
||||
aabbmin[2] = MIN3(face_v1[2], face_v2[2], face_v3[2]);
|
||||
aabbmax[0] = MAX3(face_v1[0], face_v2[0], face_v3[0]);
|
||||
aabbmax[1] = MAX3(face_v1[1], face_v2[1], face_v3[1]);
|
||||
aabbmax[2] = MAX3(face_v1[2], face_v2[2], face_v3[2]);
|
||||
aabbmin[0] = min_fff(face_v1[0], face_v2[0], face_v3[0]);
|
||||
aabbmin[1] = min_fff(face_v1[1], face_v2[1], face_v3[1]);
|
||||
aabbmin[2] = min_fff(face_v1[2], face_v2[2], face_v3[2]);
|
||||
aabbmax[0] = max_fff(face_v1[0], face_v2[0], face_v3[0]);
|
||||
aabbmax[1] = max_fff(face_v1[1], face_v2[1], face_v3[1]);
|
||||
aabbmax[2] = max_fff(face_v1[2], face_v2[2], face_v3[2]);
|
||||
|
||||
hash = vertexowner->soft->scratch->colliderhash;
|
||||
ihash = BLI_ghashIterator_new(hash);
|
||||
@ -1957,7 +1957,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
|
||||
}
|
||||
|
||||
closest_to_line_segment_v3(ve, opco, nv2, nv3);
|
||||
sub_v3_v3v3(ve, opco, ve);
|
||||
sub_v3_v3v3(ve, opco, ve);
|
||||
dist = normalize_v3(ve);
|
||||
if ((dist < outerfacethickness)&&(dist < mindistedge )) {
|
||||
copy_v3_v3(coledge, ve);
|
||||
@ -1966,7 +1966,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
|
||||
}
|
||||
|
||||
closest_to_line_segment_v3(ve, opco, nv3, nv1);
|
||||
sub_v3_v3v3(ve, opco, ve);
|
||||
sub_v3_v3v3(ve, opco, ve);
|
||||
dist = normalize_v3(ve);
|
||||
if ((dist < outerfacethickness)&&(dist < mindistedge )) {
|
||||
copy_v3_v3(coledge, ve);
|
||||
|
@ -106,8 +106,8 @@
|
||||
((arr = (void *)_##arr##_static), (_##arr##_count += (num))) \
|
||||
: \
|
||||
/* use existing static array or allocate */ \
|
||||
((BLI_array_totalsize(arr) >= _##arr##_count + num) ? \
|
||||
(_##arr##_count += num) : \
|
||||
(LIKELY(BLI_array_totalsize(arr) >= _##arr##_count + num) ? \
|
||||
(_##arr##_count += num) : /* UNLIKELY --> realloc */ \
|
||||
( \
|
||||
(void) (_##arr##_tmp = MEM_callocN( \
|
||||
sizeof(*arr) * (num < _##arr##_count ? \
|
||||
|
@ -175,6 +175,42 @@ MINLINE int max_ii(int a, int b)
|
||||
return (b < a) ? a : b;
|
||||
}
|
||||
|
||||
MINLINE float min_fff(float a, float b, float c)
|
||||
{
|
||||
return min_ff(min_ff(a, b), c);
|
||||
}
|
||||
MINLINE float max_fff(float a, float b, float c)
|
||||
{
|
||||
return max_ff(max_ff(a, b), c);
|
||||
}
|
||||
|
||||
MINLINE int min_iii(int a, int b, int c)
|
||||
{
|
||||
return min_ii(min_ii(a, b), c);
|
||||
}
|
||||
MINLINE int max_iii(int a, int b, int c)
|
||||
{
|
||||
return max_ii(max_ii(a, b), c);
|
||||
}
|
||||
|
||||
MINLINE float min_ffff(float a, float b, float c, float d)
|
||||
{
|
||||
return min_ff(min_fff(a, b, c), d);
|
||||
}
|
||||
MINLINE float max_ffff(float a, float b, float c, float d)
|
||||
{
|
||||
return max_ff(max_fff(a, b, c), d);
|
||||
}
|
||||
|
||||
MINLINE int min_iiii(int a, int b, int c, int d)
|
||||
{
|
||||
return min_ii(min_iii(a, b, c), d);
|
||||
}
|
||||
MINLINE int max_iiii(int a, int b, int c, int d)
|
||||
{
|
||||
return max_ii(max_iii(a, b, c), d);
|
||||
}
|
||||
|
||||
MINLINE float signf(float f)
|
||||
{
|
||||
return (f < 0.f) ? -1.f : 1.f;
|
||||
|
@ -266,8 +266,8 @@ void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
|
||||
|
||||
void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll)
|
||||
{
|
||||
float cmax = MAX3(r, g, b);
|
||||
float cmin = MIN3(r, g, b);
|
||||
const float cmax = max_fff(r, g, b);
|
||||
const float cmin = min_fff(r, g, b);
|
||||
float h, s, l = (cmax + cmin) / 2.0f;
|
||||
|
||||
if (cmax == cmin) {
|
||||
|
@ -140,7 +140,7 @@ float area_poly_v3(int nr, float verts[][3], const float normal[3])
|
||||
x = fabsf(normal[0]);
|
||||
y = fabsf(normal[1]);
|
||||
z = fabsf(normal[2]);
|
||||
max = MAX3(x, y, z);
|
||||
max = max_fff(x, y, z);
|
||||
if (max == y) py = 2;
|
||||
else if (max == x) {
|
||||
px = 1;
|
||||
@ -1198,10 +1198,10 @@ int isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3]
|
||||
return isect_line_tri_v3(p1,p2,v0,v1,v2,lambda);
|
||||
|
||||
/* first a simple bounding box test */
|
||||
if (MIN3(v0[a1],v1[a1],v2[a1]) > p1[a1]) return 0;
|
||||
if (MIN3(v0[a2],v1[a2],v2[a2]) > p1[a2]) return 0;
|
||||
if (MAX3(v0[a1],v1[a1],v2[a1]) < p1[a1]) return 0;
|
||||
if (MAX3(v0[a2],v1[a2],v2[a2]) < p1[a2]) return 0;
|
||||
if (min_fff(v0[a1], v1[a1], v2[a1]) > p1[a1]) return 0;
|
||||
if (min_fff(v0[a2], v1[a2], v2[a2]) > p1[a2]) return 0;
|
||||
if (max_fff(v0[a1], v1[a1], v2[a1]) < p1[a1]) return 0;
|
||||
if (max_fff(v0[a2], v1[a2], v2[a2]) < p1[a2]) return 0;
|
||||
|
||||
/* then a full intersection test */
|
||||
#endif
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* ***** 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.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): none yet.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
#ifndef __BLO_SOUNDFILE_H__
|
||||
#define __BLO_SOUNDFILE_H__
|
||||
|
||||
/** \file BLO_soundfile.h
|
||||
* \ingroup blenloader
|
||||
*/
|
||||
|
||||
#include "DNA_sound_types.h"
|
||||
#include "DNA_packedFile_types.h"
|
||||
|
||||
struct bSound;
|
||||
struct PackedFile;
|
||||
|
||||
#endif
|
||||
|
@ -52,7 +52,6 @@ set(SRC
|
||||
BLO_blend_defs.h
|
||||
BLO_readfile.h
|
||||
BLO_runtime.h
|
||||
BLO_soundfile.h
|
||||
BLO_sys_types.h
|
||||
BLO_undofile.h
|
||||
BLO_writefile.h
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user