Difference between revisions of "IC Python API:RLPy RDataBlock"

From Reallusion Wiki!
Jump to: navigation, search
(Created page with "{{TOC}} {{Parent|IC_Python_API:RL_Python_Modules|Modules}} ==Detailed Description== A data block provide a mechanism for storing values associated with a plug-in. The develope...")
 
m
 
Line 1: Line 1:
 
{{TOC}}
 
{{TOC}}
 
{{Parent|IC_Python_API:RL_Python_Modules|Modules}}
 
{{Parent|IC_Python_API:RL_Python_Modules|Modules}}
==Detailed Description==
+
{{last_modified}}
A data block provide a mechanism for storing values associated with a plug-in.
+
 
The developer can access the animation through the data block, such as position, rotation, and scale. <syntaxhighlight lang="Python">
+
== Description ==
# Get a avatar in the scene
+
 
 +
[[IC_Python_API:RLPy_RDataBlock|RDataBlock]] is used to save and access a collection of parameters. A data block can contain multiple parameter with each having its own ID and corresponding data type. In order to make it easier for developers to organize their own parameters, they can generate a composite (tree) structured data type according to their specific needs. This class is similar in concept to 3ds Max's ParamBlock, Maya's MDataBlock, and Cinema4D's BaseContainer.
 +
 
 +
Each plugin may have it's own custom parameters. For example, '''Path Control''' needs the '''Path Position''' parameter to indicate the progress of an object along a path. So if '''Path Position''' equals zero then the object position is at the start of the path and a value of one means it is at the end of the said path. Of course, a developer can create this variable in a class, but they would have to implement locks reading, saving, etc on their own. Even more troublesome is how to attach the corresponding controls when this variable needs to be animated and how to go about correctly displaying it in the Timeline or Curve Editor. Therefore, it's apparent that these tasks are nearly impossible to implement and that [[IC_Python_API:RLPy_RDataBlock|RDataBlock]] is there to help us solve these problems. One would only need to create the required parameters via this class, and other things will be left to the system to handle. The data types in [[IC_Python_API:RLPy_RDataBlock|RDataBlock]] are mainly divided into element data and composite data.
 +
 
 +
Element data is a single built-in data type with the following available values:
 +
*RLPy.EAttribute_Float - Float data.
 +
*RLPy.EAttribute_Int - Integer data.
 +
 
 +
Composite data is composed of sub-data and the following attributes can be set for hierarchical parameters:
 +
*RLPy.EAttribute_GroupXYZ - Creates a x, y, z float value data. The ID of the child data will be named after the ID of the parent plus x, y, z. For example, when creating an ID called "Reallusion", three sub-parameters "ReallusionX", "ReallusionY", and "ReallusionZ" will be automatically generated.
 +
 
 +
In addition, the attributes of the parameters can be specified during creation, as follows: '''RLPy.EAttributeFlag_Keyable''' indicates that the animation parameters can be set, if not set, then the value will be a constant. In order to make the parameters animate-able, you must deploy an animation controller. The system will automatically mount the corresponding control types for different data types. For example, if the parameter is a floating point number (like the '''Path Position''' attribute of the '''Path Control''' mentioned earlier), '''RFloatControl''' is required. During animation, parameter values can be obtained at any time via control interpolation. When '''RLPy.EAttributeFlag_Keyable''' is set, '''RLPy.EAttributeFlag_Storable''' is set as well. This flag indicates that the parameter can be stored to a file and will be serialized accordingly. When the file is read, the data for the requested IDs will be loaded, if an ID is not found then the data will be ignored. Developers can construct data blocks through the RIPlugin class and use '''CreateAttriute''' to create the parameters. For example, '''CurveRTSControl''' uses the following code to create all of its necessary parameters:
 +
 
 +
<syntaxhighlight lang="python" line='line'>
 +
class CurveRTSControl(RLPy.RTransformControl):
 +
  def Initialize(self, plugin):
 +
    # Create parameters using RIPlugin
 +
    plugin.CreateAttribute("Position", RLPy.EAttribute_GroupXYZ, RLPy.EAttributeFlag_Keyable)
 +
    plugin.CreateAttribute("Rotation", RLPy.EAttribute_GroupXYZ, RLPy.EAttributeFlag_Keyable)
 +
    plugin.CreateAttribute("Scale", RLPy.EAttribute_GroupXYZ, RLPy.EAttributeFlag_Keyable)
 +
    plugin.CreateAttribute("EulerOrder", RLPy.EAttribute_Int, RLPy.EAttributeFlag_Storable)
 +
</syntaxhighlight>
 +
 
 +
[[File:Rlpy_rdatablock_description_01.png|frame|Data created by [[IC_Python_API:RLPy_RDataBlock|RDataBlock]]]]
 +
 
 +
[[File:Rlpy_rdatablock_description_02.png|frame|The CurveRTSControl shown in the Curve Editor. After a DataBlock is created, its data can be inspected inside the Timeline and Curve Editor. ]]
 +
 
 +
[[#GetData ( self, strID, kTime, pReturnStatus = None )|GetData]] can be used to get the data value at a given time. If the data in question is a composite data, then a "/" can be used to link together the parent attribute with its child attributes. For example, the '''Position/PositionX''' ID for '''CurveRTSControl''' can gather data for the corresponding time. For consistency data blocks uses [[IC_Python_API:RLPy_RVariant|RVariant]] to save data. SetData is used to change the value of the data block. If '''RLPy.EAttributeFlag_Keyable''' is set, then a key will be set at the requested time. If more control over the key is desired, like getting the number of keys, moving keys, clearing all keys, etc. then use GetControl to retrieve the controller for more operations. There is currently no open interface for creating [[IC_Python_API:RLPy_RDataBlock|RDataBlock]], nor functions for browsing a data block's existing parameters.These function will be provided in future versions.
 +
 
 +
=== References ===
 +
 
 +
==== Maya SDK ====
 +
 
 +
*[http://www.chadvernon.com/blog/resources/maya-api-programming/introduction-to-dependency-graph-plug-ins/ Introduction to Dependency Graph Plug-ins]
 +
*[http://help.autodesk.com/view/MAYAUL/2017/ENU/?guid=__files_GUID_AABB9BB4_816F_4C7C_A526_69B0568E1587_htm The Dependency Graph]
 +
*[https://books.google.com.tw/books?id=zljjFzxsc8IC&pg=PA406&lpg=PA406&dq=Maya+MDataBlock&source=bl&ots=wLefD28_4e&sig=ACfU3U0J5tsBCL7BkbcMMic2cVgHQYb8bQ&hl=zh-TW&sa=X&ved=2ahUKEwiVtb2v1rPiAhXoG6YKHXIfCv4Q6AEwCHoECAkQAQ#v=onepage&q=Maya_MDataBlock&f=false  Complete Maya Programming]
 +
 
 +
==== 3dsMax SDK ====
 +
 
 +
*[http://help.autodesk.com/view/3DSMAX/2017/ENU/?guid=__files_GUID_CC09846C_8115_46CF_8DC1_9C4F1A06991A_htm Parameter Blocks]
 +
*[http://help.autodesk.com/view/3DSMAX/2017/ENU/?guid=__files_GUID_5D9AF70B_0627_434E_AB45_03CC9941496A_htm  Lesson 6: Parameter Blocks]
 +
 
 +
==== Cinema4D SDK ====
 +
 
 +
*[https://developers.maxon.net/docs/Cinema4DCPPSDK/html/page_manual_basecontainer.html BaseContainer]
 +
 
 +
== Member Functions ==
 +
 
 +
=== Clone ( self ) ===
 +
 
 +
Copy this data block and return a new identical object. This function is meant for internal usage and should not be called.
 +
 
 +
==== Returns ====
 +
:The copied data block object - [[IC_Python_API:RLPy_RDataBlock|RDataBlock]]
 +
 
 +
<syntaxhighlight lang="python" line='line'>
 +
# Get an avatar in the scene
 
avatar_list = RLPy.RScene.GetAvatars()
 
avatar_list = RLPy.RScene.GetAvatars()
 
avatar = avatar_list[0]
 
avatar = avatar_list[0]
 
# Set Data
 
 
transform_control = avatar.GetControl("Transform")
 
transform_control = avatar.GetControl("Transform")
data_block = transform_control.GetDataBlock() # get datablock of the control
+
 
data_block.SetData("Position/PositionX", RLPy.RTime(3000), RLPy.RVariant(100)) # set the position of x axis to 1000 at time 3000
+
# Clone RDataBlock
+
cloned_block = transform_control.GetDataBlock().Clone()
# Get Data
+
print(data_block.GetData("Position/PositionX", RLPy.RTime(3000)).ToUInt32()) # values = 100
+
 
</syntaxhighlight>
 
</syntaxhighlight>
==Member Functions==
+
 
===Clone===
+
=== GetControl ( self, strID ) ===
<syntaxhighlight lang="Python">
+
 
RLPy.RDataBlock.Clone ( self )
+
Get the control on this data block according to the provided string ID. If the given ID is not found or if the '''RLPy.EAttributeFlag_Keyable''' is not set, then '''None''' will be returned.
</syntaxhighlight>
+
 
Clone.
+
==== Parameters ====
Supports cloning, which creates a new instance of a class with the same value as an existing instance.
+
:'''strID''' [IN] parameter ID - string
====Returns====
+
 
<div style="margin-left: 2em;">Pointer to cloned data block - RLPy. RDataBlock
+
==== Returns ====
</div>
+
:The control according to the input string ID - [[IC_Python_API:RLPy_RControl|RControl]]
-----
+
 
===GetControl===
+
<syntaxhighlight lang="python" line='line'>
<syntaxhighlight lang="Python">
+
# Get an avatar in the scene
RLPy.RDataBlock.GetControl ( self, strName )
+
avatar_list = RLPy.RScene.GetAvatars()
 +
avatar = avatar_list[0]
 +
transform_control = avatar.GetControl("Transform")
 +
 
 +
# Get Control
 +
float_control = data_block.GetControl("Position/PositionX")  
 
</syntaxhighlight>
 
</syntaxhighlight>
Get control.
 
====Parameters====
 
<div style="margin-left: 2em;">
 
'''strName''' [IN] control name - string
 
</div>
 
====Returns====
 
<div style="margin-left: 2em;">Pointer to control - RLPy.RControl
 
</div>
 
-----
 
===GetData===
 
<syntaxhighlight lang="Python">
 
RLPy.RDataBlock.GetData ( self, strName, kTime, pReturnStatus = None )
 
</syntaxhighlight>
 
Get data.
 
====Parameters====
 
<div style="margin-left: 2em;">
 
'''strName''' [IN] data name - string
 
  
'''kTime''' [IN] Specifies the time to get data - RLPy.RTime
+
=== GetData ( self, strID, kTime, pReturnStatus = None ) ===
  
'''pReturnStatus''' [OUT] return status - RLPy.RStatus
+
Get the data block value at the given time. If the ID is not found then return '''None''' and '''pReturnStatus''' will return '''RLPy.RStatus.Failure'''. If '''RLPy.EAttributeFlag_Keyable''' is not set, then the data is a constant and the value returned will be fixed and does not change according to the '''kTime''' value. This function will return a [[IC_Python_API:RLPy_RVariant|RVariant]]and with [[IC_Python_API:RLPy_RVariant#GetType|RLPy.RVariant.GetType()]] one can retrieve the data type and use a corresponding function to convert it to the correct type.
</div>
+
 
====Returns====
+
==== Parameters ====
<div style="margin-left: 2em;">RVariant data - RLPy.RVariant
+
:'''strID''' [IN] parameter ID - string
</div>
+
:'''kTime''' [IN] parameter fetch time - [[IC_Python_API:RLPy_RTime|RTime]]
-----
+
:'''pReturnStatus''' [OUT] return status - [[IC_Python_API:RLPy_RStatus|RStatus]]
===SetData===
+
 
<syntaxhighlight lang="Python">
+
==== Returns ====
RLPy.RDataBlock.SetData ( self, strName, kTime, kData )
+
:Get the data block value - [[IC_Python_API:RLPy_RVariant|RVariant]]
 +
 
 +
<syntaxhighlight lang="python" line='line'>
 +
# Get an avatar in the scene
 +
avatar_list = RLPy.RScene.GetAvatars()
 +
avatar = avatar_list[0]
 +
transform_control = avatar.GetControl("Transform")
 +
 
 +
# Get Data
 +
data_block.GetData("Position/PositionX", RLPy.RTime(3000)).ToFloat()
 
</syntaxhighlight>
 
</syntaxhighlight>
Set data.
 
====Parameters====
 
<div style="margin-left: 2em;">
 
'''strName''' [IN] data name - string
 
  
'''kTime''' [IN] Specifies the time to set data - RLPy.RTime
+
=== SetData ( self, strID, kTime, kData ) ===
  
'''kData''' [OUT] data - RLPy.RVariant
+
Set the data block value at the requested time. If the given ID is not found then return '''RLPy.RStatus.Failure'''. If the  '''RLPy.EAttributeFlag_Keyable''' attribute is not set, then the data is a constant and the key will not be set.
</div>
+
====Return Values====
+
<div style="margin-left: 2em;">
+
'''RLPy.RStatus.Success''' Success
+
  
'''RLPy.RStatus.Failure''' Fail
+
==== Parameters ====
</div>
+
:'''strID''' [IN] parameter ID - string
 +
:'''kTime''' [IN] parameter time - [[IC_Python_API:RLPy_RTime|RTime]]
 +
:'''kData''' [IN] parameter value - [[IC_Python_API:RLPy_RVariant|RVariant]]
 +
 
 +
==== Returns ====
 +
:Success - RLPy.RStatus.Success
 +
:Failure - RLPy.RStatus.Failure
 +
 
 +
<syntaxhighlight lang="python" line='line'>
 +
# Get an avatar in the scene
 +
avatar_list = RLPy.RScene.GetAvatars()
 +
avatar = avatar_list[0]
 +
transform_control = avatar.GetControl("Transform")
 +
 
 +
# Set Data
 +
data_block.SetData("Position/PositionX", RLPy.RTime(3000), RLPy.RVariant(100))
 +
  # set the position of the x-axis to 1000 at time 3000
 +
</syntaxhighlight>

Latest revision as of 01:12, 28 April 2020

Main article: Modules.
Last modified: 04/28/2020

Description

RDataBlock is used to save and access a collection of parameters. A data block can contain multiple parameter with each having its own ID and corresponding data type. In order to make it easier for developers to organize their own parameters, they can generate a composite (tree) structured data type according to their specific needs. This class is similar in concept to 3ds Max's ParamBlock, Maya's MDataBlock, and Cinema4D's BaseContainer.

Each plugin may have it's own custom parameters. For example, Path Control needs the Path Position parameter to indicate the progress of an object along a path. So if Path Position equals zero then the object position is at the start of the path and a value of one means it is at the end of the said path. Of course, a developer can create this variable in a class, but they would have to implement locks reading, saving, etc on their own. Even more troublesome is how to attach the corresponding controls when this variable needs to be animated and how to go about correctly displaying it in the Timeline or Curve Editor. Therefore, it's apparent that these tasks are nearly impossible to implement and that RDataBlock is there to help us solve these problems. One would only need to create the required parameters via this class, and other things will be left to the system to handle. The data types in RDataBlock are mainly divided into element data and composite data.

Element data is a single built-in data type with the following available values:

  • RLPy.EAttribute_Float - Float data.
  • RLPy.EAttribute_Int - Integer data.

Composite data is composed of sub-data and the following attributes can be set for hierarchical parameters:

  • RLPy.EAttribute_GroupXYZ - Creates a x, y, z float value data. The ID of the child data will be named after the ID of the parent plus x, y, z. For example, when creating an ID called "Reallusion", three sub-parameters "ReallusionX", "ReallusionY", and "ReallusionZ" will be automatically generated.

In addition, the attributes of the parameters can be specified during creation, as follows: RLPy.EAttributeFlag_Keyable indicates that the animation parameters can be set, if not set, then the value will be a constant. In order to make the parameters animate-able, you must deploy an animation controller. The system will automatically mount the corresponding control types for different data types. For example, if the parameter is a floating point number (like the Path Position attribute of the Path Control mentioned earlier), RFloatControl is required. During animation, parameter values can be obtained at any time via control interpolation. When RLPy.EAttributeFlag_Keyable is set, RLPy.EAttributeFlag_Storable is set as well. This flag indicates that the parameter can be stored to a file and will be serialized accordingly. When the file is read, the data for the requested IDs will be loaded, if an ID is not found then the data will be ignored. Developers can construct data blocks through the RIPlugin class and use CreateAttriute to create the parameters. For example, CurveRTSControl uses the following code to create all of its necessary parameters:

1 class CurveRTSControl(RLPy.RTransformControl):
2   def Initialize(self, plugin):
3     # Create parameters using RIPlugin
4     plugin.CreateAttribute("Position", RLPy.EAttribute_GroupXYZ, RLPy.EAttributeFlag_Keyable)
5     plugin.CreateAttribute("Rotation", RLPy.EAttribute_GroupXYZ, RLPy.EAttributeFlag_Keyable)
6     plugin.CreateAttribute("Scale", RLPy.EAttribute_GroupXYZ, RLPy.EAttributeFlag_Keyable)
7     plugin.CreateAttribute("EulerOrder", RLPy.EAttribute_Int, RLPy.EAttributeFlag_Storable)
Data created by RDataBlock
The CurveRTSControl shown in the Curve Editor. After a DataBlock is created, its data can be inspected inside the Timeline and Curve Editor.

GetData can be used to get the data value at a given time. If the data in question is a composite data, then a "/" can be used to link together the parent attribute with its child attributes. For example, the Position/PositionX ID for CurveRTSControl can gather data for the corresponding time. For consistency data blocks uses RVariant to save data. SetData is used to change the value of the data block. If RLPy.EAttributeFlag_Keyable is set, then a key will be set at the requested time. If more control over the key is desired, like getting the number of keys, moving keys, clearing all keys, etc. then use GetControl to retrieve the controller for more operations. There is currently no open interface for creating RDataBlock, nor functions for browsing a data block's existing parameters.These function will be provided in future versions.

References

Maya SDK

3dsMax SDK

Cinema4D SDK

Member Functions

Clone ( self )

Copy this data block and return a new identical object. This function is meant for internal usage and should not be called.

Returns

The copied data block object - RDataBlock
1 # Get an avatar in the scene
2 avatar_list = RLPy.RScene.GetAvatars()
3 avatar = avatar_list[0]
4 transform_control = avatar.GetControl("Transform")
5 
6 # Clone RDataBlock
7 cloned_block = transform_control.GetDataBlock().Clone()

GetControl ( self, strID )

Get the control on this data block according to the provided string ID. If the given ID is not found or if the RLPy.EAttributeFlag_Keyable is not set, then None will be returned.

Parameters

strID [IN] parameter ID - string

Returns

The control according to the input string ID - RControl
1 # Get an avatar in the scene
2 avatar_list = RLPy.RScene.GetAvatars()
3 avatar = avatar_list[0]
4 transform_control = avatar.GetControl("Transform")
5 
6 # Get Control
7 float_control = data_block.GetControl("Position/PositionX")

GetData ( self, strID, kTime, pReturnStatus = None )

Get the data block value at the given time. If the ID is not found then return None and pReturnStatus will return RLPy.RStatus.Failure. If RLPy.EAttributeFlag_Keyable is not set, then the data is a constant and the value returned will be fixed and does not change according to the kTime value. This function will return a RVariantand with RLPy.RVariant.GetType() one can retrieve the data type and use a corresponding function to convert it to the correct type.

Parameters

strID [IN] parameter ID - string
kTime [IN] parameter fetch time - RTime
pReturnStatus [OUT] return status - RStatus

Returns

Get the data block value - RVariant
1 # Get an avatar in the scene
2 avatar_list = RLPy.RScene.GetAvatars()
3 avatar = avatar_list[0]
4 transform_control = avatar.GetControl("Transform")
5 
6 # Get Data
7 data_block.GetData("Position/PositionX", RLPy.RTime(3000)).ToFloat()

SetData ( self, strID, kTime, kData )

Set the data block value at the requested time. If the given ID is not found then return RLPy.RStatus.Failure. If the RLPy.EAttributeFlag_Keyable attribute is not set, then the data is a constant and the key will not be set.

Parameters

strID [IN] parameter ID - string
kTime [IN] parameter time - RTime
kData [IN] parameter value - RVariant

Returns

Success - RLPy.RStatus.Success
Failure - RLPy.RStatus.Failure
1 # Get an avatar in the scene
2 avatar_list = RLPy.RScene.GetAvatars()
3 avatar = avatar_list[0]
4 transform_control = avatar.GetControl("Transform")
5 
6 # Set Data
7 data_block.SetData("Position/PositionX", RLPy.RTime(3000), RLPy.RVariant(100))
8    # set the position of the x-axis to 1000 at time 3000