Logo Search packages:      
Sourcecode: blender version File versions

vector.c

/*
 * $Id: vector.c,v 1.16 2004/10/14 17:35:15 stiv Exp $
 * ***** BEGIN GPL/BL DUAL 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. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * 
 * Contributor(s): Willian P. Germano & Joseph Gilbert
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */

#include "vector.h"

//doc strings
char Vector_Zero_doc[] = "() - set all values in the vector to 0";
char Vector_Normalize_doc[] = "() - normalize the vector";
char Vector_Negate_doc[] = "() - changes vector to it's additive inverse";
char Vector_Resize2D_doc[] = "() - resize a vector to [x,y]";
char Vector_Resize3D_doc[] = "() - resize a vector to [x,y,z]";
char Vector_Resize4D_doc[] = "() - resize a vector to [x,y,z,w]";

//method table
struct PyMethodDef Vector_methods[] = {
      {"zero", ( PyCFunction ) Vector_Zero, METH_NOARGS,
       Vector_Zero_doc},
      {"normalize", ( PyCFunction ) Vector_Normalize, METH_NOARGS,
       Vector_Normalize_doc},
      {"negate", ( PyCFunction ) Vector_Negate, METH_NOARGS,
       Vector_Negate_doc},
      {"resize2D", ( PyCFunction ) Vector_Resize2D, METH_NOARGS,
       Vector_Resize2D_doc},
      {"resize3D", ( PyCFunction ) Vector_Resize3D, METH_NOARGS,
       Vector_Resize2D_doc},
      {"resize4D", ( PyCFunction ) Vector_Resize4D, METH_NOARGS,
       Vector_Resize2D_doc},
      {NULL, NULL, 0, NULL}
};

/*****************************/
//    Vector Python Object   
/*****************************/

//object methods
PyObject *Vector_Zero( VectorObject * self )
{
      int x;
      for( x = 0; x < self->size; x++ ) {
            self->vec[x] = 0.0f;
      }

      return EXPP_incr_ret( Py_None );
}

PyObject *Vector_Normalize( VectorObject * self )
{
      float norm;
      int x;

      norm = 0.0f;
      for( x = 0; x < self->size; x++ ) {
            norm += self->vec[x] * self->vec[x];
      }
      norm = ( float ) sqrt( norm );
      for( x = 0; x < self->size; x++ ) {
            self->vec[x] /= norm;
      }

      return EXPP_incr_ret( Py_None );
}

PyObject *Vector_Negate( VectorObject * self )
{
      int x;
      for( x = 0; x < self->size; x++ ) {
            self->vec[x] = -( self->vec[x] );
      }

      return EXPP_incr_ret( Py_None );
}

PyObject *Vector_Resize2D( VectorObject * self )
{
      float x, y;

      if( self->size == 4 || self->size == 3 ) {
            x = self->vec[0];
            y = self->vec[1];
            PyMem_Free( self->vec );
            self->vec = PyMem_Malloc( 2 * sizeof( float ) );
            self->vec[0] = x;
            self->vec[1] = y;
            self->size = 2;
      }

      return EXPP_incr_ret( Py_None );
}

PyObject *Vector_Resize3D( VectorObject * self )
{
      float x, y, z;

      if( self->size == 2 ) {
            x = self->vec[0];
            y = self->vec[1];
            PyMem_Free( self->vec );
            self->vec = PyMem_Malloc( 3 * sizeof( float ) );
            self->vec[0] = x;
            self->vec[1] = y;
            self->vec[2] = 0.0f;
            self->size = 3;
      } else if( self->size == 4 ) {
            x = self->vec[0];
            y = self->vec[1];
            z = self->vec[2];
            PyMem_Free( self->vec );
            self->vec = PyMem_Malloc( 3 * sizeof( float ) );
            self->vec[0] = x;
            self->vec[1] = y;
            self->vec[2] = z;
            self->size = 3;
      }

      return EXPP_incr_ret( Py_None );
}

PyObject *Vector_Resize4D( VectorObject * self )
{
      float x, y, z;

      if( self->size == 2 ) {
            x = self->vec[0];
            y = self->vec[1];
            PyMem_Free( self->vec );
            self->vec = PyMem_Malloc( 4 * sizeof( float ) );
            self->vec[0] = x;
            self->vec[1] = y;
            self->vec[2] = 0.0f;
            self->vec[3] = 1.0f;
            self->size = 4;
      } else if( self->size == 3 ) {
            x = self->vec[0];
            y = self->vec[1];
            z = self->vec[2];
            PyMem_Free( self->vec );
            self->vec = PyMem_Malloc( 4 * sizeof( float ) );
            self->vec[0] = x;
            self->vec[1] = y;
            self->vec[2] = z;
            self->vec[3] = 1.0f;
            self->size = 4;
      }

      return EXPP_incr_ret( Py_None );
}

static void Vector_dealloc( VectorObject * self )
{
      /* if we own this memory we must delete it */
      if( self->delete_pymem )
            PyMem_Free( self->vec );

      PyObject_DEL( self );
}

static PyObject *Vector_getattr( VectorObject * self, char *name )
{
      if( self->size == 4 && ELEM4( name[0], 'x', 'y', 'z', 'w' )
          && name[1] == 0 ) {
            if( ( name[0] ) == ( 'w' ) ) {
                  return PyFloat_FromDouble( self->vec[3] );
            } else {
                  return PyFloat_FromDouble( self->vec[name[0] - 'x'] );
            }
      } else if( self->size == 3 && ELEM3( name[0], 'x', 'y', 'z' )
               && name[1] == 0 )
            return PyFloat_FromDouble( self->vec[name[0] - 'x'] );
      else if( self->size == 2 && ELEM( name[0], 'x', 'y' ) && name[1] == 0 )
            return PyFloat_FromDouble( self->vec[name[0] - 'x'] );

      if( ( strcmp( name, "length" ) == 0 ) ) {
            if( self->size == 4 ) {
                  return PyFloat_FromDouble( sqrt
                                       ( self->vec[0] *
                                         self->vec[0] +
                                         self->vec[1] *
                                         self->vec[1] +
                                         self->vec[2] *
                                         self->vec[2] +
                                         self->vec[3] *
                                         self->vec[3] ) );
            } else if( self->size == 3 ) {
                  return PyFloat_FromDouble( sqrt
                                       ( self->vec[0] *
                                         self->vec[0] +
                                         self->vec[1] *
                                         self->vec[1] +
                                         self->vec[2] *
                                         self->vec[2] ) );
            } else if( self->size == 2 ) {
                  return PyFloat_FromDouble( sqrt
                                       ( self->vec[0] *
                                         self->vec[0] +
                                         self->vec[1] *
                                         self->vec[1] ) );
            } else
                  return EXPP_ReturnPyObjError( PyExc_AttributeError,
                                          "can only return the length of a 2D ,3D or 4D vector\n" );
      }

      return Py_FindMethod( Vector_methods, ( PyObject * ) self, name );
}

static int Vector_setattr( VectorObject * self, char *name, PyObject * v )
{
      float val;
      int valTemp;

      if( !PyFloat_Check( v ) ) {
            if( !PyInt_Check( v ) ) {
                  return EXPP_ReturnIntError( PyExc_TypeError,
                                        "int or float expected\n" );
            } else {
                  if( !PyArg_Parse( v, "i", &valTemp ) )
                        return EXPP_ReturnIntError( PyExc_TypeError,
                                              "unable to parse int argument\n" );
                  val = ( float ) valTemp;
            }
      } else {
            if( !PyArg_Parse( v, "f", &val ) )
                  return EXPP_ReturnIntError( PyExc_TypeError,
                                        "unable to parse float argument\n" );
      }
      if( self->size == 4 && ELEM4( name[0], 'x', 'y', 'z', 'w' )
          && name[1] == 0 ) {
            if( ( name[0] ) == ( 'w' ) ) {
                  self->vec[3] = val;
            } else {
                  self->vec[name[0] - 'x'] = val;
            }
      } else if( self->size == 3 && ELEM3( name[0], 'x', 'y', 'z' )
               && name[1] == 0 )
            self->vec[name[0] - 'x'] = val;
      else if( self->size == 2 && ELEM( name[0], 'x', 'y' ) && name[1] == 0 )
            self->vec[name[0] - 'x'] = val;
      else
            return -1;

      return 0;
}

/* Vectors Sequence methods */
static int Vector_len( VectorObject * self )
{
      return self->size;
}

static PyObject *Vector_item( VectorObject * self, int i )
{
      if( i < 0 || i >= self->size )
            return EXPP_ReturnPyObjError( PyExc_IndexError,
                                    "array index out of range\n" );

      return Py_BuildValue( "f", self->vec[i] );

}

static PyObject *Vector_slice( VectorObject * self, int begin, int end )
{
      PyObject *list;
      int count;

      if( begin < 0 )
            begin = 0;
      if( end > self->size )
            end = self->size;
      if( begin > end )
            begin = end;

      list = PyList_New( end - begin );

      for( count = begin; count < end; count++ ) {
            PyList_SetItem( list, count - begin,
                        PyFloat_FromDouble( self->vec[count] ) );
      }

      return list;
}

static int Vector_ass_item( VectorObject * self, int i, PyObject * ob )
{
      if( i < 0 || i >= self->size )
            return EXPP_ReturnIntError( PyExc_IndexError,
                                  "array assignment index out of range\n" );
      if( !PyInt_Check( ob ) && !PyFloat_Check( ob ) )
            return EXPP_ReturnIntError( PyExc_IndexError,
                                  "vector member must be a number\n" );

      self->vec[i] = ( float ) PyFloat_AsDouble( ob );

      return 0;
}

static int Vector_ass_slice( VectorObject * self, int begin, int end,
                       PyObject * seq )
{
      int count, z;

      if( begin < 0 )
            begin = 0;
      if( end > self->size )
            end = self->size;
      if( begin > end )
            begin = end;

      if( !PySequence_Check( seq ) )
            return EXPP_ReturnIntError( PyExc_TypeError,
                                  "illegal argument type for built-in operation\n" );
      if( PySequence_Length( seq ) != ( end - begin ) )
            return EXPP_ReturnIntError( PyExc_TypeError,
                                  "size mismatch in slice assignment\n" );

      z = 0;
      for( count = begin; count < end; count++ ) {
            PyObject *ob = PySequence_GetItem( seq, z );
            z++;
            if( !PyInt_Check( ob ) && !PyFloat_Check( ob ) )
                  return EXPP_ReturnIntError( PyExc_IndexError,
                                        "list member must be a number\n" );

            if( !PyArg_Parse( ob, "f", &self->vec[count] ) ) {
                  Py_DECREF( ob );
                  return -1;
            }
      }

      return 0;
}

static PyObject *Vector_repr( VectorObject * self )
{
      int i, maxindex = self->size - 1;
      char ftoa[24];
      PyObject *str1, *str2;

      str1 = PyString_FromString( "[" );

      for( i = 0; i < maxindex; i++ ) {
            sprintf( ftoa, "%.4f, ", self->vec[i] );
            str2 = PyString_FromString( ftoa );
            if( !str1 || !str2 )
                  goto error;
            PyString_ConcatAndDel( &str1, str2 );
      }

      sprintf( ftoa, "%.4f]", self->vec[maxindex] );
      str2 = PyString_FromString( ftoa );
      if( !str1 || !str2 )
            goto error;
      PyString_ConcatAndDel( &str1, str2 );

      if( str1 )
            return str1;

      error:
      Py_XDECREF( str1 );
      Py_XDECREF( str2 );
      return EXPP_ReturnPyObjError( PyExc_MemoryError,
                              "couldn't create PyString!\n" );
}


PyObject *Vector_add( PyObject * v1, PyObject * v2 )
{
      float *vec;
      int x;
      PyObject *retval;

      if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "unsupported type for this operation\n" );
      if( ( ( VectorObject * ) v1 )->flag != 0
          || ( ( VectorObject * ) v2 )->flag != 0 )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "cannot add a scalar to a vector\n" );
      if( ( ( VectorObject * ) v1 )->size !=
          ( ( VectorObject * ) v2 )->size )
            return EXPP_ReturnPyObjError( PyExc_AttributeError,
                                    "vectors must have the same dimensions for this operation\n" );

      vec = PyMem_Malloc( ( ( ( VectorObject * ) v1 )->size ) *
                      sizeof( float ) );

      for( x = 0; x < ( ( VectorObject * ) v1 )->size; x++ ) {
            vec[x] = ( ( VectorObject * ) v1 )->vec[x] +
                  ( ( VectorObject * ) v2 )->vec[x];
      }

      retval = ( PyObject * ) newVectorObject( vec,
                                     ( ( ( VectorObject * ) v1 )->
                                       size ) );
      PyMem_Free( vec );
      return retval;
}

PyObject *Vector_sub( PyObject * v1, PyObject * v2 )
{
      float *vec;
      int x;
      PyObject *retval;

      if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "unsupported type for this operation\n" );
      if( ( ( VectorObject * ) v1 )->flag != 0
          || ( ( VectorObject * ) v2 )->flag != 0 )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "cannot subtract a scalar from a vector\n" );
      if( ( ( VectorObject * ) v1 )->size !=
          ( ( VectorObject * ) v2 )->size )
            return EXPP_ReturnPyObjError( PyExc_AttributeError,
                                    "vectors must have the same dimensions for this operation\n" );

      vec = PyMem_Malloc( ( ( ( VectorObject * ) v1 )->size ) *
                      sizeof( float ) );

      for( x = 0; x < ( ( VectorObject * ) v1 )->size; x++ ) {
            vec[x] = ( ( VectorObject * ) v1 )->vec[x] -
                  ( ( VectorObject * ) v2 )->vec[x];
      }

      retval = ( PyObject * ) newVectorObject( vec,
                                     ( ( ( VectorObject * ) v1 )->
                                       size ) );
      PyMem_Free( vec );
      return retval;
}

PyObject *Vector_mul( PyObject * v1, PyObject * v2 )
{
      float *vec;
      int x;
      PyObject *retval;

      if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "unsupported type for this operation\n" );
      if( ( ( VectorObject * ) v1 )->flag == 0
          && ( ( VectorObject * ) v2 )->flag == 0 )
            return EXPP_ReturnPyObjError( PyExc_ArithmeticError,
                                    "please use the dot product or the cross product to multiply vectors\n" );
      if( ( ( VectorObject * ) v1 )->size !=
          ( ( VectorObject * ) v2 )->size )
            return EXPP_ReturnPyObjError( PyExc_AttributeError,
                                    "vector dimension error during Vector_mul\n" );

      vec = PyMem_Malloc( ( ( ( VectorObject * ) v1 )->size ) *
                      sizeof( float ) );

      for( x = 0; x < ( ( VectorObject * ) v1 )->size; x++ ) {
            vec[x] = ( ( VectorObject * ) v1 )->vec[x] *
                  ( ( VectorObject * ) v2 )->vec[x];
      }

      retval =  ( PyObject * ) newVectorObject( vec,
                                      ( ( ( VectorObject * ) v1 )->
                                        size ) );
      PyMem_Free( vec );
      return retval;
}

PyObject *Vector_div( PyObject * v1, PyObject * v2 )
{
      float *vec;
      int x;
      PyObject *retval;

      if( ( !VectorObject_Check( v1 ) ) || ( !VectorObject_Check( v2 ) ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "unsupported type for this operation\n" );
      if( ( ( VectorObject * ) v1 )->flag == 0
          && ( ( VectorObject * ) v2 )->flag == 0 )
            return EXPP_ReturnPyObjError( PyExc_ArithmeticError,
                                    "cannot divide two vectors\n" );
      if( ( ( VectorObject * ) v1 )->flag != 0
          && ( ( VectorObject * ) v2 )->flag == 0 )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "cannot divide a scalar by a vector\n" );
      if( ( ( VectorObject * ) v1 )->size !=
          ( ( VectorObject * ) v2 )->size )
            return EXPP_ReturnPyObjError( PyExc_AttributeError,
                                    "vector dimension error during Vector_mul\n" );

      vec = PyMem_Malloc( ( ( ( VectorObject * ) v1 )->size ) *
                      sizeof( float ) );

      for( x = 0; x < ( ( VectorObject * ) v1 )->size; x++ ) {
            vec[x] = ( ( VectorObject * ) v1 )->vec[x] /
                  ( ( VectorObject * ) v2 )->vec[x];
      }

      retval =  ( PyObject * ) newVectorObject( vec,
                                      ( ( ( VectorObject * ) v1 )->
                                        size ) );
      PyMem_Free( vec );
      return retval;
}

//coercion of unknown types to type VectorObject for numeric protocols
int Vector_coerce( PyObject ** v1, PyObject ** v2 )
{
      long *tempI;
      double *tempF;
      float *vec;
      int x;

      if( VectorObject_Check( *v1 ) ) {
            if( VectorObject_Check( *v2 ) ) {   //two vectors
                  Py_INCREF( *v1 );  /* fixme:  wahy are we bumping the ref count? */
                  Py_INCREF( *v2 );
                  return 0;
            } else {
                  if( Matrix_CheckPyObject( *v2 ) ) {
                        printf( "vector/matrix numeric protocols unsupported...\n" );
                        Py_INCREF( *v1 );
                        return 0;   //operation will type check
                  } else if( PyNumber_Check( *v2 ) ) {
                        if( PyInt_Check( *v2 ) ) {    //cast scalar to vector
                              tempI = PyMem_Malloc( 1 *
                                                sizeof( long ) );
                              *tempI = PyInt_AsLong( *v2 );
                              vec = PyMem_Malloc( ( ( ( VectorObject
                                                  * ) *
                                                v1 )->size ) *
                                              sizeof( float ) );
                              for( x = 0;
                                   x <  ( ( ( VectorObject * ) * v1 )->size );
                                   x++ ) {
                                    vec[x] = ( float ) *tempI;
                              }
                              PyMem_Free( tempI );
                              *v2 = newVectorObject( vec,
                                                 ( ( ( VectorObject * ) * v1 )->size ) );
                              ( ( VectorObject * ) * v2 )->flag = 1;    //int coercion
                              Py_INCREF( *v1 );
                              return 0;
                        } else if( PyFloat_Check( *v2 ) ) { //cast scalar to vector
                              tempF = PyMem_Malloc( 1 *
                                                sizeof
                                                ( double ) );
                              *tempF = PyFloat_AsDouble( *v2 );
                              vec = PyMem_Malloc( ( ( ( VectorObject
                                                  * ) *
                                                v1 )->size ) *
                                              sizeof( float ) );
                              for( x = 0;
                                   x <
                                   ( ( ( VectorObject * ) *
                                     v1 )->size ); x++ ) {
                                    vec[x] = ( float ) *tempF;
                              }
                              PyMem_Free( tempF );
                              *v2 = newVectorObject( vec,
                                                 ( ( ( VectorObject * ) * v1 )->size ) );
                              ( ( VectorObject * ) * v2 )->flag = 2;    //float coercion
                              Py_INCREF( *v1 );
                              return 0;
                        }
                  }
                  //unknown type or numeric cast failure
                  printf( "attempting vector operation with unsupported type...\n" );
                  Py_INCREF( *v1 );
                  return 0;   //operation will type check
            }
      } else {
            printf( "numeric protocol failure...\n" );
            return -1;  //this should not occur - fail
      }
      return -1;
}


static PySequenceMethods Vector_SeqMethods = {
      ( inquiry ) Vector_len, /* sq_length */
      ( binaryfunc ) 0, /* sq_concat */
      ( intargfunc ) 0, /* sq_repeat */
      ( intargfunc ) Vector_item,   /* sq_item */
      ( intintargfunc ) Vector_slice,     /* sq_slice */
      ( intobjargproc ) Vector_ass_item,  /* sq_ass_item */
      ( intintobjargproc ) Vector_ass_slice,    /* sq_ass_slice */
};

static PyNumberMethods Vector_NumMethods = {
      ( binaryfunc ) Vector_add,    /* __add__ */
      ( binaryfunc ) Vector_sub,    /* __sub__ */
      ( binaryfunc ) Vector_mul,    /* __mul__ */
      ( binaryfunc ) Vector_div,    /* __div__ */
      ( binaryfunc ) 0, /* __mod__ */
      ( binaryfunc ) 0, /* __divmod__ */
      ( ternaryfunc ) 0,      /* __pow__ */
      ( unaryfunc ) 0,  /* __neg__ */
      ( unaryfunc ) 0,  /* __pos__ */
      ( unaryfunc ) 0,  /* __abs__ */
      ( inquiry ) 0,          /* __nonzero__ */
      ( unaryfunc ) 0,  /* __invert__ */
      ( binaryfunc ) 0, /* __lshift__ */
      ( binaryfunc ) 0, /* __rshift__ */
      ( binaryfunc ) 0, /* __and__ */
      ( binaryfunc ) 0, /* __xor__ */
      ( binaryfunc ) 0, /* __or__ */
      ( coercion ) Vector_coerce,   /* __coerce__ */
      ( unaryfunc ) 0,  /* __int__ */
      ( unaryfunc ) 0,  /* __long__ */
      ( unaryfunc ) 0,  /* __float__ */
      ( unaryfunc ) 0,  /* __oct__ */
      ( unaryfunc ) 0,  /* __hex__ */

};

PyTypeObject vector_Type = {
      PyObject_HEAD_INIT( NULL ) 0, /*ob_size */
      "vector",         /*tp_name */
      sizeof( VectorObject ), /*tp_basicsize */
      0,                /*tp_itemsize */
      ( destructor ) Vector_dealloc,      /*tp_dealloc */
      ( printfunc ) 0,  /*tp_print */
      ( getattrfunc ) Vector_getattr,     /*tp_getattr */
      ( setattrfunc ) Vector_setattr,     /*tp_setattr */
      0,                /*tp_compare */
      ( reprfunc ) Vector_repr,     /*tp_repr */
      &Vector_NumMethods,     /*tp_as_number */
      &Vector_SeqMethods,     /*tp_as_sequence */
};


/* 
 * create a Vector Object( vec, size )
 *
 *  Note: Vector now  uses copy semantics like STL containers.
 *   Memory for vec member is allocated on python stack.  
 *   We own this memory and will free it later. 
 *  
 * size arg is number of floats to alloc.
 *
 * if vec arg is NULL
 *   fill our vec with zeros
 *   initialize 4d vectors to zero in homogenous coords.
 * else
 *   vec param is copied into our local memory and always freed.
 */

PyObject *newVectorObject( float *vec, int size )
{
      VectorObject *self;
      int x;

      vector_Type.ob_type = &PyType_Type;

      self = PyObject_NEW( VectorObject, &vector_Type );

      self->vec = PyMem_Malloc( size * sizeof( float ) );
      self->delete_pymem = 1; /* must free this alloc later */

      if( !vec ) {
            for( x = 0; x < size; x++ ) {
                  self->vec[x] = 0.0f;
            }
            if( size == 4 )  /* do the homogenous thing */
                  self->vec[3] = 1.0f;
      } else {
            for( x = 0; x < size; x++ ){
                  self->vec[x] = vec[x];
            }
      }

      self->size = size;
      self->flag = 0;

      return ( PyObject * ) self;
}


/*
  create a Vector that is a proxy for blender data.
  we do not own this data, we NEVER free it.
  Note: users must deal with bad pointer issue
*/

PyObject *newVectorProxy( float *vec, int size)
{
      VectorObject *proxy;
      int x;

      proxy = PyObject_NEW( VectorObject, &vector_Type );

      proxy->delete_pymem = 0;      /* must NOT free this alloc later */

      if( !vec || size < 1 ) {
            return EXPP_ReturnPyObjError( PyExc_AttributeError,
                               "cannot creat zero length vector proxy" );
      }
            
      proxy->vec = vec;
      proxy->size = size;
      proxy->flag = 0;

      return ( PyObject * ) proxy;
}
      

Generated by  Doxygen 1.6.0   Back to index