2008-11-29 13:36:08 +00:00
/**
* $ Id $
*
* * * * * * 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 ,
2010-02-12 13:34:04 +00:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
2008-11-29 13:36:08 +00:00
*
* Contributor ( s ) : Campbell Barton
*
* * * * * * END GPL LICENSE BLOCK * * * * *
*/
2011-02-14 04:15:25 +00:00
# include <Python.h>
2011-01-07 18:36:47 +00:00
# include <float.h> /* FLT_MIN/MAX */
2008-11-29 13:36:08 +00:00
# include "bpy_rna.h"
2010-01-19 00:59:36 +00:00
# include "bpy_props.h"
2009-04-07 00:49:39 +00:00
# include "bpy_util.h"
2010-02-27 13:27:06 +00:00
# include "bpy_rna_callback.h"
2011-01-07 18:36:47 +00:00
2008-11-30 14:00:14 +00:00
# include "BLI_dynstr.h"
2010-09-26 13:53:32 +00:00
# include "BLI_string.h"
2009-03-19 19:03:38 +00:00
# include "BLI_listbase.h"
2011-01-07 18:36:47 +00:00
# include "BLI_utildefines.h"
2009-03-16 15:54:43 +00:00
2010-02-15 23:43:51 +00:00
# include "RNA_enum_types.h"
2010-09-10 14:54:50 +00:00
# include "RNA_define.h" /* RNA_def_property_free_identifier */
2008-11-29 13:36:08 +00:00
# include "MEM_guardedalloc.h"
2011-01-07 19:18:31 +00:00
2010-08-10 15:46:16 +00:00
# include "BKE_idcode.h"
2009-03-19 19:03:38 +00:00
# include "BKE_context.h"
2008-11-29 13:36:08 +00:00
# include "BKE_global.h" /* evil G.* */
2009-04-19 13:37:59 +00:00
# include "BKE_report.h"
2008-11-29 13:36:08 +00:00
2009-11-25 10:13:24 +00:00
# include "BKE_animsys.h"
# include "BKE_fcurve.h"
2009-07-08 09:23:49 +00:00
/* only for keyframing */
# include "DNA_scene_types.h"
2009-11-04 15:16:41 +00:00
# include "DNA_anim_types.h"
2009-07-08 09:23:49 +00:00
# include "ED_keyframing.h"
2009-11-16 19:03:40 +00:00
# include "../generic/IDProp.h" /* for IDprop lookups */
2010-09-01 14:13:48 +00:00
# include "../generic/py_capi_utils.h"
2009-06-22 04:26:48 +00:00
2010-12-09 06:08:19 +00:00
# define USE_PEDANTIC_WRITE
# define USE_MATHUTILS
# define USE_STRING_COERCE
2010-02-21 14:48:28 +00:00
2011-01-06 04:01:06 +00:00
static PyObject * pyrna_prop_collection_values ( BPy_PropertyRNA * self ) ;
2010-12-04 06:25:36 +00:00
# ifdef USE_PEDANTIC_WRITE
static short rna_disallow_writes = FALSE ;
static int rna_id_write_error ( PointerRNA * ptr , PyObject * key )
{
ID * id = ptr - > id . data ;
if ( id ) {
const short idcode = GS ( id - > name ) ;
if ( ! ELEM ( idcode , ID_WM , ID_SCR ) ) { /* may need more added here */
const char * idtype = BKE_idcode_to_name ( idcode ) ;
const char * pyname ;
if ( key & & PyUnicode_Check ( key ) ) pyname = _PyUnicode_AsString ( key ) ;
else pyname = " <UNKNOWN> " ;
2011-02-11 00:11:17 +00:00
2010-12-04 06:25:36 +00:00
/* make a nice string error */
2011-01-09 15:12:08 +00:00
BLI_assert ( idtype ! = NULL ) ;
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_AttributeError , " Writing to ID classes in this context is not allowed: %.200s, %.200s datablock, error setting %.200s.%.200s " , id - > name + 2 , idtype , RNA_struct_identifier ( ptr - > type ) , pyname ) ;
2011-02-11 00:11:17 +00:00
2010-12-04 06:25:36 +00:00
return TRUE ;
}
}
return FALSE ;
}
2011-02-01 00:32:50 +00:00
# endif // USE_PEDANTIC_WRITE
2010-12-04 06:25:36 +00:00
2011-02-01 00:32:50 +00:00
# ifdef USE_PEDANTIC_WRITE
int pyrna_write_check ( void )
{
return ! rna_disallow_writes ;
}
# else // USE_PEDANTIC_WRITE
int pyrna_write_check ( void )
{
return TRUE ;
}
2010-12-09 06:08:19 +00:00
# endif // USE_PEDANTIC_WRITE
static Py_ssize_t pyrna_prop_collection_length ( BPy_PropertyRNA * self ) ;
static Py_ssize_t pyrna_prop_array_length ( BPy_PropertyArrayRNA * self ) ;
static int pyrna_py_to_prop ( PointerRNA * ptr , PropertyRNA * prop , void * data , PyObject * value , const char * error_prefix ) ;
static int deferred_register_prop ( StructRNA * srna , PyObject * key , PyObject * item ) ;
# ifdef USE_MATHUTILS
# include "../generic/mathutils.h" /* so we can have mathutils callbacks */
2011-01-07 05:33:30 +00:00
static PyObject * pyrna_prop_array_subscript_slice ( BPy_PropertyArrayRNA * self , PointerRNA * ptr , PropertyRNA * prop , Py_ssize_t start , Py_ssize_t stop , Py_ssize_t length ) ;
2010-12-09 06:08:19 +00:00
static short pyrna_rotation_euler_order_get ( PointerRNA * ptr , PropertyRNA * * prop_eul_order , short order_fallback ) ;
/* bpyrna vector/euler/quat callbacks */
static int mathutils_rna_array_cb_index = - 1 ; /* index for our callbacks */
2009-06-22 04:26:48 +00:00
2010-08-15 12:03:49 +00:00
/* subtype not used much yet */
2010-02-20 19:49:04 +00:00
# define MATHUTILS_CB_SUBTYPE_EUL 0
# define MATHUTILS_CB_SUBTYPE_VEC 1
# define MATHUTILS_CB_SUBTYPE_QUAT 2
2010-08-15 12:03:49 +00:00
# define MATHUTILS_CB_SUBTYPE_COLOR 3
2010-02-20 19:49:04 +00:00
2010-04-26 21:04:42 +00:00
static int mathutils_rna_generic_check ( BaseMathObject * bmo )
2009-06-22 04:26:48 +00:00
{
2010-04-26 21:04:42 +00:00
BPy_PropertyRNA * self = ( BPy_PropertyRNA * ) bmo - > cb_user ;
return self - > prop ? 1 : 0 ;
2009-06-22 04:26:48 +00:00
}
2010-04-27 19:21:36 +00:00
static int mathutils_rna_vector_get ( BaseMathObject * bmo , int subtype )
2009-06-22 04:26:48 +00:00
{
2010-04-26 21:04:42 +00:00
BPy_PropertyRNA * self = ( BPy_PropertyRNA * ) bmo - > cb_user ;
2009-06-22 04:26:48 +00:00
if ( self - > prop = = NULL )
return 0 ;
2011-02-11 00:11:17 +00:00
2010-04-27 19:21:36 +00:00
RNA_property_float_get_array ( & self - > ptr , self - > prop , bmo - > data ) ;
2011-02-11 00:11:17 +00:00
2010-04-26 21:04:42 +00:00
/* Euler order exception */
if ( subtype = = MATHUTILS_CB_SUBTYPE_EUL ) {
2010-04-27 07:50:31 +00:00
EulerObject * eul = ( EulerObject * ) bmo ;
PropertyRNA * prop_eul_order = NULL ;
eul - > order = pyrna_rotation_euler_order_get ( & self - > ptr , & prop_eul_order , eul - > order ) ;
2010-04-26 21:04:42 +00:00
}
2011-02-11 00:11:17 +00:00
2009-06-22 04:26:48 +00:00
return 1 ;
}
2010-04-27 19:21:36 +00:00
static int mathutils_rna_vector_set ( BaseMathObject * bmo , int subtype )
2009-06-22 04:26:48 +00:00
{
2010-04-26 21:04:42 +00:00
BPy_PropertyRNA * self = ( BPy_PropertyRNA * ) bmo - > cb_user ;
2010-04-10 18:35:50 +00:00
float min , max ;
2009-06-22 04:26:48 +00:00
if ( self - > prop = = NULL )
return 0 ;
2010-12-04 06:25:36 +00:00
# ifdef USE_PEDANTIC_WRITE
if ( rna_disallow_writes & & rna_id_write_error ( & self - > ptr , NULL ) ) {
return 0 ;
}
2010-12-09 06:08:19 +00:00
# endif // USE_PEDANTIC_WRITE
2010-12-04 06:25:36 +00:00
2010-08-30 12:27:34 +00:00
if ( ! RNA_property_editable_flag ( & self - > ptr , self - > prop ) ) {
PyErr_Format ( PyExc_AttributeError , " bpy_prop \" %.200s.%.200s \" is read-only " , RNA_struct_identifier ( self - > ptr . type ) , RNA_property_identifier ( self - > prop ) ) ;
return 0 ;
}
2010-04-10 18:35:50 +00:00
RNA_property_float_range ( & self - > ptr , self - > prop , & min , & max ) ;
if ( min ! = FLT_MIN | | max ! = FLT_MAX ) {
int i , len = RNA_property_array_length ( & self - > ptr , self - > prop ) ;
for ( i = 0 ; i < len ; i + + ) {
2010-04-27 19:21:36 +00:00
CLAMP ( bmo - > data [ i ] , min , max ) ;
2010-04-10 18:35:50 +00:00
}
}
2010-04-27 19:21:36 +00:00
RNA_property_float_set_array ( & self - > ptr , self - > prop , bmo - > data ) ;
2010-10-25 21:57:45 +00:00
if ( RNA_property_update_check ( self - > prop ) ) {
RNA_property_update ( BPy_GetContext ( ) , & self - > ptr , self - > prop ) ;
}
2010-04-27 07:50:31 +00:00
2010-04-26 21:04:42 +00:00
/* Euler order exception */
if ( subtype = = MATHUTILS_CB_SUBTYPE_EUL ) {
2010-04-27 07:50:31 +00:00
EulerObject * eul = ( EulerObject * ) bmo ;
PropertyRNA * prop_eul_order = NULL ;
short order = pyrna_rotation_euler_order_get ( & self - > ptr , & prop_eul_order , eul - > order ) ;
if ( order ! = eul - > order ) {
RNA_property_enum_set ( & self - > ptr , prop_eul_order , eul - > order ) ;
2010-10-25 21:57:45 +00:00
if ( RNA_property_update_check ( prop_eul_order ) ) {
RNA_property_update ( BPy_GetContext ( ) , & self - > ptr , prop_eul_order ) ;
}
2010-04-27 07:50:31 +00:00
}
2010-04-26 21:04:42 +00:00
}
2009-06-22 04:26:48 +00:00
return 1 ;
}
2010-10-13 23:25:08 +00:00
static int mathutils_rna_vector_get_index ( BaseMathObject * bmo , int UNUSED ( subtype ) , int index )
2009-06-22 04:26:48 +00:00
{
2010-04-26 21:04:42 +00:00
BPy_PropertyRNA * self = ( BPy_PropertyRNA * ) bmo - > cb_user ;
2009-06-22 04:26:48 +00:00
if ( self - > prop = = NULL )
return 0 ;
2011-02-11 00:11:17 +00:00
2010-04-27 19:21:36 +00:00
bmo - > data [ index ] = RNA_property_float_get_index ( & self - > ptr , self - > prop , index ) ;
2009-06-22 04:26:48 +00:00
return 1 ;
}
2010-10-13 23:25:08 +00:00
static int mathutils_rna_vector_set_index ( BaseMathObject * bmo , int UNUSED ( subtype ) , int index )
2009-06-22 04:26:48 +00:00
{
2010-04-26 21:04:42 +00:00
BPy_PropertyRNA * self = ( BPy_PropertyRNA * ) bmo - > cb_user ;
2009-06-22 04:26:48 +00:00
if ( self - > prop = = NULL )
return 0 ;
2011-02-11 00:11:17 +00:00
2010-12-04 06:25:36 +00:00
# ifdef USE_PEDANTIC_WRITE
if ( rna_disallow_writes & & rna_id_write_error ( & self - > ptr , NULL ) ) {
return 0 ;
}
2010-12-09 06:08:19 +00:00
# endif // USE_PEDANTIC_WRITE
2011-02-11 00:11:17 +00:00
2010-08-30 12:27:34 +00:00
if ( ! RNA_property_editable_flag ( & self - > ptr , self - > prop ) ) {
PyErr_Format ( PyExc_AttributeError , " bpy_prop \" %.200s.%.200s \" is read-only " , RNA_struct_identifier ( self - > ptr . type ) , RNA_property_identifier ( self - > prop ) ) ;
return 0 ;
}
2009-06-22 04:26:48 +00:00
2010-04-27 19:21:36 +00:00
RNA_property_float_clamp ( & self - > ptr , self - > prop , & bmo - > data [ index ] ) ;
RNA_property_float_set_index ( & self - > ptr , self - > prop , index , bmo - > data [ index ] ) ;
2010-10-25 21:57:45 +00:00
if ( RNA_property_update_check ( self - > prop ) ) {
RNA_property_update ( BPy_GetContext ( ) , & self - > ptr , self - > prop ) ;
}
2009-06-22 04:26:48 +00:00
return 1 ;
}
2011-02-13 10:52:18 +00:00
static Mathutils_Callback mathutils_rna_array_cb = {
2009-07-10 18:09:53 +00:00
( BaseMathCheckFunc ) mathutils_rna_generic_check ,
( BaseMathGetFunc ) mathutils_rna_vector_get ,
( BaseMathSetFunc ) mathutils_rna_vector_set ,
( BaseMathGetIndexFunc ) mathutils_rna_vector_get_index ,
( BaseMathSetIndexFunc ) mathutils_rna_vector_set_index
2009-06-22 04:26:48 +00:00
} ;
2009-07-10 18:09:53 +00:00
2009-06-23 13:34:45 +00:00
/* bpyrna matrix callbacks */
static int mathutils_rna_matrix_cb_index = - 1 ; /* index for our callbacks */
2010-10-13 23:25:08 +00:00
static int mathutils_rna_matrix_get ( BaseMathObject * bmo , int UNUSED ( subtype ) )
2009-06-23 13:34:45 +00:00
{
2010-04-26 21:04:42 +00:00
BPy_PropertyRNA * self = ( BPy_PropertyRNA * ) bmo - > cb_user ;
2009-06-23 13:34:45 +00:00
if ( self - > prop = = NULL )
return 0 ;
2010-04-27 19:21:36 +00:00
RNA_property_float_get_array ( & self - > ptr , self - > prop , bmo - > data ) ;
2009-06-23 13:34:45 +00:00
return 1 ;
}
2010-10-13 23:25:08 +00:00
static int mathutils_rna_matrix_set ( BaseMathObject * bmo , int UNUSED ( subtype ) )
2009-06-23 13:34:45 +00:00
{
2010-04-26 21:04:42 +00:00
BPy_PropertyRNA * self = ( BPy_PropertyRNA * ) bmo - > cb_user ;
2011-02-11 00:11:17 +00:00
2009-06-23 13:34:45 +00:00
if ( self - > prop = = NULL )
return 0 ;
2010-12-04 06:25:36 +00:00
# ifdef USE_PEDANTIC_WRITE
if ( rna_disallow_writes & & rna_id_write_error ( & self - > ptr , NULL ) ) {
return 0 ;
}
2010-12-09 06:08:19 +00:00
# endif // USE_PEDANTIC_WRITE
2010-12-04 06:25:36 +00:00
2010-08-30 12:27:34 +00:00
if ( ! RNA_property_editable_flag ( & self - > ptr , self - > prop ) ) {
PyErr_Format ( PyExc_AttributeError , " bpy_prop \" %.200s.%.200s \" is read-only " , RNA_struct_identifier ( self - > ptr . type ) , RNA_property_identifier ( self - > prop ) ) ;
return 0 ;
}
2011-02-11 00:11:17 +00:00
2010-02-21 14:48:28 +00:00
/* can ignore clamping here */
2010-04-27 19:21:36 +00:00
RNA_property_float_set_array ( & self - > ptr , self - > prop , bmo - > data ) ;
2010-10-25 21:57:45 +00:00
if ( RNA_property_update_check ( self - > prop ) ) {
RNA_property_update ( BPy_GetContext ( ) , & self - > ptr , self - > prop ) ;
}
2009-06-23 13:34:45 +00:00
return 1 ;
}
2011-02-13 10:52:18 +00:00
static Mathutils_Callback mathutils_rna_matrix_cb = {
2010-04-27 19:21:36 +00:00
mathutils_rna_generic_check ,
mathutils_rna_matrix_get ,
mathutils_rna_matrix_set ,
NULL ,
NULL
2009-06-23 13:34:45 +00:00
} ;
2010-12-09 06:08:19 +00:00
static short pyrna_rotation_euler_order_get ( PointerRNA * ptr , PropertyRNA * * prop_eul_order , short order_fallback )
2010-02-27 15:28:34 +00:00
{
2010-12-09 06:08:19 +00:00
/* attempt to get order */
if ( * prop_eul_order = = NULL )
* prop_eul_order = RNA_struct_find_property ( ptr , " rotation_mode " ) ;
if ( * prop_eul_order ) {
short order = RNA_property_enum_get ( ptr , * prop_eul_order ) ;
if ( order > = ROT_MODE_XYZ & & order < = ROT_MODE_ZYX ) /* could be quat or axisangle */
return order ;
2010-02-27 15:28:34 +00:00
}
2010-12-09 06:08:19 +00:00
return order_fallback ;
2010-02-27 15:28:34 +00:00
}
2010-12-09 06:08:19 +00:00
# endif // USE_MATHUTILS
2010-06-05 15:31:55 +00:00
# define PROP_ALL_VECTOR_SUBTYPES PROP_TRANSLATION: case PROP_DIRECTION: case PROP_VELOCITY: case PROP_ACCELERATION: case PROP_XYZ: case PROP_XYZ_LENGTH
2010-01-04 13:29:55 +00:00
2009-09-06 15:13:57 +00:00
PyObject * pyrna_math_object_from_array ( PointerRNA * ptr , PropertyRNA * prop )
{
PyObject * ret = NULL ;
# ifdef USE_MATHUTILS
2009-11-24 20:15:24 +00:00
int subtype , totdim ;
2009-09-06 15:13:57 +00:00
int len ;
2009-12-28 22:59:09 +00:00
int is_thick ;
2010-01-04 13:29:55 +00:00
int flag = RNA_property_flag ( prop ) ;
2009-09-06 15:13:57 +00:00
2009-11-24 20:15:24 +00:00
/* disallow dynamic sized arrays to be wrapped since the size could change
* to a size mathutils does not support */
2010-01-04 13:29:55 +00:00
if ( ( RNA_property_type ( prop ) ! = PROP_FLOAT ) | | ( flag & PROP_DYNAMIC ) )
2009-11-24 20:15:24 +00:00
return NULL ;
2009-09-06 15:13:57 +00:00
len = RNA_property_array_length ( ptr , prop ) ;
subtype = RNA_property_subtype ( prop ) ;
2009-09-09 19:40:46 +00:00
totdim = RNA_property_array_dimension ( ptr , prop , NULL ) ;
2010-01-04 13:29:55 +00:00
is_thick = ( flag & PROP_THICK_WRAP ) ;
2009-09-06 15:13:57 +00:00
if ( totdim = = 1 | | ( totdim = = 2 & & subtype = = PROP_MATRIX ) ) {
2009-12-28 22:59:09 +00:00
if ( ! is_thick )
ret = pyrna_prop_CreatePyObject ( ptr , prop ) ; /* owned by the Mathutils PyObject */
2009-09-06 15:13:57 +00:00
2009-12-10 10:23:53 +00:00
switch ( RNA_property_subtype ( prop ) ) {
2010-01-04 13:29:55 +00:00
case PROP_ALL_VECTOR_SUBTYPES :
2009-09-06 15:13:57 +00:00
if ( len > = 2 & & len < = 4 ) {
2009-12-28 22:59:09 +00:00
if ( is_thick ) {
ret = newVectorObject ( NULL , len , Py_NEW , NULL ) ;
RNA_property_float_get_array ( ptr , prop , ( ( VectorObject * ) ret ) - > vec ) ;
}
else {
2010-02-20 19:49:04 +00:00
PyObject * vec_cb = newVectorObject_cb ( ret , len , mathutils_rna_array_cb_index , MATHUTILS_CB_SUBTYPE_VEC ) ;
2009-12-28 22:59:09 +00:00
Py_DECREF ( ret ) ; /* the vector owns now */
ret = vec_cb ; /* return the vector instead */
}
2009-09-06 15:13:57 +00:00
}
break ;
case PROP_MATRIX :
if ( len = = 16 ) {
2009-12-28 22:59:09 +00:00
if ( is_thick ) {
ret = newMatrixObject ( NULL , 4 , 4 , Py_NEW , NULL ) ;
RNA_property_float_get_array ( ptr , prop , ( ( MatrixObject * ) ret ) - > contigPtr ) ;
}
else {
PyObject * mat_cb = newMatrixObject_cb ( ret , 4 , 4 , mathutils_rna_matrix_cb_index , FALSE ) ;
Py_DECREF ( ret ) ; /* the matrix owns now */
ret = mat_cb ; /* return the matrix instead */
}
2009-09-06 15:13:57 +00:00
}
else if ( len = = 9 ) {
2009-12-28 22:59:09 +00:00
if ( is_thick ) {
ret = newMatrixObject ( NULL , 3 , 3 , Py_NEW , NULL ) ;
RNA_property_float_get_array ( ptr , prop , ( ( MatrixObject * ) ret ) - > contigPtr ) ;
}
else {
PyObject * mat_cb = newMatrixObject_cb ( ret , 3 , 3 , mathutils_rna_matrix_cb_index , FALSE ) ;
Py_DECREF ( ret ) ; /* the matrix owns now */
ret = mat_cb ; /* return the matrix instead */
}
2009-09-06 15:13:57 +00:00
}
break ;
case PROP_EULER :
case PROP_QUATERNION :
if ( len = = 3 ) { /* euler */
2009-12-28 22:59:09 +00:00
if ( is_thick ) {
2010-11-28 06:03:30 +00:00
/* attempt to get order, only needed for thick types since wrapped with update via callbacks */
2010-04-27 07:50:31 +00:00
PropertyRNA * prop_eul_order = NULL ;
short order = pyrna_rotation_euler_order_get ( ptr , & prop_eul_order , ROT_MODE_XYZ ) ;
2010-04-25 23:33:09 +00:00
ret = newEulerObject ( NULL , order , Py_NEW , NULL ) ; // TODO, get order from RNA
2009-12-28 22:59:09 +00:00
RNA_property_float_get_array ( ptr , prop , ( ( EulerObject * ) ret ) - > eul ) ;
}
else {
2010-04-27 07:50:31 +00:00
/* order will be updated from callback on use */
PyObject * eul_cb = newEulerObject_cb ( ret , ROT_MODE_XYZ , mathutils_rna_array_cb_index , MATHUTILS_CB_SUBTYPE_EUL ) ; // TODO, get order from RNA
2010-04-11 14:22:27 +00:00
Py_DECREF ( ret ) ; /* the euler owns now */
ret = eul_cb ; /* return the euler instead */
2009-12-28 22:59:09 +00:00
}
2009-09-06 15:13:57 +00:00
}
else if ( len = = 4 ) {
2009-12-28 22:59:09 +00:00
if ( is_thick ) {
ret = newQuaternionObject ( NULL , Py_NEW , NULL ) ;
RNA_property_float_get_array ( ptr , prop , ( ( QuaternionObject * ) ret ) - > quat ) ;
}
else {
2010-02-20 19:49:04 +00:00
PyObject * quat_cb = newQuaternionObject_cb ( ret , mathutils_rna_array_cb_index , MATHUTILS_CB_SUBTYPE_QUAT ) ;
2010-04-11 14:22:27 +00:00
Py_DECREF ( ret ) ; /* the quat owns now */
ret = quat_cb ; /* return the quat instead */
2009-12-28 22:59:09 +00:00
}
2009-09-06 15:13:57 +00:00
}
break ;
2010-04-11 14:22:27 +00:00
case PROP_COLOR :
if ( len = = 3 ) { /* color */
if ( is_thick ) {
ret = newColorObject ( NULL , Py_NEW , NULL ) ; // TODO, get order from RNA
RNA_property_float_get_array ( ptr , prop , ( ( ColorObject * ) ret ) - > col ) ;
}
else {
PyObject * col_cb = newColorObject_cb ( ret , mathutils_rna_array_cb_index , MATHUTILS_CB_SUBTYPE_COLOR ) ;
Py_DECREF ( ret ) ; /* the color owns now */
ret = col_cb ; /* return the color instead */
}
}
2009-09-06 15:13:57 +00:00
default :
break ;
}
}
2009-12-28 22:59:09 +00:00
2010-01-02 17:33:44 +00:00
if ( ret = = NULL ) {
if ( is_thick ) {
/* this is an array we cant reference (since its not thin wrappable)
* and cannot be coerced into a mathutils type , so return as a list */
2010-02-15 23:43:51 +00:00
ret = pyrna_prop_array_subscript_slice ( NULL , ptr , prop , 0 , len , len ) ;
2010-01-02 17:33:44 +00:00
} else {
ret = pyrna_prop_CreatePyObject ( ptr , prop ) ; /* owned by the Mathutils PyObject */
}
}
2010-12-09 06:08:19 +00:00
# else // USE_MATHUTILS
( void ) ptr ;
( void ) prop ;
# endif // USE_MATHUTILS
2009-09-06 15:13:57 +00:00
return ret ;
}
2010-12-09 06:08:19 +00:00
/* same as RNA_enum_value_from_id but raises an exception */
int pyrna_enum_value_from_id ( EnumPropertyItem * item , const char * identifier , int * value , const char * error_prefix )
2010-04-27 07:50:31 +00:00
{
2010-12-09 06:08:19 +00:00
if ( RNA_enum_value_from_id ( item , identifier , value ) = = 0 ) {
2011-02-01 23:53:54 +00:00
const char * enum_str = BPy_enum_as_string ( item ) ;
2010-12-09 06:08:19 +00:00
PyErr_Format ( PyExc_TypeError , " %s: '%.200s' not found in (%s) " , error_prefix , identifier , enum_str ) ;
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) enum_str ) ;
2010-12-09 06:08:19 +00:00
return - 1 ;
2010-04-27 07:50:31 +00:00
}
2010-12-09 06:08:19 +00:00
return 0 ;
2010-04-27 07:50:31 +00:00
}
2008-11-29 13:36:08 +00:00
static int pyrna_struct_compare ( BPy_StructRNA * a , BPy_StructRNA * b )
2009-01-29 09:38:52 +00:00
{
2008-11-29 13:36:08 +00:00
return ( a - > ptr . data = = b - > ptr . data ) ? 0 : - 1 ;
}
static int pyrna_prop_compare ( BPy_PropertyRNA * a , BPy_PropertyRNA * b )
{
return ( a - > prop = = b - > prop & & a - > ptr . data = = b - > ptr . data ) ? 0 : - 1 ;
}
2009-01-29 09:38:52 +00:00
2009-09-03 01:52:10 +00:00
static PyObject * pyrna_struct_richcmp ( PyObject * a , PyObject * b , int op )
2009-01-29 09:38:52 +00:00
{
2009-09-03 01:52:10 +00:00
PyObject * res ;
int ok = - 1 ; /* zero is true */
if ( BPy_StructRNA_Check ( a ) & & BPy_StructRNA_Check ( b ) )
ok = pyrna_struct_compare ( ( BPy_StructRNA * ) a , ( BPy_StructRNA * ) b ) ;
switch ( op ) {
case Py_NE :
ok = ! ok ; /* pass through */
case Py_EQ :
res = ok ? Py_False : Py_True ;
break ;
case Py_LT :
case Py_LE :
case Py_GT :
case Py_GE :
res = Py_NotImplemented ;
break ;
default :
PyErr_BadArgument ( ) ;
return NULL ;
2009-01-29 09:38:52 +00:00
}
2010-09-09 17:36:54 +00:00
return Py_INCREF ( res ) , res ;
2009-01-29 09:38:52 +00:00
}
2009-09-03 01:52:10 +00:00
static PyObject * pyrna_prop_richcmp ( PyObject * a , PyObject * b , int op )
2009-01-29 09:38:52 +00:00
{
2009-09-03 01:52:10 +00:00
PyObject * res ;
int ok = - 1 ; /* zero is true */
if ( BPy_PropertyRNA_Check ( a ) & & BPy_PropertyRNA_Check ( b ) )
ok = pyrna_prop_compare ( ( BPy_PropertyRNA * ) a , ( BPy_PropertyRNA * ) b ) ;
switch ( op ) {
case Py_NE :
ok = ! ok ; /* pass through */
case Py_EQ :
res = ok ? Py_False : Py_True ;
break ;
case Py_LT :
case Py_LE :
case Py_GT :
case Py_GE :
res = Py_NotImplemented ;
break ;
default :
PyErr_BadArgument ( ) ;
return NULL ;
2009-01-29 09:38:52 +00:00
}
2010-09-09 17:36:54 +00:00
return Py_INCREF ( res ) , res ;
2009-01-29 09:38:52 +00:00
}
2009-04-07 00:49:39 +00:00
2008-11-29 13:36:08 +00:00
/*----------------------repr--------------------------------------------*/
2010-08-10 15:46:16 +00:00
static PyObject * pyrna_struct_str ( BPy_StructRNA * self )
2008-11-29 13:36:08 +00:00
{
2010-08-10 15:46:16 +00:00
PyObject * ret ;
2011-02-01 23:53:54 +00:00
const char * name ;
2009-03-23 13:28:42 +00:00
/* print name if available */
2009-07-26 18:18:14 +00:00
name = RNA_struct_name_get_alloc ( & self - > ptr , NULL , FALSE ) ;
2009-06-24 14:03:55 +00:00
if ( name ) {
2010-08-10 15:46:16 +00:00
ret = PyUnicode_FromFormat ( " <bpy_struct, %.200s( \" %.200s \" )> " , RNA_struct_identifier ( self - > ptr . type ) , name ) ;
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) name ) ;
2010-08-10 15:46:16 +00:00
return ret ;
2009-03-23 13:28:42 +00:00
}
merge own commits into render branch into trunk since 27560
27562, 27570, 27571, 27574, 27576, 27577, 27579, 27590, 27591, 27594, 27595, 27596, 27599, 27605, 27611, 27612, 27613, 27614, 27623
2010-03-20 16:41:01 +00:00
return PyUnicode_FromFormat ( " <bpy_struct, %.200s at %p> " , RNA_struct_identifier ( self - > ptr . type ) , self - > ptr . data ) ;
2008-11-29 13:36:08 +00:00
}
2010-08-10 15:46:16 +00:00
static PyObject * pyrna_struct_repr ( BPy_StructRNA * self )
{
ID * id = self - > ptr . id . data ;
if ( id = = NULL )
return pyrna_struct_str ( self ) ; /* fallback */
2011-02-11 00:11:17 +00:00
2010-08-10 15:46:16 +00:00
if ( RNA_struct_is_ID ( self - > ptr . type ) ) {
return PyUnicode_FromFormat ( " bpy.data.%s[ \" %s \" ] " , BKE_idcode_to_name_plural ( GS ( id - > name ) ) , id - > name + 2 ) ;
}
else {
PyObject * ret ;
2011-02-01 23:53:54 +00:00
const char * path ;
2010-08-10 15:46:16 +00:00
path = RNA_path_from_ID_to_struct ( & self - > ptr ) ;
if ( path ) {
ret = PyUnicode_FromFormat ( " bpy.data.%s[ \" %s \" ].%s " , BKE_idcode_to_name_plural ( GS ( id - > name ) ) , id - > name + 2 , path ) ;
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) path ) ;
2010-08-10 15:46:16 +00:00
}
else { /* cant find, print something sane */
ret = PyUnicode_FromFormat ( " bpy.data.%s[ \" %s \" ]...%s " , BKE_idcode_to_name_plural ( GS ( id - > name ) ) , id - > name + 2 , RNA_struct_identifier ( self - > ptr . type ) ) ;
}
2011-02-11 00:11:17 +00:00
2010-08-10 15:46:16 +00:00
return ret ;
}
}
static PyObject * pyrna_prop_str ( BPy_PropertyRNA * self )
2008-11-29 13:36:08 +00:00
{
2010-08-10 15:46:16 +00:00
PyObject * ret ;
2009-03-23 13:28:42 +00:00
PointerRNA ptr ;
2011-02-01 23:53:54 +00:00
const char * name ;
2010-02-15 23:43:51 +00:00
const char * type_id = NULL ;
char type_fmt [ 64 ] = " " ;
int type = RNA_property_type ( self - > prop ) ;
if ( RNA_enum_id_from_value ( property_type_items , type , & type_id ) = = 0 ) {
PyErr_SetString ( PyExc_SystemError , " could not use property type, internal error " ) ; /* should never happen */
return NULL ;
}
else {
/* this should never fail */
int len = - 1 ;
char * c = type_fmt ;
while ( ( * c + + = tolower ( * type_id + + ) ) ) { } ;
if ( type = = PROP_COLLECTION ) {
len = pyrna_prop_collection_length ( self ) ;
} else if ( RNA_property_array_check ( & self - > ptr , self - > prop ) ) {
2010-09-02 06:35:00 +00:00
len = pyrna_prop_array_length ( ( BPy_PropertyArrayRNA * ) self ) ;
2010-02-15 23:43:51 +00:00
}
if ( len ! = - 1 )
sprintf ( - - c , " [%d] " , len ) ;
}
2009-03-23 13:28:42 +00:00
/* if a pointer, try to print name of pointer target too */
2009-04-19 13:37:59 +00:00
if ( RNA_property_type ( self - > prop ) = = PROP_POINTER ) {
2009-03-23 13:28:42 +00:00
ptr = RNA_property_pointer_get ( & self - > ptr , self - > prop ) ;
2009-07-26 18:18:14 +00:00
name = RNA_struct_name_get_alloc ( & ptr , NULL , FALSE ) ;
2009-03-23 13:28:42 +00:00
2009-06-24 14:03:55 +00:00
if ( name ) {
2010-08-10 15:46:16 +00:00
ret = PyUnicode_FromFormat ( " <bpy_%.200s, %.200s.%.200s( \" %.200s \" )> " , type_fmt , RNA_struct_identifier ( self - > ptr . type ) , RNA_property_identifier ( self - > prop ) , name ) ;
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) name ) ;
2010-08-10 15:46:16 +00:00
return ret ;
2009-03-23 13:28:42 +00:00
}
}
2011-02-14 03:15:55 +00:00
if ( RNA_property_type ( self - > prop ) = = PROP_COLLECTION ) {
PointerRNA r_ptr ;
if ( RNA_property_collection_type_get ( & self - > ptr , self - > prop , & r_ptr ) ) {
return PyUnicode_FromFormat ( " <bpy_%.200s, %.200s> " , type_fmt , RNA_struct_identifier ( r_ptr . type ) ) ;
}
}
2009-03-23 13:28:42 +00:00
2010-02-15 23:43:51 +00:00
return PyUnicode_FromFormat ( " <bpy_%.200s, %.200s.%.200s> " , type_fmt , RNA_struct_identifier ( self - > ptr . type ) , RNA_property_identifier ( self - > prop ) ) ;
2008-11-29 13:36:08 +00:00
}
2009-04-09 17:31:23 +00:00
2010-08-10 15:46:16 +00:00
static PyObject * pyrna_prop_repr ( BPy_PropertyRNA * self )
{
ID * id = self - > ptr . id . data ;
PyObject * ret ;
2011-02-01 23:53:54 +00:00
const char * path ;
2011-02-11 00:11:17 +00:00
2010-08-10 15:46:16 +00:00
if ( id = = NULL )
return pyrna_prop_str ( self ) ; /* fallback */
2011-02-11 00:11:17 +00:00
2010-08-10 15:46:16 +00:00
path = RNA_path_from_ID_to_property ( & self - > ptr , self - > prop ) ;
if ( path ) {
ret = PyUnicode_FromFormat ( " bpy.data.%s[ \" %s \" ].%s " , BKE_idcode_to_name_plural ( GS ( id - > name ) ) , id - > name + 2 , path ) ;
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) path ) ;
2010-08-10 15:46:16 +00:00
}
else { /* cant find, print something sane */
ret = PyUnicode_FromFormat ( " bpy.data.%s[ \" %s \" ]...%s " , BKE_idcode_to_name_plural ( GS ( id - > name ) ) , id - > name + 2 , RNA_property_identifier ( self - > prop ) ) ;
}
2011-02-11 00:11:17 +00:00
2010-08-10 15:46:16 +00:00
return ret ;
}
2009-11-16 19:03:40 +00:00
static long pyrna_struct_hash ( BPy_StructRNA * self )
2008-12-02 14:36:35 +00:00
{
2010-04-25 21:13:42 +00:00
return _Py_HashPointer ( self - > ptr . data ) ;
}
/* from python's meth_hash v3.1.2 */
static long pyrna_prop_hash ( BPy_PropertyRNA * self )
2011-02-11 00:11:17 +00:00
{
2010-04-25 21:13:42 +00:00
long x , y ;
if ( self - > ptr . data = = NULL )
x = 0 ;
else {
x = _Py_HashPointer ( self - > ptr . data ) ;
if ( x = = - 1 )
return - 1 ;
}
y = _Py_HashPointer ( ( void * ) ( self - > prop ) ) ;
if ( y = = - 1 )
return - 1 ;
x ^ = y ;
if ( x = = - 1 )
x = - 2 ;
return x ;
2008-12-02 14:36:35 +00:00
}
2008-12-29 03:24:13 +00:00
/* use our own dealloc so we can free a property if we use one */
2009-11-16 19:03:40 +00:00
static void pyrna_struct_dealloc ( BPy_StructRNA * self )
2008-12-29 03:24:13 +00:00
{
2009-01-08 15:29:09 +00:00
if ( self - > freeptr & & self - > ptr . data ) {
2010-01-29 14:49:21 +00:00
IDP_FreeProperty ( self - > ptr . data ) ;
MEM_freeN ( self - > ptr . data ) ;
self - > ptr . data = NULL ;
2008-12-29 03:24:13 +00:00
}
2009-06-29 12:06:46 +00:00
/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
2009-03-16 15:54:43 +00:00
Py_TYPE ( self ) - > tp_free ( self ) ;
2008-12-29 03:24:13 +00:00
return ;
}
2009-04-07 00:49:39 +00:00
2010-12-03 17:05:21 +00:00
static const char * pyrna_enum_as_string ( PointerRNA * ptr , PropertyRNA * prop )
2008-12-25 10:48:36 +00:00
{
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
EnumPropertyItem * item ;
2010-12-03 17:05:21 +00:00
const char * result ;
2009-07-26 18:18:14 +00:00
int free = FALSE ;
2011-02-11 00:11:17 +00:00
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
RNA_property_enum_items ( BPy_GetContext ( ) , ptr , prop , & item , NULL , & free ) ;
2009-07-13 19:33:59 +00:00
if ( item ) {
2010-02-10 11:10:38 +00:00
result = BPy_enum_as_string ( item ) ;
2009-07-13 19:33:59 +00:00
}
else {
result = " " ;
}
2011-02-11 00:11:17 +00:00
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
if ( free )
MEM_freeN ( item ) ;
2011-02-11 00:11:17 +00:00
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
return result ;
2008-12-25 10:48:36 +00:00
}
2008-12-02 14:36:35 +00:00
2010-02-10 11:10:38 +00:00
2009-08-07 13:00:39 +00:00
static int pyrna_string_to_enum ( PyObject * item , PointerRNA * ptr , PropertyRNA * prop , int * val , const char * error_prefix )
{
2011-02-01 23:53:54 +00:00
const char * param = _PyUnicode_AsString ( item ) ;
2009-08-07 13:00:39 +00:00
if ( param = = NULL ) {
2010-12-03 17:05:21 +00:00
const char * enum_str = pyrna_enum_as_string ( ptr , prop ) ;
2009-08-07 13:00:39 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected a string enum type in (%.200s) " , error_prefix , enum_str ) ;
2010-12-03 17:05:21 +00:00
MEM_freeN ( ( void * ) enum_str ) ;
2009-08-07 13:00:39 +00:00
return 0 ;
} else {
if ( ! RNA_property_enum_value ( BPy_GetContext ( ) , ptr , prop , param , val ) ) {
2010-12-03 17:05:21 +00:00
const char * enum_str = pyrna_enum_as_string ( ptr , prop ) ;
2009-08-07 13:00:39 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s enum \" %.200s \" not found in (%.200s) " , error_prefix , param , enum_str ) ;
2010-12-03 17:05:21 +00:00
MEM_freeN ( ( void * ) enum_str ) ;
2009-08-07 13:00:39 +00:00
return 0 ;
}
}
return 1 ;
}
2010-02-01 22:04:33 +00:00
int pyrna_set_to_enum_bitfield ( EnumPropertyItem * items , PyObject * value , int * r_value , const char * error_prefix )
{
/* set of enum items, concatenate all values with OR */
int ret , flag = 0 ;
/* set looping */
Py_ssize_t pos = 0 ;
PyObject * key ;
long hash ;
* r_value = 0 ;
while ( _PySet_NextEntry ( value , & pos , & key , & hash ) ) {
2011-02-01 23:53:54 +00:00
const char * param = _PyUnicode_AsString ( key ) ;
2010-02-01 22:04:33 +00:00
if ( param = = NULL ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s expected a string, not %.200s " , error_prefix , Py_TYPE ( key ) - > tp_name ) ;
2010-02-01 22:04:33 +00:00
return - 1 ;
}
2010-02-27 15:28:34 +00:00
if ( pyrna_enum_value_from_id ( items , param , & ret , error_prefix ) < 0 )
2010-02-01 22:04:33 +00:00
return - 1 ;
flag | = ret ;
}
* r_value = flag ;
return 0 ;
}
static int pyrna_prop_to_enum_bitfield ( PointerRNA * ptr , PropertyRNA * prop , PyObject * value , int * r_value , const char * error_prefix )
{
EnumPropertyItem * item ;
int ret ;
int free = FALSE ;
* r_value = 0 ;
RNA_property_enum_items ( BPy_GetContext ( ) , ptr , prop , & item , NULL , & free ) ;
if ( item ) {
ret = pyrna_set_to_enum_bitfield ( item , value , r_value , error_prefix ) ;
}
else {
if ( PySet_GET_SIZE ( value ) ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s: empty enum \" %.200s \" could not have any values assigned " , error_prefix , RNA_property_identifier ( prop ) ) ;
2010-02-01 22:04:33 +00:00
ret = - 1 ;
}
else {
ret = 0 ;
}
}
if ( free )
MEM_freeN ( item ) ;
return ret ;
}
2010-01-23 01:02:53 +00:00
PyObject * pyrna_enum_bitfield_to_py ( EnumPropertyItem * items , int value )
{
PyObject * ret = PySet_New ( NULL ) ;
const char * identifier [ RNA_ENUM_BITFLAG_SIZE + 1 ] ;
if ( RNA_enum_bitflag_identifiers ( items , value , identifier ) ) {
PyObject * item ;
int index ;
for ( index = 0 ; identifier [ index ] ; index + + ) {
item = PyUnicode_FromString ( identifier [ index ] ) ;
PySet_Add ( ret , item ) ;
Py_DECREF ( item ) ;
}
}
return ret ;
}
2009-12-07 00:16:57 +00:00
static PyObject * pyrna_enum_to_py ( PointerRNA * ptr , PropertyRNA * prop , int val )
2008-11-29 13:36:08 +00:00
{
2009-12-07 02:20:55 +00:00
PyObject * item , * ret = NULL ;
2009-03-05 08:53:29 +00:00
2009-12-07 00:16:57 +00:00
if ( RNA_property_flag ( prop ) & PROP_ENUM_FLAG ) {
const char * identifier [ RNA_ENUM_BITFLAG_SIZE + 1 ] ;
2009-12-07 02:20:55 +00:00
ret = PySet_New ( NULL ) ;
if ( RNA_property_enum_bitflag_identifiers ( BPy_GetContext ( ) , ptr , prop , val , identifier ) ) {
int index ;
2009-12-07 00:16:57 +00:00
2009-12-07 02:20:55 +00:00
for ( index = 0 ; identifier [ index ] ; index + + ) {
item = PyUnicode_FromString ( identifier [ index ] ) ;
PySet_Add ( ret , item ) ;
Py_DECREF ( item ) ;
2009-12-07 00:16:57 +00:00
}
2009-12-07 02:20:55 +00:00
2009-12-07 00:16:57 +00:00
}
2008-11-29 13:36:08 +00:00
}
2009-12-07 00:16:57 +00:00
else {
2008-12-02 14:36:35 +00:00
const char * identifier ;
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
if ( RNA_property_enum_identifier ( BPy_GetContext ( ) , ptr , prop , val , & identifier ) ) {
2009-12-07 00:16:57 +00:00
ret = PyUnicode_FromString ( identifier ) ;
2008-11-29 17:58:17 +00:00
} else {
2011-02-14 03:15:55 +00:00
EnumPropertyItem * enum_item ;
2009-07-26 18:18:14 +00:00
int free = FALSE ;
2009-07-03 19:56:19 +00:00
/* don't throw error here, can't trust blender 100% to give the
* right values , python code should not generate error for that */
2011-02-14 03:15:55 +00:00
RNA_property_enum_items ( BPy_GetContext ( ) , ptr , prop , & enum_item , NULL , & free ) ;
if ( enum_item & & enum_item - > identifier ) {
ret = PyUnicode_FromString ( enum_item - > identifier ) ;
2009-07-08 09:23:49 +00:00
}
else {
2011-02-01 23:53:54 +00:00
const char * ptr_name = RNA_struct_name_get_alloc ( ptr , NULL , FALSE ) ;
2009-12-07 00:16:57 +00:00
2009-07-08 09:23:49 +00:00
/* prefer not fail silently incase of api errors, maybe disable it later */
2009-11-12 15:46:45 +00:00
printf ( " RNA Warning: Current value \" %d \" matches no enum in '%s', '%s', '%s' \n " , val , RNA_struct_identifier ( ptr - > type ) , ptr_name , RNA_property_identifier ( prop ) ) ;
#if 0 // gives python decoding errors while generating docs :(
char error_str [ 256 ] ;
snprintf ( error_str , sizeof ( error_str ) , " RNA Warning: Current value \" %d \" matches no enum in '%s', '%s', '%s' " , val , RNA_struct_identifier ( ptr - > type ) , ptr_name , RNA_property_identifier ( prop ) ) ;
2009-07-08 09:23:49 +00:00
PyErr_Warn ( PyExc_RuntimeWarning , error_str ) ;
2009-11-12 15:46:45 +00:00
# endif
2009-12-07 00:16:57 +00:00
if ( ptr_name )
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) ptr_name ) ;
2009-07-08 09:23:49 +00:00
2011-02-01 23:53:54 +00:00
ret = PyUnicode_FromString ( " " ) ;
2009-07-08 09:23:49 +00:00
}
2009-07-03 19:56:19 +00:00
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
if ( free )
2011-02-14 03:15:55 +00:00
MEM_freeN ( enum_item ) ;
RNA
* Enums can now be dynamically created in the _itemf callback,
using RNA_enum_item(s)_add, RNA_enum_item_end. All places asking
for enum items now need to potentially free the items.
* This callback now also gets context, this was added specifically
for operators. This doesn't fit design well at all, needed to do
some ugly hacks, but can't find a good solution at the moment.
* All enums must have a default list of items too, even with an
_itemf callback, for docs and fallback in case there is no context.
* Used by MESH_OT_merge, MESH_OT_select_similar, TFM_OT_select_orientation.
* Also changes some operator properties that were enums to booleas
(unselected, deselect), to make them consistent with other ops.
2009-07-10 19:56:13 +00:00
2009-07-03 19:56:19 +00:00
/*PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val);
ret = NULL ; */
2008-11-29 13:36:08 +00:00
}
2009-12-07 00:16:57 +00:00
}
return ret ;
}
PyObject * pyrna_prop_to_py ( PointerRNA * ptr , PropertyRNA * prop )
{
PyObject * ret ;
int type = RNA_property_type ( prop ) ;
2008-12-02 14:36:35 +00:00
2009-12-07 00:16:57 +00:00
if ( RNA_property_array_check ( ptr , prop ) ) {
return pyrna_py_from_array ( ptr , prop ) ;
}
2011-02-11 00:11:17 +00:00
2009-12-07 00:16:57 +00:00
/* see if we can coorce into a python type - PropertyType */
switch ( type ) {
case PROP_BOOLEAN :
ret = PyBool_FromLong ( RNA_property_boolean_get ( ptr , prop ) ) ;
break ;
case PROP_INT :
ret = PyLong_FromSsize_t ( ( Py_ssize_t ) RNA_property_int_get ( ptr , prop ) ) ;
break ;
case PROP_FLOAT :
ret = PyFloat_FromDouble ( RNA_property_float_get ( ptr , prop ) ) ;
break ;
case PROP_STRING :
{
2010-08-28 12:34:22 +00:00
int subtype = RNA_property_subtype ( prop ) ;
2011-02-01 23:53:54 +00:00
const char * buf ;
2009-12-07 00:16:57 +00:00
buf = RNA_property_string_get_alloc ( ptr , prop , NULL , - 1 ) ;
2010-08-28 12:34:22 +00:00
# ifdef USE_STRING_COERCE
/* only file paths get special treatment, they may contain non utf-8 chars */
if ( ELEM3 ( subtype , PROP_FILEPATH , PROP_DIRPATH , PROP_FILENAME ) ) {
2010-09-01 14:13:48 +00:00
ret = PyC_UnicodeFromByte ( buf ) ;
2010-08-28 12:34:22 +00:00
}
else {
ret = PyUnicode_FromString ( buf ) ;
}
2010-12-09 06:08:19 +00:00
# else // USE_STRING_COERCE
2010-08-28 12:34:22 +00:00
ret = PyUnicode_FromString ( buf ) ;
2010-12-09 06:08:19 +00:00
# endif // USE_STRING_COERCE
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) buf ) ;
2009-12-07 00:16:57 +00:00
break ;
}
case PROP_ENUM :
{
ret = pyrna_enum_to_py ( ptr , prop , RNA_property_enum_get ( ptr , prop ) ) ;
2008-11-29 13:36:08 +00:00
break ;
}
case PROP_POINTER :
{
PointerRNA newptr ;
2009-02-02 19:57:57 +00:00
newptr = RNA_property_pointer_get ( ptr , prop ) ;
2009-10-09 01:34:46 +00:00
if ( newptr . data ) {
2008-11-29 13:36:08 +00:00
ret = pyrna_struct_CreatePyObject ( & newptr ) ;
} else {
ret = Py_None ;
Py_INCREF ( ret ) ;
}
break ;
}
case PROP_COLLECTION :
2009-03-05 12:09:30 +00:00
ret = pyrna_prop_CreatePyObject ( ptr , prop ) ;
2008-11-29 13:36:08 +00:00
break ;
default :
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " bpy_struct internal error: unknown type '%d' (pyrna_prop_to_py) " , type ) ;
2008-11-29 13:36:08 +00:00
ret = NULL ;
break ;
}
2011-02-11 00:11:17 +00:00
2008-11-29 13:36:08 +00:00
return ret ;
}
2009-07-30 01:52:00 +00:00
/* This function is used by operators and converting dicts into collections.
* Its takes keyword args and fills them with property values */
int pyrna_pydict_to_props ( PointerRNA * ptr , PyObject * kw , int all_args , const char * error_prefix )
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
{
int error_val = 0 ;
int totkw ;
const char * arg_name = NULL ;
PyObject * item ;
totkw = kw ? PyDict_Size ( kw ) : 0 ;
2009-06-24 21:27:10 +00:00
RNA_STRUCT_BEGIN ( ptr , prop ) {
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
arg_name = RNA_property_identifier ( prop ) ;
if ( strcmp ( arg_name , " rna_type " ) = = 0 ) continue ;
if ( kw = = NULL ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s: no keywords, expected \" %.200s \" " , error_prefix , arg_name ? arg_name : " <UNKNOWN> " ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
error_val = - 1 ;
break ;
}
2009-07-30 01:52:00 +00:00
item = PyDict_GetItemString ( kw , arg_name ) ; /* wont set an error */
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
if ( item = = NULL ) {
2009-07-30 01:52:00 +00:00
if ( all_args ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s: keyword \" %.200s \" missing " , error_prefix , arg_name ? arg_name : " <UNKNOWN> " ) ;
2009-07-30 01:52:00 +00:00
error_val = - 1 ; /* pyrna_py_to_prop sets the error */
break ;
}
} else {
2010-10-13 23:25:08 +00:00
if ( pyrna_py_to_prop ( ptr , prop , NULL , item , error_prefix ) ) {
2009-07-30 01:52:00 +00:00
error_val = - 1 ;
break ;
}
totkw - - ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
}
}
2009-06-24 21:27:10 +00:00
RNA_STRUCT_END ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
if ( error_val = = 0 & & totkw > 0 ) { /* some keywords were given that were not used :/ */
PyObject * key , * value ;
Py_ssize_t pos = 0 ;
while ( PyDict_Next ( kw , & pos , & key , & value ) ) {
arg_name = _PyUnicode_AsString ( key ) ;
if ( RNA_struct_find_property ( ptr , arg_name ) = = NULL ) break ;
arg_name = NULL ;
}
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s: keyword \" %.200s \" unrecognized " , error_prefix , arg_name ? arg_name : " <UNKNOWN> " ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
error_val = - 1 ;
}
return error_val ;
}
2009-11-16 19:03:40 +00:00
static PyObject * pyrna_func_call ( PyObject * self , PyObject * args , PyObject * kw ) ;
2009-04-09 13:20:48 +00:00
2009-12-07 02:20:55 +00:00
static PyObject * pyrna_func_to_py ( BPy_DummyPointerRNA * pyrna , FunctionRNA * func )
2009-04-09 17:31:23 +00:00
{
2009-04-09 13:20:48 +00:00
static PyMethodDef func_meth = { " <generic rna function> " , ( PyCFunction ) pyrna_func_call , METH_VARARGS | METH_KEYWORDS , " python rna function " } ;
2009-07-17 12:26:40 +00:00
PyObject * self ;
2009-04-09 13:20:48 +00:00
PyObject * ret ;
2011-02-11 00:11:17 +00:00
2009-07-17 12:26:40 +00:00
if ( func = = NULL ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_RuntimeError , " %.200s: type attempted to get NULL function " , RNA_struct_identifier ( pyrna - > ptr . type ) ) ;
2009-07-17 12:26:40 +00:00
return NULL ;
}
2009-06-25 10:11:37 +00:00
2009-07-17 12:26:40 +00:00
self = PyTuple_New ( 2 ) ;
2011-02-11 00:11:17 +00:00
2009-06-25 10:11:37 +00:00
PyTuple_SET_ITEM ( self , 0 , ( PyObject * ) pyrna ) ;
Py_INCREF ( pyrna ) ;
2010-02-12 21:14:01 +00:00
PyTuple_SET_ITEM ( self , 1 , PyCapsule_New ( ( void * ) func , NULL , NULL ) ) ;
2011-02-11 00:11:17 +00:00
2009-04-09 13:20:48 +00:00
ret = PyCFunction_New ( & func_meth , self ) ;
Py_DECREF ( self ) ;
2011-02-11 00:11:17 +00:00
2009-04-09 13:20:48 +00:00
return ret ;
2009-04-07 00:49:39 +00:00
}
2008-11-29 17:58:17 +00:00
2009-04-16 13:21:18 +00:00
2009-12-07 02:20:55 +00:00
2010-10-13 23:25:08 +00:00
static int pyrna_py_to_prop ( PointerRNA * ptr , PropertyRNA * prop , void * data , PyObject * value , const char * error_prefix )
2008-11-29 17:58:17 +00:00
{
2009-04-16 13:21:18 +00:00
/* XXX hard limits should be checked here */
2009-04-19 13:37:59 +00:00
int type = RNA_property_type ( prop ) ;
2011-02-11 00:11:17 +00:00
2009-09-15 10:01:20 +00:00
if ( RNA_property_array_check ( ptr , prop ) ) {
2009-09-06 15:13:57 +00:00
/* char error_str[512]; */
Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
Mesh.add_vertices([(x, y, z), (x, y, z), ...])
Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
2009-08-25 17:06:36 +00:00
int ok = 1 ;
2009-06-23 17:10:46 +00:00
# ifdef USE_MATHUTILS
if ( MatrixObject_Check ( value ) ) {
MatrixObject * mat = ( MatrixObject * ) value ;
2009-06-25 10:11:37 +00:00
if ( ! BaseMath_ReadCallback ( mat ) )
2009-06-23 17:10:46 +00:00
return - 1 ;
2009-06-25 10:11:37 +00:00
} else /* continue... */
2010-12-09 06:08:19 +00:00
# endif // USE_MATHUTILS
Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
Mesh.add_vertices([(x, y, z), (x, y, z), ...])
Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
2009-08-25 17:06:36 +00:00
if ( ! PySequence_Check ( value ) ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s RNA array assignment to %.200s.%.200s expected a sequence, not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , Py_TYPE ( value ) - > tp_name ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
2008-11-29 17:58:17 +00:00
}
2009-06-23 17:10:46 +00:00
/* done getting the length */
2010-10-13 23:25:08 +00:00
ok = pyrna_py_to_array ( ptr , prop , data , value , error_prefix ) ;
2009-09-06 15:13:57 +00:00
Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
Mesh.add_vertices([(x, y, z), (x, y, z), ...])
Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
2009-08-25 17:06:36 +00:00
if ( ! ok ) {
2009-09-06 15:13:57 +00:00
/* PyErr_Format(PyExc_AttributeError, "%.200s %s", error_prefix, error_str); */
Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
Mesh.add_vertices([(x, y, z), (x, y, z), ...])
Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
2009-08-25 17:06:36 +00:00
return - 1 ;
2008-11-30 03:52:07 +00:00
}
Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
Mesh.add_vertices([(x, y, z), (x, y, z), ...])
Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
2009-08-25 17:06:36 +00:00
}
else {
2008-11-30 03:52:07 +00:00
/* Normal Property (not an array) */
2011-02-11 00:11:17 +00:00
2008-11-30 03:52:07 +00:00
/* see if we can coorce into a python type - PropertyType */
switch ( type ) {
case PROP_BOOLEAN :
{
2009-11-22 21:51:12 +00:00
int param ;
/* prefer not to have an exception here
* however so many poll functions return None or a valid Object .
* its a hassle to convert these into a bool before returning , */
2010-01-24 10:51:59 +00:00
if ( RNA_property_flag ( prop ) & PROP_OUTPUT )
2009-11-22 21:51:12 +00:00
param = PyObject_IsTrue ( value ) ;
else
2010-10-03 01:44:00 +00:00
param = PyLong_AsLong ( value ) ;
2011-02-11 00:11:17 +00:00
2010-10-12 23:47:43 +00:00
if ( param < 0 ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s expected True/False or 0/1, not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , Py_TYPE ( value ) - > tp_name ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
} else {
2009-04-16 13:21:18 +00:00
if ( data ) * ( ( int * ) data ) = param ;
else RNA_property_boolean_set ( ptr , prop , param ) ;
2008-11-30 03:52:07 +00:00
}
break ;
}
case PROP_INT :
{
2010-10-03 01:44:00 +00:00
int overflow ;
long param = PyLong_AsLongAndOverflow ( value , & overflow ) ;
if ( overflow | | ( param > INT_MAX ) | | ( param < INT_MIN ) ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_ValueError , " %.200s %.200s.%.200s value not in 'int' range ( " STRINGIFY ( INT_MIN ) " , " STRINGIFY ( INT_MAX ) " ) " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) ) ;
2010-10-03 01:44:00 +00:00
return - 1 ;
}
else if ( param = = - 1 & & PyErr_Occurred ( ) ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s expected an int type, not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , Py_TYPE ( value ) - > tp_name ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
} else {
2010-10-03 01:44:00 +00:00
int param_i = ( int ) param ;
RNA_property_int_clamp ( ptr , prop , & param_i ) ;
if ( data ) * ( ( int * ) data ) = param_i ;
else RNA_property_int_set ( ptr , prop , param_i ) ;
2008-11-30 03:52:07 +00:00
}
break ;
}
case PROP_FLOAT :
{
float param = PyFloat_AsDouble ( value ) ;
if ( PyErr_Occurred ( ) ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s expected a float type, not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , Py_TYPE ( value ) - > tp_name ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
} else {
2010-02-21 14:48:28 +00:00
RNA_property_float_clamp ( ptr , prop , ( float * ) & param ) ;
2009-04-16 13:21:18 +00:00
if ( data ) * ( ( float * ) data ) = param ;
else RNA_property_float_set ( ptr , prop , param ) ;
2008-11-30 03:52:07 +00:00
}
break ;
}
case PROP_STRING :
{
2010-08-28 12:34:22 +00:00
const char * param ;
# ifdef USE_STRING_COERCE
PyObject * value_coerce = NULL ;
int subtype = RNA_property_subtype ( prop ) ;
if ( ELEM3 ( subtype , PROP_FILEPATH , PROP_DIRPATH , PROP_FILENAME ) ) {
2011-01-24 03:38:34 +00:00
/* TODO, get size */
2010-10-03 23:29:43 +00:00
param = PyC_UnicodeAsByte ( value , & value_coerce ) ;
2010-08-28 12:34:22 +00:00
}
else {
2011-01-25 01:51:28 +00:00
param = _PyUnicode_AsString ( value ) ;
2010-08-28 12:34:22 +00:00
}
2010-12-09 06:08:19 +00:00
# else // USE_STRING_COERCE
2011-01-25 01:51:28 +00:00
param = _PyUnicode_AsStringSize ( value ) ;
2010-12-09 06:08:19 +00:00
# endif // USE_STRING_COERCE
2010-06-12 15:49:01 +00:00
2008-11-30 03:52:07 +00:00
if ( param = = NULL ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s expected a string type, not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , Py_TYPE ( value ) - > tp_name ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
2010-06-12 15:49:01 +00:00
}
else {
2010-09-09 13:58:38 +00:00
if ( data ) * ( ( char * * ) data ) = ( char * ) param ; /*XXX, this is suspect but needed for function calls, need to see if theres a better way */
2011-01-24 05:15:14 +00:00
else RNA_property_string_set ( ptr , prop , param ) ;
2008-11-29 17:58:17 +00:00
}
2010-08-28 12:34:22 +00:00
# ifdef USE_STRING_COERCE
Py_XDECREF ( value_coerce ) ;
2010-12-09 06:08:19 +00:00
# endif // USE_STRING_COERCE
2008-11-30 03:52:07 +00:00
break ;
}
case PROP_ENUM :
{
2010-02-01 22:04:33 +00:00
int val = 0 ;
2009-08-07 13:00:39 +00:00
if ( PyUnicode_Check ( value ) ) {
if ( ! pyrna_string_to_enum ( value , ptr , prop , & val , error_prefix ) )
return - 1 ;
}
2009-12-07 02:20:55 +00:00
else if ( PyAnySet_Check ( value ) ) {
if ( RNA_property_flag ( prop ) & PROP_ENUM_FLAG ) {
/* set of enum items, concatenate all values with OR */
2010-02-01 22:04:33 +00:00
if ( pyrna_prop_to_enum_bitfield ( ptr , prop , value , & val , error_prefix ) < 0 )
return - 1 ;
2009-12-07 02:20:55 +00:00
}
else {
PyErr_Format ( PyExc_TypeError , " %.200s, %.200s.%.200s is not a bitflag enum type " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) ) ;
return - 1 ;
2009-08-07 13:00:39 +00:00
}
}
else {
2010-12-03 17:05:21 +00:00
const char * enum_str = pyrna_enum_as_string ( ptr , prop ) ;
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s expected a string enum or a set of strings in (%.2000s), not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , enum_str , Py_TYPE ( value ) - > tp_name ) ;
2010-12-03 17:05:21 +00:00
MEM_freeN ( ( void * ) enum_str ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
2008-11-29 17:58:17 +00:00
}
2009-08-07 13:00:39 +00:00
if ( data ) * ( ( int * ) data ) = val ;
else RNA_property_enum_set ( ptr , prop , val ) ;
2011-02-11 00:11:17 +00:00
2008-11-30 03:52:07 +00:00
break ;
}
case PROP_POINTER :
{
2010-08-24 03:02:27 +00:00
PyObject * value_new = NULL ;
2011-02-11 00:11:17 +00:00
2011-02-14 03:15:55 +00:00
StructRNA * ptr_type = RNA_property_pointer_type ( ptr , prop ) ;
2009-09-16 18:04:01 +00:00
int flag = RNA_property_flag ( prop ) ;
2009-03-23 13:28:42 +00:00
2010-09-24 03:48:26 +00:00
/* this is really nasty!, so we can fake the operator having direct properties eg:
* layout . prop ( self , " filepath " )
* . . . which infact should be
* layout . prop ( self . properties , " filepath " )
2011-02-11 00:11:17 +00:00
*
2010-09-24 03:48:26 +00:00
* we need to do this trick .
* if the prop is not an operator type and the pyobject is an operator , use its properties in place of its self .
2011-02-11 00:11:17 +00:00
*
2010-09-24 03:48:26 +00:00
* this is so bad that its almost a good reason to do away with fake ' self . properties - > self ' class mixing
* if this causes problems in the future it should be removed .
*/
2011-02-14 03:15:55 +00:00
if ( ( ptr_type = = & RNA_AnyType ) & &
2010-09-24 03:48:26 +00:00
( BPy_StructRNA_Check ( value ) ) & &
( RNA_struct_is_a ( ( ( BPy_StructRNA * ) value ) - > ptr . type , & RNA_Operator ) )
) {
value = PyObject_GetAttrString ( value , " properties " ) ;
value_new = value ;
}
2010-01-26 20:43:27 +00:00
/* if property is an OperatorProperties pointer and value is a map, forward back to pyrna_pydict_to_props */
2011-02-14 03:15:55 +00:00
if ( RNA_struct_is_a ( ptr_type , & RNA_OperatorProperties ) & & PyDict_Check ( value ) ) {
2010-01-26 20:43:27 +00:00
PointerRNA opptr = RNA_property_pointer_get ( ptr , prop ) ;
return pyrna_pydict_to_props ( & opptr , value , 0 , error_prefix ) ;
}
2010-08-24 03:02:27 +00:00
/* another exception, allow to pass a collection as an RNA property */
2010-09-02 06:35:00 +00:00
if ( Py_TYPE ( value ) = = & pyrna_prop_collection_Type ) { /* ok to ignore idprop collections */
2010-08-24 03:02:27 +00:00
PointerRNA c_ptr ;
BPy_PropertyRNA * value_prop = ( BPy_PropertyRNA * ) value ;
if ( RNA_property_collection_type_get ( & value_prop - > ptr , value_prop - > prop , & c_ptr ) ) {
value = pyrna_struct_CreatePyObject ( & c_ptr ) ;
value_new = value ;
}
else {
2011-02-14 03:15:55 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s collection has no type, cant be used as a %.200s type " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , RNA_struct_identifier ( ptr_type ) ) ;
2010-08-24 03:02:27 +00:00
return - 1 ;
}
}
2009-06-07 13:09:18 +00:00
if ( ! BPy_StructRNA_Check ( value ) & & value ! = Py_None ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s expected a %.200s type, not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , RNA_struct_identifier ( ptr_type ) , Py_TYPE ( value ) - > tp_name ) ;
2010-08-24 03:02:27 +00:00
Py_XDECREF ( value_new ) ; return - 1 ;
2009-09-16 18:04:01 +00:00
} else if ( ( flag & PROP_NEVER_NULL ) & & value = = Py_None ) {
2011-02-14 03:15:55 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s does not support a 'None' assignment %.200s type " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , RNA_struct_identifier ( ptr_type ) ) ;
2010-08-24 03:02:27 +00:00
Py_XDECREF ( value_new ) ; return - 1 ;
2010-02-22 08:27:45 +00:00
} else if ( value ! = Py_None & & ( ( flag & PROP_ID_SELF_CHECK ) & & ptr - > id . data = = ( ( BPy_StructRNA * ) value ) - > ptr . id . data ) ) {
2010-03-16 17:19:42 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s ID type does not support assignment to its self " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) ) ;
2010-08-24 03:02:27 +00:00
Py_XDECREF ( value_new ) ; return - 1 ;
2009-03-23 13:28:42 +00:00
} else {
BPy_StructRNA * param = ( BPy_StructRNA * ) value ;
2009-07-26 18:18:14 +00:00
int raise_error = FALSE ;
2009-04-16 13:21:18 +00:00
if ( data ) {
2009-06-16 00:52:21 +00:00
if ( flag & PROP_RNAPTR ) {
2009-06-07 13:09:18 +00:00
if ( value = = Py_None )
memset ( data , 0 , sizeof ( PointerRNA ) ) ;
else
* ( ( PointerRNA * ) data ) = param - > ptr ;
}
else if ( value = = Py_None ) {
* ( ( void * * ) data ) = NULL ;
2009-04-16 13:21:18 +00:00
}
2011-02-14 03:15:55 +00:00
else if ( RNA_struct_is_a ( param - > ptr . type , ptr_type ) ) {
2009-04-16 13:21:18 +00:00
* ( ( void * * ) data ) = param - > ptr . data ;
2009-06-07 13:09:18 +00:00
}
else {
2009-07-26 18:18:14 +00:00
raise_error = TRUE ;
2009-04-16 13:21:18 +00:00
}
}
else {
/* data==NULL, assign to RNA */
2009-06-07 13:09:18 +00:00
if ( value = = Py_None ) {
2011-02-13 10:52:18 +00:00
PointerRNA valueptr = { { NULL } } ;
2009-06-07 13:09:18 +00:00
RNA_property_pointer_set ( ptr , prop , valueptr ) ;
}
2011-02-14 03:15:55 +00:00
else if ( RNA_struct_is_a ( param - > ptr . type , ptr_type ) ) {
2009-04-16 13:21:18 +00:00
RNA_property_pointer_set ( ptr , prop , param - > ptr ) ;
2009-06-07 13:09:18 +00:00
}
else {
2009-04-16 13:21:18 +00:00
PointerRNA tmp ;
2011-02-14 03:15:55 +00:00
RNA_pointer_create ( NULL , ptr_type , NULL , & tmp ) ;
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s expected a %.200s type. not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , RNA_struct_identifier ( tmp . type ) , RNA_struct_identifier ( param - > ptr . type ) ) ;
2010-08-24 03:02:27 +00:00
Py_XDECREF ( value_new ) ; return - 1 ;
2009-04-16 13:21:18 +00:00
}
}
2011-02-11 00:11:17 +00:00
2009-04-16 13:21:18 +00:00
if ( raise_error ) {
2009-03-23 13:28:42 +00:00
PointerRNA tmp ;
2011-02-14 03:15:55 +00:00
RNA_pointer_create ( NULL , ptr_type , NULL , & tmp ) ;
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s expected a %.200s type, not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , RNA_struct_identifier ( tmp . type ) , RNA_struct_identifier ( param - > ptr . type ) ) ;
2010-08-24 03:02:27 +00:00
Py_XDECREF ( value_new ) ; return - 1 ;
2009-03-23 13:28:42 +00:00
}
}
2011-02-11 00:11:17 +00:00
2010-09-24 03:24:15 +00:00
Py_XDECREF ( value_new ) ;
2010-08-24 03:02:27 +00:00
2008-11-30 03:52:07 +00:00
break ;
}
case PROP_COLLECTION :
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
{
int seq_len , i ;
PyObject * item ;
PointerRNA itemptr ;
2009-06-27 01:10:39 +00:00
ListBase * lb ;
CollectionPointerLink * link ;
lb = ( data ) ? ( ListBase * ) data : NULL ;
2011-02-11 00:11:17 +00:00
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
/* convert a sequence of dict's into a collection */
if ( ! PySequence_Check ( value ) ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s expected a sequence for an RNA collection, not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , Py_TYPE ( value ) - > tp_name ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
return - 1 ;
}
2010-03-16 17:19:42 +00:00
2011-01-09 14:53:18 +00:00
seq_len = PySequence_Size ( value ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
for ( i = 0 ; i < seq_len ; i + + ) {
item = PySequence_GetItem ( value , i ) ;
2010-03-16 17:19:42 +00:00
if ( item = = NULL ) {
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s failed to get sequence index '%d' for an RNA collection " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , i ) ;
Py_XDECREF ( item ) ;
return - 1 ;
}
if ( PyDict_Check ( item ) = = 0 ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s expected a each sequence member to be a dict for an RNA collection, not %.200s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , Py_TYPE ( item ) - > tp_name ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
Py_XDECREF ( item ) ;
return - 1 ;
}
2009-06-27 01:10:39 +00:00
if ( lb ) {
link = MEM_callocN ( sizeof ( CollectionPointerLink ) , " PyCollectionPointerLink " ) ;
link - > ptr = itemptr ;
BLI_addtail ( lb , link ) ;
}
else
RNA_property_collection_add ( ptr , prop , & itemptr ) ;
2009-07-30 01:52:00 +00:00
if ( pyrna_pydict_to_props ( & itemptr , item , 1 , " Converting a python list to an RNA collection " ) = = - 1 ) {
2010-09-01 14:13:48 +00:00
PyObject * msg = PyC_ExceptionBuffer ( ) ;
2011-02-01 23:53:54 +00:00
const char * msg_char = _PyUnicode_AsString ( msg ) ;
2010-03-16 17:19:42 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s %.200s.%.200s error converting a member of a collection from a dicts into an RNA collection, failed with: %s " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) , msg_char ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
Py_DECREF ( item ) ;
2010-03-16 17:19:42 +00:00
Py_DECREF ( msg ) ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
return - 1 ;
}
Py_DECREF ( item ) ;
}
2011-02-11 00:11:17 +00:00
2008-11-30 03:52:07 +00:00
break ;
PyRNA
- Support for python to convert a PyObject into a collection (uses a list of dicts - quite verbose :/)
- Operators can now take collection args when called from python.
- Support for printing operators that use collections (macro recording).
- Added RNA_pointer_as_string which prints all pointer prop values as a python dict.
Example that can run in the in test.py (F7 key)
bpy.ops.VIEW3D_OT_select_lasso(path=[{"loc":(0, 0), "time":0}, {"loc":(1000, 0), "time":0}, {"loc":(1000, 1000), "time":0}], type='SELECT')
for some reason lasso locations always print as 0,0. Need to look into why this is.
2009-06-05 12:48:58 +00:00
}
2008-11-30 03:52:07 +00:00
default :
2010-03-16 17:19:42 +00:00
PyErr_Format ( PyExc_AttributeError , " %.200s %.200s.%.200s unknown property type (pyrna_py_to_prop) " , error_prefix , RNA_struct_identifier ( ptr - > type ) , RNA_property_identifier ( prop ) ) ;
2008-11-30 03:52:07 +00:00
return - 1 ;
break ;
2008-11-29 17:58:17 +00:00
}
}
2009-10-08 07:54:20 +00:00
/* Run rna property functions */
2010-10-25 21:57:45 +00:00
if ( RNA_property_update_check ( prop ) ) {
RNA_property_update ( BPy_GetContext ( ) , ptr , prop ) ;
}
2009-10-08 07:54:20 +00:00
2008-11-30 03:52:07 +00:00
return 0 ;
2008-11-29 17:58:17 +00:00
}
2010-09-02 06:35:00 +00:00
static PyObject * pyrna_prop_array_to_py_index ( BPy_PropertyArrayRNA * self , int index )
2008-11-29 13:36:08 +00:00
{
2010-01-20 14:06:38 +00:00
return pyrna_py_from_array_index ( self , & self - > ptr , self - > prop , index ) ;
2008-11-29 13:36:08 +00:00
}
2010-09-02 06:35:00 +00:00
static int pyrna_py_to_prop_array_index ( BPy_PropertyArrayRNA * self , int index , PyObject * value )
2008-11-29 17:58:17 +00:00
{
int ret = 0 ;
2009-09-06 15:13:57 +00:00
PointerRNA * ptr = & self - > ptr ;
PropertyRNA * prop = self - > prop ;
2011-01-11 02:30:01 +00:00
const int totdim = RNA_property_array_dimension ( ptr , prop , NULL ) ;
2009-09-06 15:13:57 +00:00
if ( totdim > 1 ) {
/* char error_str[512]; */
if ( ! pyrna_py_to_array_index ( & self - > ptr , self - > prop , self - > arraydim , self - > arrayoffset , index , value , " " ) ) {
/* PyErr_SetString(PyExc_AttributeError, error_str); */
ret = - 1 ;
2008-11-29 17:58:17 +00:00
}
}
2009-09-06 15:13:57 +00:00
else {
/* see if we can coorce into a python type - PropertyType */
2011-01-11 02:30:01 +00:00
switch ( RNA_property_type ( prop ) ) {
2009-09-06 15:13:57 +00:00
case PROP_BOOLEAN :
{
2010-10-03 01:44:00 +00:00
int param = PyLong_AsLong ( value ) ;
2011-02-11 00:11:17 +00:00
2009-11-22 21:51:12 +00:00
if ( param < 0 | | param > 1 ) {
2009-09-06 15:13:57 +00:00
PyErr_SetString ( PyExc_TypeError , " expected True/False or 0/1 " ) ;
ret = - 1 ;
} else {
RNA_property_boolean_set_index ( ptr , prop , index , param ) ;
}
break ;
}
case PROP_INT :
{
2010-10-03 01:44:00 +00:00
int param = PyLong_AsLong ( value ) ;
2009-11-11 16:28:53 +00:00
if ( param = = - 1 & & PyErr_Occurred ( ) ) {
2009-09-06 15:13:57 +00:00
PyErr_SetString ( PyExc_TypeError , " expected an int type " ) ;
ret = - 1 ;
} else {
2010-02-21 14:48:28 +00:00
RNA_property_int_clamp ( ptr , prop , & param ) ;
2009-09-06 15:13:57 +00:00
RNA_property_int_set_index ( ptr , prop , index , param ) ;
}
break ;
}
case PROP_FLOAT :
{
float param = PyFloat_AsDouble ( value ) ;
if ( PyErr_Occurred ( ) ) {
PyErr_SetString ( PyExc_TypeError , " expected a float type " ) ;
ret = - 1 ;
} else {
2010-02-21 14:48:28 +00:00
RNA_property_float_clamp ( ptr , prop , & param ) ;
2009-09-06 15:13:57 +00:00
RNA_property_float_set_index ( ptr , prop , index , param ) ;
}
break ;
}
default :
PyErr_SetString ( PyExc_AttributeError , " not an array type " ) ;
2008-11-29 17:58:17 +00:00
ret = - 1 ;
2009-09-06 15:13:57 +00:00
break ;
2008-11-29 17:58:17 +00:00
}
}
2010-04-06 09:11:33 +00:00
/* Run rna property functions */
2010-10-25 21:57:45 +00:00
if ( RNA_property_update_check ( prop ) ) {
RNA_property_update ( BPy_GetContext ( ) , ptr , prop ) ;
}
2008-11-29 17:58:17 +00:00
return ret ;
}
2008-11-29 13:36:08 +00:00
//---------------sequence-------------------------------------------
2010-09-02 06:35:00 +00:00
static Py_ssize_t pyrna_prop_array_length ( BPy_PropertyArrayRNA * self )
2009-09-06 15:13:57 +00:00
{
2009-09-09 19:40:46 +00:00
if ( RNA_property_array_dimension ( & self - > ptr , self - > prop , NULL ) > 1 )
return RNA_property_multi_array_length ( & self - > ptr , self - > prop , self - > arraydim ) ;
2009-09-06 15:13:57 +00:00
else
return RNA_property_array_length ( & self - > ptr , self - > prop ) ;
}
2010-02-15 23:43:51 +00:00
static Py_ssize_t pyrna_prop_collection_length ( BPy_PropertyRNA * self )
2008-11-29 13:36:08 +00:00
{
2010-02-15 23:43:51 +00:00
return RNA_property_collection_length ( & self - > ptr , self - > prop ) ;
2008-11-29 13:36:08 +00:00
}
2010-08-27 01:50:50 +00:00
/* bool funcs are for speed, so we can avoid getting the length
* of 1000 ' s of items in a linked list for eg . */
static int pyrna_prop_array_bool ( BPy_PropertyRNA * self )
{
return RNA_property_array_length ( & self - > ptr , self - > prop ) ? 1 : 0 ;
}
static int pyrna_prop_collection_bool ( BPy_PropertyRNA * self )
{
/* no callback defined, just iterate and find the nth item */
CollectionPropertyIterator iter ;
int test ;
RNA_property_collection_begin ( & self - > ptr , self - > prop , & iter ) ;
test = iter . valid ;
RNA_property_collection_end ( & iter ) ;
return test ;
}
2009-07-01 13:31:36 +00:00
/* internal use only */
2010-02-15 23:43:51 +00:00
static PyObject * pyrna_prop_collection_subscript_int ( BPy_PropertyRNA * self , Py_ssize_t keynum )
2008-11-29 13:36:08 +00:00
{
PointerRNA newptr ;
2011-01-06 04:01:06 +00:00
Py_ssize_t keynum_abs = keynum ;
2009-07-01 13:31:36 +00:00
2011-01-06 04:01:06 +00:00
/* notice getting the length of the collection is avoided unless negative index is used
* or to detect internal error with a valid index .
* This is done for faster lookups . */
if ( keynum < 0 ) {
keynum_abs + = RNA_property_collection_length ( & self - > ptr , self - > prop ) ;
2009-07-01 13:31:36 +00:00
2011-01-06 04:01:06 +00:00
if ( keynum_abs < 0 ) {
PyErr_Format ( PyExc_IndexError , " bpy_prop_collection[%d]: out of range. " , keynum ) ;
return NULL ;
}
}
if ( RNA_property_collection_lookup_int ( & self - > ptr , self - > prop , keynum_abs , & newptr ) ) {
return pyrna_struct_CreatePyObject ( & newptr ) ;
}
else {
const int len = RNA_property_collection_length ( & self - > ptr , self - > prop ) ;
if ( keynum_abs > = len ) {
PyErr_Format ( PyExc_IndexError , " bpy_prop_collection[index]: index %d out of range, size %d " , keynum , len ) ;
2010-05-16 10:09:07 +00:00
}
2011-01-05 14:49:08 +00:00
else {
2011-01-06 04:01:06 +00:00
PyErr_Format ( PyExc_RuntimeError , " bpy_prop_collection[index]: internal error, valid index %d given in %d sized collection but value not found " , keynum_abs , len ) ;
2010-08-22 17:23:08 +00:00
}
2011-01-06 04:01:06 +00:00
return NULL ;
2010-05-16 10:09:07 +00:00
}
2009-07-01 13:31:36 +00:00
}
2009-09-06 15:13:57 +00:00
2010-09-02 06:35:00 +00:00
static PyObject * pyrna_prop_array_subscript_int ( BPy_PropertyArrayRNA * self , int keynum )
2009-07-01 13:31:36 +00:00
{
2009-09-06 15:13:57 +00:00
int len = pyrna_prop_array_length ( self ) ;
2009-07-01 13:31:36 +00:00
if ( keynum < 0 ) keynum + = len ;
if ( keynum > = 0 & & keynum < len )
2010-09-02 06:35:00 +00:00
return pyrna_prop_array_to_py_index ( self , keynum ) ;
2009-07-01 13:31:36 +00:00
2010-02-23 11:19:55 +00:00
PyErr_Format ( PyExc_IndexError , " bpy_prop_array[index]: index %d out of range " , keynum ) ;
2009-07-01 13:31:36 +00:00
return NULL ;
}
2010-08-28 12:34:22 +00:00
static PyObject * pyrna_prop_collection_subscript_str ( BPy_PropertyRNA * self , const char * keyname )
2009-07-01 13:31:36 +00:00
{
PointerRNA newptr ;
if ( RNA_property_collection_lookup_string ( & self - > ptr , self - > prop , keyname , & newptr ) )
return pyrna_struct_CreatePyObject ( & newptr ) ;
2010-02-23 11:19:55 +00:00
PyErr_Format ( PyExc_KeyError , " bpy_prop_collection[key]: key \" %.200s \" not found " , keyname ) ;
2009-07-01 13:31:36 +00:00
return NULL ;
}
2010-02-15 23:43:51 +00:00
/* static PyObject *pyrna_prop_array_subscript_str(BPy_PropertyRNA *self, char *keyname) */
2009-07-01 13:31:36 +00:00
2011-01-07 05:33:30 +00:00
static PyObject * pyrna_prop_collection_subscript_slice ( BPy_PropertyRNA * self , Py_ssize_t start , Py_ssize_t stop )
2009-07-01 13:31:36 +00:00
{
2011-01-07 05:33:30 +00:00
int count = 0 ;
2009-07-01 13:31:36 +00:00
2011-01-07 05:33:30 +00:00
PyObject * list = PyList_New ( 0 ) ;
PyObject * item ;
2009-07-01 13:31:36 +00:00
2011-01-07 05:33:30 +00:00
/* first loop up-until the start */
CollectionPropertyIterator rna_macro_iter ;
for ( RNA_property_collection_begin ( & self - > ptr , self - > prop , & rna_macro_iter ) ; rna_macro_iter . valid ; RNA_property_collection_next ( & rna_macro_iter ) ) {
/* PointerRNA itemptr= rna_macro_iter.ptr; */
if ( count = = start ) {
break ;
}
count + + ;
}
2009-07-01 13:31:36 +00:00
2011-01-07 05:33:30 +00:00
/* add items until stop */
for ( ; rna_macro_iter . valid ; RNA_property_collection_next ( & rna_macro_iter ) ) {
item = pyrna_struct_CreatePyObject ( & rna_macro_iter . ptr ) ;
PyList_Append ( list , item ) ;
Py_DECREF ( item ) ;
2011-01-06 04:01:06 +00:00
2011-01-07 05:33:30 +00:00
count + + ;
if ( count = = stop ) {
break ;
2009-07-01 13:31:36 +00:00
}
2011-01-06 04:01:06 +00:00
}
2011-01-07 05:33:30 +00:00
RNA_property_collection_end ( & rna_macro_iter ) ;
return list ;
2009-07-01 13:31:36 +00:00
}
2010-01-02 17:33:44 +00:00
/* TODO - dimensions
2010-09-02 06:35:00 +00:00
* note : could also use pyrna_prop_array_to_py_index ( self , count ) in a loop but its a lot slower
2010-01-02 17:33:44 +00:00
* since at the moment it reads ( and even allocates ) the entire array for each index .
*/
2011-01-07 05:33:30 +00:00
static PyObject * pyrna_prop_array_subscript_slice ( BPy_PropertyArrayRNA * self , PointerRNA * ptr , PropertyRNA * prop , Py_ssize_t start , Py_ssize_t stop , Py_ssize_t length )
2009-07-01 13:31:36 +00:00
{
2010-01-20 14:06:38 +00:00
int count , totdim ;
2011-01-02 09:54:44 +00:00
PyObject * tuple = PyTuple_New ( stop - start ) ;
2009-07-01 13:31:36 +00:00
2010-01-20 14:06:38 +00:00
totdim = RNA_property_array_dimension ( ptr , prop , NULL ) ;
if ( totdim > 1 ) {
for ( count = start ; count < stop ; count + + )
2011-01-02 09:54:44 +00:00
PyTuple_SET_ITEM ( tuple , count - start , pyrna_prop_array_to_py_index ( self , count ) ) ;
2010-01-20 14:06:38 +00:00
}
else {
switch ( RNA_property_type ( prop ) ) {
2010-01-02 17:33:44 +00:00
case PROP_FLOAT :
2010-01-20 14:06:38 +00:00
{
float values_stack [ PYRNA_STACK_ARRAY ] ;
float * values ;
if ( length > PYRNA_STACK_ARRAY ) { values = PyMem_MALLOC ( sizeof ( float ) * length ) ; }
else { values = values_stack ; }
RNA_property_float_get_array ( ptr , prop , values ) ;
2011-02-11 00:11:17 +00:00
2010-01-20 14:06:38 +00:00
for ( count = start ; count < stop ; count + + )
2011-01-02 09:54:44 +00:00
PyTuple_SET_ITEM ( tuple , count - start , PyFloat_FromDouble ( values [ count ] ) ) ;
2010-01-02 17:33:44 +00:00
2010-01-20 14:06:38 +00:00
if ( values ! = values_stack ) {
PyMem_FREE ( values ) ;
}
break ;
2010-01-02 17:33:44 +00:00
}
case PROP_BOOLEAN :
2010-01-20 14:06:38 +00:00
{
int values_stack [ PYRNA_STACK_ARRAY ] ;
int * values ;
if ( length > PYRNA_STACK_ARRAY ) { values = PyMem_MALLOC ( sizeof ( int ) * length ) ; }
else { values = values_stack ; }
2010-01-02 17:33:44 +00:00
2010-01-20 14:06:38 +00:00
RNA_property_boolean_get_array ( ptr , prop , values ) ;
for ( count = start ; count < stop ; count + + )
2011-01-02 09:54:44 +00:00
PyTuple_SET_ITEM ( tuple , count - start , PyBool_FromLong ( values [ count ] ) ) ;
2010-01-02 17:33:44 +00:00
2010-01-20 14:06:38 +00:00
if ( values ! = values_stack ) {
PyMem_FREE ( values ) ;
}
break ;
2010-01-02 17:33:44 +00:00
}
case PROP_INT :
2010-01-20 14:06:38 +00:00
{
int values_stack [ PYRNA_STACK_ARRAY ] ;
int * values ;
if ( length > PYRNA_STACK_ARRAY ) { values = PyMem_MALLOC ( sizeof ( int ) * length ) ; }
else { values = values_stack ; }
2009-07-01 13:31:36 +00:00
2010-01-20 14:06:38 +00:00
RNA_property_int_get_array ( ptr , prop , values ) ;
for ( count = start ; count < stop ; count + + )
2011-01-02 09:54:44 +00:00
PyTuple_SET_ITEM ( tuple , count - start , PyLong_FromSsize_t ( values [ count ] ) ) ;
2009-07-01 13:31:36 +00:00
2010-01-20 14:06:38 +00:00
if ( values ! = values_stack ) {
PyMem_FREE ( values ) ;
}
break ;
2010-01-02 17:33:44 +00:00
}
default :
2011-01-09 15:12:08 +00:00
BLI_assert ( ! " Invalid array type " ) ;
2010-12-15 10:22:26 +00:00
2010-01-02 17:33:44 +00:00
PyErr_SetString ( PyExc_TypeError , " not an array type " ) ;
2011-01-02 09:54:44 +00:00
Py_DECREF ( tuple ) ;
tuple = NULL ;
2010-01-20 14:06:38 +00:00
}
2010-01-02 17:33:44 +00:00
}
2011-01-02 09:54:44 +00:00
return tuple ;
2009-07-01 13:31:36 +00:00
}
2010-02-15 23:43:51 +00:00
static PyObject * pyrna_prop_collection_subscript ( BPy_PropertyRNA * self , PyObject * key )
2009-07-01 13:31:36 +00:00
{
2008-11-29 13:36:08 +00:00
if ( PyUnicode_Check ( key ) ) {
2010-02-15 23:43:51 +00:00
return pyrna_prop_collection_subscript_str ( self , _PyUnicode_AsString ( key ) ) ;
2009-07-01 13:31:36 +00:00
}
2009-07-08 09:23:49 +00:00
else if ( PyIndex_Check ( key ) ) {
Py_ssize_t i = PyNumber_AsSsize_t ( key , PyExc_IndexError ) ;
if ( i = = - 1 & & PyErr_Occurred ( ) )
return NULL ;
2010-02-15 23:43:51 +00:00
return pyrna_prop_collection_subscript_int ( self , i ) ;
2009-07-01 13:31:36 +00:00
}
else if ( PySlice_Check ( key ) ) {
2011-01-07 05:33:30 +00:00
PySliceObject * key_slice = ( PySliceObject * ) key ;
2011-01-06 04:01:06 +00:00
Py_ssize_t step = 1 ;
2009-07-01 13:31:36 +00:00
2011-01-07 05:33:30 +00:00
if ( key_slice - > step ! = Py_None & & ! _PyEval_SliceIndex ( key , & step ) ) {
2009-07-01 13:31:36 +00:00
return NULL ;
}
2011-01-06 04:01:06 +00:00
else if ( step ! = 1 ) {
PyErr_SetString ( PyExc_TypeError , " bpy_prop_collection[slice]: slice steps not supported " ) ;
return NULL ;
}
2011-01-07 05:33:30 +00:00
else if ( key_slice - > start = = Py_None & & key_slice - > stop = = Py_None ) {
return pyrna_prop_collection_subscript_slice ( self , 0 , PY_SSIZE_T_MAX ) ;
2009-07-01 13:31:36 +00:00
}
else {
2011-01-07 05:33:30 +00:00
Py_ssize_t start = 0 , stop = PY_SSIZE_T_MAX ;
2011-01-06 04:01:06 +00:00
2011-01-07 05:33:30 +00:00
/* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
if ( key_slice - > start ! = Py_None & & ! _PyEval_SliceIndex ( key_slice - > start , & start ) ) return NULL ;
if ( key_slice - > stop ! = Py_None & & ! _PyEval_SliceIndex ( key_slice - > stop , & stop ) ) return NULL ;
2011-01-06 04:01:06 +00:00
2011-01-07 05:33:30 +00:00
if ( start < 0 | | stop < 0 ) {
/* only get the length for negative values */
Py_ssize_t len = ( Py_ssize_t ) RNA_property_collection_length ( & self - > ptr , self - > prop ) ;
if ( start < 0 ) start + = len ;
if ( stop < 0 ) start + = len ;
}
if ( stop - start < = 0 ) {
2011-01-06 04:01:06 +00:00
return PyList_New ( 0 ) ;
}
else {
2011-01-07 05:33:30 +00:00
return pyrna_prop_collection_subscript_slice ( self , start , stop ) ;
2011-01-06 04:01:06 +00:00
}
2009-07-01 13:31:36 +00:00
}
}
else {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_TypeError , " bpy_prop_collection[key]: invalid key, must be a string or an int, not %.200s " , Py_TYPE ( key ) - > tp_name ) ;
2008-11-29 13:36:08 +00:00
return NULL ;
}
2009-07-01 13:31:36 +00:00
}
2010-09-02 06:35:00 +00:00
static PyObject * pyrna_prop_array_subscript ( BPy_PropertyArrayRNA * self , PyObject * key )
2009-07-01 13:31:36 +00:00
{
/*if (PyUnicode_Check(key)) {
2010-02-15 23:43:51 +00:00
return pyrna_prop_array_subscript_str ( self , _PyUnicode_AsString ( key ) ) ;
2009-07-01 13:31:36 +00:00
} else */
2009-07-08 09:23:49 +00:00
if ( PyIndex_Check ( key ) ) {
Py_ssize_t i = PyNumber_AsSsize_t ( key , PyExc_IndexError ) ;
if ( i = = - 1 & & PyErr_Occurred ( ) )
return NULL ;
2010-10-03 01:44:00 +00:00
return pyrna_prop_array_subscript_int ( self , PyLong_AsLong ( key ) ) ;
2009-07-01 13:31:36 +00:00
}
else if ( PySlice_Check ( key ) ) {
2011-01-06 04:01:06 +00:00
Py_ssize_t step = 1 ;
2011-01-07 05:33:30 +00:00
PySliceObject * key_slice = ( PySliceObject * ) key ;
2009-07-01 13:31:36 +00:00
2011-01-07 05:33:30 +00:00
if ( key_slice - > step ! = Py_None & & ! _PyEval_SliceIndex ( key , & step ) ) {
2009-07-01 13:31:36 +00:00
return NULL ;
2008-11-29 13:36:08 +00:00
}
2011-01-06 04:01:06 +00:00
else if ( step ! = 1 ) {
PyErr_SetString ( PyExc_TypeError , " bpy_prop_array[slice]: slice steps not supported " ) ;
return NULL ;
}
2011-01-07 05:33:30 +00:00
else if ( key_slice - > start = = Py_None & & key_slice - > stop = = Py_None ) {
2011-01-06 04:01:06 +00:00
/* note, no significant advantage with optimizing [:] slice as with collections but include here for consistency with collection slice func */
2011-01-07 05:33:30 +00:00
Py_ssize_t len = ( Py_ssize_t ) pyrna_prop_array_length ( self ) ;
2011-01-06 04:01:06 +00:00
return pyrna_prop_array_subscript_slice ( self , & self - > ptr , self - > prop , 0 , len , len ) ;
2008-11-29 13:36:08 +00:00
}
2009-07-01 13:31:36 +00:00
else {
2011-01-06 04:01:06 +00:00
int len = pyrna_prop_array_length ( self ) ;
Py_ssize_t start , stop , slicelength ;
2011-01-18 21:39:50 +00:00
if ( PySlice_GetIndicesEx ( ( void * ) key , len , & start , & stop , & step , & slicelength ) < 0 )
2011-01-06 04:01:06 +00:00
return NULL ;
if ( slicelength < = 0 ) {
return PyTuple_New ( 0 ) ;
}
else {
return pyrna_prop_array_subscript_slice ( self , & self - > ptr , self - > prop , start , stop , len ) ;
}
2008-11-29 13:36:08 +00:00
}
}
2009-07-01 13:31:36 +00:00
else {
2010-02-23 11:19:55 +00:00
PyErr_SetString ( PyExc_AttributeError , " bpy_prop_array[key]: invalid key, key must be an int " ) ;
2009-07-01 13:31:36 +00:00
return NULL ;
}
}
2010-09-02 06:35:00 +00:00
/* could call (pyrna_py_to_prop_array_index(self, i, value) in a loop but it is slow */
2010-01-04 20:53:52 +00:00
static int prop_subscript_ass_array_slice ( PointerRNA * ptr , PropertyRNA * prop , int start , int stop , int length , PyObject * value_orig )
2009-07-01 13:31:36 +00:00
{
2010-01-04 20:53:52 +00:00
PyObject * value ;
2009-07-01 13:31:36 +00:00
int count ;
2010-01-02 17:33:44 +00:00
void * values_alloc = NULL ;
int ret = 0 ;
2010-01-04 20:53:52 +00:00
if ( value_orig = = NULL ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_prop_array[slice] = value: deleting with list types is not supported by bpy_struct " ) ;
2010-01-04 20:53:52 +00:00
return - 1 ;
}
2010-04-19 22:02:53 +00:00
if ( ! ( value = PySequence_Fast ( value_orig , " bpy_prop_array[slice] = value: assignment is not a sequence type " ) ) ) {
2010-01-04 20:53:52 +00:00
return - 1 ;
}
if ( PySequence_Fast_GET_SIZE ( value ) ! = stop - start ) {
Py_DECREF ( value ) ;
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_prop_array[slice] = value: resizing bpy_struct arrays isn't supported " ) ;
2010-01-02 17:33:44 +00:00
return - 1 ;
}
switch ( RNA_property_type ( prop ) ) {
case PROP_FLOAT :
{
float values_stack [ PYRNA_STACK_ARRAY ] ;
2010-02-21 14:48:28 +00:00
float * values , fval ;
float min , max ;
RNA_property_float_range ( ptr , prop , & min , & max ) ;
2010-01-02 17:33:44 +00:00
if ( length > PYRNA_STACK_ARRAY ) { values = values_alloc = PyMem_MALLOC ( sizeof ( float ) * length ) ; }
else { values = values_stack ; }
if ( start ! = 0 | | stop ! = length ) /* partial assignment? - need to get the array */
RNA_property_float_get_array ( ptr , prop , values ) ;
2011-02-11 00:11:17 +00:00
2010-02-21 14:48:28 +00:00
for ( count = start ; count < stop ; count + + ) {
fval = PyFloat_AsDouble ( PySequence_Fast_GET_ITEM ( value , count - start ) ) ;
CLAMP ( fval , min , max ) ;
values [ count ] = fval ;
}
2010-01-02 17:33:44 +00:00
if ( PyErr_Occurred ( ) ) ret = - 1 ;
else RNA_property_float_set_array ( ptr , prop , values ) ;
break ;
}
case PROP_BOOLEAN :
{
int values_stack [ PYRNA_STACK_ARRAY ] ;
int * values ;
if ( length > PYRNA_STACK_ARRAY ) { values = values_alloc = PyMem_MALLOC ( sizeof ( int ) * length ) ; }
else { values = values_stack ; }
if ( start ! = 0 | | stop ! = length ) /* partial assignment? - need to get the array */
RNA_property_boolean_get_array ( ptr , prop , values ) ;
2011-02-11 00:11:17 +00:00
2010-01-02 17:33:44 +00:00
for ( count = start ; count < stop ; count + + )
2010-10-03 01:44:00 +00:00
values [ count ] = PyLong_AsLong ( PySequence_Fast_GET_ITEM ( value , count - start ) ) ;
2010-01-02 17:33:44 +00:00
if ( PyErr_Occurred ( ) ) ret = - 1 ;
else RNA_property_boolean_set_array ( ptr , prop , values ) ;
break ;
}
case PROP_INT :
{
int values_stack [ PYRNA_STACK_ARRAY ] ;
2010-02-21 14:48:28 +00:00
int * values , ival ;
int min , max ;
RNA_property_int_range ( ptr , prop , & min , & max ) ;
2010-01-02 17:33:44 +00:00
if ( length > PYRNA_STACK_ARRAY ) { values = values_alloc = PyMem_MALLOC ( sizeof ( int ) * length ) ; }
else { values = values_stack ; }
if ( start ! = 0 | | stop ! = length ) /* partial assignment? - need to get the array */
RNA_property_int_get_array ( ptr , prop , values ) ;
2009-07-01 13:31:36 +00:00
2010-02-21 14:48:28 +00:00
for ( count = start ; count < stop ; count + + ) {
2010-10-03 01:44:00 +00:00
ival = PyLong_AsLong ( PySequence_Fast_GET_ITEM ( value , count - start ) ) ;
2010-02-21 14:48:28 +00:00
CLAMP ( ival , min , max ) ;
values [ count ] = ival ;
}
2008-11-29 17:58:17 +00:00
2010-01-02 17:33:44 +00:00
if ( PyErr_Occurred ( ) ) ret = - 1 ;
else RNA_property_int_set_array ( ptr , prop , values ) ;
break ;
2009-07-01 13:31:36 +00:00
}
2010-01-02 17:33:44 +00:00
default :
PyErr_SetString ( PyExc_TypeError , " not an array type " ) ;
ret = - 1 ;
2009-07-01 13:31:36 +00:00
}
2010-01-04 20:53:52 +00:00
Py_DECREF ( value ) ;
2011-02-11 00:11:17 +00:00
2010-01-02 17:33:44 +00:00
if ( values_alloc ) {
PyMem_FREE ( values_alloc ) ;
}
2011-02-11 00:11:17 +00:00
2010-01-02 17:33:44 +00:00
return ret ;
2009-07-01 13:31:36 +00:00
}
2010-09-02 06:35:00 +00:00
static int prop_subscript_ass_array_int ( BPy_PropertyArrayRNA * self , Py_ssize_t keynum , PyObject * value )
2008-11-29 17:58:17 +00:00
{
2009-09-06 15:13:57 +00:00
int len = pyrna_prop_array_length ( self ) ;
2009-07-01 13:31:36 +00:00
if ( keynum < 0 ) keynum + = len ;
if ( keynum > = 0 & & keynum < len )
2010-09-02 06:35:00 +00:00
return pyrna_py_to_prop_array_index ( self , keynum , value ) ;
2009-07-01 13:31:36 +00:00
2010-02-23 11:19:55 +00:00
PyErr_SetString ( PyExc_IndexError , " bpy_prop_array[index] = value: index out of range " ) ;
2009-07-01 13:31:36 +00:00
return - 1 ;
}
2010-09-02 06:35:00 +00:00
static int pyrna_prop_array_ass_subscript ( BPy_PropertyArrayRNA * self , PyObject * key , PyObject * value )
2009-07-01 13:31:36 +00:00
{
/* char *keyname = NULL; */ /* not supported yet */
2010-04-19 13:37:44 +00:00
int ret = - 1 ;
2010-02-23 11:19:55 +00:00
if ( ! RNA_property_editable_flag ( & self - > ptr , self - > prop ) ) {
PyErr_Format ( PyExc_AttributeError , " bpy_prop_collection: attribute \" %.200s \" from \" %.200s \" is read-only " , RNA_property_identifier ( self - > prop ) , RNA_struct_identifier ( self - > ptr . type ) ) ;
2010-04-19 13:37:44 +00:00
ret = - 1 ;
2008-11-30 03:52:07 +00:00
}
2009-07-01 13:31:36 +00:00
2010-04-19 13:37:44 +00:00
else if ( PyIndex_Check ( key ) ) {
2009-07-08 09:23:49 +00:00
Py_ssize_t i = PyNumber_AsSsize_t ( key , PyExc_IndexError ) ;
2010-04-19 13:37:44 +00:00
if ( i = = - 1 & & PyErr_Occurred ( ) ) {
ret = - 1 ;
}
else {
ret = prop_subscript_ass_array_int ( self , i , value ) ;
}
2009-07-01 13:31:36 +00:00
}
else if ( PySlice_Check ( key ) ) {
Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
Mesh.add_vertices([(x, y, z), (x, y, z), ...])
Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
2009-08-25 17:06:36 +00:00
int len = RNA_property_array_length ( & self - > ptr , self - > prop ) ;
2009-07-01 13:31:36 +00:00
Py_ssize_t start , stop , step , slicelength ;
2011-01-18 21:39:50 +00:00
if ( PySlice_GetIndicesEx ( ( void * ) key , len , & start , & stop , & step , & slicelength ) < 0 ) {
2010-04-19 13:37:44 +00:00
ret = - 1 ;
}
else if ( slicelength < = 0 ) {
ret = 0 ; /* do nothing */
2008-11-29 17:58:17 +00:00
}
2009-07-01 13:31:36 +00:00
else if ( step = = 1 ) {
2010-04-19 13:37:44 +00:00
ret = prop_subscript_ass_array_slice ( & self - > ptr , self - > prop , start , stop , len , value ) ;
2009-07-01 13:31:36 +00:00
}
else {
PyErr_SetString ( PyExc_TypeError , " slice steps not supported with rna " ) ;
2010-04-19 13:37:44 +00:00
ret = - 1 ;
2008-11-29 17:58:17 +00:00
}
}
2009-07-01 13:31:36 +00:00
else {
PyErr_SetString ( PyExc_AttributeError , " invalid key, key must be an int " ) ;
2010-04-19 13:37:44 +00:00
ret = - 1 ;
2009-07-01 13:31:36 +00:00
}
2010-01-27 17:23:28 +00:00
2010-04-19 13:37:44 +00:00
if ( ret ! = - 1 ) {
2010-10-25 21:57:45 +00:00
if ( RNA_property_update_check ( self - > prop ) ) {
RNA_property_update ( BPy_GetContext ( ) , & self - > ptr , self - > prop ) ;
}
2010-04-19 13:37:44 +00:00
}
return ret ;
2008-11-29 17:58:17 +00:00
}
2010-02-15 23:43:51 +00:00
/* for slice only */
static PyMappingMethods pyrna_prop_array_as_mapping = {
( lenfunc ) pyrna_prop_array_length , /* mp_length */
( binaryfunc ) pyrna_prop_array_subscript , /* mp_subscript */
( objobjargproc ) pyrna_prop_array_ass_subscript , /* mp_ass_subscript */
} ;
2008-11-29 17:58:17 +00:00
2010-02-15 23:43:51 +00:00
static PyMappingMethods pyrna_prop_collection_as_mapping = {
( lenfunc ) pyrna_prop_collection_length , /* mp_length */
( binaryfunc ) pyrna_prop_collection_subscript , /* mp_subscript */
( objobjargproc ) NULL , /* mp_ass_subscript */
2008-11-29 13:36:08 +00:00
} ;
2010-08-27 01:50:50 +00:00
/* only for fast bool's, large structs, assign nb_bool on init */
static PyNumberMethods pyrna_prop_array_as_number = {
NULL , /* nb_add */
NULL , /* nb_subtract */
NULL , /* nb_multiply */
NULL , /* nb_remainder */
NULL , /* nb_divmod */
NULL , /* nb_power */
NULL , /* nb_negative */
NULL , /* nb_positive */
NULL , /* nb_absolute */
( inquiry ) pyrna_prop_array_bool , /* nb_bool */
} ;
static PyNumberMethods pyrna_prop_collection_as_number = {
NULL , /* nb_add */
NULL , /* nb_subtract */
NULL , /* nb_multiply */
NULL , /* nb_remainder */
NULL , /* nb_divmod */
NULL , /* nb_power */
NULL , /* nb_negative */
NULL , /* nb_positive */
NULL , /* nb_absolute */
( inquiry ) pyrna_prop_collection_bool , /* nb_bool */
} ;
2009-11-16 19:03:40 +00:00
2010-02-15 23:43:51 +00:00
static int pyrna_prop_array_contains ( BPy_PropertyRNA * self , PyObject * value )
{
return pyrna_array_contains_py ( & self - > ptr , self - > prop , value ) ;
}
2009-11-16 19:03:40 +00:00
2010-02-15 23:43:51 +00:00
static int pyrna_prop_collection_contains ( BPy_PropertyRNA * self , PyObject * value )
{
PointerRNA newptr ; /* not used, just so RNA_property_collection_lookup_string runs */
2009-11-16 19:03:40 +00:00
2010-02-15 23:43:51 +00:00
/* key in dict style check */
2011-02-01 23:53:54 +00:00
const char * keyname = _PyUnicode_AsString ( value ) ;
2009-11-16 19:03:40 +00:00
2010-02-15 23:43:51 +00:00
if ( keyname = = NULL ) {
2010-02-23 11:19:55 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_prop_collection.__contains__: expected a string " ) ;
2009-12-08 09:40:30 +00:00
return - 1 ;
}
2009-11-16 19:03:40 +00:00
2010-02-15 23:43:51 +00:00
if ( RNA_property_collection_lookup_string ( & self - > ptr , self - > prop , keyname , & newptr ) )
return 1 ;
2009-06-13 08:04:43 +00:00
return 0 ;
}
2009-11-16 19:03:40 +00:00
static int pyrna_struct_contains ( BPy_StructRNA * self , PyObject * value )
{
IDProperty * group ;
2011-02-01 23:53:54 +00:00
const char * name = _PyUnicode_AsString ( value ) ;
2009-11-16 19:03:40 +00:00
if ( ! name ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_struct.__contains__: expected a string " ) ;
2009-11-16 19:03:40 +00:00
return - 1 ;
}
2010-08-19 10:16:30 +00:00
if ( RNA_struct_idprops_check ( self - > ptr . type ) = = 0 ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_struct: this type doesnt support IDProperties " ) ;
2009-11-16 19:03:40 +00:00
return - 1 ;
}
2010-08-19 10:16:30 +00:00
group = RNA_struct_idprops ( & self - > ptr , 0 ) ;
2011-02-11 00:11:17 +00:00
2009-11-16 19:03:40 +00:00
if ( ! group )
return 0 ;
2011-02-11 00:11:17 +00:00
2009-11-16 19:03:40 +00:00
return IDP_GetPropertyFromGroup ( group , name ) ? 1 : 0 ;
}
2010-02-15 23:43:51 +00:00
static PySequenceMethods pyrna_prop_array_as_sequence = {
( lenfunc ) pyrna_prop_array_length , /* Cant set the len otherwise it can evaluate as false */
2009-06-13 08:04:43 +00:00
NULL , /* sq_concat */
NULL , /* sq_repeat */
2010-02-15 23:43:51 +00:00
( ssizeargfunc ) pyrna_prop_array_subscript_int , /* sq_item */ /* Only set this so PySequence_Check() returns True */
2009-06-13 08:04:43 +00:00
NULL , /* sq_slice */
2010-02-15 23:43:51 +00:00
( ssizeobjargproc ) prop_subscript_ass_array_int , /* sq_ass_item */
NULL , /* *was* sq_ass_slice */
( objobjproc ) pyrna_prop_array_contains , /* sq_contains */
2010-05-16 10:09:07 +00:00
( binaryfunc ) NULL , /* sq_inplace_concat */
( ssizeargfunc ) NULL , /* sq_inplace_repeat */
2010-02-15 23:43:51 +00:00
} ;
static PySequenceMethods pyrna_prop_collection_as_sequence = {
( lenfunc ) pyrna_prop_collection_length , /* Cant set the len otherwise it can evaluate as false */
NULL , /* sq_concat */
NULL , /* sq_repeat */
( ssizeargfunc ) pyrna_prop_collection_subscript_int , /* sq_item */ /* Only set this so PySequence_Check() returns True */
NULL , /* *was* sq_slice */
2009-06-13 08:04:43 +00:00
NULL , /* sq_ass_item */
2010-02-15 23:43:51 +00:00
NULL , /* *was* sq_ass_slice */
( objobjproc ) pyrna_prop_collection_contains , /* sq_contains */
2010-05-16 10:09:07 +00:00
( binaryfunc ) NULL , /* sq_inplace_concat */
( ssizeargfunc ) NULL , /* sq_inplace_repeat */
2009-06-13 08:04:43 +00:00
} ;
2009-11-16 19:03:40 +00:00
static PySequenceMethods pyrna_struct_as_sequence = {
NULL , /* Cant set the len otherwise it can evaluate as false */
NULL , /* sq_concat */
NULL , /* sq_repeat */
NULL , /* sq_item */ /* Only set this so PySequence_Check() returns True */
2010-02-15 23:43:51 +00:00
NULL , /* *was* sq_slice */
2009-11-16 19:03:40 +00:00
NULL , /* sq_ass_item */
2010-02-15 23:43:51 +00:00
NULL , /* *was* sq_ass_slice */
2009-11-16 19:03:40 +00:00
( objobjproc ) pyrna_struct_contains , /* sq_contains */
2010-05-16 10:09:07 +00:00
( binaryfunc ) NULL , /* sq_inplace_concat */
( ssizeargfunc ) NULL , /* sq_inplace_repeat */
2009-11-16 19:03:40 +00:00
} ;
2009-07-08 09:23:49 +00:00
2009-11-16 19:03:40 +00:00
static PyObject * pyrna_struct_subscript ( BPy_StructRNA * self , PyObject * key )
{
/* mostly copied from BPy_IDGroup_Map_GetItem */
IDProperty * group , * idprop ;
2011-02-01 23:53:54 +00:00
const char * name = _PyUnicode_AsString ( key ) ;
2009-11-16 19:03:40 +00:00
2010-08-19 10:16:30 +00:00
if ( RNA_struct_idprops_check ( self - > ptr . type ) = = 0 ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " this type doesn't support IDProperties " ) ;
2009-11-17 12:21:41 +00:00
return NULL ;
}
2009-11-16 19:03:40 +00:00
if ( name = = NULL ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_struct[key]: only strings are allowed as keys of ID properties " ) ;
2009-11-16 19:03:40 +00:00
return NULL ;
}
2010-08-19 10:16:30 +00:00
group = RNA_struct_idprops ( & self - > ptr , 0 ) ;
2009-11-16 19:03:40 +00:00
if ( group = = NULL ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_KeyError , " bpy_struct[key]: key \" %s \" not found " , name ) ;
2009-11-16 19:03:40 +00:00
return NULL ;
}
idprop = IDP_GetPropertyFromGroup ( group , name ) ;
if ( idprop = = NULL ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_KeyError , " bpy_struct[key]: key \" %s \" not found " , name ) ;
2009-11-16 19:03:40 +00:00
return NULL ;
}
return BPy_IDGroup_WrapData ( self - > ptr . id . data , idprop ) ;
}
static int pyrna_struct_ass_subscript ( BPy_StructRNA * self , PyObject * key , PyObject * value )
{
2010-08-19 10:16:30 +00:00
IDProperty * group = RNA_struct_idprops ( & self - > ptr , 1 ) ;
2009-11-16 19:03:40 +00:00
2010-12-04 06:25:36 +00:00
# ifdef USE_PEDANTIC_WRITE
if ( rna_disallow_writes & & rna_id_write_error ( & self - > ptr , key ) ) {
return - 1 ;
}
2010-12-09 06:08:19 +00:00
# endif // USE_STRING_COERCE
2010-12-04 06:25:36 +00:00
2009-11-16 19:03:40 +00:00
if ( group = = NULL ) {
2010-02-23 11:19:55 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_struct[key] = val: id properties not supported for this type " ) ;
2009-11-16 19:03:40 +00:00
return - 1 ;
}
2009-11-16 22:21:39 +00:00
return BPy_Wrap_SetMapItem ( group , key , value ) ;
2009-11-16 19:03:40 +00:00
}
static PyMappingMethods pyrna_struct_as_mapping = {
( lenfunc ) NULL , /* mp_length */
( binaryfunc ) pyrna_struct_subscript , /* mp_subscript */
( objobjargproc ) pyrna_struct_ass_subscript , /* mp_ass_subscript */
} ;
2010-04-10 18:35:50 +00:00
static char pyrna_struct_keys_doc [ ] =
" .. method:: keys() \n "
" \n "
" Returns the keys of this objects custom properties (matches pythons dictionary function of the same name). \n "
" \n "
" :return: custom property keys. \n "
" :rtype: list of strings \n "
" \n "
" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties. \n " ;
2009-11-16 20:16:45 +00:00
static PyObject * pyrna_struct_keys ( BPy_PropertyRNA * self )
{
IDProperty * group ;
2010-08-19 10:16:30 +00:00
if ( RNA_struct_idprops_check ( self - > ptr . type ) = = 0 ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_struct.keys(): this type doesn't support IDProperties " ) ;
2009-11-16 20:16:45 +00:00
return NULL ;
}
2010-08-19 10:16:30 +00:00
group = RNA_struct_idprops ( & self - > ptr , 0 ) ;
2009-11-16 20:16:45 +00:00
if ( group = = NULL )
return PyList_New ( 0 ) ;
return BPy_Wrap_GetKeys ( group ) ;
}
2010-04-10 18:35:50 +00:00
static char pyrna_struct_items_doc [ ] =
" .. method:: items() \n "
" \n "
" Returns the items of this objects custom properties (matches pythons dictionary function of the same name). \n "
" \n "
" :return: custom property key, value pairs. \n "
" :rtype: list of key, value tuples \n "
" \n "
" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties. \n " ;
2009-11-16 20:16:45 +00:00
static PyObject * pyrna_struct_items ( BPy_PropertyRNA * self )
{
IDProperty * group ;
2010-08-19 10:16:30 +00:00
if ( RNA_struct_idprops_check ( self - > ptr . type ) = = 0 ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_struct.items(): this type doesn't support IDProperties " ) ;
2009-11-16 20:16:45 +00:00
return NULL ;
}
2010-08-19 10:16:30 +00:00
group = RNA_struct_idprops ( & self - > ptr , 0 ) ;
2009-11-16 20:16:45 +00:00
if ( group = = NULL )
return PyList_New ( 0 ) ;
return BPy_Wrap_GetItems ( self - > ptr . id . data , group ) ;
}
2010-04-10 18:35:50 +00:00
static char pyrna_struct_values_doc [ ] =
" .. method:: values() \n "
" \n "
" Returns the values of this objects custom properties (matches pythons dictionary function of the same name). \n "
" \n "
" :return: custom property values. \n "
" :rtype: list \n "
" \n "
" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties. \n " ;
2009-11-16 20:16:45 +00:00
static PyObject * pyrna_struct_values ( BPy_PropertyRNA * self )
{
IDProperty * group ;
2010-08-19 10:16:30 +00:00
if ( RNA_struct_idprops_check ( self - > ptr . type ) = = 0 ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_struct.values(): this type doesn't support IDProperties " ) ;
2009-11-16 20:16:45 +00:00
return NULL ;
}
2010-08-19 10:16:30 +00:00
group = RNA_struct_idprops ( & self - > ptr , 0 ) ;
2009-11-16 20:16:45 +00:00
if ( group = = NULL )
return PyList_New ( 0 ) ;
return BPy_Wrap_GetValues ( self - > ptr . id . data , group ) ;
}
2010-04-11 09:13:37 +00:00
/* for keyframes and drivers */
2010-05-10 18:47:03 +00:00
static int pyrna_struct_anim_args_parse ( PointerRNA * ptr , const char * error_prefix , const char * path ,
2011-02-01 23:53:54 +00:00
const char * * path_full , int * index )
2009-07-08 09:23:49 +00:00
{
2010-09-25 10:11:36 +00:00
const int is_idbase = RNA_struct_is_ID ( ptr - > type ) ;
2009-10-30 17:23:40 +00:00
PropertyRNA * prop ;
2010-09-25 10:11:36 +00:00
PointerRNA r_ptr ;
2011-02-11 00:11:17 +00:00
2010-02-22 12:25:58 +00:00
if ( ptr - > data = = NULL ) {
2010-02-23 11:19:55 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s this struct has no data, can't be animated " , error_prefix ) ;
2010-02-22 12:25:58 +00:00
return - 1 ;
2009-07-08 09:23:49 +00:00
}
2011-02-11 00:11:17 +00:00
2010-09-25 10:11:36 +00:00
/* full paths can only be given from ID base */
if ( is_idbase ) {
int r_index = - 1 ;
if ( RNA_path_resolve_full ( ptr , path , & r_ptr , & prop , & r_index ) = = 0 ) {
prop = NULL ;
}
else if ( r_index ! = - 1 ) {
PyErr_Format ( PyExc_ValueError , " %.200s path includes index, must be a separate argument " , error_prefix , path ) ;
return - 1 ;
}
else if ( ptr - > id . data ! = r_ptr . id . data ) {
PyErr_Format ( PyExc_ValueError , " %.200s path spans ID blocks " , error_prefix , path ) ;
return - 1 ;
}
}
2011-02-11 00:11:17 +00:00
else {
2010-09-25 10:11:36 +00:00
prop = RNA_struct_find_property ( ptr , path ) ;
r_ptr = * ptr ;
2011-02-11 00:11:17 +00:00
}
2010-09-25 10:11:36 +00:00
2009-10-30 17:23:40 +00:00
if ( prop = = NULL ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s property \" %s \" not found " , error_prefix , path ) ;
2010-02-22 12:25:58 +00:00
return - 1 ;
2009-10-30 17:23:40 +00:00
}
2010-09-25 10:11:36 +00:00
if ( ! RNA_property_animateable ( & r_ptr , prop ) ) {
2010-04-10 18:35:50 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s property \" %s \" not animatable " , error_prefix , path ) ;
2010-02-22 12:25:58 +00:00
return - 1 ;
2009-10-30 17:23:40 +00:00
}
2010-09-25 10:11:36 +00:00
if ( RNA_property_array_check ( & r_ptr , prop ) = = 0 ) {
2010-04-10 18:35:50 +00:00
if ( ( * index ) = = - 1 ) {
* index = 0 ;
}
else {
PyErr_Format ( PyExc_TypeError , " %.200s index %d was given while property \" %s \" is not an array " , error_prefix , * index , path ) ;
return - 1 ;
}
}
else {
2010-09-25 10:11:36 +00:00
int array_len = RNA_property_array_length ( & r_ptr , prop ) ;
2010-04-10 18:35:50 +00:00
if ( ( * index ) < - 1 | | ( * index ) > = array_len ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s index out of range \" %s \" , given %d, array length is %d " , error_prefix , path , * index , array_len ) ;
2010-04-10 18:35:50 +00:00
return - 1 ;
}
}
2011-02-11 00:11:17 +00:00
2010-09-25 10:11:36 +00:00
if ( is_idbase ) {
* path_full = BLI_strdup ( path ) ;
}
else {
* path_full = RNA_path_from_ID_to_property ( & r_ptr , prop ) ;
2011-02-11 00:11:17 +00:00
2010-09-25 10:11:36 +00:00
if ( * path_full = = NULL ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s could not make path to \" %s \" " , error_prefix , path ) ;
2010-09-25 10:11:36 +00:00
return - 1 ;
}
2009-10-30 17:23:40 +00:00
}
2009-07-08 09:23:49 +00:00
2010-04-11 09:13:37 +00:00
return 0 ;
}
/* internal use for insert and delete */
2010-05-10 18:47:03 +00:00
static int pyrna_struct_keyframe_parse ( PointerRNA * ptr , PyObject * args , PyObject * kw , const char * parse_str , const char * error_prefix ,
2011-02-01 23:53:54 +00:00
const char * * path_full , int * index , float * cfra , const char * * group_name ) /* return values */
2010-04-11 09:13:37 +00:00
{
2010-12-03 17:05:21 +00:00
static const char * kwlist [ ] = { " data_path " , " index " , " frame " , " group " , NULL } ;
2011-02-01 23:53:54 +00:00
const char * path ;
2010-04-11 09:13:37 +00:00
2010-05-10 18:47:03 +00:00
/* note, parse_str MUST start with 's|ifs' */
if ( ! PyArg_ParseTupleAndKeywords ( args , kw , parse_str , ( char * * ) kwlist , & path , index , cfra , group_name ) )
2010-04-11 09:13:37 +00:00
return - 1 ;
2011-02-11 00:11:17 +00:00
if ( pyrna_struct_anim_args_parse ( ptr , error_prefix , path , path_full , index ) < 0 )
2010-04-11 09:13:37 +00:00
return - 1 ;
2011-02-11 00:11:17 +00:00
2010-02-22 12:25:58 +00:00
if ( * cfra = = FLT_MAX )
* cfra = CTX_data_scene ( BPy_GetContext ( ) ) - > r . cfra ;
return 0 ; /* success */
}
2010-04-05 22:37:09 +00:00
static char pyrna_struct_keyframe_insert_doc [ ] =
2010-06-14 12:36:28 +00:00
" .. method:: keyframe_insert(data_path, index=-1, frame=bpy.context.scene.frame_current, group= \" \" ) \n "
2010-04-05 22:37:09 +00:00
" \n "
2010-04-10 18:35:50 +00:00
" Insert a keyframe on the property given, adding fcurves and animation data when necessary. \n "
2010-04-05 22:37:09 +00:00
" \n "
2010-06-14 12:36:28 +00:00
" :arg data_path: path to the property to key, analogous to the fcurve's data path. \n "
" :type data_path: string \n "
2011-01-18 01:58:19 +00:00
" :arg index: array index of the property to key. Defaults to -1 which will key all indices or a single channel if the property is not an array. \n "
2010-04-05 22:37:09 +00:00
" :type index: int \n "
" :arg frame: The frame on which the keyframe is inserted, defaulting to the current frame. \n "
2010-04-06 04:25:48 +00:00
" :type frame: float \n "
2010-04-10 18:35:50 +00:00
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet. \n "
" :type group: str \n "
" :return: Success of keyframe insertion. \n "
" :rtype: boolean " ;
2010-04-05 22:37:09 +00:00
2010-05-10 18:47:03 +00:00
static PyObject * pyrna_struct_keyframe_insert ( BPy_StructRNA * self , PyObject * args , PyObject * kw )
2010-02-22 12:25:58 +00:00
{
/* args, pyrna_struct_keyframe_parse handles these */
2011-02-01 23:53:54 +00:00
const char * path_full = NULL ;
2010-02-22 12:25:58 +00:00
int index = - 1 ;
float cfra = FLT_MAX ;
2011-02-01 23:53:54 +00:00
const char * group_name = NULL ;
2010-02-22 12:25:58 +00:00
2010-12-31 05:40:30 +00:00
if ( pyrna_struct_keyframe_parse ( & self - > ptr , args , kw , " s|ifs:bpy_struct.keyframe_insert() " , " bpy_struct.keyframe_insert() " , & path_full , & index , & cfra , & group_name ) = = - 1 ) {
2010-02-22 12:25:58 +00:00
return NULL ;
2010-12-31 05:40:30 +00:00
}
else {
short result ;
ReportList reports ;
2010-02-22 12:25:58 +00:00
2010-12-31 05:40:30 +00:00
BKE_reports_init ( & reports , RPT_STORE ) ;
2009-10-30 17:23:40 +00:00
2010-12-31 05:40:30 +00:00
result = insert_keyframe ( & reports , ( ID * ) self - > ptr . id . data , NULL , group_name , path_full , index , cfra , 0 ) ;
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) path_full ) ;
2010-12-31 05:40:30 +00:00
if ( BPy_reports_to_error ( & reports , TRUE ) )
return NULL ;
return PyBool_FromLong ( result ) ;
}
2009-07-08 09:23:49 +00:00
}
2010-04-05 22:37:09 +00:00
static char pyrna_struct_keyframe_delete_doc [ ] =
2010-06-14 12:36:28 +00:00
" .. method:: keyframe_delete(data_path, index=-1, frame=bpy.context.scene.frame_current, group= \" \" ) \n "
2010-04-05 22:37:09 +00:00
" \n "
2010-04-10 18:35:50 +00:00
" Remove a keyframe from this properties fcurve. \n "
2010-04-05 22:37:09 +00:00
" \n "
2010-06-14 12:36:28 +00:00
" :arg data_path: path to the property to remove a key, analogous to the fcurve's data path. \n "
" :type data_path: string \n "
2011-01-18 01:58:19 +00:00
" :arg index: array index of the property to remove a key. Defaults to -1 removing all indices or a single channel if the property is not an array. \n "
2010-04-05 22:37:09 +00:00
" :type index: int \n "
" :arg frame: The frame on which the keyframe is deleted, defaulting to the current frame. \n "
2010-04-06 07:49:10 +00:00
" :type frame: float \n "
2010-04-10 18:35:50 +00:00
" :arg group: The name of the group the F-Curve should be added to if it doesn't exist yet. \n "
" :type group: str \n "
" :return: Success of keyframe deleation. \n "
" :rtype: boolean " ;
2010-04-05 22:37:09 +00:00
2010-05-10 18:47:03 +00:00
static PyObject * pyrna_struct_keyframe_delete ( BPy_StructRNA * self , PyObject * args , PyObject * kw )
2010-02-22 12:25:58 +00:00
{
/* args, pyrna_struct_keyframe_parse handles these */
2011-02-01 23:53:54 +00:00
const char * path_full = NULL ;
2010-02-22 12:25:58 +00:00
int index = - 1 ;
float cfra = FLT_MAX ;
2011-02-01 23:53:54 +00:00
const char * group_name = NULL ;
2010-02-22 12:25:58 +00:00
2010-12-31 05:40:30 +00:00
if ( pyrna_struct_keyframe_parse ( & self - > ptr , args , kw , " s|ifs:bpy_struct.keyframe_delete() " , " bpy_struct.keyframe_insert() " , & path_full , & index , & cfra , & group_name ) = = - 1 ) {
2010-02-22 12:25:58 +00:00
return NULL ;
2010-12-31 05:40:30 +00:00
}
else {
short result ;
ReportList reports ;
2010-02-22 12:25:58 +00:00
2010-12-31 05:40:30 +00:00
BKE_reports_init ( & reports , RPT_STORE ) ;
result = delete_keyframe ( & reports , ( ID * ) self - > ptr . id . data , NULL , group_name , path_full , index , cfra , 0 ) ;
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) path_full ) ;
2010-12-31 05:40:30 +00:00
if ( BPy_reports_to_error ( & reports , TRUE ) )
return NULL ;
return PyBool_FromLong ( result ) ;
}
2010-02-22 12:25:58 +00:00
}
2009-11-04 15:16:41 +00:00
2010-04-06 07:49:10 +00:00
static char pyrna_struct_driver_add_doc [ ] =
2010-04-10 18:35:50 +00:00
" .. method:: driver_add(path, index=-1) \n "
2010-04-06 07:49:10 +00:00
" \n "
2010-04-10 18:35:50 +00:00
" Adds driver(s) to the given property \n "
2010-04-06 07:49:10 +00:00
" \n "
" :arg path: path to the property to drive, analogous to the fcurve's data path. \n "
" :type path: string \n "
2011-01-18 01:58:19 +00:00
" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array. \n "
2010-04-10 18:35:50 +00:00
" :type index: int \n "
" :return: The driver(s) added. \n "
" :rtype: :class:`FCurve` or list if index is -1 with an array property. " ;
2010-04-06 07:49:10 +00:00
2009-11-16 19:03:40 +00:00
static PyObject * pyrna_struct_driver_add ( BPy_StructRNA * self , PyObject * args )
2009-11-04 15:16:41 +00:00
{
2011-02-01 23:53:54 +00:00
const char * path , * path_full ;
2010-04-10 18:35:50 +00:00
int index = - 1 ;
2009-11-04 15:16:41 +00:00
if ( ! PyArg_ParseTuple ( args , " s|i:driver_add " , & path , & index ) )
return NULL ;
2010-12-31 05:40:30 +00:00
if ( pyrna_struct_anim_args_parse ( & self - > ptr , " bpy_struct.driver_add(): " , path , & path_full , & index ) < 0 ) {
2009-11-04 15:16:41 +00:00
return NULL ;
2010-12-31 05:40:30 +00:00
}
else {
PyObject * ret = NULL ;
ReportList reports ;
int result ;
BKE_reports_init ( & reports , RPT_STORE ) ;
2009-11-04 15:16:41 +00:00
2010-12-31 05:40:30 +00:00
result = ANIM_add_driver ( & reports , ( ID * ) self - > ptr . id . data , path_full , index , 0 , DRIVER_TYPE_PYTHON ) ;
2009-11-25 10:13:24 +00:00
2010-12-31 05:40:30 +00:00
if ( BPy_reports_to_error ( & reports , TRUE ) )
return NULL ;
2009-11-25 10:13:24 +00:00
2010-12-31 05:40:30 +00:00
if ( result ) {
ID * id = self - > ptr . id . data ;
AnimData * adt = BKE_animdata_from_id ( id ) ;
FCurve * fcu ;
PointerRNA tptr ;
PyObject * item ;
if ( index = = - 1 ) { /* all, use a list */
int i = 0 ;
ret = PyList_New ( 0 ) ;
while ( ( fcu = list_find_fcurve ( & adt - > drivers , path_full , i + + ) ) ) {
RNA_pointer_create ( id , & RNA_FCurve , fcu , & tptr ) ;
item = pyrna_struct_CreatePyObject ( & tptr ) ;
PyList_Append ( ret , item ) ;
Py_DECREF ( item ) ;
}
}
else {
fcu = list_find_fcurve ( & adt - > drivers , path_full , index ) ;
2009-11-25 10:13:24 +00:00
RNA_pointer_create ( id , & RNA_FCurve , fcu , & tptr ) ;
2010-12-31 05:40:30 +00:00
ret = pyrna_struct_CreatePyObject ( & tptr ) ;
2009-11-25 10:13:24 +00:00
}
}
else {
2010-12-31 05:40:30 +00:00
/* XXX, should be handled by reports, */
PyErr_SetString ( PyExc_TypeError , " bpy_struct.driver_add(): failed because of an internal error " ) ;
return NULL ;
2009-11-25 10:13:24 +00:00
}
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) path_full ) ;
2009-11-04 15:16:41 +00:00
2010-12-31 05:40:30 +00:00
return ret ;
}
2009-11-04 15:16:41 +00:00
}
2010-04-11 09:13:37 +00:00
static char pyrna_struct_driver_remove_doc [ ] =
" .. method:: driver_remove(path, index=-1) \n "
" \n "
" Remove driver(s) from the given property \n "
" \n "
" :arg path: path to the property to drive, analogous to the fcurve's data path. \n "
" :type path: string \n "
2011-01-18 01:58:19 +00:00
" :arg index: array index of the property drive. Defaults to -1 for all indices or a single channel if the property is not an array. \n "
2010-04-11 09:13:37 +00:00
" :type index: int \n "
" :return: Success of driver removal. \n "
" :rtype: boolean " ;
static PyObject * pyrna_struct_driver_remove ( BPy_StructRNA * self , PyObject * args )
{
2011-02-01 23:53:54 +00:00
const char * path , * path_full ;
2010-04-11 09:13:37 +00:00
int index = - 1 ;
if ( ! PyArg_ParseTuple ( args , " s|i:driver_remove " , & path , & index ) )
return NULL ;
2010-12-31 05:40:30 +00:00
if ( pyrna_struct_anim_args_parse ( & self - > ptr , " bpy_struct.driver_remove(): " , path , & path_full , & index ) < 0 ) {
2010-04-11 09:13:37 +00:00
return NULL ;
2010-12-31 05:40:30 +00:00
}
else {
short result ;
ReportList reports ;
2010-04-11 09:13:37 +00:00
2010-12-31 05:40:30 +00:00
BKE_reports_init ( & reports , RPT_STORE ) ;
2010-04-11 09:13:37 +00:00
2010-12-31 05:40:30 +00:00
result = ANIM_remove_driver ( & reports , ( ID * ) self - > ptr . id . data , path_full , index , 0 ) ;
2010-04-11 09:13:37 +00:00
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) path_full ) ;
2010-12-31 05:40:30 +00:00
if ( BPy_reports_to_error ( & reports , TRUE ) )
return NULL ;
return PyBool_FromLong ( result ) ;
}
2010-04-11 09:13:37 +00:00
}
2010-04-10 18:35:50 +00:00
static char pyrna_struct_is_property_set_doc [ ] =
" .. method:: is_property_set(property) \n "
" \n "
" Check if a property is set, use for testing operator properties. \n "
" \n "
" :return: True when the property has been set. \n "
" :rtype: boolean " ;
2009-11-16 19:03:40 +00:00
static PyObject * pyrna_struct_is_property_set ( BPy_StructRNA * self , PyObject * args )
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
{
2010-08-13 06:30:04 +00:00
PropertyRNA * prop ;
2011-02-01 23:53:54 +00:00
const char * name ;
2010-08-13 06:30:04 +00:00
int ret ;
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
if ( ! PyArg_ParseTuple ( args , " s:is_property_set " , & name ) )
return NULL ;
2010-08-13 06:30:04 +00:00
if ( ( prop = RNA_struct_find_property ( & self - > ptr , name ) ) = = NULL ) {
PyErr_Format ( PyExc_TypeError , " %.200s.is_property_set( \" %.200s \" ) not found " , RNA_struct_identifier ( self - > ptr . type ) , name ) ;
return NULL ;
}
/* double property lookup, could speed up */
/* return PyBool_FromLong(RNA_property_is_set(&self->ptr, name)); */
if ( RNA_property_flag ( prop ) & PROP_IDPROPERTY ) {
2011-02-11 00:11:17 +00:00
IDProperty * group = RNA_struct_idprops ( & self - > ptr , 0 ) ;
2010-08-13 06:30:04 +00:00
if ( group ) {
ret = IDP_GetPropertyFromGroup ( group , name ) ? 1 : 0 ;
}
else {
ret = 0 ;
}
}
else {
ret = 1 ;
}
2011-02-11 00:11:17 +00:00
2010-08-13 06:30:04 +00:00
return PyBool_FromLong ( ret ) ;
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
}
2010-04-10 18:35:50 +00:00
static char pyrna_struct_is_property_hidden_doc [ ] =
" .. method:: is_property_hidden(property) \n "
" \n "
" Check if a property is hidden. \n "
" \n "
" :return: True when the property is hidden. \n "
" :rtype: boolean " ;
2009-11-16 19:03:40 +00:00
static PyObject * pyrna_struct_is_property_hidden ( BPy_StructRNA * self , PyObject * args )
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
{
PropertyRNA * prop ;
2011-02-01 23:53:54 +00:00
const char * name ;
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
if ( ! PyArg_ParseTuple ( args , " s:is_property_hidden " , & name ) )
return NULL ;
2010-08-13 06:30:04 +00:00
if ( ( prop = RNA_struct_find_property ( & self - > ptr , name ) ) = = NULL ) {
PyErr_Format ( PyExc_TypeError , " %.200s.is_property_hidden( \" %.200s \" ) not found " , RNA_struct_identifier ( self - > ptr . type ) , name ) ;
return NULL ;
}
return PyBool_FromLong ( RNA_property_flag ( prop ) & PROP_HIDDEN ) ;
Key Configuration
Keymaps are now saveable and configurable from the user preferences, note
that editing one item in a keymap means the whole keymap is now defined by
the user and will not be updated by Blender, an option for syncing might be
added later. The outliner interface is still there, but I will probably
remove it.
There's actually 3 levels now:
* Default builtin key configuration.
* Key configuration loaded from .py file, for configs like Blender 2.4x
or other 3D applications.
* Keymaps edited by the user and saved in .B.blend. These can be saved
to .py files as well to make creating distributable configurations
easier.
Also, user preferences sections were reorganized a bit, now there is:
Interface, Editing, Input, Files and System.
Implementation notes:
* wmKeyConfig was added which represents a key configuration containing
keymaps.
* wmKeymapItem was renamed to wmKeyMapItem for consistency with wmKeyMap.
* Modal maps are not wrapped yet.
* User preferences DNA file reading did not support newdataadr() yet,
added this now for reading keymaps.
* Key configuration related settings are now RNA wrapped.
* is_property_set and is_property_hidden python methods were added.
2009-10-08 18:40:03 +00:00
}
2010-04-06 07:49:10 +00:00
static char pyrna_struct_path_resolve_doc [ ] =
2010-08-23 05:36:21 +00:00
" .. method:: path_resolve(path, coerce=True) \n "
2010-04-06 07:49:10 +00:00
" \n "
2010-08-23 05:36:21 +00:00
" Returns the property from the path, raise an exception when not found. \n "
" \n "
" :arg path: path which this property resolves. \n "
" :type path: string \n "
" :arg coerce: optional argument, when True, the property will be converted into its python representation. \n "
" :type coerce: boolean \n " ;
2010-04-06 07:49:10 +00:00
2010-08-23 05:36:21 +00:00
static PyObject * pyrna_struct_path_resolve ( BPy_StructRNA * self , PyObject * args )
2009-11-17 20:46:59 +00:00
{
2011-02-01 23:53:54 +00:00
const char * path ;
2010-08-23 05:36:21 +00:00
PyObject * coerce = Py_True ;
2009-11-17 20:46:59 +00:00
PointerRNA r_ptr ;
PropertyRNA * r_prop ;
2010-09-23 02:12:33 +00:00
int index = - 1 ;
2009-11-17 20:46:59 +00:00
2010-08-23 05:36:21 +00:00
if ( ! PyArg_ParseTuple ( args , " s|O!:path_resolve " , & path , & PyBool_Type , & coerce ) )
2009-11-17 20:46:59 +00:00
return NULL ;
2010-09-23 02:12:33 +00:00
if ( RNA_path_resolve_full ( & self - > ptr , path , & r_ptr , & r_prop , & index ) ) {
2010-08-30 09:18:21 +00:00
if ( r_prop ) {
2010-09-23 02:12:33 +00:00
if ( index ! = - 1 ) {
if ( index > = RNA_property_array_length ( & r_ptr , r_prop ) | | index < 0 ) {
PyErr_Format ( PyExc_TypeError , " %.200s.path_resolve( \" %.200s \" ) index out of range " , RNA_struct_identifier ( self - > ptr . type ) , path ) ;
return NULL ;
}
else {
return pyrna_array_index ( & r_ptr , r_prop , index ) ;
}
2010-08-30 09:18:21 +00:00
}
else {
2010-09-23 02:12:33 +00:00
if ( coerce = = Py_False ) {
return pyrna_prop_CreatePyObject ( & r_ptr , r_prop ) ;
}
else {
return pyrna_prop_to_py ( & r_ptr , r_prop ) ;
}
2010-08-30 09:18:21 +00:00
}
2010-08-23 05:36:21 +00:00
}
else {
2010-08-30 09:18:21 +00:00
return pyrna_struct_CreatePyObject ( & r_ptr ) ;
2010-08-23 05:36:21 +00:00
}
}
else {
PyErr_Format ( PyExc_TypeError , " %.200s.path_resolve( \" %.200s \" ) could not be resolved " , RNA_struct_identifier ( self - > ptr . type ) , path ) ;
return NULL ;
}
2009-11-17 20:46:59 +00:00
}
2010-04-06 07:49:10 +00:00
static char pyrna_struct_path_from_id_doc [ ] =
2010-04-10 18:35:50 +00:00
" .. method:: path_from_id(property= \" \" ) \n "
2010-04-06 07:49:10 +00:00
" \n "
" Returns the data path from the ID to this object (string). \n "
" \n "
" :arg property: Optional property name which can be used if the path is to a property of this object. \n "
2010-04-10 18:35:50 +00:00
" :type property: string \n "
" :return: The path from :class:`bpy_struct.id_data` to this struct and property (when given). \n "
" :rtype: str " ;
2010-04-06 07:49:10 +00:00
static PyObject * pyrna_struct_path_from_id ( BPy_StructRNA * self , PyObject * args )
2009-11-23 23:17:23 +00:00
{
2011-02-01 23:53:54 +00:00
const char * name = NULL ;
const char * path ;
2009-11-23 23:17:23 +00:00
PropertyRNA * prop ;
PyObject * ret ;
2010-04-06 07:49:10 +00:00
if ( ! PyArg_ParseTuple ( args , " |s:path_from_id " , & name ) )
2009-11-23 23:17:23 +00:00
return NULL ;
if ( name ) {
prop = RNA_struct_find_property ( & self - > ptr , name ) ;
if ( prop = = NULL ) {
2010-04-06 07:49:10 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s.path_from_id( \" %.200s \" ) not found " , RNA_struct_identifier ( self - > ptr . type ) , name ) ;
2009-11-23 23:17:23 +00:00
return NULL ;
}
path = RNA_path_from_ID_to_property ( & self - > ptr , prop ) ;
}
else {
path = RNA_path_from_ID_to_struct ( & self - > ptr ) ;
}
if ( path = = NULL ) {
2010-04-06 07:49:10 +00:00
if ( name ) PyErr_Format ( PyExc_TypeError , " %.200s.path_from_id( \" %s \" ) found but does not support path creation " , RNA_struct_identifier ( self - > ptr . type ) , name ) ;
else PyErr_Format ( PyExc_TypeError , " %.200s.path_from_id() does not support path creation for this type " , RNA_struct_identifier(self->ptr.type)) ;
2009-11-23 23:17:23 +00:00
return NULL ;
}
ret = PyUnicode_FromString ( path ) ;
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) path ) ;
2009-11-23 23:17:23 +00:00
return ret ;
}
2010-04-06 07:49:10 +00:00
static char pyrna_prop_path_from_id_doc [ ] =
2010-04-10 18:35:50 +00:00
" .. method:: path_from_id() \n "
2010-04-06 07:49:10 +00:00
" \n "
2010-04-10 18:35:50 +00:00
" Returns the data path from the ID to this property (string). \n "
" \n "
" :return: The path from :class:`bpy_struct.id_data` to this property. \n "
" :rtype: str " ;
2010-04-06 07:49:10 +00:00
static PyObject * pyrna_prop_path_from_id ( BPy_PropertyRNA * self )
2009-11-23 23:17:23 +00:00
{
2011-02-01 23:53:54 +00:00
const char * path ;
2009-11-25 09:25:58 +00:00
PropertyRNA * prop = self - > prop ;
2009-11-23 23:17:23 +00:00
PyObject * ret ;
path = RNA_path_from_ID_to_property ( & self - > ptr , self - > prop ) ;
if ( path = = NULL ) {
2010-04-06 07:49:10 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s.%.200s.path_from_id() does not support path creation for this type " , RNA_struct_identifier ( self - > ptr . type ) , RNA_property_identifier ( prop ) ) ;
2009-11-23 23:17:23 +00:00
return NULL ;
}
ret = PyUnicode_FromString ( path ) ;
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) path ) ;
2009-11-23 23:17:23 +00:00
return ret ;
}
2009-11-20 10:00:54 +00:00
2010-08-25 01:51:38 +00:00
static char pyrna_struct_type_recast_doc [ ] =
" .. method:: type_recast() \n "
2010-04-10 18:35:50 +00:00
" \n "
" Return a new instance, this is needed because types such as textures can be changed at runtime. \n "
" \n "
" :return: a new instance of this object with the type initialized again. \n "
" :rtype: subclass of :class:`bpy_struct` " ;
2010-10-13 23:25:08 +00:00
static PyObject * pyrna_struct_type_recast ( BPy_StructRNA * self )
2010-04-10 18:35:50 +00:00
{
PointerRNA r_ptr ;
RNA_pointer_recast ( & self - > ptr , & r_ptr ) ;
return pyrna_struct_CreatePyObject ( & r_ptr ) ;
}
2009-11-20 10:00:54 +00:00
static void pyrna_dir_members_py ( PyObject * list , PyObject * self )
{
PyObject * dict ;
PyObject * * dict_ptr ;
PyObject * list_tmp ;
dict_ptr = _PyObject_GetDictPtr ( ( PyObject * ) self ) ;
if ( dict_ptr & & ( dict = * dict_ptr ) ) {
list_tmp = PyDict_Keys ( dict ) ;
PyList_SetSlice ( list , INT_MAX , INT_MAX , list_tmp ) ;
Py_DECREF ( list_tmp ) ;
}
dict = ( ( PyTypeObject * ) Py_TYPE ( self ) ) - > tp_dict ;
if ( dict ) {
list_tmp = PyDict_Keys ( dict ) ;
PyList_SetSlice ( list , INT_MAX , INT_MAX , list_tmp ) ;
Py_DECREF ( list_tmp ) ;
}
}
static void pyrna_dir_members_rna ( PyObject * list , PointerRNA * ptr )
2008-11-30 14:00:14 +00:00
{
2009-03-21 06:55:30 +00:00
PyObject * pystring ;
2009-11-20 10:00:54 +00:00
const char * idname ;
2009-04-09 16:52:18 +00:00
/* for looping over attrs and funcs */
2009-11-20 10:00:54 +00:00
PointerRNA tptr ;
2009-04-09 16:52:18 +00:00
PropertyRNA * iterprop ;
2009-03-21 06:55:30 +00:00
2009-11-20 10:00:54 +00:00
{
RNA_pointer_create ( NULL , & RNA_Struct , ptr - > type , & tptr ) ;
iterprop = RNA_struct_find_property ( & tptr , " functions " ) ;
2009-03-21 06:55:30 +00:00
2009-11-20 10:00:54 +00:00
RNA_PROP_BEGIN ( & tptr , itemptr , iterprop ) {
idname = RNA_function_identifier ( itemptr . data ) ;
2009-11-19 18:22:21 +00:00
2009-11-20 10:00:54 +00:00
pystring = PyUnicode_FromString ( idname ) ;
PyList_Append ( list , pystring ) ;
Py_DECREF ( pystring ) ;
}
RNA_PROP_END ;
2009-03-05 12:09:30 +00:00
}
2009-11-20 10:00:54 +00:00
2009-03-11 17:28:37 +00:00
{
2009-04-09 16:52:18 +00:00
/*
* Collect RNA attributes
*/
2009-03-05 12:09:30 +00:00
char name [ 256 ] , * nameptr ;
2009-11-20 10:00:54 +00:00
iterprop = RNA_struct_iterator_property ( ptr - > type ) ;
2009-03-05 12:09:30 +00:00
2009-11-20 10:00:54 +00:00
RNA_PROP_BEGIN ( ptr , itemptr , iterprop ) {
2009-06-24 21:27:10 +00:00
nameptr = RNA_struct_name_get_alloc ( & itemptr , name , sizeof ( name ) ) ;
2009-06-24 14:03:55 +00:00
if ( nameptr ) {
2009-11-13 16:08:03 +00:00
pystring = PyUnicode_FromString ( nameptr ) ;
2009-11-20 10:00:54 +00:00
PyList_Append ( list , pystring ) ;
2009-11-13 16:08:03 +00:00
Py_DECREF ( pystring ) ;
2009-06-24 14:03:55 +00:00
if ( name ! = nameptr )
2009-03-05 12:09:30 +00:00
MEM_freeN ( nameptr ) ;
}
2008-11-29 13:36:08 +00:00
}
2009-06-24 21:27:10 +00:00
RNA_PROP_END ;
2009-04-09 16:52:18 +00:00
}
2009-11-20 10:00:54 +00:00
}
2009-04-09 16:52:18 +00:00
2009-11-20 10:00:54 +00:00
static PyObject * pyrna_struct_dir ( BPy_StructRNA * self )
{
PyObject * ret ;
PyObject * pystring ;
2009-11-11 17:12:48 +00:00
2009-11-20 10:00:54 +00:00
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
* */
ret = PyList_New ( 0 ) ;
if ( ! BPy_StructRNA_CheckExact ( self ) )
pyrna_dir_members_py ( ret , ( PyObject * ) self ) ;
pyrna_dir_members_rna ( ret , & self - > ptr ) ;
2009-06-20 14:55:28 +00:00
if ( self - > ptr . type = = & RNA_Context ) {
ListBase lb = CTX_data_dir_get ( self - > ptr . data ) ;
LinkData * link ;
for ( link = lb . first ; link ; link = link - > next ) {
pystring = PyUnicode_FromString ( link - > data ) ;
PyList_Append ( ret , pystring ) ;
Py_DECREF ( pystring ) ;
}
BLI_freelistN ( & lb ) ;
}
2011-01-27 06:48:14 +00:00
{
/* set(), this is needed to remove-doubles because the deferred
* register - props will be in both the python __dict__ and accessed as RNA */
PyObject * set = PySet_New ( ret ) ;
Py_DECREF ( ret ) ;
ret = PySequence_List ( set ) ;
Py_DECREF ( set ) ;
}
2009-03-11 17:28:37 +00:00
return ret ;
}
//---------------getattr--------------------------------------------
2009-11-16 19:03:40 +00:00
static PyObject * pyrna_struct_getattro ( BPy_StructRNA * self , PyObject * pyname )
2009-03-11 17:28:37 +00:00
{
2011-02-01 23:53:54 +00:00
const char * name = _PyUnicode_AsString ( pyname ) ;
2009-03-11 17:28:37 +00:00
PyObject * ret ;
PropertyRNA * prop ;
2009-04-07 00:49:39 +00:00
FunctionRNA * func ;
2011-02-11 00:11:17 +00:00
2010-09-09 13:58:38 +00:00
if ( name = = NULL ) {
PyErr_SetString ( PyExc_AttributeError , " bpy_struct: __getattr__ must be a string " ) ;
ret = NULL ;
}
else if ( name [ 0 ] = = ' _ ' ) { // rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups
2009-11-17 12:21:41 +00:00
/* annoying exception, maybe we need to have different types for this... */
2010-08-19 10:16:30 +00:00
if ( ( strcmp ( name , " __getitem__ " ) = = 0 | | strcmp ( name , " __setitem__ " ) = = 0 ) & & ! RNA_struct_idprops_check ( self - > ptr . type ) ) {
2010-02-23 11:19:55 +00:00
PyErr_SetString ( PyExc_AttributeError , " bpy_struct: no __getitem__ support for this type " ) ;
2009-11-17 12:21:41 +00:00
ret = NULL ;
}
else {
ret = PyObject_GenericGetAttr ( ( PyObject * ) self , pyname ) ;
}
2009-11-14 23:11:46 +00:00
}
else if ( ( prop = RNA_struct_find_property ( & self - > ptr , name ) ) ) {
2010-03-22 09:30:00 +00:00
ret = pyrna_prop_to_py ( & self - > ptr , prop ) ;
2010-06-14 02:05:37 +00:00
}
2009-12-28 22:48:10 +00:00
/* RNA function only if callback is declared (no optional functions) */
else if ( ( func = RNA_struct_find_function ( & self - > ptr , name ) ) & & RNA_function_defined ( func ) ) {
2009-11-11 16:28:53 +00:00
ret = pyrna_func_to_py ( ( BPy_DummyPointerRNA * ) self , func ) ;
2009-03-11 17:28:37 +00:00
}
2009-04-07 00:49:39 +00:00
else if ( self - > ptr . type = = & RNA_Context ) {
2010-01-27 10:54:11 +00:00
bContext * C = self - > ptr . data ;
if ( C = = NULL ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_AttributeError , " bpy_struct: Context is 'NULL', can't get \" %.200s \" from context " , name ) ;
2010-01-27 10:54:11 +00:00
ret = NULL ;
}
else {
PointerRNA newptr ;
ListBase newlb ;
2010-04-24 19:26:05 +00:00
short newtype ;
2009-03-19 19:03:38 +00:00
2010-04-24 19:26:05 +00:00
int done = CTX_data_get ( C , name , & newptr , & newlb , & newtype ) ;
2009-03-19 19:03:38 +00:00
2010-01-27 10:54:11 +00:00
if ( done = = 1 ) { /* found */
2010-04-24 19:26:05 +00:00
switch ( newtype ) {
case CTX_DATA_TYPE_POINTER :
2010-04-25 19:56:43 +00:00
if ( newptr . data = = NULL ) {
ret = Py_None ;
Py_INCREF ( ret ) ;
}
else {
ret = pyrna_struct_CreatePyObject ( & newptr ) ;
}
2010-04-24 19:26:05 +00:00
break ;
case CTX_DATA_TYPE_COLLECTION :
{
CollectionPointerLink * link ;
PyObject * linkptr ;
2011-02-11 00:11:17 +00:00
2010-04-24 19:26:05 +00:00
ret = PyList_New ( 0 ) ;
2011-02-11 00:11:17 +00:00
2010-04-24 19:26:05 +00:00
for ( link = newlb . first ; link ; link = link - > next ) {
linkptr = pyrna_struct_CreatePyObject ( & link - > ptr ) ;
PyList_Append ( ret , linkptr ) ;
Py_DECREF ( linkptr ) ;
}
2010-01-27 10:54:11 +00:00
}
2010-04-24 19:26:05 +00:00
break ;
2010-05-04 07:26:57 +00:00
default :
/* should never happen */
2011-01-09 15:12:08 +00:00
BLI_assert ( ! " Invalid context type " ) ;
2010-12-15 10:22:26 +00:00
2010-05-04 07:26:57 +00:00
PyErr_Format ( PyExc_AttributeError , " bpy_struct: Context type invalid %d, can't get \" %.200s \" from context " , newtype , name ) ;
ret = NULL ;
2009-11-10 15:09:53 +00:00
}
}
2010-01-27 10:54:11 +00:00
else if ( done = = - 1 ) { /* found but not set */
2009-11-10 15:09:53 +00:00
ret = Py_None ;
Py_INCREF ( ret ) ;
2009-03-19 19:03:38 +00:00
}
2010-01-27 10:54:11 +00:00
else { /* not found in the context */
/* lookup the subclass. raise an error if its not found */
ret = PyObject_GenericGetAttr ( ( PyObject * ) self , pyname ) ;
}
2009-03-19 19:03:38 +00:00
2010-01-27 10:54:11 +00:00
BLI_freelistN ( & newlb ) ;
}
2009-03-19 19:03:38 +00:00
}
2009-03-05 12:09:30 +00:00
else {
2009-11-08 01:13:19 +00:00
#if 0
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_AttributeError , " bpy_struct: attribute \" %.200s \" not found " , name ) ;
2009-03-05 12:09:30 +00:00
ret = NULL ;
2009-11-08 01:13:19 +00:00
# endif
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
*
* Also needed to return methods when its not a subtype
* */
/* The error raised here will be displayed */
ret = PyObject_GenericGetAttr ( ( PyObject * ) self , pyname ) ;
2008-11-29 13:36:08 +00:00
}
2011-02-11 00:11:17 +00:00
2008-11-29 17:58:17 +00:00
return ret ;
}
2008-11-29 13:36:08 +00:00
2009-11-19 18:22:21 +00:00
#if 0
static int pyrna_struct_pydict_contains ( PyObject * self , PyObject * pyname )
{
PyObject * dict = * ( _PyObject_GetDictPtr ( ( PyObject * ) self ) ) ;
if ( dict = = NULL ) /* unlikely */
return 0 ;
return PyDict_Contains ( dict , pyname ) ;
}
# endif
2008-11-29 17:58:17 +00:00
//--------------- setattr-------------------------------------------
2010-09-10 14:54:50 +00:00
static int pyrna_is_deferred_prop ( PyObject * value )
{
return PyTuple_CheckExact ( value ) & & PyTuple_GET_SIZE ( value ) = = 2 & & PyCallable_Check ( PyTuple_GET_ITEM ( value , 0 ) ) & & PyDict_CheckExact ( PyTuple_GET_ITEM ( value , 1 ) ) ;
}
2010-09-09 05:37:22 +00:00
2011-02-14 07:26:07 +00:00
#if 0
2011-01-25 06:54:57 +00:00
static PyObject * pyrna_struct_meta_idprop_getattro ( PyObject * cls , PyObject * attr )
2010-09-09 05:37:22 +00:00
{
2011-01-25 06:54:57 +00:00
PyObject * ret = PyType_Type . tp_getattro ( cls , attr ) ;
2011-01-27 06:48:14 +00:00
/* Allows:
* > > > bpy . types . Scene . foo = BoolProperty ( )
* > > > bpy . types . Scene . foo
* < bpy_struct , BooleanProperty ( " foo " ) >
* . . . rather then returning the defered class register tuple as checked by pyrna_is_deferred_prop ( )
*
* Disable for now , this is faking internal behavior in a way thats too tricky to maintain well . */
#if 0
if ( ret = = NULL ) { // || pyrna_is_deferred_prop(ret)
2011-01-25 06:54:57 +00:00
StructRNA * srna = srna_from_self ( cls , " StructRNA.__getattr__ " ) ;
if ( srna ) {
PropertyRNA * prop = RNA_struct_type_find_property ( srna , _PyUnicode_AsString ( attr ) ) ;
if ( prop ) {
PointerRNA tptr ;
PyErr_Clear ( ) ; /* clear error from tp_getattro */
RNA_pointer_create ( NULL , & RNA_Property , prop , & tptr ) ;
ret = pyrna_struct_CreatePyObject ( & tptr ) ;
}
}
}
2011-01-27 06:48:14 +00:00
# endif
2011-01-25 06:54:57 +00:00
return ret ;
2010-09-10 14:54:50 +00:00
}
2011-02-14 07:26:07 +00:00
# endif
2010-09-10 14:54:50 +00:00
static int pyrna_struct_meta_idprop_setattro ( PyObject * cls , PyObject * attr , PyObject * value )
{
2011-01-25 06:54:57 +00:00
StructRNA * srna = srna_from_self ( cls , " StructRNA.__setattr__ " ) ;
2010-09-10 14:54:50 +00:00
if ( srna = = NULL ) {
if ( value & & pyrna_is_deferred_prop ( value ) ) {
PyErr_Format ( PyExc_AttributeError , " pyrna_struct_meta_idprop_setattro() unable to get srna from class '%.200s' " , ( ( PyTypeObject * ) cls ) - > tp_name ) ;
2010-09-09 05:37:22 +00:00
return - 1 ;
}
2010-09-10 14:54:50 +00:00
/* srna_from_self may set an error */
2011-02-11 00:11:17 +00:00
PyErr_Clear ( ) ;
2010-09-10 14:54:50 +00:00
return PyType_Type . tp_setattro ( cls , attr , value ) ;
2010-09-09 05:37:22 +00:00
}
2010-09-10 14:54:50 +00:00
if ( value ) {
/* check if the value is a property */
if ( pyrna_is_deferred_prop ( value ) ) {
2011-01-27 06:48:14 +00:00
int ret = deferred_register_prop ( srna , attr , value ) ;
if ( ret = = - 1 ) {
/* error set */
return ret ;
}
/* pass through and assign to the classes __dict__ as well
* when the value isn ' t assigned it still creates the RNA property
* but gets confusing from script writers POV if the assigned value cant be read back . */
2010-09-10 14:54:50 +00:00
}
else {
/* remove existing property if its set or we also end up with confusement */
2011-02-01 23:53:54 +00:00
const char * attr_str = _PyUnicode_AsString ( attr ) ;
2010-09-10 14:54:50 +00:00
RNA_def_property_free_identifier ( srna , attr_str ) ; /* ignore on failier */
}
2010-09-09 05:37:22 +00:00
}
2010-09-10 14:54:50 +00:00
else { /* __delattr__ */
/* first find if this is a registered property */
2011-02-01 23:53:54 +00:00
const char * attr_str = _PyUnicode_AsString ( attr ) ;
2010-09-10 14:54:50 +00:00
int ret = RNA_def_property_free_identifier ( srna , attr_str ) ;
if ( ret = = - 1 ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " struct_meta_idprop.detattr(): '%s' not a dynamic property " , attr_str ) ;
2010-09-10 14:54:50 +00:00
return - 1 ;
}
}
2011-01-25 06:54:57 +00:00
2010-09-10 14:54:50 +00:00
/* fallback to standard py, delattr/setattr */
return PyType_Type . tp_setattro ( cls , attr , value ) ;
2010-09-09 05:37:22 +00:00
}
2011-02-11 00:11:17 +00:00
2009-11-16 19:03:40 +00:00
static int pyrna_struct_setattro ( BPy_StructRNA * self , PyObject * pyname , PyObject * value )
2008-11-29 17:58:17 +00:00
{
2011-02-01 23:53:54 +00:00
const char * name = _PyUnicode_AsString ( pyname ) ;
2010-06-14 02:05:37 +00:00
PropertyRNA * prop = NULL ;
2010-12-04 06:25:36 +00:00
# ifdef USE_PEDANTIC_WRITE
if ( rna_disallow_writes & & rna_id_write_error ( & self - > ptr , pyname ) ) {
return - 1 ;
}
2010-12-09 06:08:19 +00:00
# endif // USE_STRING_COERCE
2010-12-04 06:25:36 +00:00
2010-09-09 13:58:38 +00:00
if ( name = = NULL ) {
PyErr_SetString ( PyExc_AttributeError , " bpy_struct: __setattr__ must be a string " ) ;
return - 1 ;
}
else if ( name [ 0 ] ! = ' _ ' & & ( prop = RNA_struct_find_property ( & self - > ptr , name ) ) ) {
2010-06-14 02:05:37 +00:00
if ( ! RNA_property_editable_flag ( & self - > ptr , prop ) ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_AttributeError , " bpy_struct: attribute \" %.200s \" from \" %.200s \" is read-only " , RNA_property_identifier ( prop ) , RNA_struct_identifier ( self - > ptr . type ) ) ;
2010-06-14 02:05:37 +00:00
return - 1 ;
}
2008-11-30 03:52:07 +00:00
}
2010-06-14 02:05:37 +00:00
else if ( self - > ptr . type = = & RNA_Context ) {
/* code just raises correct error, context prop's cant be set, unless its apart of the py class */
bContext * C = self - > ptr . data ;
if ( C = = NULL ) {
PyErr_Format ( PyExc_AttributeError , " bpy_struct: Context is 'NULL', can't set \" %.200s \" from context " , name ) ;
return - 1 ;
}
else {
PointerRNA newptr ;
ListBase newlb ;
short newtype ;
int done = CTX_data_get ( C , name , & newptr , & newlb , & newtype ) ;
if ( done = = 1 ) {
PyErr_Format ( PyExc_AttributeError , " bpy_struct: Context property \" %.200s \" is read-only " , name ) ;
BLI_freelistN ( & newlb ) ;
return - 1 ;
}
BLI_freelistN ( & newlb ) ;
}
}
2008-11-30 03:52:07 +00:00
/* pyrna_py_to_prop sets its own exceptions */
2010-08-24 23:52:20 +00:00
if ( prop ) {
if ( value = = NULL ) {
PyErr_SetString ( PyExc_AttributeError , " bpy_struct: del not supported " ) ;
return - 1 ;
}
2010-10-13 23:25:08 +00:00
return pyrna_py_to_prop ( & self - > ptr , prop , NULL , value , " bpy_struct: item.attr = val: " ) ;
2010-08-24 23:52:20 +00:00
}
else {
2010-06-14 02:05:37 +00:00
return PyObject_GenericSetAttr ( ( PyObject * ) self , pyname , value ) ;
2010-08-24 23:52:20 +00:00
}
2008-11-29 13:36:08 +00:00
}
2009-11-20 10:00:54 +00:00
static PyObject * pyrna_prop_dir ( BPy_PropertyRNA * self )
{
PyObject * ret ;
PointerRNA r_ptr ;
/* Include this incase this instance is a subtype of a python class
* In these instances we may want to return a function or variable provided by the subtype
* */
ret = PyList_New ( 0 ) ;
if ( ! BPy_PropertyRNA_CheckExact ( self ) )
pyrna_dir_members_py ( ret , ( PyObject * ) self ) ;
if ( RNA_property_collection_type_get ( & self - > ptr , self - > prop , & r_ptr ) )
pyrna_dir_members_rna ( ret , & r_ptr ) ;
return ret ;
}
2010-02-15 23:43:51 +00:00
static PyObject * pyrna_prop_array_getattro ( BPy_PropertyRNA * self , PyObject * pyname )
{
return PyObject_GenericGetAttr ( ( PyObject * ) self , pyname ) ;
}
static PyObject * pyrna_prop_collection_getattro ( BPy_PropertyRNA * self , PyObject * pyname )
2009-11-03 16:07:29 +00:00
{
2011-02-01 23:53:54 +00:00
const char * name = _PyUnicode_AsString ( pyname ) ;
2009-11-03 16:07:29 +00:00
2010-09-09 13:58:38 +00:00
if ( name = = NULL ) {
PyErr_SetString ( PyExc_AttributeError , " bpy_prop_collection: __getattr__ must be a string " ) ;
return NULL ;
}
else if ( name [ 0 ] ! = ' _ ' ) {
2010-02-15 23:43:51 +00:00
PyObject * ret ;
PropertyRNA * prop ;
FunctionRNA * func ;
2009-11-13 16:37:44 +00:00
2010-02-15 23:43:51 +00:00
PointerRNA r_ptr ;
if ( RNA_property_collection_type_get ( & self - > ptr , self - > prop , & r_ptr ) ) {
if ( ( prop = RNA_struct_find_property ( & r_ptr , name ) ) ) {
ret = pyrna_prop_to_py ( & r_ptr , prop ) ;
2009-11-03 16:07:29 +00:00
2010-02-15 23:43:51 +00:00
return ret ;
}
else if ( ( func = RNA_struct_find_function ( & r_ptr , name ) ) ) {
PyObject * self_collection = pyrna_struct_CreatePyObject ( & r_ptr ) ;
ret = pyrna_func_to_py ( ( BPy_DummyPointerRNA * ) self_collection , func ) ;
Py_DECREF ( self_collection ) ;
2009-11-14 23:11:46 +00:00
2010-02-15 23:43:51 +00:00
return ret ;
2009-11-13 16:37:44 +00:00
}
2009-11-13 16:08:03 +00:00
}
2009-11-11 16:28:53 +00:00
}
2009-11-03 16:07:29 +00:00
2009-11-13 16:08:03 +00:00
/* The error raised here will be displayed */
return PyObject_GenericGetAttr ( ( PyObject * ) self , pyname ) ;
2009-11-11 16:28:53 +00:00
}
2009-11-03 16:07:29 +00:00
2009-11-13 16:08:03 +00:00
//--------------- setattr-------------------------------------------
2010-02-15 23:43:51 +00:00
static int pyrna_prop_collection_setattro ( BPy_PropertyRNA * self , PyObject * pyname , PyObject * value )
2009-11-11 16:28:53 +00:00
{
2011-02-01 23:53:54 +00:00
const char * name = _PyUnicode_AsString ( pyname ) ;
2009-11-13 16:08:03 +00:00
PropertyRNA * prop ;
2010-02-15 23:43:51 +00:00
PointerRNA r_ptr ;
2009-11-11 16:28:53 +00:00
2010-12-04 06:25:36 +00:00
# ifdef USE_PEDANTIC_WRITE
if ( rna_disallow_writes & & rna_id_write_error ( & self - > ptr , pyname ) ) {
return - 1 ;
}
2010-12-09 06:08:19 +00:00
# endif // USE_STRING_COERCE
2010-12-04 06:25:36 +00:00
2010-09-09 13:58:38 +00:00
if ( name = = NULL ) {
PyErr_SetString ( PyExc_AttributeError , " bpy_prop: __setattr__ must be a string " ) ;
return - 1 ;
}
else if ( value = = NULL ) {
2010-08-24 02:12:09 +00:00
PyErr_SetString ( PyExc_AttributeError , " bpy_prop: del not supported " ) ;
return - 1 ;
}
2010-09-09 13:58:38 +00:00
else if ( RNA_property_collection_type_get ( & self - > ptr , self - > prop , & r_ptr ) ) {
2010-02-15 23:43:51 +00:00
if ( ( prop = RNA_struct_find_property ( & r_ptr , name ) ) ) {
/* pyrna_py_to_prop sets its own exceptions */
2010-10-13 23:25:08 +00:00
return pyrna_py_to_prop ( & r_ptr , prop , NULL , value , " BPy_PropertyRNA - Attribute (setattr) : " ) ;
2009-11-13 16:08:03 +00:00
}
2009-11-03 16:07:29 +00:00
}
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_AttributeError , " bpy_prop_collection: attribute \" %.200s \" not found " , name ) ;
2009-11-13 16:08:03 +00:00
return - 1 ;
2009-11-03 16:07:29 +00:00
}
2009-11-11 16:28:53 +00:00
/* odd case, we need to be able return a python method from a tp_getset */
2010-09-02 06:35:00 +00:00
static PyObject * pyrna_prop_collection_idprop_add ( BPy_PropertyRNA * self )
2009-11-03 16:07:29 +00:00
{
2009-11-11 16:28:53 +00:00
PointerRNA r_ptr ;
2009-11-03 16:07:29 +00:00
2009-11-11 16:28:53 +00:00
RNA_property_collection_add ( & self - > ptr , self - > prop , & r_ptr ) ;
if ( ! r_ptr . data ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_prop_collection.add(): not supported for this collection " ) ;
2009-11-11 16:28:53 +00:00
return NULL ;
}
else {
return pyrna_struct_CreatePyObject ( & r_ptr ) ;
}
}
2009-11-03 16:07:29 +00:00
2010-09-02 06:35:00 +00:00
static PyObject * pyrna_prop_collection_idprop_remove ( BPy_PropertyRNA * self , PyObject * value )
2009-11-11 16:28:53 +00:00
{
2010-10-03 01:44:00 +00:00
int key = PyLong_AsLong ( value ) ;
2009-11-11 16:28:53 +00:00
if ( key = = - 1 & & PyErr_Occurred ( ) ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_prop_collection.remove(): expected one int argument " ) ;
2009-11-11 16:28:53 +00:00
return NULL ;
}
if ( ! RNA_property_collection_remove ( & self - > ptr , self - > prop , key ) ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_prop_collection.remove() not supported for this collection " ) ;
2009-11-11 16:28:53 +00:00
return NULL ;
}
2010-09-09 17:36:54 +00:00
Py_RETURN_NONE ;
2009-11-11 16:28:53 +00:00
}
2010-09-02 06:35:00 +00:00
static PyObject * pyrna_prop_collection_idprop_move ( BPy_PropertyRNA * self , PyObject * args )
2010-03-10 20:54:14 +00:00
{
int key = 0 , pos = 0 ;
if ( ! PyArg_ParseTuple ( args , " ii " , & key , & pos ) ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_prop_collection.move(): expected two ints as arguments " ) ;
2010-03-10 20:54:14 +00:00
return NULL ;
}
if ( ! RNA_property_collection_move ( & self - > ptr , self - > prop , key , pos ) ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " bpy_prop_collection.move() not supported for this collection " ) ;
2010-03-10 20:54:14 +00:00
return NULL ;
}
2010-09-09 17:36:54 +00:00
Py_RETURN_NONE ;
2010-03-10 20:54:14 +00:00
}
2010-08-23 22:10:13 +00:00
static PyObject * pyrna_struct_get_id_data ( BPy_DummyPointerRNA * self )
2009-12-13 10:46:34 +00:00
{
2010-08-23 22:10:13 +00:00
/* used for struct and pointer since both have a ptr */
2009-12-13 10:46:34 +00:00
if ( self - > ptr . id . data ) {
PointerRNA id_ptr ;
RNA_id_pointer_create ( ( ID * ) self - > ptr . id . data , & id_ptr ) ;
return pyrna_struct_CreatePyObject ( & id_ptr ) ;
}
Py_RETURN_NONE ;
}
2009-11-11 16:28:53 +00:00
/*****************************************************************************/
/* Python attributes get/set structure: */
/*****************************************************************************/
2010-08-23 22:10:13 +00:00
2009-11-11 16:28:53 +00:00
static PyGetSetDef pyrna_prop_getseters [ ] = {
2010-12-03 17:05:21 +00:00
{ ( char * ) " id_data " , ( getter ) pyrna_struct_get_id_data , ( setter ) NULL , ( char * ) " The :class:`ID` object this datablock is from or None, (not available for all data types) " , NULL } ,
2009-11-11 16:28:53 +00:00
{ NULL , NULL , NULL , NULL , NULL } /* Sentinel */
} ;
2010-08-23 22:10:13 +00:00
2009-11-11 16:28:53 +00:00
2009-12-13 10:46:34 +00:00
static PyGetSetDef pyrna_struct_getseters [ ] = {
2010-12-03 17:05:21 +00:00
{ ( char * ) " id_data " , ( getter ) pyrna_struct_get_id_data , ( setter ) NULL , ( char * ) " The :class:`ID` object this datablock is from or None, (not available for all data types) " , NULL } ,
2009-12-13 10:46:34 +00:00
{ NULL , NULL , NULL , NULL , NULL } /* Sentinel */
} ;
2011-01-06 04:01:06 +00:00
static PyObject * pyrna_prop_collection_keys ( BPy_PropertyRNA * self )
2008-11-29 13:36:08 +00:00
{
2010-02-23 11:19:55 +00:00
PyObject * ret = PyList_New ( 0 ) ;
PyObject * item ;
char name [ 256 ] , * nameptr ;
2008-11-29 13:36:08 +00:00
2010-02-23 11:19:55 +00:00
RNA_PROP_BEGIN ( & self - > ptr , itemptr , self - > prop ) {
nameptr = RNA_struct_name_get_alloc ( & itemptr , name , sizeof ( name ) ) ;
2009-06-24 14:03:55 +00:00
2010-02-23 11:19:55 +00:00
if ( nameptr ) {
/* add to python list */
item = PyUnicode_FromString ( nameptr ) ;
PyList_Append ( ret , item ) ;
Py_DECREF ( item ) ;
/* done */
if ( name ! = nameptr )
MEM_freeN ( nameptr ) ;
2008-11-29 13:36:08 +00:00
}
}
2010-02-23 11:19:55 +00:00
RNA_PROP_END ;
2011-02-11 00:11:17 +00:00
2008-11-29 13:36:08 +00:00
return ret ;
}
2011-01-06 04:01:06 +00:00
static PyObject * pyrna_prop_collection_items ( BPy_PropertyRNA * self )
2008-11-29 13:36:08 +00:00
{
2010-02-23 11:19:55 +00:00
PyObject * ret = PyList_New ( 0 ) ;
PyObject * item ;
char name [ 256 ] , * nameptr ;
int i = 0 ;
2008-11-29 13:36:08 +00:00
2010-02-23 11:19:55 +00:00
RNA_PROP_BEGIN ( & self - > ptr , itemptr , self - > prop ) {
if ( itemptr . data ) {
/* add to python list */
item = PyTuple_New ( 2 ) ;
nameptr = RNA_struct_name_get_alloc ( & itemptr , name , sizeof ( name ) ) ;
if ( nameptr ) {
PyTuple_SET_ITEM ( item , 0 , PyUnicode_FromString ( nameptr ) ) ;
if ( name ! = nameptr )
MEM_freeN ( nameptr ) ;
}
else {
PyTuple_SET_ITEM ( item , 0 , PyLong_FromSsize_t ( i ) ) ; /* a bit strange but better then returning an empty list */
2008-11-29 13:36:08 +00:00
}
2010-02-23 11:19:55 +00:00
PyTuple_SET_ITEM ( item , 1 , pyrna_struct_CreatePyObject ( & itemptr ) ) ;
PyList_Append ( ret , item ) ;
Py_DECREF ( item ) ;
i + + ;
2008-11-29 13:36:08 +00:00
}
}
2010-02-23 11:19:55 +00:00
RNA_PROP_END ;
2011-02-11 00:11:17 +00:00
2008-11-29 13:36:08 +00:00
return ret ;
}
2011-01-06 04:01:06 +00:00
static PyObject * pyrna_prop_collection_values ( BPy_PropertyRNA * self )
2008-11-29 13:36:08 +00:00
{
2011-01-07 05:33:30 +00:00
/* re-use slice*/
return pyrna_prop_collection_subscript_slice ( self , 0 , PY_SSIZE_T_MAX ) ;
2008-11-29 13:36:08 +00:00
}
2010-04-10 18:35:50 +00:00
static char pyrna_struct_get_doc [ ] =
" .. method:: get(key, default=None) \n "
" \n "
" Returns the value of the custom property assigned to key or default when not found (matches pythons dictionary function of the same name). \n "
" \n "
" :arg key: The key assosiated with the custom property. \n "
" :type key: string \n "
" :arg default: Optional argument for the value to return if *key* is not found. \n "
// " :type default: Undefined\n"
" \n "
" .. note:: Only :class:`ID`, :class:`Bone` and :class:`PoseBone` classes support custom properties. \n " ;
2009-11-23 23:17:23 +00:00
static PyObject * pyrna_struct_get ( BPy_StructRNA * self , PyObject * args )
{
IDProperty * group , * idprop ;
2011-02-01 23:53:54 +00:00
const char * key ;
2009-11-23 23:17:23 +00:00
PyObject * def = Py_None ;
if ( ! PyArg_ParseTuple ( args , " s|O:get " , & key , & def ) )
return NULL ;
/* mostly copied from BPy_IDGroup_Map_GetItem */
2010-08-19 10:16:30 +00:00
if ( RNA_struct_idprops_check ( self - > ptr . type ) = = 0 ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " this type doesn't support IDProperties " ) ;
2009-11-23 23:17:23 +00:00
return NULL ;
}
2010-08-19 10:16:30 +00:00
group = RNA_struct_idprops ( & self - > ptr , 0 ) ;
2009-11-23 23:17:23 +00:00
if ( group ) {
idprop = IDP_GetPropertyFromGroup ( group , key ) ;
if ( idprop )
return BPy_IDGroup_WrapData ( self - > ptr . id . data , idprop ) ;
}
2010-09-09 17:36:54 +00:00
return Py_INCREF ( def ) , def ;
2009-11-23 23:17:23 +00:00
}
2010-04-10 18:35:50 +00:00
static char pyrna_struct_as_pointer_doc [ ] =
" .. method:: as_pointer() \n "
" \n "
2010-09-01 15:25:22 +00:00
" Returns the memory address which holds a pointer to blenders internal data \n "
2010-04-10 18:35:50 +00:00
" \n "
2010-09-08 10:43:36 +00:00
" :return: int (memory address). \n "
2010-09-01 15:25:22 +00:00
" :rtype: int \n "
2010-04-10 18:35:50 +00:00
" \n "
" .. note:: This is intended only for advanced script writers who need to pass blender data to their own C/Python modules. \n " ;
2010-03-06 12:37:29 +00:00
static PyObject * pyrna_struct_as_pointer ( BPy_StructRNA * self )
{
2010-09-01 15:25:22 +00:00
return PyLong_FromVoidPtr ( self - > ptr . data ) ;
2010-03-06 12:37:29 +00:00
}
2011-01-06 04:01:06 +00:00
static PyObject * pyrna_prop_collection_get ( BPy_PropertyRNA * self , PyObject * args )
2009-07-09 08:06:26 +00:00
{
PointerRNA newptr ;
2011-02-11 00:11:17 +00:00
2011-02-01 23:53:54 +00:00
const char * key ;
2009-07-09 08:06:26 +00:00
PyObject * def = Py_None ;
if ( ! PyArg_ParseTuple ( args , " s|O:get " , & key , & def ) )
return NULL ;
2011-02-11 00:11:17 +00:00
2009-07-09 08:06:26 +00:00
if ( RNA_property_collection_lookup_string ( & self - > ptr , self - > prop , key , & newptr ) )
return pyrna_struct_CreatePyObject ( & newptr ) ;
2010-09-09 17:36:54 +00:00
return Py_INCREF ( def ) , def ;
2009-07-09 08:06:26 +00:00
}
2011-02-01 23:53:54 +00:00
static void foreach_attr_type ( BPy_PropertyRNA * self , const char * attr ,
2009-06-30 12:52:16 +00:00
/* values to assign */
RawPropertyType * raw_type , int * attr_tot , int * attr_signed )
{
PropertyRNA * prop ;
2010-01-04 22:30:09 +00:00
* raw_type = PROP_RAW_UNSET ;
2009-06-30 12:52:16 +00:00
* attr_tot = 0 ;
2009-07-26 18:18:14 +00:00
* attr_signed = FALSE ;
2009-06-30 12:52:16 +00:00
2010-01-05 13:55:51 +00:00
/* note: this is fail with zero length lists, so dont let this get caled in that case */
2009-06-30 12:52:16 +00:00
RNA_PROP_BEGIN ( & self - > ptr , itemptr , self - > prop ) {
prop = RNA_struct_find_property ( & itemptr , attr ) ;
* raw_type = RNA_property_raw_type ( prop ) ;
Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
Mesh.add_vertices([(x, y, z), (x, y, z), ...])
Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
2009-08-25 17:06:36 +00:00
* attr_tot = RNA_property_array_length ( & itemptr , prop ) ;
2009-07-26 18:18:14 +00:00
* attr_signed = ( RNA_property_subtype ( prop ) = = PROP_UNSIGNED ) ? FALSE : TRUE ;
2009-06-30 12:52:16 +00:00
break ;
}
RNA_PROP_END ;
}
2011-01-06 04:01:06 +00:00
/* pyrna_prop_collection_foreach_get/set both use this */
2009-06-30 12:52:16 +00:00
static int foreach_parse_args (
BPy_PropertyRNA * self , PyObject * args ,
/*values to assign */
2011-02-01 23:53:54 +00:00
const char * * attr , PyObject * * seq , int * tot , int * size , RawPropertyType * raw_type , int * attr_tot , int * attr_signed )
2009-06-30 12:52:16 +00:00
{
2009-07-01 13:31:36 +00:00
#if 0
2009-06-30 12:52:16 +00:00
int array_tot ;
int target_tot ;
2009-07-01 13:31:36 +00:00
# endif
2009-06-30 12:52:16 +00:00
2010-01-04 22:30:09 +00:00
* size = * attr_tot = * attr_signed = FALSE ;
* raw_type = PROP_RAW_UNSET ;
2009-06-30 12:52:16 +00:00
if ( ! PyArg_ParseTuple ( args , " sO " , attr , seq ) | | ( ! PySequence_Check ( * seq ) & & PyObject_CheckBuffer ( * seq ) ) ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_TypeError , " foreach_get(attr, sequence) expects a string and a sequence " ) ;
2009-06-30 12:52:16 +00:00
return - 1 ;
}
2011-01-09 14:53:18 +00:00
* tot = PySequence_Size ( * seq ) ; // TODO - buffer may not be a sequence! array.array() is tho.
2009-06-30 12:52:16 +00:00
if ( * tot > 0 ) {
foreach_attr_type ( self , * attr , raw_type , attr_tot , attr_signed ) ;
* size = RNA_raw_type_sizeof ( * raw_type ) ;
#if 0 // works fine but not strictly needed, we could allow RNA_property_collection_raw_* to do the checks
if ( ( * attr_tot ) < 1 )
* attr_tot = 1 ;
if ( RNA_property_type ( self - > prop ) = = PROP_COLLECTION )
array_tot = RNA_property_collection_length ( & self - > ptr , self - > prop ) ;
else
Implemented dynamic and multidimensional array support in RNA.
Example code: http://www.pasteall.org/7332/c.
New API functions: http://www.pasteall.org/7330/c.
Maximum number of dimensions is currently limited to 3, but can be increased arbitrarily if needed.
What this means for ID property access:
* MeshFace.verts - dynamic array, size 3 or 4 depending on MFace.v4
* MeshTextureFace.uv - dynamic, 2-dimensional array, size depends on MFace.v4
* Object.matrix - 2-dimensional array
What this means for functions:
* more intuitive API possibility, for example:
Mesh.add_vertices([(x, y, z), (x, y, z), ...])
Mesh.add_faces([(1, 2, 3), (4, 5, 6), ...])
Python part is not complete yet, e.g. it is possible to:
MeshFace.verts = (1, 2, 3) # even if Mesh.verts is (1, 2, 3, 4) and vice-versa
MeshTextureFace.uv = [(0.0, 0.0)] * 4 # only if a corresponding MFace is a quad
but the following won't work:
MeshTextureFace.uv[3] = (0.0, 0.0) # setting uv[3] modifies MTFace.uv[1][0] instead of MTFace.uv[3]
2009-08-25 17:06:36 +00:00
array_tot = RNA_property_array_length ( & self - > ptr , self - > prop ) ;
2009-06-30 12:52:16 +00:00
target_tot = array_tot * ( * attr_tot ) ;
/* rna_access.c - rna_raw_access(...) uses this same method */
if ( target_tot ! = ( * tot ) ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " foreach_get(attr, sequence) sequence length mismatch given %d, needed %d " , * tot , target_tot ) ;
2009-06-30 12:52:16 +00:00
return - 1 ;
}
# endif
}
2010-01-05 13:55:51 +00:00
/* check 'attr_tot' otherwise we dont know if any values were set
* this isnt ideal because it means running on an empty list may fail silently when its not compatible . */
if ( * size = = 0 & & * attr_tot ! = 0 ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_AttributeError , " attribute does not support foreach method " ) ;
2010-01-04 22:30:09 +00:00
return - 1 ;
}
2009-06-30 12:52:16 +00:00
return 0 ;
}
static int foreach_compat_buffer ( RawPropertyType raw_type , int attr_signed , const char * format )
{
char f = format ? * format : ' B ' ; /* B is assumed when not set */
switch ( raw_type ) {
case PROP_RAW_CHAR :
if ( attr_signed ) return ( f = = ' b ' ) ? 1 : 0 ;
else return ( f = = ' B ' ) ? 1 : 0 ;
case PROP_RAW_SHORT :
if ( attr_signed ) return ( f = = ' h ' ) ? 1 : 0 ;
else return ( f = = ' H ' ) ? 1 : 0 ;
case PROP_RAW_INT :
if ( attr_signed ) return ( f = = ' i ' ) ? 1 : 0 ;
else return ( f = = ' I ' ) ? 1 : 0 ;
case PROP_RAW_FLOAT :
return ( f = = ' f ' ) ? 1 : 0 ;
case PROP_RAW_DOUBLE :
return ( f = = ' d ' ) ? 1 : 0 ;
2010-01-08 13:52:38 +00:00
case PROP_RAW_UNSET :
return 0 ;
2009-06-30 12:52:16 +00:00
}
return 0 ;
}
static PyObject * foreach_getset ( BPy_PropertyRNA * self , PyObject * args , int set )
{
2009-10-21 17:56:26 +00:00
PyObject * item = NULL ;
2009-11-11 10:51:40 +00:00
int i = 0 , ok = 0 , buffer_is_compat ;
2009-06-30 12:52:16 +00:00
void * array = NULL ;
/* get/set both take the same args currently */
2011-02-01 23:53:54 +00:00
const char * attr ;
2009-06-30 12:52:16 +00:00
PyObject * seq ;
int tot , size , attr_tot , attr_signed ;
RawPropertyType raw_type ;
if ( foreach_parse_args ( self , args , & attr , & seq , & tot , & size , & raw_type , & attr_tot , & attr_signed ) < 0 )
return NULL ;
if ( tot = = 0 )
Py_RETURN_NONE ;
if ( set ) { /* get the array from python */
2009-07-26 18:18:14 +00:00
buffer_is_compat = FALSE ;
2009-06-30 12:52:16 +00:00
if ( PyObject_CheckBuffer ( seq ) ) {
Py_buffer buf ;
PyObject_GetBuffer ( seq , & buf , PyBUF_SIMPLE | PyBUF_FORMAT ) ;
2009-07-01 13:31:36 +00:00
/* check if the buffer matches */
2009-06-30 12:52:16 +00:00
buffer_is_compat = foreach_compat_buffer ( raw_type , attr_signed , buf . format ) ;
if ( buffer_is_compat ) {
ok = RNA_property_collection_raw_set ( NULL , & self - > ptr , self - > prop , attr , buf . buf , raw_type , tot ) ;
}
PyBuffer_Release ( & buf ) ;
}
/* could not use the buffer, fallback to sequence */
if ( ! buffer_is_compat ) {
array = PyMem_Malloc ( size * tot ) ;
for ( ; i < tot ; i + + ) {
item = PySequence_GetItem ( seq , i ) ;
switch ( raw_type ) {
case PROP_RAW_CHAR :
2010-10-03 01:44:00 +00:00
( ( char * ) array ) [ i ] = ( char ) PyLong_AsLong ( item ) ;
2009-06-30 12:52:16 +00:00
break ;
case PROP_RAW_SHORT :
2010-10-03 01:44:00 +00:00
( ( short * ) array ) [ i ] = ( short ) PyLong_AsLong ( item ) ;
2009-06-30 12:52:16 +00:00
break ;
case PROP_RAW_INT :
2010-10-03 01:44:00 +00:00
( ( int * ) array ) [ i ] = ( int ) PyLong_AsLong ( item ) ;
2009-06-30 12:52:16 +00:00
break ;
case PROP_RAW_FLOAT :
( ( float * ) array ) [ i ] = ( float ) PyFloat_AsDouble ( item ) ;
break ;
case PROP_RAW_DOUBLE :
( ( double * ) array ) [ i ] = ( double ) PyFloat_AsDouble ( item ) ;
break ;
2010-01-08 13:52:38 +00:00
case PROP_RAW_UNSET :
/* should never happen */
2011-01-09 15:12:08 +00:00
BLI_assert ( ! " Invalid array type - set " ) ;
2010-01-08 13:52:38 +00:00
break ;
2009-06-30 12:52:16 +00:00
}
Py_DECREF ( item ) ;
}
ok = RNA_property_collection_raw_set ( NULL , & self - > ptr , self - > prop , attr , array , raw_type , tot ) ;
}
}
else {
2009-07-26 18:18:14 +00:00
buffer_is_compat = FALSE ;
2009-06-30 12:52:16 +00:00
if ( PyObject_CheckBuffer ( seq ) ) {
Py_buffer buf ;
PyObject_GetBuffer ( seq , & buf , PyBUF_SIMPLE | PyBUF_FORMAT ) ;
/* check if the buffer matches, TODO - signed/unsigned types */
buffer_is_compat = foreach_compat_buffer ( raw_type , attr_signed , buf . format ) ;
if ( buffer_is_compat ) {
ok = RNA_property_collection_raw_get ( NULL , & self - > ptr , self - > prop , attr , buf . buf , raw_type , tot ) ;
}
PyBuffer_Release ( & buf ) ;
}
/* could not use the buffer, fallback to sequence */
if ( ! buffer_is_compat ) {
array = PyMem_Malloc ( size * tot ) ;
ok = RNA_property_collection_raw_get ( NULL , & self - > ptr , self - > prop , attr , array , raw_type , tot ) ;
if ( ! ok ) i = tot ; /* skip the loop */
for ( ; i < tot ; i + + ) {
switch ( raw_type ) {
case PROP_RAW_CHAR :
item = PyLong_FromSsize_t ( ( Py_ssize_t ) ( ( char * ) array ) [ i ] ) ;
break ;
case PROP_RAW_SHORT :
item = PyLong_FromSsize_t ( ( Py_ssize_t ) ( ( short * ) array ) [ i ] ) ;
break ;
case PROP_RAW_INT :
item = PyLong_FromSsize_t ( ( Py_ssize_t ) ( ( int * ) array ) [ i ] ) ;
break ;
case PROP_RAW_FLOAT :
item = PyFloat_FromDouble ( ( double ) ( ( float * ) array ) [ i ] ) ;
break ;
case PROP_RAW_DOUBLE :
item = PyFloat_FromDouble ( ( double ) ( ( double * ) array ) [ i ] ) ;
break ;
2010-01-08 13:52:38 +00:00
case PROP_RAW_UNSET :
/* should never happen */
2011-01-09 15:12:08 +00:00
BLI_assert ( ! " Invalid array type - get " ) ;
2010-01-08 13:52:38 +00:00
break ;
2009-06-30 12:52:16 +00:00
}
PySequence_SetItem ( seq , i , item ) ;
Py_DECREF ( item ) ;
}
}
}
2009-12-08 09:40:30 +00:00
if ( array )
PyMem_Free ( array ) ;
2009-06-30 12:52:16 +00:00
if ( PyErr_Occurred ( ) ) {
/* Maybe we could make our own error */
PyErr_Print ( ) ;
PyErr_SetString ( PyExc_SystemError , " could not access the py sequence " ) ;
return NULL ;
}
if ( ! ok ) {
PyErr_SetString ( PyExc_SystemError , " internal error setting the array " ) ;
return NULL ;
}
Py_RETURN_NONE ;
}
2011-01-18 11:27:52 +00:00
static char pyrna_prop_collection_foreach_get_doc [ ] =
" .. method:: foreach_get(attr, seq) \n "
" \n "
" This is a function to give fast access to attribites within a collection. \n "
" \n "
" .. code-block:: python \n "
" \n "
" collection.foreach_get(someseq, attr) \n "
" \n "
" # Python equivelent \n "
" for i in range(len(seq)): someseq[i] = getattr(collection, attr) \n "
" \n "
;
2011-01-06 04:01:06 +00:00
static PyObject * pyrna_prop_collection_foreach_get ( BPy_PropertyRNA * self , PyObject * args )
2009-06-30 12:52:16 +00:00
{
return foreach_getset ( self , args , 0 ) ;
}
2011-01-18 11:27:52 +00:00
static char pyrna_prop_collection_foreach_set_doc [ ] =
" .. method:: foreach_set(attr, seq) \n "
" \n "
" This is a function to give fast access to attribites within a collection. \n "
" \n "
" .. code-block:: python \n "
" \n "
" collection.foreach_set(seq, attr) \n "
" \n "
" # Python equivelent \n "
" for i in range(len(seq)): setattr(collection[i], attr, seq[i]) \n "
" \n "
;
2011-01-06 04:01:06 +00:00
static PyObject * pyrna_prop_collection_foreach_set ( BPy_PropertyRNA * self , PyObject * args )
2009-06-30 12:52:16 +00:00
{
return foreach_getset ( self , args , 1 ) ;
}
2008-12-02 15:27:10 +00:00
/* A bit of a kludge, make a list out of a collection or array,
* then return the lists iter function , not especially fast but convenient for now */
2011-02-13 10:52:18 +00:00
static PyObject * pyrna_prop_array_iter ( BPy_PropertyArrayRNA * self )
2008-12-02 15:27:10 +00:00
{
/* Try get values from a collection */
2009-09-15 10:01:20 +00:00
PyObject * ret ;
2010-02-09 19:22:57 +00:00
PyObject * iter = NULL ;
2010-02-15 23:43:51 +00:00
int len = pyrna_prop_array_length ( self ) ;
ret = pyrna_prop_array_subscript_slice ( self , & self - > ptr , self - > prop , 0 , len , len ) ;
2011-02-11 00:11:17 +00:00
2010-02-15 23:43:51 +00:00
/* we know this is a list so no need to PyIter_Check
* otherwise it could be NULL ( unlikely ) if conversion failed */
if ( ret ) {
iter = PyObject_GetIter ( ret ) ;
Py_DECREF ( ret ) ;
2008-12-02 15:27:10 +00:00
}
2010-02-15 23:43:51 +00:00
return iter ;
}
2011-02-13 10:52:18 +00:00
static PyObject * pyrna_prop_collection_iter ( BPy_PropertyRNA * self )
2010-02-15 23:43:51 +00:00
{
/* Try get values from a collection */
PyObject * ret ;
PyObject * iter = NULL ;
2011-01-06 04:01:06 +00:00
ret = pyrna_prop_collection_values ( self ) ;
2011-02-11 00:11:17 +00:00
2010-02-09 19:22:57 +00:00
/* we know this is a list so no need to PyIter_Check
* otherwise it could be NULL ( unlikely ) if conversion failed */
if ( ret ) {
iter = PyObject_GetIter ( ret ) ;
Py_DECREF ( ret ) ;
}
2009-09-15 10:01:20 +00:00
return iter ;
2008-12-02 15:27:10 +00:00
}
2009-03-11 17:28:37 +00:00
static struct PyMethodDef pyrna_struct_methods [ ] = {
2009-07-08 09:23:49 +00:00
2009-11-16 20:16:45 +00:00
/* only for PointerRNA's with ID'props */
2010-04-10 18:35:50 +00:00
{ " keys " , ( PyCFunction ) pyrna_struct_keys , METH_NOARGS , pyrna_struct_keys_doc } ,
{ " values " , ( PyCFunction ) pyrna_struct_values , METH_NOARGS , pyrna_struct_values_doc } ,
{ " items " , ( PyCFunction ) pyrna_struct_items , METH_NOARGS , pyrna_struct_items_doc } ,
2009-11-16 20:16:45 +00:00
2010-04-10 18:35:50 +00:00
{ " get " , ( PyCFunction ) pyrna_struct_get , METH_VARARGS , pyrna_struct_get_doc } ,
2009-11-23 23:17:23 +00:00
2010-04-10 18:35:50 +00:00
{ " as_pointer " , ( PyCFunction ) pyrna_struct_as_pointer , METH_NOARGS , pyrna_struct_as_pointer_doc } ,
2010-03-06 12:37:29 +00:00
2010-05-10 18:47:03 +00:00
{ " keyframe_insert " , ( PyCFunction ) pyrna_struct_keyframe_insert , METH_VARARGS | METH_KEYWORDS , pyrna_struct_keyframe_insert_doc } ,
{ " keyframe_delete " , ( PyCFunction ) pyrna_struct_keyframe_delete , METH_VARARGS | METH_KEYWORDS , pyrna_struct_keyframe_delete_doc } ,
2010-04-06 07:49:10 +00:00
{ " driver_add " , ( PyCFunction ) pyrna_struct_driver_add , METH_VARARGS , pyrna_struct_driver_add_doc } ,
2010-04-11 09:13:37 +00:00
{ " driver_remove " , ( PyCFunction ) pyrna_struct_driver_remove , METH_VARARGS , pyrna_struct_driver_remove_doc } ,
2010-04-10 18:35:50 +00:00
{ " is_property_set " , ( PyCFunction ) pyrna_struct_is_property_set , METH_VARARGS , pyrna_struct_is_property_set_doc } ,
{ " is_property_hidden " , ( PyCFunction ) pyrna_struct_is_property_hidden , METH_VARARGS , pyrna_struct_is_property_hidden_doc } ,
2010-08-23 05:36:21 +00:00
{ " path_resolve " , ( PyCFunction ) pyrna_struct_path_resolve , METH_VARARGS , pyrna_struct_path_resolve_doc } ,
2010-04-06 07:49:10 +00:00
{ " path_from_id " , ( PyCFunction ) pyrna_struct_path_from_id , METH_VARARGS , pyrna_struct_path_from_id_doc } ,
2010-08-25 01:51:38 +00:00
{ " type_recast " , ( PyCFunction ) pyrna_struct_type_recast , METH_NOARGS , pyrna_struct_type_recast_doc } ,
2009-06-30 12:52:16 +00:00
{ " __dir__ " , ( PyCFunction ) pyrna_struct_dir , METH_NOARGS , NULL } ,
2010-02-27 13:27:06 +00:00
/* experemental */
{ " callback_add " , ( PyCFunction ) pyrna_callback_add , METH_VARARGS , NULL } ,
{ " callback_remove " , ( PyCFunction ) pyrna_callback_remove , METH_VARARGS , NULL } ,
2008-12-29 12:04:25 +00:00
{ NULL , NULL , 0 , NULL }
2009-03-11 17:28:37 +00:00
} ;
2008-11-29 13:36:08 +00:00
static struct PyMethodDef pyrna_prop_methods [ ] = {
2010-04-06 07:49:10 +00:00
{ " path_from_id " , ( PyCFunction ) pyrna_prop_path_from_id , METH_NOARGS , pyrna_prop_path_from_id_doc } ,
2010-02-15 23:43:51 +00:00
{ " __dir__ " , ( PyCFunction ) pyrna_prop_dir , METH_NOARGS , NULL } ,
{ NULL , NULL , 0 , NULL }
} ;
static struct PyMethodDef pyrna_prop_array_methods [ ] = {
{ NULL , NULL , 0 , NULL }
} ;
static struct PyMethodDef pyrna_prop_collection_methods [ ] = {
2011-01-18 11:27:52 +00:00
{ " foreach_get " , ( PyCFunction ) pyrna_prop_collection_foreach_get , METH_VARARGS , pyrna_prop_collection_foreach_get_doc } ,
{ " foreach_set " , ( PyCFunction ) pyrna_prop_collection_foreach_set , METH_VARARGS , pyrna_prop_collection_foreach_set_doc } ,
2010-02-16 19:27:38 +00:00
2011-01-06 04:01:06 +00:00
{ " keys " , ( PyCFunction ) pyrna_prop_collection_keys , METH_NOARGS , NULL } ,
{ " items " , ( PyCFunction ) pyrna_prop_collection_items , METH_NOARGS , NULL } ,
{ " values " , ( PyCFunction ) pyrna_prop_collection_values , METH_NOARGS , NULL } ,
2011-02-11 00:11:17 +00:00
2011-01-06 04:01:06 +00:00
{ " get " , ( PyCFunction ) pyrna_prop_collection_get , METH_VARARGS , NULL } ,
2010-09-02 06:35:00 +00:00
{ NULL , NULL , 0 , NULL }
} ;
2009-06-30 12:52:16 +00:00
2010-09-02 06:35:00 +00:00
static struct PyMethodDef pyrna_prop_collection_idprop_methods [ ] = {
{ " add " , ( PyCFunction ) pyrna_prop_collection_idprop_add , METH_NOARGS , NULL } ,
{ " remove " , ( PyCFunction ) pyrna_prop_collection_idprop_remove , METH_O , NULL } ,
{ " move " , ( PyCFunction ) pyrna_prop_collection_idprop_move , METH_VARARGS , NULL } ,
2008-11-29 13:36:08 +00:00
{ NULL , NULL , 0 , NULL }
} ;
2008-12-01 16:59:18 +00:00
/* only needed for subtyping, so a new class gets a valid BPy_StructRNA
* todo - also accept useful args */
2011-02-14 11:30:35 +00:00
static PyObject * pyrna_struct_new ( PyTypeObject * type , PyObject * args , PyObject * UNUSED ( kwds ) )
{
if ( PyTuple_GET_SIZE ( args ) = = 1 ) {
BPy_StructRNA * base = ( BPy_StructRNA * ) PyTuple_GET_ITEM ( args , 0 ) ;
if ( type = = Py_TYPE ( base ) ) {
Py_INCREF ( base ) ;
return ( PyObject * ) base ;
}
else if ( PyType_IsSubtype ( type , & pyrna_struct_Type ) ) {
/* this almost never runs, only when using user defined subclasses of built-in object.
* this isnt common since its NOT related to registerable subclasses . eg :
> > > class MyObSubclass ( bpy . types . Object ) :
. . . def test_func ( self ) :
. . . print ( 100 )
. . .
> > > myob = MyObSubclass ( bpy . context . object )
> > > myob . test_func ( )
100
*
* Keep this since it could be useful .
*/
BPy_StructRNA * ret ;
if ( ( ret = ( BPy_StructRNA * ) type - > tp_alloc ( type , 0 ) ) ) {
ret - > ptr = base - > ptr ;
}
/* pass on exception & NULL if tp_alloc fails */
return ( PyObject * ) ret ;
}
2011-02-11 00:11:17 +00:00
2011-02-14 11:30:35 +00:00
/* error, invalid type given */
PyErr_Format ( PyExc_TypeError , " bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct " , type - > tp_name ) ;
2008-12-01 16:59:18 +00:00
return NULL ;
}
2010-07-28 12:11:40 +00:00
else {
2011-02-14 11:30:35 +00:00
PyErr_Format ( PyExc_TypeError , " bpy_struct.__new__(type): expected a single argument " ) ;
2010-07-28 12:11:40 +00:00
return NULL ;
}
2008-12-01 16:59:18 +00:00
}
/* only needed for subtyping, so a new class gets a valid BPy_StructRNA
* todo - also accept useful args */
2010-10-13 23:25:08 +00:00
static PyObject * pyrna_prop_new ( PyTypeObject * type , PyObject * args , PyObject * UNUSED ( kwds ) ) {
2008-12-01 16:59:18 +00:00
2010-07-28 12:11:40 +00:00
BPy_PropertyRNA * base ;
2011-02-11 00:11:17 +00:00
2010-07-28 12:11:40 +00:00
if ( ! PyArg_ParseTuple ( args , " O!:bpy_prop.__new__ " , & pyrna_prop_Type , & base ) )
2008-12-01 16:59:18 +00:00
return NULL ;
2011-02-11 00:11:17 +00:00
2010-07-28 12:11:40 +00:00
if ( type = = Py_TYPE ( base ) ) {
Py_INCREF ( base ) ;
return ( PyObject * ) base ;
} else if ( PyType_IsSubtype ( type , & pyrna_prop_Type ) ) {
2008-12-01 16:59:18 +00:00
BPy_PropertyRNA * ret = ( BPy_PropertyRNA * ) type - > tp_alloc ( type , 0 ) ;
ret - > ptr = base - > ptr ;
ret - > prop = base - > prop ;
return ( PyObject * ) ret ;
}
2010-07-28 12:11:40 +00:00
else {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop " , type - > tp_name ) ;
2010-07-28 12:11:40 +00:00
return NULL ;
}
2008-12-01 16:59:18 +00:00
}
2011-02-13 10:52:18 +00:00
static PyObject * pyrna_param_to_py ( PointerRNA * ptr , PropertyRNA * prop , void * data )
2009-04-07 00:49:39 +00:00
{
PyObject * ret ;
2009-04-19 13:37:59 +00:00
int type = RNA_property_type ( prop ) ;
2010-01-08 13:52:38 +00:00
int flag = RNA_property_flag ( prop ) ;
2009-04-07 00:49:39 +00:00
2009-09-15 10:01:20 +00:00
if ( RNA_property_array_check ( ptr , prop ) ) {
2010-10-05 21:22:33 +00:00
int a , len ;
2010-01-24 10:51:59 +00:00
if ( flag & PROP_DYNAMIC ) {
2010-08-31 11:31:21 +00:00
ParameterDynAlloc * data_alloc = data ;
len = data_alloc - > array_tot ;
data = data_alloc - > array ;
2010-01-24 10:51:59 +00:00
}
else
len = RNA_property_array_length ( ptr , prop ) ;
2009-09-15 10:01:20 +00:00
2009-04-07 00:49:39 +00:00
/* resolve the array from a new pytype */
2009-09-06 15:13:57 +00:00
/* kazanbas: TODO make multidim sequences here */
2009-04-07 00:49:39 +00:00
switch ( type ) {
case PROP_BOOLEAN :
2010-01-04 13:29:55 +00:00
ret = PyTuple_New ( len ) ;
2009-04-07 00:49:39 +00:00
for ( a = 0 ; a < len ; a + + )
PyTuple_SET_ITEM ( ret , a , PyBool_FromLong ( ( ( int * ) data ) [ a ] ) ) ;
break ;
case PROP_INT :
2010-01-04 13:29:55 +00:00
ret = PyTuple_New ( len ) ;
2009-04-07 00:49:39 +00:00
for ( a = 0 ; a < len ; a + + )
PyTuple_SET_ITEM ( ret , a , PyLong_FromSsize_t ( ( Py_ssize_t ) ( ( int * ) data ) [ a ] ) ) ;
break ;
case PROP_FLOAT :
2010-01-04 13:29:55 +00:00
switch ( RNA_property_subtype ( prop ) ) {
2010-12-09 06:08:19 +00:00
# ifdef USE_MATHUTILS
2010-01-04 13:29:55 +00:00
case PROP_ALL_VECTOR_SUBTYPES :
ret = newVectorObject ( data , len , Py_NEW , NULL ) ;
break ;
case PROP_MATRIX :
if ( len = = 16 ) {
ret = newMatrixObject ( data , 4 , 4 , Py_NEW , NULL ) ;
break ;
}
else if ( len = = 9 ) {
ret = newMatrixObject ( data , 3 , 3 , Py_NEW , NULL ) ;
break ;
}
/* pass through */
2010-12-09 06:08:19 +00:00
# endif
2010-01-04 13:29:55 +00:00
default :
ret = PyTuple_New ( len ) ;
for ( a = 0 ; a < len ; a + + )
PyTuple_SET_ITEM ( ret , a , PyFloat_FromDouble ( ( ( float * ) data ) [ a ] ) ) ;
}
2009-04-07 00:49:39 +00:00
break ;
default :
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " RNA Error: unknown array type \" %d \" (pyrna_param_to_py) " , type ) ;
2009-04-07 00:49:39 +00:00
ret = NULL ;
break ;
}
}
else {
/* see if we can coorce into a python type - PropertyType */
switch ( type ) {
case PROP_BOOLEAN :
ret = PyBool_FromLong ( * ( int * ) data ) ;
break ;
case PROP_INT :
ret = PyLong_FromSsize_t ( ( Py_ssize_t ) * ( int * ) data ) ;
break ;
case PROP_FLOAT :
ret = PyFloat_FromDouble ( * ( float * ) data ) ;
break ;
case PROP_STRING :
{
2010-08-28 12:34:22 +00:00
char * data_ch ;
PyObject * value_coerce = NULL ;
int subtype = RNA_property_subtype ( prop ) ;
if ( flag & PROP_THICK_WRAP )
data_ch = ( char * ) data ;
2010-01-08 13:52:38 +00:00
else
2010-08-28 12:34:22 +00:00
data_ch = * ( char * * ) data ;
# ifdef USE_STRING_COERCE
if ( ELEM3 ( subtype , PROP_FILEPATH , PROP_DIRPATH , PROP_FILENAME ) ) {
2010-09-01 14:13:48 +00:00
ret = PyC_UnicodeFromByte ( data_ch ) ;
2010-08-28 12:34:22 +00:00
}
else {
ret = PyUnicode_FromString ( data_ch ) ;
}
# else
ret = PyUnicode_FromString ( data_ch ) ;
# endif
# ifdef USE_STRING_COERCE
Py_XDECREF ( value_coerce ) ;
# endif
2009-04-07 00:49:39 +00:00
break ;
}
case PROP_ENUM :
{
2009-12-07 00:16:57 +00:00
ret = pyrna_enum_to_py ( ptr , prop , * ( int * ) data ) ;
2009-04-07 00:49:39 +00:00
break ;
}
case PROP_POINTER :
{
PointerRNA newptr ;
2011-02-14 03:15:55 +00:00
StructRNA * ptype = RNA_property_pointer_type ( ptr , prop ) ;
2009-04-07 00:49:39 +00:00
2009-06-16 00:52:21 +00:00
if ( flag & PROP_RNAPTR ) {
2009-04-07 00:49:39 +00:00
/* in this case we get the full ptr */
newptr = * ( PointerRNA * ) data ;
}
else {
2011-02-14 03:15:55 +00:00
if ( RNA_struct_is_ID ( ptype ) ) {
2009-07-28 01:06:56 +00:00
RNA_id_pointer_create ( * ( void * * ) data , & newptr ) ;
} else {
2009-11-16 09:20:21 +00:00
/* note: this is taken from the function's ID pointer
* and will break if a function returns a pointer from
* another ID block , watch this ! - it should at least be
* easy to debug since they are all ID ' s */
2011-02-14 03:15:55 +00:00
RNA_pointer_create ( ptr - > id . data , ptype , * ( void * * ) data , & newptr ) ;
2009-07-28 01:06:56 +00:00
}
2009-04-07 00:49:39 +00:00
}
if ( newptr . data ) {
ret = pyrna_struct_CreatePyObject ( & newptr ) ;
} else {
ret = Py_None ;
Py_INCREF ( ret ) ;
}
break ;
}
case PROP_COLLECTION :
2009-06-27 01:10:39 +00:00
{
ListBase * lb = ( ListBase * ) data ;
CollectionPointerLink * link ;
PyObject * linkptr ;
ret = PyList_New ( 0 ) ;
for ( link = lb - > first ; link ; link = link - > next ) {
linkptr = pyrna_struct_CreatePyObject ( & link - > ptr ) ;
PyList_Append ( ret , linkptr ) ;
Py_DECREF ( linkptr ) ;
}
2009-04-07 00:49:39 +00:00
break ;
2009-06-27 01:10:39 +00:00
}
2009-04-07 00:49:39 +00:00
default :
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " RNA Error: unknown type \" %d \" (pyrna_param_to_py) " , type ) ;
2009-04-07 00:49:39 +00:00
ret = NULL ;
break ;
}
}
return ret ;
}
2009-11-16 19:03:40 +00:00
static PyObject * pyrna_func_call ( PyObject * self , PyObject * args , PyObject * kw )
2009-04-09 13:20:48 +00:00
{
2009-11-11 16:28:53 +00:00
/* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here */
PointerRNA * self_ptr = & ( ( ( BPy_DummyPointerRNA * ) PyTuple_GET_ITEM ( self , 0 ) ) - > ptr ) ;
2010-02-12 21:14:01 +00:00
FunctionRNA * self_func = PyCapsule_GetPointer ( PyTuple_GET_ITEM ( self , 1 ) , NULL ) ;
2009-04-09 13:20:48 +00:00
2009-04-07 00:49:39 +00:00
PointerRNA funcptr ;
2009-07-17 02:31:28 +00:00
ParameterList parms ;
2009-04-07 00:49:39 +00:00
ParameterIterator iter ;
2010-01-02 10:42:38 +00:00
PropertyRNA * parm ;
2009-04-07 00:49:39 +00:00
PyObject * ret , * item ;
2010-02-26 12:28:44 +00:00
int i , pyargs_len , pykw_len , parms_len , ret_len , flag , err = 0 , kw_tot = 0 , kw_arg ;
2009-07-17 02:31:28 +00:00
const char * parm_id ;
2010-01-02 10:42:38 +00:00
PropertyRNA * pret_single = NULL ;
void * retdata_single = NULL ;
2009-04-07 00:49:39 +00:00
2009-07-17 12:26:40 +00:00
/* Should never happen but it does in rare cases */
2011-01-09 15:12:08 +00:00
BLI_assert ( self_ptr ! = NULL ) ;
2010-12-15 10:22:26 +00:00
2009-07-17 12:26:40 +00:00
if ( self_ptr = = NULL ) {
PyErr_SetString ( PyExc_RuntimeError , " rna functions internal rna pointer is NULL, this is a bug. aborting " ) ;
return NULL ;
}
2011-02-11 00:11:17 +00:00
2009-07-17 12:26:40 +00:00
if ( self_func = = NULL ) {
2009-07-23 13:48:15 +00:00
PyErr_Format ( PyExc_RuntimeError , " %.200s.<unknown>(): rna function internal function is NULL, this is a bug. aborting " , RNA_struct_identifier ( self_ptr - > type ) ) ;
2009-07-17 12:26:40 +00:00
return NULL ;
}
2011-02-11 00:11:17 +00:00
2009-11-16 09:20:21 +00:00
/* include the ID pointer for pyrna_param_to_py() so we can include the
* ID pointer on return values , this only works when returned values have
* the same ID as the functions . */
RNA_pointer_create ( self_ptr - > id . data , & RNA_Function , self_func , & funcptr ) ;
2009-04-07 00:49:39 +00:00
2010-02-26 12:28:44 +00:00
pyargs_len = PyTuple_GET_SIZE ( args ) ;
pykw_len = kw ? PyDict_Size ( kw ) : 0 ;
2009-04-07 00:49:39 +00:00
2009-07-17 02:31:28 +00:00
RNA_parameter_list_create ( & parms , self_ptr , self_func ) ;
RNA_parameter_list_begin ( & parms , & iter ) ;
2010-03-23 15:04:06 +00:00
parms_len = RNA_parameter_list_arg_count ( & parms ) ;
2010-01-02 10:42:38 +00:00
ret_len = 0 ;
2009-07-17 02:31:28 +00:00
2010-02-26 12:28:44 +00:00
if ( pyargs_len + pykw_len > parms_len ) {
2010-01-02 19:01:19 +00:00
RNA_parameter_list_end ( & iter ) ;
2010-02-26 12:28:44 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s.%.200s(): takes at most %d arguments, got %d " , RNA_struct_identifier ( self_ptr - > type ) , RNA_function_identifier ( self_func ) , parms_len , pyargs_len + pykw_len ) ;
2009-07-17 02:31:28 +00:00
err = - 1 ;
}
2009-04-07 00:49:39 +00:00
/* parse function parameters */
2009-07-17 02:31:28 +00:00
for ( i = 0 ; iter . valid & & err = = 0 ; RNA_parameter_list_next ( & iter ) ) {
2009-04-07 00:49:39 +00:00
parm = iter . parm ;
2010-01-02 10:42:38 +00:00
flag = RNA_property_flag ( parm ) ;
/* only useful for single argument returns, we'll need another list loop for multiple */
2010-01-24 10:51:59 +00:00
if ( flag & PROP_OUTPUT ) {
2010-01-02 10:42:38 +00:00
ret_len + + ;
if ( pret_single = = NULL ) {
pret_single = parm ;
retdata_single = iter . data ;
}
2009-04-07 00:49:39 +00:00
continue ;
}
2009-07-17 02:31:28 +00:00
parm_id = RNA_property_identifier ( parm ) ;
2009-04-07 00:49:39 +00:00
item = NULL ;
2010-03-23 15:25:33 +00:00
if ( i < pyargs_len ) {
2009-04-07 00:49:39 +00:00
item = PyTuple_GET_ITEM ( args , i ) ;
2009-04-11 01:45:05 +00:00
i + + ;
2009-07-23 13:48:15 +00:00
2009-07-26 18:18:14 +00:00
kw_arg = FALSE ;
2009-04-11 01:45:05 +00:00
}
2009-07-17 02:31:28 +00:00
else if ( kw ! = NULL ) {
item = PyDict_GetItemString ( kw , parm_id ) ; /* borrow ref */
if ( item )
kw_tot + + ; /* make sure invalid keywords are not given */
2009-07-23 13:48:15 +00:00
2009-07-26 18:18:14 +00:00
kw_arg = TRUE ;
2009-07-17 02:31:28 +00:00
}
2009-04-07 00:49:39 +00:00
if ( item = = NULL ) {
2009-04-11 01:45:05 +00:00
if ( flag & PROP_REQUIRED ) {
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_TypeError , " %.200s.%.200s(): required parameter \" %.200s \" not specified " , RNA_struct_identifier ( self_ptr - > type ) , RNA_function_identifier ( self_func ) , parm_id ) ;
2009-04-11 01:45:05 +00:00
err = - 1 ;
break ;
}
2009-07-17 02:31:28 +00:00
else /* PyDict_GetItemString wont raise an error */
2009-04-11 01:45:05 +00:00
continue ;
2009-04-07 00:49:39 +00:00
}
2010-10-13 23:25:08 +00:00
err = pyrna_py_to_prop ( & funcptr , parm , iter . data , item , " " ) ;
2009-07-23 13:48:15 +00:00
if ( err ! = 0 ) {
/* the error generated isnt that useful, so generate it again with a useful prefix
* could also write a function to prepend to error messages */
char error_prefix [ 512 ] ;
PyErr_Clear ( ) ; /* re-raise */
2009-07-26 18:18:14 +00:00
if ( kw_arg = = TRUE )
2009-07-23 13:48:15 +00:00
snprintf ( error_prefix , sizeof ( error_prefix ) , " %s.%s(): error with keyword argument \" %s \" - " , RNA_struct_identifier ( self_ptr - > type ) , RNA_function_identifier ( self_func ) , parm_id ) ;
else
snprintf ( error_prefix , sizeof ( error_prefix ) , " %s.%s(): error with argument %d, \" %s \" - " , RNA_struct_identifier ( self_ptr - > type ) , RNA_function_identifier ( self_func ) , i , parm_id ) ;
2010-10-13 23:25:08 +00:00
pyrna_py_to_prop ( & funcptr , parm , iter . data , item , error_prefix ) ;
2009-04-07 00:49:39 +00:00
break ;
2009-07-23 13:48:15 +00:00
}
2009-04-07 00:49:39 +00:00
}
2011-02-11 00:11:17 +00:00
2010-01-02 19:01:19 +00:00
RNA_parameter_list_end ( & iter ) ;
2009-04-07 00:49:39 +00:00
2009-07-17 02:31:28 +00:00
/* Check if we gave args that dont exist in the function
* printing the error is slow but it should only happen when developing .
2009-09-17 00:14:47 +00:00
* the if below is quick , checking if it passed less keyword args then we gave .
* ( Dont overwrite the error if we have one , otherwise can skip important messages and confuse with args )
*/
2010-02-26 12:28:44 +00:00
if ( err = = 0 & & kw & & ( pykw_len > kw_tot ) ) {
2009-07-17 02:31:28 +00:00
PyObject * key , * value ;
Py_ssize_t pos = 0 ;
DynStr * bad_args = BLI_dynstr_new ( ) ;
DynStr * good_args = BLI_dynstr_new ( ) ;
2011-02-01 23:53:54 +00:00
const char * arg_name , * bad_args_str , * good_args_str ;
2009-07-26 18:18:14 +00:00
int found = FALSE , first = TRUE ;
2009-07-17 02:31:28 +00:00
while ( PyDict_Next ( kw , & pos , & key , & value ) ) {
arg_name = _PyUnicode_AsString ( key ) ;
2009-07-26 18:18:14 +00:00
found = FALSE ;
2009-07-17 02:31:28 +00:00
if ( arg_name = = NULL ) { /* unlikely the argname is not a string but ignore if it is*/
PyErr_Clear ( ) ;
}
else {
/* Search for arg_name */
RNA_parameter_list_begin ( & parms , & iter ) ;
for ( ; iter . valid ; RNA_parameter_list_next ( & iter ) ) {
parm = iter . parm ;
if ( strcmp ( arg_name , RNA_property_identifier ( parm ) ) = = 0 ) {
2009-07-26 18:18:14 +00:00
found = TRUE ;
2009-07-17 02:31:28 +00:00
break ;
}
}
RNA_parameter_list_end ( & iter ) ;
2009-07-26 18:18:14 +00:00
if ( found = = FALSE ) {
2009-07-17 02:31:28 +00:00
BLI_dynstr_appendf ( bad_args , first ? " %s " : " , %s " , arg_name ) ;
2009-07-26 18:18:14 +00:00
first = FALSE ;
2009-07-17 02:31:28 +00:00
}
}
}
/* list good args */
2009-07-26 18:18:14 +00:00
first = TRUE ;
2009-07-17 02:31:28 +00:00
RNA_parameter_list_begin ( & parms , & iter ) ;
for ( ; iter . valid ; RNA_parameter_list_next ( & iter ) ) {
parm = iter . parm ;
2010-01-24 10:51:59 +00:00
if ( RNA_property_flag ( parm ) & PROP_OUTPUT )
2009-12-10 11:20:43 +00:00
continue ;
2009-07-17 02:31:28 +00:00
BLI_dynstr_appendf ( good_args , first ? " %s " : " , %s " , RNA_property_identifier ( parm ) ) ;
2009-07-26 18:18:14 +00:00
first = FALSE ;
2009-07-17 02:31:28 +00:00
}
RNA_parameter_list_end ( & iter ) ;
bad_args_str = BLI_dynstr_get_cstring ( bad_args ) ;
good_args_str = BLI_dynstr_get_cstring ( good_args ) ;
PyErr_Format ( PyExc_TypeError , " %.200s.%.200s(): was called with invalid keyword arguments(s) (%s), expected (%s) " , RNA_struct_identifier ( self_ptr - > type ) , RNA_function_identifier ( self_func ) , bad_args_str , good_args_str ) ;
BLI_dynstr_free ( bad_args ) ;
BLI_dynstr_free ( good_args ) ;
2011-02-01 23:53:54 +00:00
MEM_freeN ( ( void * ) bad_args_str ) ;
MEM_freeN ( ( void * ) good_args_str ) ;
2009-07-17 02:31:28 +00:00
err = - 1 ;
}
2009-04-07 00:49:39 +00:00
ret = NULL ;
if ( err = = 0 ) {
/* call function */
2009-06-18 19:48:55 +00:00
ReportList reports ;
bContext * C = BPy_GetContext ( ) ;
BKE_reports_init ( & reports , RPT_STORE ) ;
2009-07-17 02:31:28 +00:00
RNA_function_call ( C , & reports , self_ptr , self_func , & parms ) ;
2009-06-18 19:48:55 +00:00
2010-12-31 05:40:30 +00:00
err = ( BPy_reports_to_error ( & reports , TRUE ) ) ? - 1 : 0 ;
2009-04-07 00:49:39 +00:00
/* return value */
2009-07-17 02:31:28 +00:00
if ( err = = 0 ) {
2010-01-02 10:42:38 +00:00
if ( ret_len > 0 ) {
if ( ret_len > 1 ) {
ret = PyTuple_New ( ret_len ) ;
i = 0 ; /* arg index */
RNA_parameter_list_begin ( & parms , & iter ) ;
for ( ; iter . valid ; RNA_parameter_list_next ( & iter ) ) {
parm = iter . parm ;
flag = RNA_property_flag ( parm ) ;
2010-01-24 10:51:59 +00:00
if ( flag & PROP_OUTPUT )
2010-10-13 23:25:08 +00:00
PyTuple_SET_ITEM ( ret , i + + , pyrna_param_to_py ( & funcptr , parm , iter . data ) ) ;
2010-01-02 10:42:38 +00:00
}
RNA_parameter_list_end ( & iter ) ;
}
else
2010-10-13 23:25:08 +00:00
ret = pyrna_param_to_py ( & funcptr , pret_single , retdata_single ) ;
2009-07-17 02:31:28 +00:00
/* possible there is an error in conversion */
if ( ret = = NULL )
err = - 1 ;
}
}
2009-04-07 00:49:39 +00:00
}
/* cleanup */
RNA_parameter_list_end ( & iter ) ;
2009-07-17 02:31:28 +00:00
RNA_parameter_list_free ( & parms ) ;
2009-04-07 00:49:39 +00:00
if ( ret )
return ret ;
if ( err = = - 1 )
return NULL ;
Py_RETURN_NONE ;
}
2010-09-10 14:54:50 +00:00
2010-09-09 05:37:22 +00:00
/* subclasses of pyrna_struct_Type which support idprop definitions use this as a metaclass */
/* note: tp_base member is set to &PyType_Type on init */
PyTypeObject pyrna_struct_meta_idprop_Type = {
PyVarObject_HEAD_INIT ( NULL , 0 )
" bpy_struct_meta_idprop " , /* tp_name */
2010-09-10 14:54:50 +00:00
sizeof ( PyHeapTypeObject ) , /* tp_basicsize */ // XXX, would be PyTypeObject, but subtypes of Type must be PyHeapTypeObject's
2010-09-09 05:37:22 +00:00
0 , /* tp_itemsize */
/* methods */
NULL , /* tp_dealloc */
NULL , /* printfunc tp_print; */
NULL , /* getattrfunc tp_getattr; */
NULL , /* setattrfunc tp_setattr; */
NULL , /* tp_compare */ /* DEPRECATED in python 3.0! */
NULL , /* tp_repr */
/* Method suites for standard classes */
NULL , /* PyNumberMethods *tp_as_number; */
NULL , /* PySequenceMethods *tp_as_sequence; */
NULL , /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
NULL , /* hashfunc tp_hash; */
NULL , /* ternaryfunc tp_call; */
NULL , /* reprfunc tp_str; */
2011-02-14 07:26:07 +00:00
NULL /*(getattrofunc) pyrna_struct_meta_idprop_getattro*/ , /* getattrofunc tp_getattro; */
2010-09-10 14:54:50 +00:00
( setattrofunc ) pyrna_struct_meta_idprop_setattro , /* setattrofunc tp_setattro; */
2010-09-09 05:37:22 +00:00
/* Functions to access object as input/output buffer */
NULL , /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* long tp_flags; */
2011-02-14 07:26:07 +00:00
NULL , /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL , /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL , /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
NULL , /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0 , /* long tp_weaklistoffset; */
/*** Added in release 2.2 ***/
/* Iterators */
NULL , /* getiterfunc tp_iter; */
NULL , /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
NULL , /* struct PyMethodDef *tp_methods; */
NULL , /* struct PyMemberDef *tp_members; */
NULL , /* struct PyGetSetDef *tp_getset; */
NULL , /* struct _typeobject *tp_base; */
NULL , /* PyObject *tp_dict; */
NULL , /* descrgetfunc tp_descr_get; */
NULL , /* descrsetfunc tp_descr_set; */
0 , /* long tp_dictoffset; */
NULL , /* initproc tp_init; */
NULL , /* allocfunc tp_alloc; */
NULL , /* newfunc tp_new; */
/* Low-level free-memory routine */
NULL , /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL , /* inquiry tp_is_gc; */
NULL , /* PyObject *tp_bases; */
/* method resolution order */
NULL , /* PyObject *tp_mro; */
NULL , /* PyObject *tp_cache; */
NULL , /* PyObject *tp_subclasses; */
NULL , /* PyObject *tp_weaklist; */
NULL
2010-09-09 05:37:22 +00:00
} ;
2008-11-29 13:36:08 +00:00
/*-----------------------BPy_StructRNA method def------------------------------*/
PyTypeObject pyrna_struct_Type = {
2009-01-29 09:38:52 +00:00
PyVarObject_HEAD_INIT ( NULL , 0 )
2010-02-23 11:19:55 +00:00
" bpy_struct " , /* tp_name */
2008-11-29 13:36:08 +00:00
sizeof ( BPy_StructRNA ) , /* tp_basicsize */
0 , /* tp_itemsize */
/* methods */
2008-12-29 03:24:13 +00:00
( destructor ) pyrna_struct_dealloc , /* tp_dealloc */
2008-11-29 13:36:08 +00:00
NULL , /* printfunc tp_print; */
2008-12-01 16:59:18 +00:00
NULL , /* getattrfunc tp_getattr; */
NULL , /* setattrfunc tp_setattr; */
2009-02-26 05:50:19 +00:00
NULL , /* tp_compare */ /* DEPRECATED in python 3.0! */
2008-11-29 13:36:08 +00:00
( reprfunc ) pyrna_struct_repr , /* tp_repr */
/* Method suites for standard classes */
NULL , /* PyNumberMethods *tp_as_number; */
2009-11-16 19:03:40 +00:00
& pyrna_struct_as_sequence , /* PySequenceMethods *tp_as_sequence; */
& pyrna_struct_as_mapping , /* PyMappingMethods *tp_as_mapping; */
2008-11-29 13:36:08 +00:00
/* More standard operations (here for binary compatibility) */
2008-12-02 14:36:35 +00:00
( hashfunc ) pyrna_struct_hash , /* hashfunc tp_hash; */
2008-12-01 16:59:18 +00:00
NULL , /* ternaryfunc tp_call; */
2010-08-10 15:46:16 +00:00
( reprfunc ) pyrna_struct_str , /* reprfunc tp_str; */
2008-12-01 16:59:18 +00:00
( getattrofunc ) pyrna_struct_getattro , /* getattrofunc tp_getattro; */
( setattrofunc ) pyrna_struct_setattro , /* setattrofunc tp_setattro; */
2008-11-29 13:36:08 +00:00
/* Functions to access object as input/output buffer */
NULL , /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
2008-12-01 16:59:18 +00:00
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* long tp_flags; */
2008-11-29 13:36:08 +00:00
NULL , /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL , /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL , /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
2009-01-29 09:38:52 +00:00
( richcmpfunc ) pyrna_struct_richcmp , /* richcmpfunc tp_richcompare; */
2008-11-29 13:36:08 +00:00
/*** weak reference enabler ***/
0 , /* long tp_weaklistoffset; */
/*** Added in release 2.2 ***/
/* Iterators */
NULL , /* getiterfunc tp_iter; */
NULL , /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
2009-03-11 17:28:37 +00:00
pyrna_struct_methods , /* struct PyMethodDef *tp_methods; */
2008-11-29 13:36:08 +00:00
NULL , /* struct PyMemberDef *tp_members; */
2009-12-13 10:46:34 +00:00
pyrna_struct_getseters , /* struct PyGetSetDef *tp_getset; */
2008-11-29 13:36:08 +00:00
NULL , /* struct _typeobject *tp_base; */
NULL , /* PyObject *tp_dict; */
NULL , /* descrgetfunc tp_descr_get; */
NULL , /* descrsetfunc tp_descr_set; */
0 , /* long tp_dictoffset; */
NULL , /* initproc tp_init; */
NULL , /* allocfunc tp_alloc; */
2008-12-01 16:59:18 +00:00
pyrna_struct_new , /* newfunc tp_new; */
2008-11-29 13:36:08 +00:00
/* Low-level free-memory routine */
NULL , /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL , /* inquiry tp_is_gc; */
NULL , /* PyObject *tp_bases; */
/* method resolution order */
NULL , /* PyObject *tp_mro; */
NULL , /* PyObject *tp_cache; */
NULL , /* PyObject *tp_subclasses; */
NULL , /* PyObject *tp_weaklist; */
NULL
} ;
/*-----------------------BPy_PropertyRNA method def------------------------------*/
PyTypeObject pyrna_prop_Type = {
2009-01-29 09:38:52 +00:00
PyVarObject_HEAD_INIT ( NULL , 0 )
2010-02-23 11:19:55 +00:00
" bpy_prop " , /* tp_name */
2008-11-29 13:36:08 +00:00
sizeof ( BPy_PropertyRNA ) , /* tp_basicsize */
0 , /* tp_itemsize */
/* methods */
NULL , /* tp_dealloc */
2010-05-16 10:09:07 +00:00
NULL , /* printfunc tp_print; */
2008-11-30 14:00:14 +00:00
NULL , /* getattrfunc tp_getattr; */
2008-11-29 13:36:08 +00:00
NULL , /* setattrfunc tp_setattr; */
2009-02-26 05:50:19 +00:00
NULL , /* tp_compare */ /* DEPRECATED in python 3.0! */
2010-08-10 15:46:16 +00:00
( reprfunc ) pyrna_prop_repr , /* tp_repr */
2008-11-29 13:36:08 +00:00
/* Method suites for standard classes */
NULL , /* PyNumberMethods *tp_as_number; */
2010-02-15 23:43:51 +00:00
NULL , /* PySequenceMethods *tp_as_sequence; */
NULL , /* PyMappingMethods *tp_as_mapping; */
2008-11-29 13:36:08 +00:00
/* More standard operations (here for binary compatibility) */
2010-04-25 21:13:42 +00:00
( hashfunc ) pyrna_prop_hash , /* hashfunc tp_hash; */
2008-11-29 13:36:08 +00:00
NULL , /* ternaryfunc tp_call; */
2010-08-10 15:46:16 +00:00
( reprfunc ) pyrna_prop_str , /* reprfunc tp_str; */
2009-11-03 16:07:29 +00:00
/* will only use these if this is a subtype of a py class */
2010-02-15 23:43:51 +00:00
NULL , /* getattrofunc tp_getattro; */
NULL , /* setattrofunc tp_setattro; */
2008-11-29 13:36:08 +00:00
/* Functions to access object as input/output buffer */
NULL , /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
2008-12-01 16:59:18 +00:00
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* long tp_flags; */
2008-11-29 13:36:08 +00:00
NULL , /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL , /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL , /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
2009-01-29 09:38:52 +00:00
( richcmpfunc ) pyrna_prop_richcmp , /* richcmpfunc tp_richcompare; */
2008-11-29 13:36:08 +00:00
/*** weak reference enabler ***/
0 , /* long tp_weaklistoffset; */
/*** Added in release 2.2 ***/
/* Iterators */
2010-02-15 23:43:51 +00:00
NULL , /* getiterfunc tp_iter; */
2008-11-29 13:36:08 +00:00
NULL , /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
pyrna_prop_methods , /* struct PyMethodDef *tp_methods; */
NULL , /* struct PyMemberDef *tp_members; */
2010-08-23 22:10:13 +00:00
pyrna_prop_getseters , /* struct PyGetSetDef *tp_getset; */
2008-11-29 13:36:08 +00:00
NULL , /* struct _typeobject *tp_base; */
NULL , /* PyObject *tp_dict; */
NULL , /* descrgetfunc tp_descr_get; */
NULL , /* descrsetfunc tp_descr_set; */
0 , /* long tp_dictoffset; */
NULL , /* initproc tp_init; */
NULL , /* allocfunc tp_alloc; */
2008-12-01 16:59:18 +00:00
pyrna_prop_new , /* newfunc tp_new; */
2008-11-29 13:36:08 +00:00
/* Low-level free-memory routine */
NULL , /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL , /* inquiry tp_is_gc; */
NULL , /* PyObject *tp_bases; */
/* method resolution order */
NULL , /* PyObject *tp_mro; */
NULL , /* PyObject *tp_cache; */
NULL , /* PyObject *tp_subclasses; */
NULL , /* PyObject *tp_weaklist; */
NULL
} ;
2010-02-15 23:43:51 +00:00
PyTypeObject pyrna_prop_array_Type = {
PyVarObject_HEAD_INIT ( NULL , 0 )
2010-02-23 11:19:55 +00:00
" bpy_prop_array " , /* tp_name */
2010-09-02 06:35:00 +00:00
sizeof ( BPy_PropertyArrayRNA ) , /* tp_basicsize */
2010-02-15 23:43:51 +00:00
0 , /* tp_itemsize */
/* methods */
NULL , /* tp_dealloc */
NULL , /* printfunc tp_print; */
NULL , /* getattrfunc tp_getattr; */
NULL , /* setattrfunc tp_setattr; */
NULL , /* tp_compare */ /* DEPRECATED in python 3.0! */
NULL , /* subclassed */ /* tp_repr */
/* Method suites for standard classes */
2010-08-27 01:50:50 +00:00
& pyrna_prop_array_as_number , /* PyNumberMethods *tp_as_number; */
2010-02-15 23:43:51 +00:00
& pyrna_prop_array_as_sequence , /* PySequenceMethods *tp_as_sequence; */
& pyrna_prop_array_as_mapping , /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
NULL , /* hashfunc tp_hash; */
NULL , /* ternaryfunc tp_call; */
NULL , /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
( getattrofunc ) pyrna_prop_array_getattro , /* getattrofunc tp_getattro; */
NULL , /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL , /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* long tp_flags; */
NULL , /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL , /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL , /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
NULL , /* subclassed */ /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0 , /* long tp_weaklistoffset; */
/*** Added in release 2.2 ***/
/* Iterators */
( getiterfunc ) pyrna_prop_array_iter , /* getiterfunc tp_iter; */
NULL , /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
pyrna_prop_array_methods , /* struct PyMethodDef *tp_methods; */
NULL , /* struct PyMemberDef *tp_members; */
NULL /*pyrna_prop_getseters*/ , /* struct PyGetSetDef *tp_getset; */
& pyrna_prop_Type , /* struct _typeobject *tp_base; */
NULL , /* PyObject *tp_dict; */
NULL , /* descrgetfunc tp_descr_get; */
NULL , /* descrsetfunc tp_descr_set; */
0 , /* long tp_dictoffset; */
NULL , /* initproc tp_init; */
NULL , /* allocfunc tp_alloc; */
NULL , /* newfunc tp_new; */
/* Low-level free-memory routine */
NULL , /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL , /* inquiry tp_is_gc; */
NULL , /* PyObject *tp_bases; */
/* method resolution order */
NULL , /* PyObject *tp_mro; */
NULL , /* PyObject *tp_cache; */
NULL , /* PyObject *tp_subclasses; */
NULL , /* PyObject *tp_weaklist; */
NULL
} ;
PyTypeObject pyrna_prop_collection_Type = {
PyVarObject_HEAD_INIT ( NULL , 0 )
2010-02-23 11:19:55 +00:00
" bpy_prop_collection " , /* tp_name */
2010-02-15 23:43:51 +00:00
sizeof ( BPy_PropertyRNA ) , /* tp_basicsize */
0 , /* tp_itemsize */
/* methods */
NULL , /* tp_dealloc */
NULL , /* printfunc tp_print; */
NULL , /* getattrfunc tp_getattr; */
NULL , /* setattrfunc tp_setattr; */
NULL , /* tp_compare */ /* DEPRECATED in python 3.0! */
NULL , /* subclassed */ /* tp_repr */
/* Method suites for standard classes */
2010-08-27 01:50:50 +00:00
& pyrna_prop_collection_as_number , /* PyNumberMethods *tp_as_number; */
2010-02-15 23:43:51 +00:00
& pyrna_prop_collection_as_sequence , /* PySequenceMethods *tp_as_sequence; */
& pyrna_prop_collection_as_mapping , /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
NULL , /* hashfunc tp_hash; */
NULL , /* ternaryfunc tp_call; */
NULL , /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
( getattrofunc ) pyrna_prop_collection_getattro , /* getattrofunc tp_getattro; */
( setattrofunc ) pyrna_prop_collection_setattro , /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL , /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* long tp_flags; */
NULL , /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL , /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL , /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
NULL , /* subclassed */ /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0 , /* long tp_weaklistoffset; */
/*** Added in release 2.2 ***/
/* Iterators */
( getiterfunc ) pyrna_prop_collection_iter , /* getiterfunc tp_iter; */
NULL , /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
pyrna_prop_collection_methods , /* struct PyMethodDef *tp_methods; */
NULL , /* struct PyMemberDef *tp_members; */
NULL /*pyrna_prop_getseters*/ , /* struct PyGetSetDef *tp_getset; */
& pyrna_prop_Type , /* struct _typeobject *tp_base; */
NULL , /* PyObject *tp_dict; */
NULL , /* descrgetfunc tp_descr_get; */
NULL , /* descrsetfunc tp_descr_set; */
0 , /* long tp_dictoffset; */
NULL , /* initproc tp_init; */
NULL , /* allocfunc tp_alloc; */
NULL , /* newfunc tp_new; */
/* Low-level free-memory routine */
NULL , /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL , /* inquiry tp_is_gc; */
NULL , /* PyObject *tp_bases; */
/* method resolution order */
NULL , /* PyObject *tp_mro; */
NULL , /* PyObject *tp_cache; */
NULL , /* PyObject *tp_subclasses; */
NULL , /* PyObject *tp_weaklist; */
NULL
} ;
2010-09-02 06:35:00 +00:00
/* only for add/remove/move methods */
2011-02-13 10:52:18 +00:00
static PyTypeObject pyrna_prop_collection_idprop_Type = {
2010-09-02 06:35:00 +00:00
PyVarObject_HEAD_INIT ( NULL , 0 )
" bpy_prop_collection_idprop " , /* tp_name */
sizeof ( BPy_PropertyRNA ) , /* tp_basicsize */
0 , /* tp_itemsize */
/* methods */
NULL , /* tp_dealloc */
NULL , /* printfunc tp_print; */
NULL , /* getattrfunc tp_getattr; */
NULL , /* setattrfunc tp_setattr; */
NULL , /* tp_compare */ /* DEPRECATED in python 3.0! */
NULL , /* subclassed */ /* tp_repr */
/* Method suites for standard classes */
NULL , /* PyNumberMethods *tp_as_number; */
NULL , /* PySequenceMethods *tp_as_sequence; */
NULL , /* PyMappingMethods *tp_as_mapping; */
/* More standard operations (here for binary compatibility) */
NULL , /* hashfunc tp_hash; */
NULL , /* ternaryfunc tp_call; */
NULL , /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
NULL , /* getattrofunc tp_getattro; */
NULL , /* setattrofunc tp_setattro; */
/* Functions to access object as input/output buffer */
NULL , /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE , /* long tp_flags; */
NULL , /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
NULL , /* traverseproc tp_traverse; */
/* delete references to contained objects */
NULL , /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/
NULL , /* subclassed */ /* richcmpfunc tp_richcompare; */
/*** weak reference enabler ***/
0 , /* long tp_weaklistoffset; */
/*** Added in release 2.2 ***/
/* Iterators */
NULL , /* getiterfunc tp_iter; */
NULL , /* iternextfunc tp_iternext; */
/*** Attribute descriptor and subclassing stuff ***/
pyrna_prop_collection_idprop_methods , /* struct PyMethodDef *tp_methods; */
NULL , /* struct PyMemberDef *tp_members; */
NULL /*pyrna_prop_getseters*/ , /* struct PyGetSetDef *tp_getset; */
& pyrna_prop_collection_Type , /* struct _typeobject *tp_base; */
NULL , /* PyObject *tp_dict; */
NULL , /* descrgetfunc tp_descr_get; */
NULL , /* descrsetfunc tp_descr_set; */
0 , /* long tp_dictoffset; */
NULL , /* initproc tp_init; */
NULL , /* allocfunc tp_alloc; */
NULL , /* newfunc tp_new; */
/* Low-level free-memory routine */
NULL , /* freefunc tp_free; */
/* For PyObject_IS_GC */
NULL , /* inquiry tp_is_gc; */
NULL , /* PyObject *tp_bases; */
/* method resolution order */
NULL , /* PyObject *tp_mro; */
NULL , /* PyObject *tp_cache; */
NULL , /* PyObject *tp_subclasses; */
NULL , /* PyObject *tp_weaklist; */
NULL
} ;
2009-04-19 13:37:59 +00:00
static void pyrna_subtype_set_rna ( PyObject * newclass , StructRNA * srna )
{
2009-08-16 12:29:46 +00:00
PointerRNA ptr ;
2009-04-19 13:37:59 +00:00
PyObject * item ;
2009-05-26 06:29:15 +00:00
Py_INCREF ( newclass ) ;
2009-08-15 09:53:38 +00:00
2009-05-26 06:29:15 +00:00
if ( RNA_struct_py_type_get ( srna ) )
2010-09-01 14:13:48 +00:00
PyC_ObSpit ( " RNA WAS SET - " , RNA_struct_py_type_get ( srna ) ) ;
2009-05-28 02:03:48 +00:00
2009-05-28 10:31:56 +00:00
Py_XDECREF ( ( ( PyObject * ) RNA_struct_py_type_get ( srna ) ) ) ;
2009-05-26 06:29:15 +00:00
2009-04-19 13:37:59 +00:00
RNA_struct_py_type_set ( srna , ( void * ) newclass ) ; /* Store for later use */
/* Not 100% needed but useful,
* having an instance within a type looks wrong however this instance IS an rna type */
2009-08-15 05:05:23 +00:00
2009-08-16 12:29:46 +00:00
/* python deals with the curcular ref */
RNA_pointer_create ( NULL , & RNA_Struct , srna , & ptr ) ;
item = pyrna_struct_CreatePyObject ( & ptr ) ;
2009-08-15 05:05:23 +00:00
2010-09-07 08:10:19 +00:00
/* note, must set the class not the __dict__ else the internal slots are not updated correctly */
PyObject_SetAttrString ( newclass , " bl_rna " , item ) ;
2009-04-19 13:37:59 +00:00
Py_DECREF ( item ) ;
2010-09-07 08:10:19 +00:00
2009-04-19 13:37:59 +00:00
/* done with rna instance */
}
2009-04-07 00:49:39 +00:00
2009-11-07 22:07:46 +00:00
static PyObject * pyrna_srna_Subtype ( StructRNA * srna ) ;
/* return a borrowed reference */
static PyObject * pyrna_srna_PyBase ( StructRNA * srna ) //, PyObject *bpy_types_dict)
{
/* Assume RNA_struct_py_type_get(srna) was already checked */
StructRNA * base ;
PyObject * py_base = NULL ;
/* get the base type */
base = RNA_struct_base ( srna ) ;
2009-11-08 01:13:19 +00:00
2009-11-07 22:07:46 +00:00
if ( base & & base ! = srna ) {
/*/printf("debug subtype %s %p\n", RNA_struct_identifier(srna), srna); */
py_base = pyrna_srna_Subtype ( base ) ; //, bpy_types_dict);
Py_DECREF ( py_base ) ; /* srna owns, this is only to pass as an arg */
}
if ( py_base = = NULL ) {
py_base = ( PyObject * ) & pyrna_struct_Type ;
}
return py_base ;
}
2009-11-08 01:13:19 +00:00
/* check if we have a native python subclass, use it when it exists
* return a borrowed reference */
2010-09-09 05:37:22 +00:00
static PyObject * bpy_types_dict = NULL ;
2009-11-08 01:13:19 +00:00
static PyObject * pyrna_srna_ExternalType ( StructRNA * srna )
{
const char * idname = RNA_struct_identifier ( srna ) ;
PyObject * newclass ;
if ( bpy_types_dict = = NULL ) {
2010-12-03 17:05:21 +00:00
PyObject * bpy_types = PyImport_ImportModuleLevel ( ( char * ) " bpy_types " , NULL , NULL , NULL , 0 ) ;
2009-11-08 01:13:19 +00:00
if ( bpy_types = = NULL ) {
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
fprintf ( stderr , " pyrna_srna_ExternalType: failed to find 'bpy_types' module \n " ) ;
return NULL ;
}
bpy_types_dict = PyModule_GetDict ( bpy_types ) ; // borrow
Py_DECREF ( bpy_types ) ; // fairly safe to assume the dict is kept
}
newclass = PyDict_GetItemString ( bpy_types_dict , idname ) ;
/* sanity check, could skip this unless in debug mode */
if ( newclass ) {
PyObject * base_compare = pyrna_srna_PyBase ( srna ) ;
2009-12-05 23:41:45 +00:00
//PyObject *slots= PyObject_GetAttrString(newclass, "__slots__"); // cant do this because it gets superclasses values!
2009-12-24 11:40:14 +00:00
//PyObject *bases= PyObject_GetAttrString(newclass, "__bases__"); // can do this but faster not to.
PyObject * bases = ( ( PyTypeObject * ) newclass ) - > tp_bases ;
2009-12-05 23:41:45 +00:00
PyObject * slots = PyDict_GetItemString ( ( ( PyTypeObject * ) newclass ) - > tp_dict , " __slots__ " ) ;
2009-11-08 01:13:19 +00:00
2009-12-05 23:41:45 +00:00
if ( slots = = NULL ) {
fprintf ( stderr , " pyrna_srna_ExternalType: expected class '%s' to have __slots__ defined \n \n See bpy_types.py \n " , idname ) ;
newclass = NULL ;
}
else if ( PyTuple_GET_SIZE ( bases ) ) {
2009-11-08 01:13:19 +00:00
PyObject * base = PyTuple_GET_ITEM ( bases , 0 ) ;
if ( base_compare ! = base ) {
2009-12-05 23:41:45 +00:00
fprintf ( stderr , " pyrna_srna_ExternalType: incorrect subclassing of SRNA '%s' \n See bpy_types.py \n " , idname ) ;
2010-09-01 14:13:48 +00:00
PyC_ObSpit ( " Expected! " , base_compare ) ;
2009-11-08 01:13:19 +00:00
newclass = NULL ;
}
else {
if ( G . f & G_DEBUG )
fprintf ( stderr , " SRNA Subclassed: '%s' \n " , idname ) ;
}
}
}
return newclass ;
}
2009-11-07 22:07:46 +00:00
static PyObject * pyrna_srna_Subtype ( StructRNA * srna )
2009-03-13 07:50:07 +00:00
{
PyObject * newclass = NULL ;
2010-08-24 02:12:09 +00:00
/* stupid/simple case */
2009-07-10 04:25:49 +00:00
if ( srna = = NULL ) {
2009-03-13 07:50:07 +00:00
newclass = NULL ; /* Nothing to do */
2010-08-24 02:12:09 +00:00
} /* the class may have alredy been declared & allocated */
else if ( ( newclass = RNA_struct_py_type_get ( srna ) ) ) {
2009-03-21 06:55:30 +00:00
Py_INCREF ( newclass ) ;
2010-08-24 02:12:09 +00:00
} /* check if bpy_types.py module has the class defined in it */
else if ( ( newclass = pyrna_srna_ExternalType ( srna ) ) ) {
2009-11-08 01:13:19 +00:00
pyrna_subtype_set_rna ( newclass , srna ) ;
Py_INCREF ( newclass ) ;
2010-08-24 02:12:09 +00:00
} /* create a new class instance with the C api
* maintly for the purposing of matching the C / rna type hierarchy */
else {
2009-03-13 07:50:07 +00:00
/* subclass equivelents
- class myClass ( myBase ) :
some = ' value ' # or . . .
2009-07-10 04:25:49 +00:00
- myClass = type ( name = ' myClass ' , bases = ( myBase , ) , dict = { ' __module__ ' : ' bpy . types ' } )
2009-03-13 07:50:07 +00:00
*/
2010-07-17 18:08:14 +00:00
/* Assume RNA_struct_py_type_get(srna) was already checked */
2009-11-07 22:07:46 +00:00
PyObject * py_base = pyrna_srna_PyBase ( srna ) ;
2010-09-09 05:37:22 +00:00
PyObject * metaclass ;
2009-07-22 19:50:21 +00:00
const char * idname = RNA_struct_identifier ( srna ) ;
2010-09-09 05:37:22 +00:00
2010-08-24 02:12:09 +00:00
/* remove __doc__ for now */
// const char *descr= RNA_struct_ui_description(srna);
// if(!descr) descr= "(no docs)";
// "__doc__",descr
2010-09-09 05:37:22 +00:00
2010-09-09 06:06:37 +00:00
if ( RNA_struct_idprops_check ( srna ) & & ! PyObject_IsSubclass ( py_base , ( PyObject * ) & pyrna_struct_meta_idprop_Type ) ) {
2010-09-09 05:37:22 +00:00
metaclass = ( PyObject * ) & pyrna_struct_meta_idprop_Type ;
}
else {
metaclass = ( PyObject * ) & PyType_Type ;
}
2009-08-14 12:29:55 +00:00
/* always use O not N when calling, N causes refcount errors */
2010-12-03 17:05:21 +00:00
newclass = PyObject_CallFunction ( metaclass , ( char * ) " s(O){sss()} " , idname , py_base , " __module__ " , " bpy.types " , " __slots__ " ) ;
2010-09-09 05:37:22 +00:00
2009-08-15 09:53:38 +00:00
/* newclass will now have 2 ref's, ???, probably 1 is internal since decrefing here segfaults */
2010-09-01 14:13:48 +00:00
/* PyC_ObSpit("new class ref", newclass); */
2009-03-21 06:55:30 +00:00
2009-07-10 04:25:49 +00:00
if ( newclass ) {
2009-08-15 09:53:38 +00:00
/* srna owns one, and the other is owned by the caller */
2009-07-10 04:25:49 +00:00
pyrna_subtype_set_rna ( newclass , srna ) ;
2009-08-14 12:29:55 +00:00
2010-08-24 02:12:09 +00:00
// XXX, adding this back segfaults blender on load.
// Py_DECREF(newclass); /* let srna own */
2009-07-10 04:25:49 +00:00
}
else {
/* this should not happen */
2010-09-09 05:37:22 +00:00
printf ( " Error registering '%s' \n " , idname ) ;
2009-07-10 04:25:49 +00:00
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
}
2009-03-13 07:50:07 +00:00
}
return newclass ;
}
2009-08-14 12:29:55 +00:00
/* use for subtyping so we know which srna is used for a PointerRNA */
static StructRNA * srna_from_ptr ( PointerRNA * ptr )
{
if ( ptr - > type = = & RNA_Struct ) {
return ptr - > data ;
}
else {
return ptr - > type ;
}
}
/* always returns a new ref, be sure to decref when done */
2009-11-07 22:07:46 +00:00
static PyObject * pyrna_struct_Subtype ( PointerRNA * ptr )
2009-07-10 18:09:53 +00:00
{
2009-08-14 12:29:55 +00:00
return pyrna_srna_Subtype ( srna_from_ptr ( ptr ) ) ;
2009-07-10 18:09:53 +00:00
}
2008-11-29 13:36:08 +00:00
/*-----------------------CreatePyObject---------------------------------*/
PyObject * pyrna_struct_CreatePyObject ( PointerRNA * ptr )
{
2009-03-21 06:55:30 +00:00
BPy_StructRNA * pyrna = NULL ;
2010-04-25 19:56:43 +00:00
/* note: don't rely on this to return None since NULL data with a valid type can often crash */
2009-03-14 13:43:30 +00:00
if ( ptr - > data = = NULL & & ptr - > type = = NULL ) { /* Operator RNA has NULL data */
2009-03-05 16:24:30 +00:00
Py_RETURN_NONE ;
}
2009-07-10 04:25:49 +00:00
else {
2009-03-21 16:03:26 +00:00
PyTypeObject * tp = ( PyTypeObject * ) pyrna_struct_Subtype ( ptr ) ;
2009-03-21 06:55:30 +00:00
if ( tp ) {
pyrna = ( BPy_StructRNA * ) tp - > tp_alloc ( tp , 0 ) ;
2009-08-14 12:29:55 +00:00
Py_DECREF ( tp ) ; /* srna owns, cant hold a ref */
2009-03-21 06:55:30 +00:00
}
else {
fprintf ( stderr , " Could not make type \n " ) ;
pyrna = ( BPy_StructRNA * ) PyObject_NEW ( BPy_StructRNA , & pyrna_struct_Type ) ;
}
2009-03-11 17:28:37 +00:00
}
2009-07-10 04:25:49 +00:00
2008-11-29 13:36:08 +00:00
if ( ! pyrna ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_MemoryError , " couldn't create bpy_struct object " ) ;
2008-11-29 13:36:08 +00:00
return NULL ;
}
2008-12-29 03:24:13 +00:00
pyrna - > ptr = * ptr ;
2009-07-26 18:18:14 +00:00
pyrna - > freeptr = FALSE ;
2009-07-10 04:25:49 +00:00
2010-09-01 14:13:48 +00:00
// PyC_ObSpit("NewStructRNA: ", (PyObject *)pyrna);
2009-07-10 04:25:49 +00:00
2008-11-29 13:36:08 +00:00
return ( PyObject * ) pyrna ;
}
PyObject * pyrna_prop_CreatePyObject ( PointerRNA * ptr , PropertyRNA * prop )
{
BPy_PropertyRNA * pyrna ;
2010-09-02 06:35:00 +00:00
if ( RNA_property_array_check ( ptr , prop ) = = 0 ) {
PyTypeObject * type ;
if ( RNA_property_type ( prop ) ! = PROP_COLLECTION ) {
type = & pyrna_prop_Type ;
}
else {
if ( ( RNA_property_flag ( prop ) & PROP_IDPROPERTY ) = = 0 ) {
type = & pyrna_prop_collection_Type ;
}
else {
type = & pyrna_prop_collection_idprop_Type ;
}
}
pyrna = ( BPy_PropertyRNA * ) PyObject_NEW ( BPy_PropertyRNA , type ) ;
}
else {
pyrna = ( BPy_PropertyRNA * ) PyObject_NEW ( BPy_PropertyArrayRNA , & pyrna_prop_array_Type ) ;
( ( BPy_PropertyArrayRNA * ) pyrna ) - > arraydim = 0 ;
( ( BPy_PropertyArrayRNA * ) pyrna ) - > arrayoffset = 0 ;
}
2008-11-29 13:36:08 +00:00
if ( ! pyrna ) {
2010-11-23 16:45:17 +00:00
PyErr_SetString ( PyExc_MemoryError , " couldn't create BPy_rna object " ) ;
2008-11-29 13:36:08 +00:00
return NULL ;
}
pyrna - > ptr = * ptr ;
pyrna - > prop = prop ;
return ( PyObject * ) pyrna ;
}
2009-11-08 01:13:19 +00:00
void BPY_rna_init ( void )
2008-11-29 13:36:08 +00:00
{
2009-06-22 04:26:48 +00:00
# ifdef USE_MATHUTILS // register mathutils callbacks, ok to run more then once.
2009-06-25 10:11:37 +00:00
mathutils_rna_array_cb_index = Mathutils_RegisterCallback ( & mathutils_rna_array_cb ) ;
2009-06-23 13:34:45 +00:00
mathutils_rna_matrix_cb_index = Mathutils_RegisterCallback ( & mathutils_rna_matrix_cb ) ;
2009-06-22 04:26:48 +00:00
# endif
2010-09-09 05:37:22 +00:00
/* metaclass */
pyrna_struct_meta_idprop_Type . tp_base = & PyType_Type ;
if ( PyType_Ready ( & pyrna_struct_meta_idprop_Type ) < 0 )
return ;
2009-03-13 07:50:07 +00:00
if ( PyType_Ready ( & pyrna_struct_Type ) < 0 )
2009-11-08 01:13:19 +00:00
return ;
2009-03-13 07:50:07 +00:00
if ( PyType_Ready ( & pyrna_prop_Type ) < 0 )
2009-11-08 01:13:19 +00:00
return ;
2010-02-15 23:43:51 +00:00
if ( PyType_Ready ( & pyrna_prop_array_Type ) < 0 )
return ;
if ( PyType_Ready ( & pyrna_prop_collection_Type ) < 0 )
return ;
2010-09-02 06:35:00 +00:00
if ( PyType_Ready ( & pyrna_prop_collection_idprop_Type ) < 0 )
return ;
2009-11-08 01:13:19 +00:00
}
/* bpy.data from python */
static PointerRNA * rna_module_ptr = NULL ;
PyObject * BPY_rna_module ( void )
{
BPy_StructRNA * pyrna ;
PointerRNA ptr ;
2009-03-13 07:50:07 +00:00
2008-11-29 13:36:08 +00:00
/* for now, return the base RNA type rather then a real module */
RNA_main_pointer_create ( G . main , & ptr ) ;
2009-08-15 09:53:38 +00:00
pyrna = ( BPy_StructRNA * ) pyrna_struct_CreatePyObject ( & ptr ) ;
2008-11-29 13:36:08 +00:00
2009-08-15 09:53:38 +00:00
rna_module_ptr = & pyrna - > ptr ;
return ( PyObject * ) pyrna ;
}
void BPY_update_rna_module ( void )
{
RNA_main_pointer_create ( G . main , rna_module_ptr ) ;
2008-11-29 13:36:08 +00:00
}
2008-12-16 16:32:48 +00:00
2009-03-13 07:50:07 +00:00
#if 0
2008-12-16 16:32:48 +00:00
/* This is a way we can access docstrings for RNA types
* without having the datatypes in blender */
PyObject * BPY_rna_doc ( void )
{
PointerRNA ptr ;
/* for now, return the base RNA type rather then a real module */
RNA_blender_rna_pointer_create ( & ptr ) ;
return pyrna_struct_CreatePyObject ( & ptr ) ;
}
2009-03-13 07:50:07 +00:00
# endif
2008-12-16 16:32:48 +00:00
2009-03-11 17:28:37 +00:00
2009-03-21 06:55:30 +00:00
/* pyrna_basetype_* - BPy_BaseTypeRNA is just a BPy_PropertyRNA struct with a differnt type
* the self - > ptr and self - > prop are always set to the " structs " collection */
//---------------getattr--------------------------------------------
2009-11-16 19:03:40 +00:00
static PyObject * pyrna_basetype_getattro ( BPy_BaseTypeRNA * self , PyObject * pyname )
2009-03-21 06:55:30 +00:00
{
PointerRNA newptr ;
PyObject * ret ;
2011-02-01 23:53:54 +00:00
const char * name = _PyUnicode_AsString ( pyname ) ;
2010-09-09 13:58:38 +00:00
if ( name = = NULL ) {
PyErr_SetString ( PyExc_AttributeError , " bpy.types: __getattr__ must be a string " ) ;
ret = NULL ;
}
2010-01-22 14:06:42 +00:00
else if ( RNA_property_collection_lookup_string ( & self - > ptr , self - > prop , name , & newptr ) ) {
2009-04-11 15:05:42 +00:00
ret = pyrna_struct_Subtype ( & newptr ) ;
if ( ret = = NULL ) {
2009-07-09 08:06:26 +00:00
PyErr_Format ( PyExc_SystemError , " bpy.types.%.200s subtype could not be generated, this is a bug! " , _PyUnicode_AsString ( pyname ) ) ;
2009-04-11 15:05:42 +00:00
}
2009-03-11 17:28:37 +00:00
}
2009-11-08 01:13:19 +00:00
else {
#if 0
2009-07-17 02:31:28 +00:00
PyErr_Format ( PyExc_AttributeError , " bpy.types.%.200s RNA_Struct does not exist " , _PyUnicode_AsString ( pyname ) ) ;
2009-03-21 06:55:30 +00:00
return NULL ;
2009-11-08 01:13:19 +00:00
# endif
/* The error raised here will be displayed */
ret = PyObject_GenericGetAttr ( ( PyObject * ) self , pyname ) ;
2009-03-21 06:55:30 +00:00
}
2009-11-08 01:13:19 +00:00
return ret ;
2009-03-21 06:55:30 +00:00
}
static PyObject * pyrna_basetype_dir ( BPy_BaseTypeRNA * self ) ;
2011-02-11 00:11:17 +00:00
static PyObject * pyrna_register_class ( PyObject * self , PyObject * py_class ) ;
static PyObject * pyrna_unregister_class ( PyObject * self , PyObject * py_class ) ;
2010-07-23 01:43:30 +00:00
2009-03-21 06:55:30 +00:00
static struct PyMethodDef pyrna_basetype_methods [ ] = {
{ " __dir__ " , ( PyCFunction ) pyrna_basetype_dir , METH_NOARGS , " " } ,
{ NULL , NULL , 0 , NULL }
} ;
static PyObject * pyrna_basetype_dir ( BPy_BaseTypeRNA * self )
{
2011-02-11 00:11:17 +00:00
PyObject * list ;
#if 0
PyObject * name ;
2009-03-21 06:55:30 +00:00
PyMethodDef * meth ;
2011-02-11 00:11:17 +00:00
# endif
2011-01-06 04:01:06 +00:00
list = pyrna_prop_collection_keys ( self ) ; /* like calling structs.keys(), avoids looping here */
2009-03-21 06:55:30 +00:00
2011-02-11 00:11:17 +00:00
#if 0 /* for now only contains __dir__ */
2009-03-21 06:55:30 +00:00
for ( meth = pyrna_basetype_methods ; meth - > ml_name ; meth + + ) {
name = PyUnicode_FromString ( meth - > ml_name ) ;
PyList_Append ( list , name ) ;
Py_DECREF ( name ) ;
}
2011-02-11 00:11:17 +00:00
# endif
2009-03-21 06:55:30 +00:00
return list ;
}
2011-02-13 10:52:18 +00:00
static PyTypeObject pyrna_basetype_Type = BLANK_PYTHON_TYPE ;
2009-03-21 06:55:30 +00:00
PyObject * BPY_rna_types ( void )
{
BPy_BaseTypeRNA * self ;
2009-04-07 15:20:12 +00:00
2009-04-11 16:17:39 +00:00
if ( ( pyrna_basetype_Type . tp_flags & Py_TPFLAGS_READY ) = = 0 ) {
pyrna_basetype_Type . tp_name = " RNA_Types " ;
pyrna_basetype_Type . tp_basicsize = sizeof ( BPy_BaseTypeRNA ) ;
pyrna_basetype_Type . tp_getattro = ( getattrofunc ) pyrna_basetype_getattro ;
pyrna_basetype_Type . tp_flags = Py_TPFLAGS_DEFAULT ;
pyrna_basetype_Type . tp_methods = pyrna_basetype_methods ;
if ( PyType_Ready ( & pyrna_basetype_Type ) < 0 )
return NULL ;
}
2009-03-13 07:50:07 +00:00
2009-03-21 06:55:30 +00:00
self = ( BPy_BaseTypeRNA * ) PyObject_NEW ( BPy_BaseTypeRNA , & pyrna_basetype_Type ) ;
2010-01-30 13:15:39 +00:00
2009-03-21 06:55:30 +00:00
/* avoid doing this lookup for every getattr */
RNA_blender_rna_pointer_create ( & self - > ptr ) ;
self - > prop = RNA_struct_find_property ( & self - > ptr , " structs " ) ;
2010-01-30 13:15:39 +00:00
2009-03-21 06:55:30 +00:00
return ( PyObject * ) self ;
2009-03-11 17:28:37 +00:00
}
2009-03-16 15:54:43 +00:00
2010-03-16 17:20:15 +00:00
StructRNA * pyrna_struct_as_srna ( PyObject * self , int parent , const char * error_prefix )
2009-08-15 05:05:23 +00:00
{
2009-10-21 17:56:26 +00:00
BPy_StructRNA * py_srna = NULL ;
2009-08-16 12:29:46 +00:00
StructRNA * srna ;
2009-08-22 17:06:10 +00:00
/* ack, PyObject_GetAttrString wont look up this types tp_dict first :/ */
if ( PyType_Check ( self ) ) {
2009-10-31 13:31:23 +00:00
py_srna = ( BPy_StructRNA * ) PyDict_GetItemString ( ( ( PyTypeObject * ) self ) - > tp_dict , " bl_rna " ) ;
2009-08-22 17:06:10 +00:00
Py_XINCREF ( py_srna ) ;
}
2010-03-16 17:20:15 +00:00
if ( parent ) {
/* be very careful with this since it will return a parent classes srna.
* modifying this will do confusing stuff ! */
if ( py_srna = = NULL )
py_srna = ( BPy_StructRNA * ) PyObject_GetAttrString ( self , " bl_rna " ) ;
}
2009-08-15 05:05:23 +00:00
if ( py_srna = = NULL ) {
2010-07-26 05:55:56 +00:00
PyErr_Format ( PyExc_SystemError , " %.200s, missing bl_rna attribute from '%.200s' instance (may not be registered) " , error_prefix , Py_TYPE ( self ) - > tp_name ) ;
2009-08-15 05:05:23 +00:00
return NULL ;
}
2009-08-16 12:29:46 +00:00
if ( ! BPy_StructRNA_Check ( py_srna ) ) {
2010-07-26 05:55:56 +00:00
PyErr_Format ( PyExc_SystemError , " %.200s, bl_rna attribute wrong type '%.200s' on '%.200s'' instance " , error_prefix , Py_TYPE ( py_srna ) - > tp_name , Py_TYPE ( self ) - > tp_name ) ;
2010-03-22 09:30:00 +00:00
Py_DECREF ( py_srna ) ;
2009-08-16 12:29:46 +00:00
return NULL ;
}
if ( py_srna - > ptr . type ! = & RNA_Struct ) {
2010-07-26 05:55:56 +00:00
PyErr_Format ( PyExc_SystemError , " %.200s, bl_rna attribute not a RNA_Struct, on '%.200s'' instance " , error_prefix , Py_TYPE ( self ) - > tp_name ) ;
2010-03-22 09:30:00 +00:00
Py_DECREF ( py_srna ) ;
2009-08-15 05:05:23 +00:00
return NULL ;
}
2009-08-16 12:29:46 +00:00
srna = py_srna - > ptr . data ;
2009-08-15 05:05:23 +00:00
Py_DECREF ( py_srna ) ;
2009-08-16 12:29:46 +00:00
return srna ;
2009-08-15 05:05:23 +00:00
}
2009-03-16 15:54:43 +00:00
/* Orphan functions, not sure where they should go */
2009-08-09 10:05:33 +00:00
/* get the srna for methods attached to types */
2011-01-25 06:54:57 +00:00
/*
* Caller needs to raise error . */
2010-03-16 17:20:15 +00:00
StructRNA * srna_from_self ( PyObject * self , const char * error_prefix )
2009-08-09 10:05:33 +00:00
{
2010-01-19 00:59:36 +00:00
2009-08-09 10:05:33 +00:00
if ( self = = NULL ) {
return NULL ;
}
2010-02-12 21:14:01 +00:00
else if ( PyCapsule_CheckExact ( self ) ) {
return PyCapsule_GetPointer ( self , NULL ) ;
2009-08-09 10:05:33 +00:00
}
2009-08-11 02:27:25 +00:00
else if ( PyType_Check ( self ) = = 0 ) {
return NULL ;
}
2011-01-25 06:54:57 +00:00
else {
/* These cases above not errors, they just mean the type was not compatible
* After this any errors will be raised in the script */
PyObject * error_type , * error_value , * error_traceback ;
StructRNA * srna ;
PyErr_Fetch ( & error_type , & error_value , & error_traceback ) ;
PyErr_Clear ( ) ;
2009-08-09 10:05:33 +00:00
2011-01-25 06:54:57 +00:00
srna = pyrna_struct_as_srna ( self , 0 , error_prefix ) ;
if ( ! PyErr_Occurred ( ) ) {
PyErr_Restore ( error_type , error_value , error_traceback ) ;
}
return srna ;
}
2009-08-09 10:05:33 +00:00
}
2010-09-10 14:54:50 +00:00
static int deferred_register_prop ( StructRNA * srna , PyObject * key , PyObject * item )
2009-08-22 17:30:47 +00:00
{
2009-11-20 20:58:46 +00:00
/* We only care about results from C which
* are for sure types , save some time with error */
2010-09-10 14:54:50 +00:00
if ( pyrna_is_deferred_prop ( item ) ) {
2009-08-22 17:30:47 +00:00
2010-09-08 10:43:36 +00:00
PyObject * py_func , * py_kw , * py_srna_cobject , * py_ret ;
2009-08-22 17:30:47 +00:00
2010-09-08 10:43:36 +00:00
if ( PyArg_ParseTuple ( item , " OO! " , & py_func , & PyDict_Type , & py_kw ) ) {
PyObject * args_fake ;
2009-08-22 17:30:47 +00:00
2009-12-11 00:51:14 +00:00
if ( * _PyUnicode_AsString ( key ) = = ' _ ' ) {
2010-02-23 11:19:55 +00:00
PyErr_Format ( PyExc_ValueError , " bpy_struct \" %.200s \" registration error: %.200s could not register because the property starts with an '_' \n " , RNA_struct_identifier ( srna ) , _PyUnicode_AsString ( key ) ) ;
2009-12-11 00:51:14 +00:00
return - 1 ;
}
2010-02-12 21:14:01 +00:00
py_srna_cobject = PyCapsule_New ( srna , NULL , NULL ) ;
define operator properties in the class, similar to django fields
# Before
[
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""),
bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True),
bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True),
bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True),
bpy.props.BoolProperty(attr="use_colors", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
]
# After
path = StringProperty(attr="", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= "")
use_modifiers = BoolProperty(attr="", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True)
use_normals = BoolProperty(attr="", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True)
use_uvs = BoolProperty(attr="", name="Export UVs", description="Exort the active UV layer", default= True)
use_colors = BoolProperty(attr="", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
2009-10-31 16:40:14 +00:00
2009-11-20 20:58:46 +00:00
/* not 100% nice :/, modifies the dict passed, should be ok */
PyDict_SetItemString ( py_kw , " attr " , key ) ;
2010-09-08 10:43:36 +00:00
args_fake = PyTuple_New ( 1 ) ;
PyTuple_SET_ITEM ( args_fake , 0 , py_srna_cobject ) ;
py_ret = PyObject_Call ( py_func , args_fake , py_kw ) ;
define operator properties in the class, similar to django fields
# Before
[
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""),
bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True),
bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True),
bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True),
bpy.props.BoolProperty(attr="use_colors", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
]
# After
path = StringProperty(attr="", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= "")
use_modifiers = BoolProperty(attr="", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True)
use_normals = BoolProperty(attr="", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True)
use_uvs = BoolProperty(attr="", name="Export UVs", description="Exort the active UV layer", default= True)
use_colors = BoolProperty(attr="", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
2009-10-31 16:40:14 +00:00
2010-09-08 10:43:36 +00:00
Py_DECREF ( args_fake ) ; /* free's py_srna_cobject too */
2009-11-20 20:58:46 +00:00
if ( py_ret ) {
Py_DECREF ( py_ret ) ;
2009-08-22 17:30:47 +00:00
}
else {
2009-11-20 20:58:46 +00:00
PyErr_Print ( ) ;
define operator properties in the class, similar to django fields
# Before
[
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""),
bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True),
bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True),
bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True),
bpy.props.BoolProperty(attr="use_colors", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
]
# After
path = StringProperty(attr="", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= "")
use_modifiers = BoolProperty(attr="", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True)
use_normals = BoolProperty(attr="", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True)
use_uvs = BoolProperty(attr="", name="Export UVs", description="Exort the active UV layer", default= True)
use_colors = BoolProperty(attr="", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
2009-10-31 16:40:14 +00:00
PyErr_Clear ( ) ;
2010-09-01 14:13:48 +00:00
// PyC_LineSpit();
2010-02-23 11:19:55 +00:00
PyErr_Format ( PyExc_ValueError , " bpy_struct \" %.200s \" registration error: %.200s could not register \n " , RNA_struct_identifier ( srna ) , _PyUnicode_AsString ( key ) ) ;
2009-11-20 20:58:46 +00:00
return - 1 ;
2009-08-22 17:30:47 +00:00
}
}
2009-11-20 20:58:46 +00:00
else {
/* Since this is a class dict, ignore args that can't be passed */
/* for testing only */
2010-09-01 14:13:48 +00:00
/* PyC_ObSpit("Why doesn't this work??", item);
2009-11-20 20:58:46 +00:00
PyErr_Print ( ) ; */
PyErr_Clear ( ) ;
}
}
return 0 ;
}
2010-08-19 10:16:30 +00:00
static int pyrna_deferred_register_props ( StructRNA * srna , PyObject * class_dict )
2009-11-20 20:58:46 +00:00
{
PyObject * item , * key ;
PyObject * order ;
Py_ssize_t pos = 0 ;
2010-12-13 07:54:35 +00:00
int ret = 0 ;
2009-11-20 20:58:46 +00:00
2010-09-27 02:52:12 +00:00
/* in both cases PyDict_CheckExact(class_dict) will be true even
* though Operators have a metaclass dict namespace */
if ( ( order = PyDict_GetItemString ( class_dict , " order " ) ) & & PyList_CheckExact ( order ) ) {
2009-11-20 20:58:46 +00:00
for ( pos = 0 ; pos < PyList_GET_SIZE ( order ) ; pos + + ) {
key = PyList_GET_ITEM ( order , pos ) ;
item = PyDict_GetItem ( class_dict , key ) ;
2010-09-10 14:54:50 +00:00
ret = deferred_register_prop ( srna , key , item ) ;
2010-12-13 07:54:35 +00:00
if ( ret ! = 0 )
2009-11-20 20:58:46 +00:00
break ;
}
}
else {
while ( PyDict_Next ( class_dict , & pos , & key , & item ) ) {
2010-09-10 14:54:50 +00:00
ret = deferred_register_prop ( srna , key , item ) ;
2009-11-20 20:58:46 +00:00
2010-12-13 07:54:35 +00:00
if ( ret ! = 0 )
2009-11-20 20:58:46 +00:00
break ;
}
2009-08-22 17:30:47 +00:00
}
2010-12-13 07:54:35 +00:00
return ret ;
2009-08-22 17:30:47 +00:00
}
2010-08-19 10:16:30 +00:00
static int pyrna_deferred_register_class_recursive ( StructRNA * srna , PyTypeObject * py_class )
{
const int len = PyTuple_GET_SIZE ( py_class - > tp_bases ) ;
int i , ret ;
/* first scan base classes for registerable properties */
for ( i = 0 ; i < len ; i + + ) {
PyTypeObject * py_superclass = ( PyTypeObject * ) PyTuple_GET_ITEM ( py_class - > tp_bases , i ) ;
/* the rules for using these base classes are not clear,
* ' object ' is ofcourse not worth looking into and
* existing subclasses of RNA would cause a lot more dictionary
* looping then is needed ( SomeOperator would scan Operator . __dict__ )
* which is harmless but not at all useful .
*
* So only scan base classes which are not subclasses if blender types .
* This best fits having ' mix - in ' classes for operators and render engines .
* */
if ( py_superclass ! = & PyBaseObject_Type & &
! PyObject_IsSubclass ( ( PyObject * ) py_superclass , ( PyObject * ) & pyrna_struct_Type )
) {
ret = pyrna_deferred_register_class_recursive ( srna , py_superclass ) ;
if ( ret ! = 0 ) {
return ret ;
}
}
}
/* not register out own properties */
return pyrna_deferred_register_props ( srna , py_class - > tp_dict ) ; /* getattr(..., "__dict__") returns a proxy */
}
int pyrna_deferred_register_class ( StructRNA * srna , PyObject * py_class )
{
/* Panels and Menus dont need this
* save some time and skip the checks here */
if ( ! RNA_struct_idprops_register_check ( srna ) )
return 0 ;
return pyrna_deferred_register_class_recursive ( srna , ( PyTypeObject * ) py_class ) ;
}
2009-04-19 13:37:59 +00:00
/*-------------------- Type Registration ------------------------*/
static int rna_function_arg_count ( FunctionRNA * func )
{
const ListBase * lb = RNA_function_defined_parameters ( func ) ;
PropertyRNA * parm ;
Link * link ;
2010-08-05 16:05:30 +00:00
int count = ( RNA_function_flag ( func ) & FUNC_NO_SELF ) ? 0 : 1 ;
2009-04-19 13:37:59 +00:00
for ( link = lb - > first ; link ; link = link - > next ) {
parm = ( PropertyRNA * ) link ;
2010-01-24 10:51:59 +00:00
if ( ! ( RNA_property_flag ( parm ) & PROP_OUTPUT ) )
2009-04-19 13:37:59 +00:00
count + + ;
}
return count ;
}
static int bpy_class_validate ( PointerRNA * dummyptr , void * py_data , int * have_function )
{
const ListBase * lb ;
Link * link ;
FunctionRNA * func ;
PropertyRNA * prop ;
StructRNA * srna = dummyptr - > type ;
const char * class_type = RNA_struct_identifier ( srna ) ;
PyObject * py_class = ( PyObject * ) py_data ;
PyObject * base_class = RNA_struct_py_type_get ( srna ) ;
2010-08-08 23:46:49 +00:00
PyObject * item ;
2009-04-19 13:37:59 +00:00
PyObject * py_arg_count ;
int i , flag , arg_count , func_arg_count ;
2009-12-24 16:10:26 +00:00
const char * py_class_name = ( ( PyTypeObject * ) py_class ) - > tp_name ; // __name__
2009-04-19 13:37:59 +00:00
if ( base_class ) {
if ( ! PyObject_IsSubclass ( py_class , base_class ) ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " expected %.200s subclass of class \" %.200s \" " , class_type , py_class_name ) ;
2009-04-19 13:37:59 +00:00
return - 1 ;
}
}
/* verify callback functions */
2011-01-25 07:31:11 +00:00
lb = RNA_struct_type_functions ( srna ) ;
2009-04-19 13:37:59 +00:00
i = 0 ;
for ( link = lb - > first ; link ; link = link - > next ) {
func = ( FunctionRNA * ) link ;
flag = RNA_function_flag ( func ) ;
if ( ! ( flag & FUNC_REGISTER ) )
continue ;
item = PyObject_GetAttrString ( py_class , RNA_function_identifier ( func ) ) ;
have_function [ i ] = ( item ! = NULL ) ;
i + + ;
if ( item = = NULL ) {
if ( ( flag & FUNC_REGISTER_OPTIONAL ) = = 0 ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_AttributeError , " expected %.200s, %.200s class to have an \" %.200s \" attribute " , class_type , py_class_name , RNA_function_identifier ( func ) ) ;
2009-04-19 13:37:59 +00:00
return - 1 ;
}
PyErr_Clear ( ) ;
}
else {
2010-08-08 23:46:49 +00:00
Py_DECREF ( item ) ; /* no need to keep a ref, the class owns it (technically we should keep a ref but...) */
2010-08-09 01:37:09 +00:00
if ( flag & FUNC_NO_SELF ) {
if ( PyMethod_Check ( item ) = = 0 ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " expected %.200s, %.200s class \" %.200s \" attribute to be a method, not a %.200s " , class_type , py_class_name , RNA_function_identifier ( func ) , Py_TYPE ( item ) - > tp_name ) ;
2010-08-09 01:37:09 +00:00
return - 1 ;
}
item = ( ( PyMethodObject * ) item ) - > im_func ;
}
else {
if ( PyFunction_Check ( item ) = = 0 ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " expected %.200s, %.200s class \" %.200s \" attribute to be a function, not a %.200s " , class_type , py_class_name , RNA_function_identifier ( func ) , Py_TYPE ( item ) - > tp_name ) ;
2010-08-09 01:37:09 +00:00
return - 1 ;
}
2009-04-19 13:37:59 +00:00
}
func_arg_count = rna_function_arg_count ( func ) ;
if ( func_arg_count > = 0 ) { /* -1 if we dont care*/
2010-08-08 23:46:49 +00:00
py_arg_count = PyObject_GetAttrString ( PyFunction_GET_CODE ( item ) , " co_argcount " ) ;
2010-10-03 01:44:00 +00:00
arg_count = PyLong_AsLong ( py_arg_count ) ;
2009-04-19 13:37:59 +00:00
Py_DECREF ( py_arg_count ) ;
2010-08-09 01:37:09 +00:00
/* note, the number of args we check for and the number of args we give to
* @ classmethods are different ( quirk of python ) , this is why rna_function_arg_count ( ) doesn ' t return the value - 1 */
if ( flag & FUNC_NO_SELF )
func_arg_count + + ;
2009-04-19 13:37:59 +00:00
if ( arg_count ! = func_arg_count ) {
2011-02-14 11:30:35 +00:00
PyErr_Format ( PyExc_ValueError , " expected %.200s, %.200s class \" %.200s \" function to have %d args, found %d " , class_type , py_class_name , RNA_function_identifier ( func ) , func_arg_count , arg_count ) ;
2009-04-19 13:37:59 +00:00
return - 1 ;
}
}
}
}
/* verify properties */
2011-01-25 06:54:57 +00:00
lb = RNA_struct_type_properties ( srna ) ;
2009-04-19 13:37:59 +00:00
for ( link = lb - > first ; link ; link = link - > next ) {
2009-12-24 16:10:26 +00:00
const char * identifier ;
2009-04-19 13:37:59 +00:00
prop = ( PropertyRNA * ) link ;
flag = RNA_property_flag ( prop ) ;
if ( ! ( flag & PROP_REGISTER ) )
continue ;
2009-10-31 13:31:23 +00:00
identifier = RNA_property_identifier ( prop ) ;
2009-04-19 13:37:59 +00:00
item = PyObject_GetAttrString ( py_class , identifier ) ;
if ( item = = NULL ) {
2009-10-31 18:48:58 +00:00
/* Sneaky workaround to use the class name as the bl_idname */
2009-04-19 13:37:59 +00:00
2010-01-05 20:19:54 +00:00
# define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
if ( strcmp ( identifier , rna_attr ) = = 0 ) { \
item = PyObject_GetAttrString ( py_class , py_attr ) ; \
if ( item & & item ! = Py_None ) { \
2010-10-13 23:25:08 +00:00
if ( pyrna_py_to_prop ( dummyptr , prop , NULL , item , " validating class error: " ) ! = 0 ) { \
2010-01-05 20:19:54 +00:00
Py_DECREF ( item ) ; \
return - 1 ; \
} \
} \
Py_XDECREF ( item ) ; \
} \
2009-04-19 13:37:59 +00:00
2010-01-05 20:19:54 +00:00
BPY_REPLACEMENT_STRING ( " bl_idname " , " __name__ " ) ;
BPY_REPLACEMENT_STRING ( " bl_description " , " __doc__ " ) ;
2009-10-31 18:48:58 +00:00
2010-01-05 20:19:54 +00:00
# undef BPY_REPLACEMENT_STRING
2009-12-24 19:50:43 +00:00
2009-10-31 18:48:58 +00:00
if ( item = = NULL & & ( ( ( flag & PROP_REGISTER_OPTIONAL ) ! = PROP_REGISTER_OPTIONAL ) ) ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_AttributeError , " expected %.200s, %.200s class to have an \" %.200s \" attribute " , class_type , py_class_name , identifier ) ;
2009-04-19 13:37:59 +00:00
return - 1 ;
}
PyErr_Clear ( ) ;
}
else {
Py_DECREF ( item ) ; /* no need to keep a ref, the class owns it */
2010-10-13 23:25:08 +00:00
if ( pyrna_py_to_prop ( dummyptr , prop , NULL , item , " validating class error: " ) ! = 0 )
2009-04-19 13:37:59 +00:00
return - 1 ;
}
}
return 0 ;
}
2010-01-02 10:42:38 +00:00
/* TODO - multiple return values like with rna functions */
2010-12-07 04:12:15 +00:00
static int bpy_class_call ( bContext * C , PointerRNA * ptr , FunctionRNA * func , ParameterList * parms )
2009-04-19 13:37:59 +00:00
{
PyObject * args ;
2010-02-27 14:44:46 +00:00
PyObject * ret = NULL , * py_srna = NULL , * py_class , * py_class_instance = NULL , * parmitem ;
void * * py_class_instance_store = NULL ;
2010-01-02 10:42:38 +00:00
PropertyRNA * parm ;
2009-04-19 13:37:59 +00:00
ParameterIterator iter ;
PointerRNA funcptr ;
2010-01-02 10:42:38 +00:00
int err = 0 , i , flag , ret_len = 0 ;
2010-08-05 16:05:30 +00:00
int is_static = RNA_function_flag ( func ) & FUNC_NO_SELF ;
2010-01-02 10:42:38 +00:00
PropertyRNA * pret_single = NULL ;
void * retdata_single = NULL ;
2009-04-19 13:37:59 +00:00
2009-08-07 16:20:19 +00:00
PyGILState_STATE gilstate ;
2009-04-19 13:37:59 +00:00
2010-12-04 06:25:36 +00:00
# ifdef USE_PEDANTIC_WRITE
2011-02-01 00:32:50 +00:00
const char * func_id = RNA_function_identifier ( func ) ;
2010-12-04 06:25:36 +00:00
/* testing, for correctness, not operator and not draw function */
2011-02-01 20:38:24 +00:00
const short is_readonly = strstr ( " draw " , func_id ) | | /*strstr("render", func_id) ||*/ ! RNA_struct_is_a ( ptr - > type , & RNA_Operator ) ;
2010-12-04 06:25:36 +00:00
# endif
2009-04-19 13:37:59 +00:00
py_class = RNA_struct_py_type_get ( ptr - > type ) ;
2010-08-02 04:20:41 +00:00
/* rare case. can happen when registering subclasses */
if ( py_class = = NULL ) {
fprintf ( stderr , " bpy_class_call(): unable to get python class for rna struct '%.200s' \n " , RNA_struct_identifier ( ptr - > type ) ) ;
return - 1 ;
}
2010-08-26 22:44:05 +00:00
2010-12-08 03:25:31 +00:00
/* XXX, this is needed because render engine calls without a context
* this should be supported at some point but at the moment its not ! */
if ( C = = NULL )
C = BPy_GetContext ( ) ;
2010-08-02 04:20:41 +00:00
bpy_context_set ( C , & gilstate ) ;
2010-08-05 16:05:30 +00:00
if ( ! is_static ) {
/* exception, operators store their PyObjects for re-use */
if ( ptr - > data ) {
if ( RNA_struct_is_a ( ptr - > type , & RNA_Operator ) ) {
wmOperator * op = ptr - > data ;
if ( op - > py_instance ) {
py_class_instance = op - > py_instance ;
Py_INCREF ( py_class_instance ) ;
}
else {
/* store the instance here once its created */
py_class_instance_store = & op - > py_instance ;
}
2010-02-27 14:44:46 +00:00
}
}
2010-08-05 16:05:30 +00:00
/* end exception */
if ( py_class_instance = = NULL )
py_srna = pyrna_struct_CreatePyObject ( ptr ) ;
if ( py_class_instance ) {
/* special case, instance is cached */
}
else if ( py_srna = = NULL ) {
py_class_instance = NULL ;
2010-07-28 12:11:40 +00:00
}
2010-08-05 16:05:30 +00:00
else if ( py_srna = = Py_None ) { /* probably wont ever happen but possible */
Py_DECREF ( py_srna ) ;
py_class_instance = NULL ;
}
else {
2011-02-14 11:30:35 +00:00
/* 'almost' all the time calling the class isnt needed.
* We could just do . . .
py_class_instance = py_srna ;
Py_INCREF ( py_class_instance ) ;
* This would work fine but means __init__ functions wouldnt run .
* none of blenders default scripts use __init__ but its nice to call it
* for general correctness . just to note why this is here when it could be safely removed .
*/
2010-08-05 16:05:30 +00:00
args = PyTuple_New ( 1 ) ;
PyTuple_SET_ITEM ( args , 0 , py_srna ) ;
py_class_instance = PyObject_Call ( py_class , args , NULL ) ;
Py_DECREF ( args ) ;
if ( py_class_instance = = NULL ) {
err = - 1 ; /* so the error is not overridden below */
}
else if ( py_class_instance_store ) {
* py_class_instance_store = py_class_instance ;
Py_INCREF ( py_class_instance ) ;
}
2010-02-27 14:44:46 +00:00
}
2009-05-20 05:35:53 +00:00
}
2009-04-19 13:37:59 +00:00
2010-08-05 16:05:30 +00:00
if ( is_static | | py_class_instance ) { /* Initializing the class worked, now run its invoke function */
2010-02-27 14:44:46 +00:00
PyObject * item = PyObject_GetAttrString ( py_class , RNA_function_identifier ( func ) ) ;
2010-01-02 10:42:38 +00:00
// flag= RNA_function_flag(func);
2009-04-19 13:37:59 +00:00
if ( item ) {
RNA_pointer_create ( NULL , & RNA_Function , func , & funcptr ) ;
2009-11-20 10:00:54 +00:00
args = PyTuple_New ( rna_function_arg_count ( func ) ) ; /* first arg is included in 'item' */
2010-08-09 01:37:09 +00:00
2010-08-05 16:05:30 +00:00
if ( is_static ) {
i = 0 ;
}
else {
PyTuple_SET_ITEM ( args , 0 , py_class_instance ) ;
i = 1 ;
}
2009-04-19 13:37:59 +00:00
RNA_parameter_list_begin ( parms , & iter ) ;
/* parse function parameters */
2010-08-05 16:05:30 +00:00
for ( ; iter . valid ; RNA_parameter_list_next ( & iter ) ) {
2009-04-19 13:37:59 +00:00
parm = iter . parm ;
2010-01-02 10:42:38 +00:00
flag = RNA_property_flag ( parm ) ;
/* only useful for single argument returns, we'll need another list loop for multiple */
2010-01-24 10:51:59 +00:00
if ( flag & PROP_OUTPUT ) {
2010-01-02 10:42:38 +00:00
ret_len + + ;
if ( pret_single = = NULL ) {
pret_single = parm ;
retdata_single = iter . data ;
}
2009-04-19 13:37:59 +00:00
continue ;
}
2010-10-13 23:25:08 +00:00
parmitem = pyrna_param_to_py ( & funcptr , parm , iter . data ) ;
2009-04-19 13:37:59 +00:00
PyTuple_SET_ITEM ( args , i , parmitem ) ;
i + + ;
}
2010-12-04 06:25:36 +00:00
# ifdef USE_PEDANTIC_WRITE
rna_disallow_writes = is_readonly ? TRUE : FALSE ;
# endif
/* *** Main Caller *** */
2009-04-19 13:37:59 +00:00
ret = PyObject_Call ( item , args , NULL ) ;
2010-12-04 06:25:36 +00:00
/* *** Done Calling *** */
# ifdef USE_PEDANTIC_WRITE
rna_disallow_writes = FALSE ;
# endif
2010-01-02 19:01:19 +00:00
RNA_parameter_list_end ( & iter ) ;
2009-04-19 13:37:59 +00:00
Py_DECREF ( item ) ;
2009-05-20 05:35:53 +00:00
Py_DECREF ( args ) ;
2009-04-19 13:37:59 +00:00
}
else {
2009-11-20 10:00:54 +00:00
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_TypeError , " could not find function %.200s in %.200s to execute callback " , RNA_function_identifier ( func ) , RNA_struct_identifier ( ptr - > type ) ) ;
2009-04-19 13:37:59 +00:00
err = - 1 ;
}
}
else {
2010-07-28 12:11:40 +00:00
/* the error may be alredy set if the class instance couldnt be created */
if ( err ! = - 1 ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_RuntimeError , " could not create instance of %.200s to call callback function %.200s " , RNA_struct_identifier ( ptr - > type ) , RNA_function_identifier ( func ) ) ;
2010-07-28 12:11:40 +00:00
err = - 1 ;
}
2009-04-19 13:37:59 +00:00
}
if ( ret = = NULL ) { /* covers py_class_instance failing too */
err = - 1 ;
}
else {
2010-09-17 05:58:06 +00:00
if ( ret_len = = 0 & & ret ! = Py_None ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_RuntimeError , " expected class %.200s, function %.200s to return None, not %.200s " , RNA_struct_identifier ( ptr - > type ) , RNA_function_identifier ( func ) , Py_TYPE ( ret ) - > tp_name ) ;
2010-09-17 05:58:06 +00:00
err = - 1 ;
}
else if ( ret_len = = 1 ) {
2010-10-13 23:25:08 +00:00
err = pyrna_py_to_prop ( & funcptr , pret_single , retdata_single , ret , " calling class function: " ) ;
2010-01-02 10:42:38 +00:00
}
else if ( ret_len > 1 ) {
if ( PyTuple_Check ( ret ) = = 0 ) {
2011-02-14 08:14:52 +00:00
PyErr_Format ( PyExc_RuntimeError , " expected class %.200s, function %.200s to return a tuple of size %d, not %.200s " , RNA_struct_identifier ( ptr - > type ) , RNA_function_identifier ( func ) , ret_len , Py_TYPE ( ret ) - > tp_name ) ;
2010-01-02 10:42:38 +00:00
err = - 1 ;
}
else if ( PyTuple_GET_SIZE ( ret ) ! = ret_len ) {
2010-11-23 16:45:17 +00:00
PyErr_Format ( PyExc_RuntimeError , " class %.200s, function %.200s to returned %d items, expected %d " , RNA_struct_identifier ( ptr - > type ) , RNA_function_identifier ( func ) , PyTuple_GET_SIZE ( ret ) , ret_len ) ;
2010-01-02 10:42:38 +00:00
err = - 1 ;
}
else {
RNA_parameter_list_begin ( parms , & iter ) ;
/* parse function parameters */
for ( i = 0 ; iter . valid ; RNA_parameter_list_next ( & iter ) ) {
parm = iter . parm ;
flag = RNA_property_flag ( parm ) ;
/* only useful for single argument returns, we'll need another list loop for multiple */
2010-01-24 10:51:59 +00:00
if ( flag & PROP_OUTPUT ) {
2010-10-13 23:25:08 +00:00
err = pyrna_py_to_prop ( & funcptr , parm , iter . data , PyTuple_GET_ITEM ( ret , i + + ) , " calling class function: " ) ;
2010-01-02 10:42:38 +00:00
if ( err )
break ;
}
}
2010-01-02 19:01:19 +00:00
RNA_parameter_list_end ( & iter ) ;
2010-01-02 10:42:38 +00:00
}
}
2009-04-19 13:37:59 +00:00
Py_DECREF ( ret ) ;
}
2009-07-23 13:48:15 +00:00
if ( err ! = 0 ) {
2010-11-20 16:39:15 +00:00
ReportList * reports ;
/* alert the user, else they wont know unless they see the console. */
if ( ! is_static & & ptr - > data & & RNA_struct_is_a ( ptr - > type , & RNA_Operator ) ) {
wmOperator * op = ptr - > data ;
reports = op - > reports ;
}
else {
/* wont alert users but they can view in 'info' space */
reports = CTX_wm_reports ( C ) ;
}
BPy_errors_to_report ( reports ) ;
/* also print in the console for py */
2009-07-23 13:48:15 +00:00
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
}
2009-08-07 16:20:19 +00:00
bpy_context_clear ( C , & gilstate ) ;
2009-04-19 13:37:59 +00:00
return err ;
}
static void bpy_class_free ( void * pyob_ptr )
{
2009-08-14 12:29:55 +00:00
PyObject * self = ( PyObject * ) pyob_ptr ;
PyGILState_STATE gilstate ;
gilstate = PyGILState_Ensure ( ) ;
2010-02-15 11:24:43 +00:00
// breaks re-registering classes
// PyDict_Clear(((PyTypeObject*)self)->tp_dict);
//
// remove the rna attribute instead.
PyDict_DelItemString ( ( ( PyTypeObject * ) self ) - > tp_dict , " bl_rna " ) ;
if ( PyErr_Occurred ( ) )
PyErr_Clear ( ) ;
2009-08-14 12:29:55 +00:00
2011-01-09 11:54:12 +00:00
#if 0 /* needs further investigation, too annoying so quiet for now */
2009-05-28 02:03:48 +00:00
if ( G . f & G_DEBUG ) {
2009-08-14 12:29:55 +00:00
if ( self - > ob_refcnt > 1 ) {
2010-09-01 14:13:48 +00:00
PyC_ObSpit ( " zombie class - ref should be 1 " , self ) ;
2009-08-14 12:29:55 +00:00
}
2009-05-28 02:03:48 +00:00
}
2011-01-09 11:54:12 +00:00
# endif
2009-04-19 13:37:59 +00:00
Py_DECREF ( ( PyObject * ) pyob_ptr ) ;
2009-08-14 12:29:55 +00:00
PyGILState_Release ( gilstate ) ;
}
2009-08-15 09:53:38 +00:00
void pyrna_alloc_types ( void )
{
PyGILState_STATE gilstate ;
PointerRNA ptr ;
PropertyRNA * prop ;
2009-08-15 10:50:30 +00:00
gilstate = PyGILState_Ensure ( ) ;
2009-08-15 09:53:38 +00:00
/* avoid doing this lookup for every getattr */
RNA_blender_rna_pointer_create ( & ptr ) ;
prop = RNA_struct_find_property ( & ptr , " structs " ) ;
RNA_PROP_BEGIN ( & ptr , itemptr , prop ) {
2010-08-02 04:20:41 +00:00
PyObject * item = pyrna_struct_Subtype ( & itemptr ) ;
if ( item = = NULL ) {
if ( PyErr_Occurred ( ) ) {
PyErr_Print ( ) ;
PyErr_Clear ( ) ;
}
}
else {
Py_DECREF ( item ) ;
}
2009-08-15 09:53:38 +00:00
}
RNA_PROP_END ;
PyGILState_Release ( gilstate ) ;
}
2009-08-14 12:29:55 +00:00
void pyrna_free_types ( void )
{
PointerRNA ptr ;
PropertyRNA * prop ;
/* avoid doing this lookup for every getattr */
RNA_blender_rna_pointer_create ( & ptr ) ;
prop = RNA_struct_find_property ( & ptr , " structs " ) ;
RNA_PROP_BEGIN ( & ptr , itemptr , prop ) {
StructRNA * srna = srna_from_ptr ( & itemptr ) ;
void * py_ptr = RNA_struct_py_type_get ( srna ) ;
if ( py_ptr ) {
#if 0 // XXX - should be able to do this but makes python crash on exit
bpy_class_free ( py_ptr ) ;
# endif
RNA_struct_py_type_set ( srna , NULL ) ;
}
}
RNA_PROP_END ;
2009-12-24 19:50:43 +00:00
2009-04-19 13:37:59 +00:00
}
2009-08-16 04:59:11 +00:00
/* Note! MemLeak XXX
*
* There is currently a bug where moving registering a python class does
* not properly manage refcounts from the python class , since the srna owns
* the python class this should not be so tricky but changing the references as
* youd expect when changing ownership crashes blender on exit so I had to comment out
* the decref . This is not so bad because the leak only happens when re - registering ( hold F8 )
* - Should still be fixed - Campbell
* */
2011-02-11 00:11:17 +00:00
static char pyrna_register_class_doc [ ] =
" .. method:: register_class(cls) \n "
" \n "
" Register a subclass of a blender type in (:class:`Panel`, :class:`Menu`, :class:`Header`, :class:`Operator`, :class:`KeyingSetInfo`, :class:`RenderEngine`). \n "
" \n "
" .. note:: :exc:`ValueError` exception is raised if the class is not a subclass of a registerable blender class. \n "
" \n "
;
PyMethodDef meth_bpy_register_class = { " register_class " , pyrna_register_class , METH_O , pyrna_register_class_doc } ;
static PyObject * pyrna_register_class ( PyObject * UNUSED ( self ) , PyObject * py_class )
2009-04-19 13:37:59 +00:00
{
bContext * C = NULL ;
ReportList reports ;
StructRegisterFunc reg ;
StructRNA * srna ;
2009-08-15 09:53:38 +00:00
StructRNA * srna_new ;
2010-08-19 10:16:30 +00:00
const char * identifier ;
2009-04-19 13:37:59 +00:00
2010-03-22 09:30:00 +00:00
if ( PyDict_GetItemString ( ( ( PyTypeObject * ) py_class ) - > tp_dict , " bl_rna " ) ) {
2011-02-11 00:11:17 +00:00
PyErr_SetString ( PyExc_AttributeError , " register_class(...): already registered as a subclass " ) ;
2010-02-14 11:21:21 +00:00
return NULL ;
2010-03-22 09:30:00 +00:00
}
2010-02-14 11:21:21 +00:00
2010-03-22 09:30:00 +00:00
/* warning: gets parent classes srna, only for the register function */
2011-02-11 00:11:17 +00:00
srna = pyrna_struct_as_srna ( py_class , 1 , " register_class(...): " ) ;
2009-08-15 05:05:23 +00:00
if ( srna = = NULL )
2009-04-19 13:37:59 +00:00
return NULL ;
2010-08-02 04:20:41 +00:00
/* fails in cases, cant use this check but would like to :| */
/*
if ( RNA_struct_py_type_get ( srna ) ) {
2011-02-11 00:11:17 +00:00
PyErr_Format ( PyExc_ValueError , " register_class(...): %.200s's parent class %.200s is alredy registered, this is not allowed " , ( ( PyTypeObject * ) py_class ) - > tp_name , RNA_struct_identifier ( srna ) ) ;
2010-08-02 04:20:41 +00:00
return NULL ;
}
*/
2009-04-19 13:37:59 +00:00
/* check that we have a register callback for this type */
2009-08-15 05:05:23 +00:00
reg = RNA_struct_register ( srna ) ;
2009-04-19 13:37:59 +00:00
if ( ! reg ) {
2011-02-11 00:11:17 +00:00
PyErr_Format ( PyExc_ValueError , " register_class(...): expected a subclass of a registerable rna type (%.200s does not support registration) " , RNA_struct_identifier ( srna ) ) ;
2009-04-19 13:37:59 +00:00
return NULL ;
}
/* get the context, so register callback can do necessary refreshes */
2009-05-25 13:48:44 +00:00
C = BPy_GetContext ( ) ;
2009-04-19 13:37:59 +00:00
2.5: RNA, defining enums, pointers and collections properties is now
possible from python, but it's still work in progress.
Pointers and collections are restricted to types derived from
IDPropertyGroup (same as for operators), because RNA knows how to
allocate/deallocate those.
Collections have .add() and .remove(number) functions that can be
used. The remove function should be fixed to take an other argument
than a number.
With the IDPropertyGroup restriction, pointers are more like nested
structs. They don't have add(), remove() yet, not sure where to put
them. Currently the pointer / nested struct is automatically allocated
in the get() function, this needs to be fixed, rule is that RNA get()
will not change any data for thread safety.
Also, it is only possible to add properties to structs after they have
been registered, which needs to be improved as well.
Example code:
http://www.pasteall.org/7201/python
2009-08-18 01:29:25 +00:00
/* call the register callback with reports & identifier */
2009-06-18 19:48:55 +00:00
BKE_reports_init ( & reports , RPT_STORE ) ;
2.5: RNA, defining enums, pointers and collections properties is now
possible from python, but it's still work in progress.
Pointers and collections are restricted to types derived from
IDPropertyGroup (same as for operators), because RNA knows how to
allocate/deallocate those.
Collections have .add() and .remove(number) functions that can be
used. The remove function should be fixed to take an other argument
than a number.
With the IDPropertyGroup restriction, pointers are more like nested
structs. They don't have add(), remove() yet, not sure where to put
them. Currently the pointer / nested struct is automatically allocated
in the get() function, this needs to be fixed, rule is that RNA get()
will not change any data for thread safety.
Also, it is only possible to add properties to structs after they have
been registered, which needs to be improved as well.
Example code:
http://www.pasteall.org/7201/python
2009-08-18 01:29:25 +00:00
2010-08-19 10:16:30 +00:00
identifier = ( ( PyTypeObject * ) py_class ) - > tp_name ;
2.5: RNA, defining enums, pointers and collections properties is now
possible from python, but it's still work in progress.
Pointers and collections are restricted to types derived from
IDPropertyGroup (same as for operators), because RNA knows how to
allocate/deallocate those.
Collections have .add() and .remove(number) functions that can be
used. The remove function should be fixed to take an other argument
than a number.
With the IDPropertyGroup restriction, pointers are more like nested
structs. They don't have add(), remove() yet, not sure where to put
them. Currently the pointer / nested struct is automatically allocated
in the get() function, this needs to be fixed, rule is that RNA get()
will not change any data for thread safety.
Also, it is only possible to add properties to structs after they have
been registered, which needs to be improved as well.
Example code:
http://www.pasteall.org/7201/python
2009-08-18 01:29:25 +00:00
srna_new = reg ( C , & reports , py_class , identifier , bpy_class_validate , bpy_class_call , bpy_class_free ) ;
2009-04-19 13:37:59 +00:00
2010-12-31 05:40:30 +00:00
if ( BPy_reports_to_error ( & reports , TRUE ) )
2009-04-19 13:37:59 +00:00
return NULL ;
2011-01-03 18:15:15 +00:00
/* python errors validating are not converted into reports so the check above will fail.
* the cause for returning NULL will be printed as an error */
if ( srna_new = = NULL )
return NULL ;
2009-04-19 13:37:59 +00:00
2009-08-15 09:53:38 +00:00
pyrna_subtype_set_rna ( py_class , srna_new ) ; /* takes a ref to py_class */
/* old srna still references us, keep the check incase registering somehow can free it */
if ( RNA_struct_py_type_get ( srna ) ) {
RNA_struct_py_type_set ( srna , NULL ) ;
// Py_DECREF(py_class); // shuld be able to do this XXX since the old rna adds a new ref.
}
2009-04-19 13:37:59 +00:00
define operator properties in the class, similar to django fields
# Before
[
bpy.props.StringProperty(attr="path", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= ""),
bpy.props.BoolProperty(attr="use_modifiers", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True),
bpy.props.BoolProperty(attr="use_normals", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True),
bpy.props.BoolProperty(attr="use_uvs", name="Export UVs", description="Exort the active UV layer", default= True),
bpy.props.BoolProperty(attr="use_colors", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
]
# After
path = StringProperty(attr="", name="File Path", description="File path used for exporting the PLY file", maxlen= 1024, default= "")
use_modifiers = BoolProperty(attr="", name="Apply Modifiers", description="Apply Modifiers to the exported mesh", default= True)
use_normals = BoolProperty(attr="", name="Export Normals", description="Export Normals for smooth and hard shaded faces", default= True)
use_uvs = BoolProperty(attr="", name="Export UVs", description="Exort the active UV layer", default= True)
use_colors = BoolProperty(attr="", name="Export Vertex Colors", description="Exort the active vertex color layer", default= True)
2009-10-31 16:40:14 +00:00
/* Can't use this because it returns a dict proxy
*
* item = PyObject_GetAttrString ( py_class , " __dict__ " ) ;
*/
2010-08-19 10:16:30 +00:00
if ( pyrna_deferred_register_class ( srna_new , py_class ) ! = 0 )
return NULL ;
2009-08-22 17:30:47 +00:00
2009-04-19 13:37:59 +00:00
Py_RETURN_NONE ;
}
2010-07-23 01:43:30 +00:00
static int pyrna_srna_contains_pointer_prop_srna ( StructRNA * srna_props , StructRNA * srna , const char * * prop_identifier )
{
2011-01-25 07:31:11 +00:00
PropertyRNA * prop ;
LinkData * link ;
2010-07-23 01:43:30 +00:00
2011-01-25 07:31:11 +00:00
/* verify properties */
const ListBase * lb = RNA_struct_type_properties ( srna ) ;
for ( link = lb - > first ; link ; link = link - > next ) {
prop = ( PropertyRNA * ) link ;
if ( RNA_property_type ( prop ) = = PROP_POINTER & & ! ( RNA_property_flag ( prop ) & PROP_BUILTIN ) ) {
PointerRNA tptr ;
RNA_pointer_create ( NULL , & RNA_Struct , srna_props , & tptr ) ;
if ( RNA_property_pointer_type ( & tptr , prop ) = = srna ) {
2010-07-23 01:43:30 +00:00
* prop_identifier = RNA_property_identifier ( prop ) ;
return 1 ;
}
}
}
2011-01-25 07:31:11 +00:00
2010-07-23 01:43:30 +00:00
return 0 ;
}
2011-02-11 00:11:17 +00:00
static char pyrna_unregister_class_doc [ ] =
" .. method:: unregister_class(cls) \n "
" \n "
" Unload the python class from blender. \n "
;
PyMethodDef meth_bpy_unregister_class = { " unregister_class " , pyrna_unregister_class , METH_O , pyrna_unregister_class_doc } ;
static PyObject * pyrna_unregister_class ( PyObject * UNUSED ( self ) , PyObject * py_class )
2009-04-19 13:37:59 +00:00
{
bContext * C = NULL ;
StructUnregisterFunc unreg ;
2009-08-15 05:05:23 +00:00
StructRNA * srna ;
2009-04-19 13:37:59 +00:00
2010-03-22 09:30:00 +00:00
/*if(PyDict_GetItemString(((PyTypeObject*)py_class)->tp_dict, "bl_rna")==NULL) {
2010-07-23 01:43:30 +00:00
PWM_cursor_wait ( 0 ) ;
2011-02-11 00:11:17 +00:00
PyErr_SetString ( PyExc_ValueError , " unregister_class(): not a registered as a subclass " ) ;
2010-02-15 11:24:43 +00:00
return NULL ;
2010-03-22 09:30:00 +00:00
} */
2010-02-15 11:24:43 +00:00
2011-02-11 00:11:17 +00:00
srna = pyrna_struct_as_srna ( py_class , 0 , " unregister_class(...): " ) ;
2009-08-15 05:05:23 +00:00
if ( srna = = NULL )
2009-04-19 13:37:59 +00:00
return NULL ;
/* check that we have a unregister callback for this type */
2009-08-15 05:05:23 +00:00
unreg = RNA_struct_unregister ( srna ) ;
2009-04-19 13:37:59 +00:00
if ( ! unreg ) {
2011-02-11 00:11:17 +00:00
PyErr_SetString ( PyExc_ValueError , " unregister_class(...): expected a Type subclassed from a registerable rna type (no unregister supported) " ) ;
2009-04-19 13:37:59 +00:00
return NULL ;
}
2010-07-23 01:43:30 +00:00
/* should happen all the time but very slow */
if ( G . f & G_DEBUG ) {
/* remove all properties using this class */
StructRNA * srna_iter ;
PointerRNA ptr_rna ;
PropertyRNA * prop_rna ;
const char * prop_identifier = NULL ;
RNA_blender_rna_pointer_create ( & ptr_rna ) ;
prop_rna = RNA_struct_find_property ( & ptr_rna , " structs " ) ;
/* loop over all structs */
RNA_PROP_BEGIN ( & ptr_rna , itemptr , prop_rna ) {
srna_iter = itemptr . data ;
if ( pyrna_srna_contains_pointer_prop_srna ( srna_iter , srna , & prop_identifier ) ) {
break ;
}
}
RNA_PROP_END ;
if ( prop_identifier ) {
2011-02-11 00:11:17 +00:00
PyErr_Format ( PyExc_SystemError , " unregister_class(...): Cant unregister %s because %s.%s pointer property is using this " , RNA_struct_identifier ( srna ) , RNA_struct_identifier ( srna_iter ) , prop_identifier ) ;
2010-07-23 01:43:30 +00:00
return NULL ;
}
}
2009-04-19 13:37:59 +00:00
/* get the context, so register callback can do necessary refreshes */
2009-05-25 13:48:44 +00:00
C = BPy_GetContext ( ) ;
2009-04-19 13:37:59 +00:00
/* call unregister */
2009-08-15 09:53:38 +00:00
unreg ( C , srna ) ; /* calls bpy_class_free, this decref's py_class */
2009-04-19 13:37:59 +00:00
2010-02-15 11:24:43 +00:00
PyDict_DelItemString ( ( ( PyTypeObject * ) py_class ) - > tp_dict , " bl_rna " ) ;
if ( PyErr_Occurred ( ) )
PyErr_Clear ( ) ; //return NULL;
2010-02-14 23:33:18 +00:00
2009-04-19 13:37:59 +00:00
Py_RETURN_NONE ;
}