Merge branch 'master' into blender2.8
This commit is contained in:
@@ -4,7 +4,7 @@ Persistent Handler Example
|
||||
|
||||
By default handlers are freed when loading new files, in some cases you may
|
||||
wan't the handler stay running across multiple files (when the handler is
|
||||
part of an addon for example).
|
||||
part of an add-on for example).
|
||||
|
||||
For this the :data:`bpy.app.handlers.persistent` decorator needs to be used.
|
||||
"""
|
||||
|
||||
@@ -5,7 +5,7 @@ Intro
|
||||
.. warning::
|
||||
|
||||
Most of this object should only be useful if you actually manipulate i18n stuff from Python.
|
||||
If you are a regular addon, you should only bother about :const:`contexts` member,
|
||||
If you are a regular add-on, you should only bother about :const:`contexts` member,
|
||||
and the :func:`register`/:func:`unregister` functions! The :func:`pgettext` family of functions
|
||||
should only be used in rare, specific cases (like e.g. complex "composited" UI strings...).
|
||||
|
||||
@@ -21,7 +21,7 @@ Intro
|
||||
Then, call ``bpy.app.translations.register(__name__, your_dict)`` in your ``register()`` function, and
|
||||
``bpy.app.translations.unregister(__name__)`` in your ``unregister()`` one.
|
||||
|
||||
The ``Manage UI translations`` addon has several functions to help you collect strings to translate, and
|
||||
The ``Manage UI translations`` add-on has several functions to help you collect strings to translate, and
|
||||
generate the needed python code (the translation dictionary), as well as optional intermediary po files
|
||||
if you want some... See
|
||||
`How to Translate Blender <http://wiki.blender.org/index.php/Dev:Doc/Process/Translate_Blender>`_ and
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
bl_info = {
|
||||
"name": "Example Addon Preferences",
|
||||
"name": "Example Add-on Preferences",
|
||||
"author": "Your Name Here",
|
||||
"version": (1, 0),
|
||||
"blender": (2, 65, 0),
|
||||
"location": "SpaceBar Search -> Addon Preferences Example",
|
||||
"description": "Example Addon",
|
||||
"location": "SpaceBar Search -> Add-on Preferences Example",
|
||||
"description": "Example Add-on",
|
||||
"warning": "",
|
||||
"wiki_url": "",
|
||||
"tracker_url": "",
|
||||
@@ -18,7 +18,7 @@ from bpy.props import StringProperty, IntProperty, BoolProperty
|
||||
|
||||
|
||||
class ExampleAddonPreferences(AddonPreferences):
|
||||
# this must match the addon name, use '__package__'
|
||||
# this must match the add-on name, use '__package__'
|
||||
# when defining this in a submodule of a python package.
|
||||
bl_idname = __name__
|
||||
|
||||
@@ -37,7 +37,7 @@ class ExampleAddonPreferences(AddonPreferences):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.label(text="This is a preferences view for our addon")
|
||||
layout.label(text="This is a preferences view for our add-on")
|
||||
layout.prop(self, "filepath")
|
||||
layout.prop(self, "number")
|
||||
layout.prop(self, "boolean")
|
||||
@@ -46,7 +46,7 @@ class ExampleAddonPreferences(AddonPreferences):
|
||||
class OBJECT_OT_addon_prefs_example(Operator):
|
||||
"""Display example preferences"""
|
||||
bl_idname = "object.addon_prefs_example"
|
||||
bl_label = "Addon Preferences Example"
|
||||
bl_label = "Add-on Preferences Example"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
Extending Menus
|
||||
+++++++++++++++
|
||||
|
||||
When creating menus for addons you can't reference menus in Blender's default
|
||||
scripts.
|
||||
Instead, the addon can add menu items to existing menus.
|
||||
When creating menus for add-ons you can't reference menus
|
||||
in Blender's default scripts.
|
||||
Instead, the add-on can add menu items to existing menus.
|
||||
|
||||
The function menu_draw acts like :class:`Menu.draw`.
|
||||
"""
|
||||
|
||||
@@ -13,7 +13,7 @@ be animated, accessed from the user interface and from python.
|
||||
definitions are not, this means whenever you load blender the class needs
|
||||
to be registered too.
|
||||
|
||||
This is best done by creating an addon which loads on startup and registers
|
||||
This is best done by creating an add-on which loads on startup and registers
|
||||
your properties.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -77,22 +77,22 @@ To run as modules:
|
||||
- The obvious way, ``import some_module`` command from the text window or interactive console.
|
||||
- Open as a text block and tick "Register" option, this will load with the blend file.
|
||||
- copy into one of the directories ``scripts/startup``, where they will be automatically imported on startup.
|
||||
- define as an addon, enabling the addon will load it as a Python module.
|
||||
- define as an add-on, enabling the add-on will load it as a Python module.
|
||||
|
||||
|
||||
Addons
|
||||
Add-ons
|
||||
------
|
||||
|
||||
Some of Blenders functionality is best kept optional,
|
||||
alongside scripts loaded at startup we have addons which are kept in their own directory ``scripts/addons``,
|
||||
alongside scripts loaded at startup we have add-ons which are kept in their own directory ``scripts/addons``,
|
||||
and only load on startup if selected from the user preferences.
|
||||
|
||||
The only difference between addons and built-in Python modules is that addons must contain a ``bl_info``
|
||||
The only difference between add-ons and built-in Python modules is that add-ons must contain a ``bl_info``
|
||||
variable which Blender uses to read metadata such as name, author, category and URL.
|
||||
|
||||
The user preferences addon listing uses **bl_info** to display information about each addon.
|
||||
The User Preferences add-on listing uses **bl_info** to display information about each add-on.
|
||||
|
||||
`See Addons <http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons>`__
|
||||
`See Add-ons <http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons>`__
|
||||
for details on the ``bl_info`` dictionary.
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ These functions usually appear at the bottom of the script containing class regi
|
||||
You can also use them for internal purposes setting up data for your own tools but take care
|
||||
since register won't re-run when a new blend file is loaded.
|
||||
|
||||
The register/unregister calls are used so it's possible to toggle addons and reload scripts while Blender runs.
|
||||
The register/unregister calls are used so it's possible to toggle add-ons and reload scripts while Blender runs.
|
||||
If the register calls were placed in the body of the script, registration would be called on import,
|
||||
meaning there would be no distinction between importing a module or loading its classes into Blender.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
Addon Tutorial
|
||||
##############
|
||||
Add-on Tutorial
|
||||
###############
|
||||
|
||||
************
|
||||
Introduction
|
||||
@@ -36,6 +36,7 @@ Suggested reading before starting this tutorial.
|
||||
To best troubleshoot any error message Python prints while writing scripts you run blender with from a terminal,
|
||||
see :ref:`Use The Terminal <use_the_terminal>`.
|
||||
|
||||
|
||||
Documentation Links
|
||||
===================
|
||||
|
||||
@@ -46,51 +47,48 @@ While going through the tutorial you may want to look into our reference documen
|
||||
- :mod:`bpy.context` api reference. -
|
||||
*Handy to have a list of available items your script may operate on.*
|
||||
- :class:`bpy.types.Operator`. -
|
||||
*The following addons define operators, these docs give details and more examples of operators.*
|
||||
*The following add-ons define operators, these docs give details and more examples of operators.*
|
||||
|
||||
|
||||
******
|
||||
Addons
|
||||
******
|
||||
*******
|
||||
Add-ons
|
||||
*******
|
||||
|
||||
What is an Add-on?
|
||||
==================
|
||||
|
||||
What is an Addon?
|
||||
=================
|
||||
|
||||
An addon is simply a Python module with some additional requirements so Blender can display it in a list with useful
|
||||
An add-on is simply a Python module with some additional requirements so Blender can display it in a list with useful
|
||||
information.
|
||||
|
||||
To give an example, here is the simplest possible addon.
|
||||
|
||||
To give an example, here is the simplest possible add-on.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bl_info = {"name": "My Test Addon", "category": "Object"}
|
||||
bl_info = {"name": "My Test Add-on", "category": "Object"}
|
||||
def register():
|
||||
print("Hello World")
|
||||
def unregister():
|
||||
print("Goodbye World")
|
||||
|
||||
|
||||
- ``bl_info`` is a dictionary containing addon meta-data such as the title, version and author to be displayed in the
|
||||
user preferences addon list.
|
||||
- ``register`` is a function which only runs when enabling the addon, this means the module can be loaded without
|
||||
activating the addon.
|
||||
- ``unregister`` is a function to unload anything setup by ``register``, this is called when the addon is disabled.
|
||||
- ``bl_info`` is a dictionary containing add-on metadata such as the title,
|
||||
version and author to be displayed in the user preferences add-on list.
|
||||
- ``register`` is a function which only runs when enabling the add-on,
|
||||
this means the module can be loaded without activating the add-on.
|
||||
- ``unregister`` is a function to unload anything setup by ``register``, this is called when the add-on is disabled.
|
||||
|
||||
|
||||
Notice this add-on does not do anything related to Blender, (the :mod:`bpy` module is not imported for example).
|
||||
|
||||
Notice this addon does not do anything related to Blender, (the :mod:`bpy` module is not imported for example).
|
||||
This is a contrived example of an add-on that serves to illustrate the point
|
||||
that the base requirements of an add-on are simple.
|
||||
|
||||
This is a contrived example of an addon that serves to illustrate the point
|
||||
that the base requirements of an addon are simple.
|
||||
|
||||
An addon will typically register operators, panels, menu items etc, but its worth noting that _any_ script can do this,
|
||||
An add-on will typically register operators, panels, menu items etc, but its worth noting that _any_ script can do this,
|
||||
when executed from the text editor or even the interactive console - there is nothing inherently different about an
|
||||
addon that allows it to integrate with Blender, such functionality is just provided by the :mod:`bpy` module for any
|
||||
add-on that allows it to integrate with Blender, such functionality is just provided by the :mod:`bpy` module for any
|
||||
script to access.
|
||||
|
||||
So an addon is just a way to encapsulate a Python module in a way a user can easily utilize.
|
||||
So an add-on is just a way to encapsulate a Python module in a way a user can easily utilize.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -99,14 +97,14 @@ So an addon is just a way to encapsulate a Python module in a way a user can eas
|
||||
Messages will be printed when enabling and disabling.
|
||||
|
||||
|
||||
Your First Addon
|
||||
================
|
||||
Your First Add-on
|
||||
=================
|
||||
|
||||
The simplest possible addon above was useful as an example but not much else.
|
||||
This next addon is simple but shows how to integrate a script into Blender using an ``Operator``
|
||||
The simplest possible add-on above is useful as an example but not much else.
|
||||
This next add-on is simple but shows how to integrate a script into Blender using an ``Operator``
|
||||
which is the typical way to define a tool accessed from menus, buttons and keyboard shortcuts.
|
||||
|
||||
For the first example we'll make a script that simply moves all objects in a scene.
|
||||
For the first example we will make a script that simply moves all objects in a scene.
|
||||
|
||||
|
||||
Write The Script
|
||||
@@ -130,13 +128,13 @@ Add the following script to the text editor in Blender.
|
||||
:alt: Run Script button
|
||||
|
||||
Click the Run Script button, all objects in the active scene are moved by 1.0 Blender unit.
|
||||
Next we'll make this script into an addon.
|
||||
Next we will make this script into an add-on.
|
||||
|
||||
|
||||
Write the Addon (Simple)
|
||||
------------------------
|
||||
Write the Add-on (Simple)
|
||||
-------------------------
|
||||
|
||||
This addon takes the body of the script above, and adds them to an operator's ``execute()`` function.
|
||||
This add-on takes the body of the script above, and adds them to an operator's ``execute()`` function.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
@@ -173,7 +171,7 @@ This addon takes the body of the script above, and adds them to an operator's ``
|
||||
|
||||
|
||||
# This allows you to run the script directly from blenders text editor
|
||||
# to test the addon without having to install it.
|
||||
# to test the add-on without having to install it.
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
@@ -206,33 +204,33 @@ Do this by pressing :kbd:`Spacebar` to bring up the operator search dialog and t
|
||||
|
||||
The objects should move as before.
|
||||
|
||||
*Keep this addon open in Blender for the next step - Installing.*
|
||||
*Keep this add-on open in Blender for the next step - Installing.*
|
||||
|
||||
|
||||
Install The Addon
|
||||
-----------------
|
||||
Install The Add-on
|
||||
------------------
|
||||
|
||||
Once you have your addon within in Blender's text editor,
|
||||
Once you have your add-on within in Blender's text editor,
|
||||
you will want to be able to install it so it can be enabled in the user preferences to load on startup.
|
||||
|
||||
Even though the addon above is a test, lets go through the steps anyway so you know how to do it for later.
|
||||
Even though the add-on above is a test, lets go through the steps anyway so you know how to do it for later.
|
||||
|
||||
To install the Blender text as an addon you will first have to save it to disk, take care to obey the naming
|
||||
To install the Blender text as an add-on you will first have to save it to disk, take care to obey the naming
|
||||
restrictions that apply to Python modules and end with a ``.py`` extension.
|
||||
|
||||
Once the file is on disk, you can install it as you would for an addon downloaded online.
|
||||
Once the file is on disk, you can install it as you would for an add-on downloaded online.
|
||||
|
||||
Open the user :menuselection:`File -> User Preferences`,
|
||||
Select the *Addon* section, press *Install Addon...* and select the file.
|
||||
Open the user :menuselection:`File --> User Preferences`,
|
||||
Select the *Add-on* section, press *Install Add-on...* and select the file.
|
||||
|
||||
Now the addon will be listed and you can enable it by pressing the check-box,
|
||||
Now the add-on will be listed and you can enable it by pressing the check-box,
|
||||
if you want it to be enabled on restart, press *Save as Default*.
|
||||
|
||||
.. note::
|
||||
|
||||
The destination of the addon depends on your Blender configuration.
|
||||
When installing an addon the source and destination path are printed in the console.
|
||||
You can also find addon path locations by running this in the Python console.
|
||||
The destination of the add-on depends on your Blender configuration.
|
||||
When installing an add-on the source and destination path are printed in the console.
|
||||
You can also find add-on path locations by running this in the Python console.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -243,17 +241,17 @@ if you want it to be enabled on restart, press *Save as Default*.
|
||||
`Directory Layout <https://www.blender.org/manual/getting_started/installing_blender/directorylayout.html>`_
|
||||
|
||||
|
||||
Your Second Addon
|
||||
=================
|
||||
Your Second Add-on
|
||||
==================
|
||||
|
||||
For our second addon, we will focus on object instancing - this is - to make linked copies of an object in a
|
||||
For our second add-on, we will focus on object instancing - this is - to make linked copies of an object in a
|
||||
similar way to what you may have seen with the array modifier.
|
||||
|
||||
|
||||
Write The Script
|
||||
----------------
|
||||
|
||||
As before, first we will start with a script, develop it, then convert into an addon.
|
||||
As before, first we will start with a script, develop it, then convert into an add-on.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -324,17 +322,17 @@ allows vectors to be multiplied by numbers and matrices.
|
||||
|
||||
If you are interested in this area, read into :class:`mathutils.Vector` - there are many handy utility functions
|
||||
such as getting the angle between vectors, cross product, dot products
|
||||
as well as more advanced functions in :mod:`mathutils.geometry` such as bezier spline interpolation and
|
||||
as well as more advanced functions in :mod:`mathutils.geometry` such as Bézier Spline interpolation and
|
||||
ray-triangle intersection.
|
||||
|
||||
For now we'll focus on making this script an addon, but its good to know that this 3D math module is available and
|
||||
For now we will focus on making this script an add-on, but its good to know that this 3D math module is available and
|
||||
can help you with more advanced functionality later on.
|
||||
|
||||
|
||||
Write the Addon
|
||||
---------------
|
||||
Write the Add-on
|
||||
----------------
|
||||
|
||||
The first step is to convert the script as-is into an addon.
|
||||
The first step is to convert the script as-is into an add-on.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
@@ -381,7 +379,7 @@ The first step is to convert the script as-is into an addon.
|
||||
register()
|
||||
|
||||
|
||||
Everything here has been covered in the previous steps, you may want to try run the addon still
|
||||
Everything here has been covered in the previous steps, you may want to try run the add-on still
|
||||
and consider what could be done to make it more useful.
|
||||
|
||||
|
||||
@@ -434,7 +432,7 @@ however the link above includes examples of more advanced property usage.
|
||||
Menu Item
|
||||
^^^^^^^^^
|
||||
|
||||
Addons can add to the user interface of existing panels, headers and menus defined in Python.
|
||||
Add-ons can add to the user interface of existing panels, headers and menus defined in Python.
|
||||
|
||||
For this example we'll add to an existing menu.
|
||||
|
||||
@@ -464,7 +462,7 @@ For docs on extending menus see: :doc:`bpy.types.Menu`.
|
||||
Keymap
|
||||
^^^^^^
|
||||
|
||||
In Blender addons have their own key-maps so as not to interfere with Blenders built in key-maps.
|
||||
In Blender, add-ons have their own keymaps so as not to interfere with Blenders built in key-maps.
|
||||
|
||||
In the example below, a new object-mode :class:`bpy.types.KeyMap` is added,
|
||||
then a :class:`bpy.types.KeyMapItem` is added to the key-map which references our newly added operator,
|
||||
@@ -502,7 +500,7 @@ this allows you to have multiple keys accessing the same operator with different
|
||||
|
||||
.. note::
|
||||
|
||||
While :kbd:`Ctrl-Shift-Space` isn't a default Blender key shortcut, its hard to make sure addons won't
|
||||
While :kbd:`Ctrl-Shift-Space` isn't a default Blender key shortcut, its hard to make sure add-ons won't
|
||||
overwrite each others keymaps, At least take care when assigning keys that they don't
|
||||
conflict with important functionality within Blender.
|
||||
|
||||
@@ -606,14 +604,14 @@ After selecting it from the menu, you can choose how many instance of the cube y
|
||||
.. note::
|
||||
|
||||
Directly executing the script multiple times will add the menu each time too.
|
||||
While not useful behavior, theres nothing to worry about since addons won't register them selves multiple
|
||||
While not useful behavior, theres nothing to worry about since add-ons won't register them selves multiple
|
||||
times when enabled through the user preferences.
|
||||
|
||||
|
||||
Conclusions
|
||||
===========
|
||||
|
||||
Addons can encapsulate certain functionality neatly for writing tools to improve your work-flow or for writing utilities
|
||||
Add-ons can encapsulate certain functionality neatly for writing tools to improve your work-flow or for writing utilities
|
||||
for others to use.
|
||||
|
||||
While there are limits to what Python can do within Blender, there is certainly a lot that can be achieved without
|
||||
@@ -636,7 +634,7 @@ Here are some sites you might like to check on after completing this tutorial.
|
||||
*For more background details on Blender/Python integration.*
|
||||
- `How to Think Like a Computer Scientist <http://interactivepython.org/courselib/static/thinkcspy/index.html>`_ -
|
||||
*Great info for those who are still learning Python.*
|
||||
- `Blender Development (Wiki) <http://wiki.blender.org/index.php/Dev:Contents>`_ -
|
||||
- `Blender Development (Wiki) <https://wiki.blender.org/index.php/Dev:Contents>`_ -
|
||||
*Blender Development, general information and helpful links.*
|
||||
- `Blender Artists (Coding Section) <http://blenderartists.org/forum/forumdisplay.php?47-Coding>`_ -
|
||||
*forum where people ask Python development questions*
|
||||
|
||||
@@ -363,7 +363,7 @@ INFO_DOCS = (
|
||||
("info_overview.rst",
|
||||
"Blender/Python API Overview: a more complete explanation of Python integration"),
|
||||
("info_tutorial_addon.rst",
|
||||
"Blender/Python Addon Tutorial: a step by step guide on how to write an addon from scratch"),
|
||||
"Blender/Python Add-on Tutorial: a step by step guide on how to write an add-on from scratch"),
|
||||
("info_api_reference.rst",
|
||||
"Blender/Python API Reference Usage: examples of how to use the API reference docs"),
|
||||
("info_best_practice.rst",
|
||||
|
||||
@@ -221,14 +221,6 @@ ccl_device_inline void camera_sample_panorama(KernelGlobals *kg,
|
||||
|
||||
/* create ray form raster position */
|
||||
ray->P = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
#ifdef __CAMERA_CLIPPING__
|
||||
/* clipping */
|
||||
ray->t = kernel_data.cam.cliplength;
|
||||
#else
|
||||
ray->t = FLT_MAX;
|
||||
#endif
|
||||
|
||||
ray->D = panorama_to_direction(kg, Pcamera.x, Pcamera.y);
|
||||
|
||||
/* indicates ray should not receive any light, outside of the lens */
|
||||
@@ -302,6 +294,14 @@ ccl_device_inline void camera_sample_panorama(KernelGlobals *kg,
|
||||
ray->dD.dy = spherical_stereo_direction(kg, tD, tP, Pcamera) - Ddiff;
|
||||
/* dP.dy is zero, since the omnidirectional panorama only shift the eyes horizontally */
|
||||
#endif
|
||||
|
||||
#ifdef __CAMERA_CLIPPING__
|
||||
/* clipping */
|
||||
ray->P += kernel_data.cam.nearclip*ray->D;
|
||||
ray->t = kernel_data.cam.cliplength;
|
||||
#else
|
||||
ray->t = FLT_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Common */
|
||||
|
||||
@@ -462,12 +462,13 @@ ccl_device_inline float3 operator*(const float f, const float3& a)
|
||||
|
||||
ccl_device_inline float3 operator/(const float f, const float3& a)
|
||||
{
|
||||
#ifdef __KERNEL_SSE__
|
||||
__m128 rc = _mm_rcp_ps(a.m128);
|
||||
return float3(_mm_mul_ps(_mm_set1_ps(f),rc));
|
||||
#else
|
||||
/* TODO(sergey): Currently disabled, gives speedup but makes intersection tets non-watertight. */
|
||||
// #ifdef __KERNEL_SSE__
|
||||
// __m128 rc = _mm_rcp_ps(a.m128);
|
||||
// return float3(_mm_mul_ps(_mm_set1_ps(f),rc));
|
||||
// #else
|
||||
return make_float3(f / a.x, f / a.y, f / a.z);
|
||||
#endif
|
||||
// #endif
|
||||
}
|
||||
|
||||
ccl_device_inline float3 operator/(const float3& a, const float f)
|
||||
|
||||
@@ -865,7 +865,7 @@ char **BKE_sound_get_device_names(void)
|
||||
audio_device_names = AUD_getDeviceNames();
|
||||
#else
|
||||
static const char *names[] = {
|
||||
"Null", "SDL", "OpenAL", "Jack", NULL
|
||||
"Null", "SDL", "OpenAL", "JACK", NULL
|
||||
};
|
||||
audio_device_names = (char **)names;
|
||||
#endif
|
||||
|
||||
@@ -2624,6 +2624,84 @@ static bAnimChannelType ACF_DSGPENCIL =
|
||||
acf_dsgpencil_setting_ptr /* pointer for setting */
|
||||
};
|
||||
|
||||
/* World Expander ------------------------------------------- */
|
||||
|
||||
// TODO: just get this from RNA?
|
||||
static int acf_dsmclip_icon(bAnimListElem *UNUSED(ale))
|
||||
{
|
||||
return ICON_SEQUENCE;
|
||||
}
|
||||
|
||||
/* get the appropriate flag(s) for the setting when it is valid */
|
||||
static int acf_dsmclip_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
|
||||
{
|
||||
/* clear extra return data first */
|
||||
*neg = false;
|
||||
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
return MCLIP_DATA_EXPAND;
|
||||
|
||||
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
|
||||
return ADT_NLA_EVAL_OFF;
|
||||
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
|
||||
*neg = true;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* get pointer to the setting */
|
||||
static void *acf_dsmclip_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
|
||||
{
|
||||
MovieClip *clip = (MovieClip *)ale->data;
|
||||
|
||||
/* clear extra return data first */
|
||||
*type = 0;
|
||||
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
return GET_ACF_FLAG_PTR(clip->flag, type);
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
|
||||
if (clip->adt != NULL) {
|
||||
return GET_ACF_FLAG_PTR(clip->adt->flag, type);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
default: /* unsupported */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* world expander type define */
|
||||
static bAnimChannelType ACF_DSMCLIP =
|
||||
{
|
||||
"Movieclip Expander", /* type name */
|
||||
ACHANNEL_ROLE_EXPANDER, /* role */
|
||||
|
||||
acf_generic_dataexpand_color, /* backdrop color */
|
||||
acf_generic_dataexpand_backdrop, /* backdrop */
|
||||
acf_generic_indention_1, /* indent level */
|
||||
acf_generic_basic_offset, /* offset */
|
||||
|
||||
acf_generic_idblock_name , /* name */
|
||||
acf_generic_idfill_name_prop, /* name prop */
|
||||
acf_dsmclip_icon, /* icon */
|
||||
|
||||
acf_generic_dataexpand_setting_valid, /* has setting */
|
||||
acf_dsmclip_setting_flag, /* flag for setting */
|
||||
acf_dsmclip_setting_ptr /* pointer for setting */
|
||||
};
|
||||
|
||||
/* ShapeKey Entry ------------------------------------------- */
|
||||
|
||||
/* name for ShapeKey */
|
||||
@@ -3424,6 +3502,7 @@ static void ANIM_init_channel_typeinfo_data(void)
|
||||
animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */
|
||||
animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */
|
||||
animchannelTypeInfo[type++] = &ACF_DSGPENCIL; /* GreasePencil Channel */
|
||||
animchannelTypeInfo[type++] = &ACF_DSMCLIP; /* MovieClip Channel */
|
||||
|
||||
animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
|
||||
case ANIMTYPE_DSLINESTYLE:
|
||||
case ANIMTYPE_DSSPK:
|
||||
case ANIMTYPE_DSGPENCIL:
|
||||
case ANIMTYPE_DSMCLIP:
|
||||
{
|
||||
/* need to verify that this data is valid for now */
|
||||
if (ale->adt) {
|
||||
@@ -188,6 +189,7 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datat
|
||||
case ANIMTYPE_DSNTREE:
|
||||
case ANIMTYPE_DSTEX:
|
||||
case ANIMTYPE_DSGPENCIL:
|
||||
case ANIMTYPE_DSMCLIP:
|
||||
{
|
||||
/* need to verify that this data is valid for now */
|
||||
if (ale && ale->adt) {
|
||||
@@ -288,6 +290,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
|
||||
case ANIMTYPE_DSLINESTYLE:
|
||||
case ANIMTYPE_DSSPK:
|
||||
case ANIMTYPE_DSGPENCIL:
|
||||
case ANIMTYPE_DSMCLIP:
|
||||
{
|
||||
if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
|
||||
sel = ACHANNEL_SETFLAG_CLEAR;
|
||||
@@ -383,6 +386,7 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
|
||||
case ANIMTYPE_DSLINESTYLE:
|
||||
case ANIMTYPE_DSSPK:
|
||||
case ANIMTYPE_DSGPENCIL:
|
||||
case ANIMTYPE_DSMCLIP:
|
||||
{
|
||||
/* need to verify that this data is valid for now */
|
||||
if (ale->adt) {
|
||||
@@ -2733,6 +2737,7 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
|
||||
case ANIMTYPE_DSLINESTYLE:
|
||||
case ANIMTYPE_DSSPK:
|
||||
case ANIMTYPE_DSGPENCIL:
|
||||
case ANIMTYPE_DSMCLIP:
|
||||
{
|
||||
/* sanity checking... */
|
||||
if (ale->adt) {
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meta_types.h"
|
||||
#include "DNA_movieclip_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
@@ -828,6 +829,19 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
|
||||
ale->adt = BKE_animdata_from_id(data);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_DSMCLIP:
|
||||
{
|
||||
MovieClip *clip = (MovieClip *)data;
|
||||
AnimData *adt = clip->adt;
|
||||
|
||||
ale->flag = EXPANDED_MCLIP(clip);
|
||||
|
||||
ale->key_data = (adt) ? adt->action : NULL;
|
||||
ale->datatype = ALE_ACT;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(data);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_NLACONTROLS:
|
||||
{
|
||||
AnimData *adt = (AnimData *)data;
|
||||
@@ -2721,6 +2735,50 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d
|
||||
return items;
|
||||
}
|
||||
|
||||
static size_t animdata_filter_ds_movieclip(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, MovieClip *clip, int filter_mode)
|
||||
{
|
||||
ListBase tmp_data = {NULL, NULL};
|
||||
size_t tmp_items = 0;
|
||||
size_t items = 0;
|
||||
/* add world animation channels */
|
||||
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MCLIP(clip))
|
||||
{
|
||||
/* animation data filtering */
|
||||
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)clip, filter_mode);
|
||||
}
|
||||
END_ANIMFILTER_SUBCHANNELS;
|
||||
/* did we find anything? */
|
||||
if (tmp_items) {
|
||||
/* include data-expand widget first */
|
||||
if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
|
||||
/* check if filtering by active status */
|
||||
if (ANIMCHANNEL_ACTIVEOK(clip)) {
|
||||
ANIMCHANNEL_NEW_CHANNEL(clip, ANIMTYPE_DSMCLIP, clip);
|
||||
}
|
||||
}
|
||||
/* now add the list of collected channels */
|
||||
BLI_movelisttolist(anim_data, &tmp_data);
|
||||
BLI_assert(BLI_listbase_is_empty(&tmp_data));
|
||||
items += tmp_items;
|
||||
}
|
||||
/* return the number of items added to the list */
|
||||
return items;
|
||||
}
|
||||
|
||||
static size_t animdata_filter_dopesheet_movieclips(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode)
|
||||
{
|
||||
size_t items = 0;
|
||||
MovieClip *clip;
|
||||
for (clip = G.main->movieclip.first; clip != NULL; clip = clip->id.next) {
|
||||
/* only show if gpd is used by something... */
|
||||
if (ID_REAL_USERS(clip) < 1) {
|
||||
continue;
|
||||
}
|
||||
items += animdata_filter_ds_movieclip(ac, anim_data, ads, clip, filter_mode);
|
||||
}
|
||||
/* return the number of items added to the list */
|
||||
return items;
|
||||
}
|
||||
|
||||
/* Helper for animdata_filter_dopesheet() - For checking if an object should be included or not */
|
||||
static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base, int filter_mode)
|
||||
@@ -2854,9 +2912,12 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b
|
||||
items += animdata_filter_ds_cachefile(ac, anim_data, ads, cache_file, filter_mode);
|
||||
}
|
||||
|
||||
/* movie clip's animation */
|
||||
items += animdata_filter_dopesheet_movieclips(ac, anim_data, ads, filter_mode);
|
||||
|
||||
/* scene-linked animation - e.g. world, compositing nodes, scene anim (including sequencer currently) */
|
||||
items += animdata_filter_dopesheet_scene(ac, anim_data, ads, scene, filter_mode);
|
||||
|
||||
|
||||
/* If filtering for channel drawing, we want the objects in alphabetical order,
|
||||
* to make it easier to predict where items are in the hierarchy
|
||||
* - This order only really matters if we need to show all channels in the list (e.g. for drawing)
|
||||
|
||||
@@ -169,6 +169,7 @@ typedef enum eAnim_ChannelType {
|
||||
ANIMTYPE_DSLINESTYLE,
|
||||
ANIMTYPE_DSSPK,
|
||||
ANIMTYPE_DSGPENCIL,
|
||||
ANIMTYPE_DSMCLIP,
|
||||
|
||||
ANIMTYPE_SHAPEKEY,
|
||||
|
||||
@@ -327,6 +328,8 @@ typedef enum eAnimFilter_Flags {
|
||||
#define SEL_NLT(nlt) (nlt->flag & NLATRACK_SELECTED)
|
||||
#define EDITABLE_NLT(nlt) ((nlt->flag & NLATRACK_PROTECTED) == 0)
|
||||
|
||||
/* Movie clip only */
|
||||
#define EXPANDED_MCLIP(clip) (clip->flag & MCLIP_DATA_EXPAND)
|
||||
|
||||
/* AnimData - NLA mostly... */
|
||||
#define SEL_ANIMDATA(adt) (adt->flag & ADT_UI_SELECTED)
|
||||
|
||||
@@ -808,7 +808,7 @@ int UI_searchbox_size_y(void)
|
||||
|
||||
int UI_searchbox_size_x(void)
|
||||
{
|
||||
return 10 * UI_UNIT_X;
|
||||
return 12 * UI_UNIT_X;
|
||||
}
|
||||
|
||||
int UI_search_items_find_index(uiSearchItems *items, const char *name)
|
||||
|
||||
@@ -739,7 +739,10 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
|
||||
if (oglrender->is_animation) {
|
||||
BLI_task_pool_work_and_wait(oglrender->task_pool);
|
||||
BLI_task_pool_free(oglrender->task_pool);
|
||||
BLI_task_scheduler_free(oglrender->task_scheduler);
|
||||
/* Depending on various things we might or might not use global scheduler. */
|
||||
if (oglrender->task_scheduler != NULL) {
|
||||
BLI_task_scheduler_free(oglrender->task_scheduler);
|
||||
}
|
||||
BLI_spin_end(&oglrender->reports_lock);
|
||||
}
|
||||
BLI_mutex_end(&oglrender->task_mutex);
|
||||
|
||||
@@ -103,7 +103,7 @@ static void sclip_zoom_set(const bContext *C, float zoom, float location[2])
|
||||
width *= sc->zoom;
|
||||
height *= sc->zoom;
|
||||
|
||||
if ((width < 4) && (height < 4))
|
||||
if ((width < 4) && (height < 4) && sc->zoom < oldzoom)
|
||||
sc->zoom = oldzoom;
|
||||
else if (BLI_rcti_size_x(&ar->winrct) <= sc->zoom)
|
||||
sc->zoom = oldzoom;
|
||||
|
||||
@@ -122,7 +122,7 @@ static void sima_zoom_set(SpaceImage *sima, ARegion *ar, float zoom, const float
|
||||
width *= sima->zoom;
|
||||
height *= sima->zoom;
|
||||
|
||||
if ((width < 4) && (height < 4))
|
||||
if ((width < 4) && (height < 4) && sima->zoom < oldzoom)
|
||||
sima->zoom = oldzoom;
|
||||
else if (BLI_rcti_size_x(&ar->winrct) <= sima->zoom)
|
||||
sima->zoom = oldzoom;
|
||||
|
||||
@@ -146,6 +146,7 @@ enum {
|
||||
MCLIP_USE_PROXY = (1 << 0),
|
||||
MCLIP_USE_PROXY_CUSTOM_DIR = (1 << 1),
|
||||
/* MCLIP_CUSTOM_START_FRAME = (1<<2), */ /* UNUSED */
|
||||
MCLIP_DATA_EXPAND = (1 << 3),
|
||||
|
||||
MCLIP_TIMECODE_FLAGS = (MCLIP_USE_PROXY | MCLIP_USE_PROXY_CUSTOM_DIR)
|
||||
};
|
||||
|
||||
@@ -83,7 +83,7 @@ static EnumPropertyItem audio_device_items[] = {
|
||||
{2, "OPENAL", 0, "OpenAL", "OpenAL device - supports 3D audio, recommended for game engine usage"},
|
||||
#endif
|
||||
#ifdef WITH_JACK
|
||||
{3, "JACK", 0, "Jack", "JACK - Audio Connection Kit, recommended for pro audio users"},
|
||||
{3, "JACK", 0, "JACK", "JACK Audio Connection Kit, recommended for pro audio users"},
|
||||
#endif
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user