Logo Search packages:      
Sourcecode: blender version File versions

sceneRadio.c

/* 
 * $Id: sceneRadio.c,v 1.5 2004/09/25 20:30:40 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.
 *
 * This is a new part of Blender.
 *
 * Contributor(s): Willian P. Germano
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
*/

#include "sceneRadio.h"       /* includes Python.h */
#include "radio.h"
#include <BKE_object.h>       /* disable_where_script() */

#include "gen_utils.h"
#include "constant.h"

/* bitflags */
#define EXPP_RADIO_flag_SHOWLIM 1
#define EXPP_RADIO_flag_Z 2
/* shorts */
#define EXPP_RADIO_hemires_MIN 100
#define EXPP_RADIO_hemires_MAX 1000
#define EXPP_RADIO_maxiter_MIN 0
#define EXPP_RADIO_maxiter_MAX 10000
#define EXPP_RADIO_subshootp_MIN 0
#define EXPP_RADIO_subshootp_MAX 10
#define EXPP_RADIO_subshoote_MIN 0
#define EXPP_RADIO_subshoote_MAX 10
#define EXPP_RADIO_nodelim_MIN 0
#define EXPP_RADIO_nodelim_MAX 50
#define EXPP_RADIO_maxsublamp_MIN 1
#define EXPP_RADIO_maxsublamp_MAX 250
#define EXPP_RADIO_pama_MIN 10
#define EXPP_RADIO_pama_MAX 1000
#define EXPP_RADIO_pami_MIN 10
#define EXPP_RADIO_pami_MAX 1000
#define EXPP_RADIO_elma_MIN 1
#define EXPP_RADIO_elma_MAX 500
#define EXPP_RADIO_elmi_MIN 1
#define EXPP_RADIO_elmi_MAX 500
/* ints */
#define EXPP_RADIO_maxnode_MIN 1
#define EXPP_RADIO_maxnode_MAX 250000
/* floats */
#define EXPP_RADIO_convergence_MIN 0.0
#define EXPP_RADIO_convergence_MAX 0.1
#define EXPP_RADIO_radfac_MIN 0.001
#define EXPP_RADIO_radfac_MAX 250.0
#define EXPP_RADIO_gamma_MIN 0.2
#define EXPP_RADIO_gamma_MAX 10.0
/* drawtypes */
#define EXPP_RADIO_drawtype_WIRE 0
#define EXPP_RADIO_drawtype_SOLID 1
#define EXPP_RADIO_drawtype_GOURAUD 2

static int EXPP_check_scene( Scene * scene )
{
      if( scene != G.scene ) {
            PyErr_SetString( PyExc_EnvironmentError,
                         "\nradiosity only works on the current scene, check scene.makeCurrent()." );
            return 0;
      } else if( !scene->radio ) {
            PyErr_SetString( PyExc_EnvironmentError,
                         "\nradiosity data was deleted from scene!" );
            return 0;
      }

      return 1;
}

static PyObject *Radio_collectMeshes( BPy_Radio * self );
static PyObject *Radio_go( BPy_Radio * self );
static PyObject *Radio_freeData( BPy_Radio * self );
static PyObject *Radio_replaceMeshes( BPy_Radio * self );
static PyObject *Radio_addMesh( BPy_Radio * self );
static PyObject *Radio_filterFaces( BPy_Radio * self );
static PyObject *Radio_filterElems( BPy_Radio * self );
static PyObject *Radio_limitSubdivide( BPy_Radio * self );
static PyObject *Radio_subdividePatches( BPy_Radio * self );
static PyObject *Radio_subdivideElems( BPy_Radio * self );
static PyObject *Radio_removeDoubles( BPy_Radio * self );

static void Radio_dealloc( BPy_Radio * self );
static PyObject *Radio_repr( BPy_Radio * self );

static PyObject *EXPP_create_ret_PyInt( int value )
{
      PyObject *pyval = PyInt_FromLong( value );

      if( !pyval )
            PyErr_SetString( PyExc_MemoryError,
                         "couldn't create py int!" );

      return pyval;
}

static PyObject *EXPP_create_ret_PyFloat( float value )
{
      PyObject *pyval = PyFloat_FromDouble( ( double ) value );

      if( !pyval )
            PyErr_SetString( PyExc_MemoryError,
                         "couldn't create py int!" );

      return pyval;
}

static PyObject *Radio_get_hemires( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->hemires );
}

static PyObject *Radio_get_maxiter( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->maxiter );
}

static PyObject *Radio_get_subshootp( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->subshootp );
}

static PyObject *Radio_get_subshoote( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->subshoote );
}

static PyObject *Radio_get_nodelim( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->nodelim );
}

static PyObject *Radio_get_maxsublamp( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->maxsublamp );
}

static PyObject *Radio_get_pama( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->pama );
}

static PyObject *Radio_get_pami( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->pami );
}

static PyObject *Radio_get_elma( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->elma );
}

static PyObject *Radio_get_elmi( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->elmi );
}

static PyObject *Radio_get_drawtype( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->drawtype );
}

static PyObject *Radio_get_flag( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->flag );
}

static PyObject *Radio_get_maxnode( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyInt( ( int ) self->scene->radio->maxnode );
}

static PyObject *Radio_get_convergence( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyFloat( self->scene->radio->convergence );
}

static PyObject *Radio_get_radfac( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyFloat( self->scene->radio->radfac );
}

static PyObject *Radio_get_gamma( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_create_ret_PyFloat( self->scene->radio->gamma );
}

static PyObject *EXPP_unpack_set_int( PyObject * args, int *ptr,
                              int min, int max )
{
      int value;

      if( !PyArg_ParseTuple( args, "i", &value ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected int argument" );

      *ptr = EXPP_ClampInt( value, min, max );

      return EXPP_incr_ret( Py_None );
}

/* could merge with set_int, but is cleaner this way */
static PyObject *EXPP_unpack_set_short( PyObject * args, short *ptr,
                              short min, short max )
{
      int value;

      if( !PyArg_ParseTuple( args, "i", &value ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected int argument" );

      *ptr = ( short ) EXPP_ClampInt( value, min, max );

      return EXPP_incr_ret( Py_None );
}

static PyObject *EXPP_unpack_set_float( PyObject * args, float *ptr,
                              float min, float max )
{
      float value;

      if( !PyArg_ParseTuple( args, "f", &value ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected float argument" );

      *ptr = EXPP_ClampFloat( value, min, max );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_set_hemires( BPy_Radio * self, PyObject * args )
{
      PyObject *ret;

      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      ret = EXPP_unpack_set_short( args, &self->scene->radio->hemires,
                             EXPP_RADIO_hemires_MIN,
                             EXPP_RADIO_hemires_MAX );

      if( ret )
            rad_setlimits(  );

      return ret;
}

static PyObject *Radio_set_maxiter( BPy_Radio * self, PyObject * args )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_unpack_set_short( args, &self->scene->radio->maxiter,
                              EXPP_RADIO_maxiter_MIN,
                              EXPP_RADIO_maxiter_MAX );
}

static PyObject *Radio_set_subshootp( BPy_Radio * self, PyObject * args )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_unpack_set_short( args, &self->scene->radio->subshootp,
                              EXPP_RADIO_subshootp_MIN,
                              EXPP_RADIO_subshootp_MAX );
}

static PyObject *Radio_set_subshoote( BPy_Radio * self, PyObject * args )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_unpack_set_short( args, &self->scene->radio->subshoote,
                              EXPP_RADIO_subshoote_MIN,
                              EXPP_RADIO_subshoote_MAX );
}

static PyObject *Radio_set_nodelim( BPy_Radio * self, PyObject * args )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_unpack_set_short( args, &self->scene->radio->nodelim,
                              EXPP_RADIO_nodelim_MIN,
                              EXPP_RADIO_nodelim_MAX );
}

static PyObject *Radio_set_maxsublamp( BPy_Radio * self, PyObject * args )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_unpack_set_short( args, &self->scene->radio->maxsublamp,
                              EXPP_RADIO_maxsublamp_MIN,
                              EXPP_RADIO_maxsublamp_MAX );
}

static PyObject *Radio_set_pama( BPy_Radio * self, PyObject * args )
{
      PyObject *ret;

      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      ret = EXPP_unpack_set_short( args, &self->scene->radio->pama,
                             EXPP_RADIO_pama_MIN,
                             EXPP_RADIO_pama_MAX );

      if( ret )
            rad_setlimits(  );

      return ret;
}

static PyObject *Radio_set_pami( BPy_Radio * self, PyObject * args )
{
      PyObject *ret;

      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      ret = EXPP_unpack_set_short( args, &self->scene->radio->pami,
                             EXPP_RADIO_pami_MIN,
                             EXPP_RADIO_pami_MAX );

      if( ret )
            rad_setlimits(  );

      return ret;
}

static PyObject *Radio_set_elma( BPy_Radio * self, PyObject * args )
{
      PyObject *ret;

      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      ret = EXPP_unpack_set_short( args, &self->scene->radio->elma,
                             EXPP_RADIO_elma_MIN,
                             EXPP_RADIO_elma_MAX );

      if( ret )
            rad_setlimits(  );

      return ret;
}

static PyObject *Radio_set_elmi( BPy_Radio * self, PyObject * args )
{
      PyObject *ret;

      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      ret = EXPP_unpack_set_short( args, &self->scene->radio->elmi,
                             EXPP_RADIO_elmi_MIN,
                             EXPP_RADIO_elmi_MAX );

      if( ret )
            rad_setlimits(  );

      return ret;
}

static PyObject *Radio_set_drawtype( BPy_Radio * self, PyObject * args )
{
      PyObject *pyob = NULL;
      char *str = NULL;
      short dt = EXPP_RADIO_drawtype_WIRE;

      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( !PyArg_ParseTuple( args, "O", &pyob ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected int or string and another optional int as arguments" );

      if( PyString_Check( pyob ) ) {
            str = PyString_AsString( pyob );
            if( !str )
                  return EXPP_ReturnPyObjError( PyExc_MemoryError,
                                          "couldn't create py string!" );
            else if( !strcmp( str, "Wire" ) )
                  dt = EXPP_RADIO_drawtype_WIRE;
            else if( !strcmp( str, "Solid" ) )
                  dt = EXPP_RADIO_drawtype_SOLID;
            else if( !strcmp( str, "Gouraud" ) )
                  dt = EXPP_RADIO_drawtype_GOURAUD;
            else
                  return EXPP_ReturnPyObjError( PyExc_AttributeError,
                                          "unknown drawtype string" );
      } else if( PyInt_Check( pyob ) ) {
            dt = ( short ) EXPP_ClampInt( PyInt_AsLong( pyob ),
                                    EXPP_RADIO_drawtype_WIRE,
                                    EXPP_RADIO_drawtype_GOURAUD );
      } else
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected int or string as argument" );

      self->scene->radio->drawtype = dt;

      set_radglobal(  );      /* needed to update 3d view(s) */

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_set_flag( BPy_Radio * self, PyObject * args )
{
      int i, imode = 0;
      char *mode[2] = { NULL, NULL };

      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( !PyArg_ParseTuple( args, "|ss", &mode[0], &mode[1] ) )
            return EXPP_ReturnPyObjError( PyExc_TypeError,
                                    "expected string arguments (or nothing)" );

      for( i = 0; i < 2; i++ ) {
            if( !mode[i] )
                  break;
            else if( !strcmp( mode[i], "ShowLimits" ) )
                  imode |= EXPP_RADIO_flag_SHOWLIM;
            else if( !strcmp( mode[i], "Z" ) )
                  imode |= EXPP_RADIO_flag_Z;
            else
                  return EXPP_ReturnPyObjError( PyExc_AttributeError,
                                          "unknown mode string" );
      }

      self->scene->radio->flag = ( short ) EXPP_ClampInt( imode, 0, 3 );

      set_radglobal(  );      /* needed to update 3d view(s) */

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_set_maxnode( BPy_Radio * self, PyObject * args )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_unpack_set_int( args, &self->scene->radio->maxnode,
                            EXPP_RADIO_maxnode_MIN,
                            EXPP_RADIO_maxnode_MAX );
}

static PyObject *Radio_set_convergence( BPy_Radio * self, PyObject * args )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_unpack_set_float( args, &self->scene->radio->convergence,
                              EXPP_RADIO_convergence_MIN,
                              EXPP_RADIO_convergence_MAX );
}

static PyObject *Radio_set_radfac( BPy_Radio * self, PyObject * args )
{
      PyObject *ret;

      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      ret = EXPP_unpack_set_float( args, &self->scene->radio->radfac,
                             EXPP_RADIO_radfac_MIN,
                             EXPP_RADIO_radfac_MAX );

      if( ret ) {
            set_radglobal(  );
            if( rad_phase(  ) & RAD_PHASE_FACES )
                  make_face_tab(  );
            else
                  make_node_display(  );
      }

      return ret;
}

static PyObject *Radio_set_gamma( BPy_Radio * self, PyObject * args )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;
      return EXPP_unpack_set_float( args, &self->scene->radio->gamma,
                              EXPP_RADIO_gamma_MIN,
                              EXPP_RADIO_gamma_MAX );
}

static PyMethodDef BPy_Radio_methods[] = {
      {"collectMeshes", ( PyCFunction ) Radio_collectMeshes, METH_NOARGS,
       "() - Convert selected meshes to patches."},
      {"go", ( PyCFunction ) Radio_go, METH_NOARGS,
       "() - Start radiosity calculations."},
      {"freeData", ( PyCFunction ) Radio_freeData, METH_NOARGS,
       "() - Free all memory used by radiosity."},
      {"addMesh", ( PyCFunction ) Radio_addMesh, METH_NOARGS,
       "() - Add a new mesh with the radio values as vertex colors to Blender."},
      {"replaceMeshes", ( PyCFunction ) Radio_replaceMeshes, METH_NOARGS,
       "() - Replace input meshes with the one created by radiosity simulation."},
      {"limitSubdivide", ( PyCFunction ) Radio_limitSubdivide, METH_NOARGS,
       "() - Subdivide patches."},
      {"filterFaces", ( PyCFunction ) Radio_filterFaces, METH_NOARGS,
       "() - Force an extra smoothing."},
      {"filterElems", ( PyCFunction ) Radio_filterElems, METH_NOARGS,
       "() - Filter elements to remove aliasing artifacts."},
      {"subdividePatches", ( PyCFunction ) Radio_subdividePatches,
       METH_NOARGS,
       "() - Pre-subdivision: detect high-energy patches and subdivide them."},
      {"subdivideElems", ( PyCFunction ) Radio_subdivideElems, METH_NOARGS,
       "() - Pre-subdivision: detect high-energy elements and subdivide them."},
      {"removeDoubles", ( PyCFunction ) Radio_removeDoubles, METH_NOARGS,
       "() - Join elements which differ less than the defined node limit."},
      {"getHemiRes", ( PyCFunction ) Radio_get_hemires, METH_NOARGS,
       "() - Get hemicube size."},
      {"setHemiRes", ( PyCFunction ) Radio_set_hemires, METH_VARARGS,
       "(int) - Set hemicube size, the range is [100, 1000]."},
      {"getMaxIter", ( PyCFunction ) Radio_get_maxiter, METH_NOARGS,
       "() - Get maximum number of radiosity rounds."},
      {"setMaxIter", ( PyCFunction ) Radio_set_maxiter, METH_VARARGS,
       "(i) - Set maximum number of radiosity rounds in [0, 10000]."},
      {"getSubShPatch", ( PyCFunction ) Radio_get_subshootp, METH_NOARGS,
       "() - Get max number of times environment is tested to detect patches."},
      {"setSubShPatch", ( PyCFunction ) Radio_set_subshootp, METH_VARARGS,
       "(i) - Set max number of times environment is tested to detect patches.\n\
      Range is [0, 10]."},
      {"getSubShElem", ( PyCFunction ) Radio_get_subshoote, METH_NOARGS,
       "() - Get number of times environment is tested to detect elements."},
      {"setSubShElem", ( PyCFunction ) Radio_set_subshoote, METH_VARARGS,
       "(i) - Set number of times environment is tested to detect elements.\n\
      Range is [0, 10]."},
      {"getElemLimit", ( PyCFunction ) Radio_get_nodelim, METH_NOARGS,
       "() - Get the range for removing doubles."},
      {"setElemLimit", ( PyCFunction ) Radio_set_nodelim, METH_VARARGS,
       "(i) - Set the range for removing doubles in [0, 50]."},
      {"getMaxSubdivSh", ( PyCFunction ) Radio_get_maxsublamp, METH_NOARGS,
       "() - Get max number of initial shoot patches evaluated."},
      {"setMaxSubdivSh", ( PyCFunction ) Radio_set_maxsublamp, METH_VARARGS,
       "(i) - Set max number of initial shoot patches evaluated in [1, 250]."},
      {"getPatchMax", ( PyCFunction ) Radio_get_pama, METH_NOARGS,
       "() - Get max size of a patch."},
      {"setPatchMax", ( PyCFunction ) Radio_set_pama, METH_VARARGS,
       "(i) - Set max size of a patch in [10, 1000]."},
      {"getPatchMin", ( PyCFunction ) Radio_get_pami, METH_NOARGS,
       "() - Get minimum size of a patch."},
      {"setPatchMin", ( PyCFunction ) Radio_set_pami, METH_VARARGS,
       "(i) - Set minimum size of a patch in [10, 1000]."},
      {"getElemMax", ( PyCFunction ) Radio_get_elma, METH_NOARGS,
       "() - Get max size of an element."},
      {"setElemMax", ( PyCFunction ) Radio_set_elma, METH_VARARGS,
       "(i) - Set max size of an element in [1, 100]."},
      {"getElemMin", ( PyCFunction ) Radio_get_elmi, METH_NOARGS,
       "() - Get minimum size of an element."},
      {"setElemMin", ( PyCFunction ) Radio_set_elmi, METH_VARARGS,
       "(i) - Set minimum size of an element in [1, 100]."},
      {"getMaxElems", ( PyCFunction ) Radio_get_maxnode, METH_NOARGS,
       "() - Get maximum number of elements."},
      {"setMaxElems", ( PyCFunction ) Radio_set_maxnode, METH_VARARGS,
       "(i) - Set maximum nunber of elements in [1, 250000]."},
      {"getConvergence", ( PyCFunction ) Radio_get_convergence, METH_NOARGS,
       "() - Get lower threshold of unshot energy."},
      {"setConvergence", ( PyCFunction ) Radio_set_convergence, METH_VARARGS,
       "(f) - Set lower threshold of unshot energy in [0.0, 1.0]."},
      {"getMult", ( PyCFunction ) Radio_get_radfac, METH_NOARGS,
       "() - Get energy value multiplier."},
      {"setMult", ( PyCFunction ) Radio_set_radfac, METH_VARARGS,
       "(f) - Set energy value multiplier in [0.001, 250.0]."},
      {"getGamma", ( PyCFunction ) Radio_get_gamma, METH_NOARGS,
       "() - Get change in the contrast of energy values."},
      {"setGamma", ( PyCFunction ) Radio_set_gamma, METH_VARARGS,
       "(f) - Set change in the contrast of energy values in [0.2, 10.0]."},
      {"getDrawType", ( PyCFunction ) Radio_get_drawtype, METH_NOARGS,
       "() - Get the draw type: Wire, Solid or Gouraud as an int value."},
      {"setDrawType", ( PyCFunction ) Radio_set_drawtype, METH_VARARGS,
       "(i or s) - Set the draw type: wire, solid (default) or gouraud."},
      {"getMode", ( PyCFunction ) Radio_get_flag, METH_NOARGS,
       "() - Get mode as int (or'ed bitflags), see Radio.Modes dict."},
      {"setMode", ( PyCFunction ) Radio_set_flag, METH_VARARGS,
       "(|ss) - Set mode flags as strings: 'ShowLimits', 'Z'."},
      {NULL, NULL, 0, NULL}
};

static PyTypeObject Radio_Type = {
      PyObject_HEAD_INIT( NULL ) 
      0,    /*ob_size */
      "Blender Radiosity",    /*tp_name */
      sizeof( BPy_Radio ),    /*tp_basicsize */
      0,                /*tp_itemsize */
      ( destructor ) Radio_dealloc, /*tp_dealloc */
      0,                /*tp_print */
      0,                /*tp_getattr */
      0,                /*tp_setattr */
      0,                /*tp_compare */
      ( reprfunc ) Radio_repr,      /*tp_repr */
      0,                /*tp_as_number */
      0,                /*tp_as_sequence */
      0,                /*tp_as_mapping */
      0,                /*tp_hash */
      0,                /*tp_call */
      0,                /*tp_str */
      0,                /*tp_getattro */
      0,                /*tp_setattro */
      0,                /*tp_as_buffer */
      Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags */
      "Blender radiosity",    /* tp_doc */
      0,                /* tp_traverse */
      0,                /* tp_clear */
      0,                /* tp_richcompare */
      0,                /* tp_weaklistoffset */
      0,                /* tp_iter */
      0,                /* tp_iternext */
      BPy_Radio_methods,      /* tp_methods */
      0,                /* tp_members */
      0,                /* tp_getset */
      0,                /* tp_base */
      0,                /* tp_dict */
      0,                /* tp_descr_get */
      0,                /* tp_descr_set */
      0,                /* tp_dictoffset */
      0,                /* tp_init */
      0,                /* tp_alloc */
      0,                /* tp_new */
      0, 0, 0, 0, 0, 0, 0, 0, /* up to tp_del, so we don't get a warning */
};

static void Radio_dealloc( BPy_Radio * self )
{
      PyObject_DEL( self );
}

static PyObject *Radio_repr( BPy_Radio * self )
{
      if( self->radio )
            return PyString_FromFormat( "[Radiosity \"%s\"]",
                                  self->scene->id.name + 2 );
      else
            return PyString_FromString( "NULL" );
}

PyObject *Radio_CreatePyObject( struct Scene * scene )
{
      BPy_Radio *py_radio;

      if( scene != G.scene ) {
            return EXPP_ReturnPyObjError( PyExc_EnvironmentError,
                                    "\nradiosity only works on the current scene, check scene.makeCurrent()." );
      }

      py_radio = ( BPy_Radio * ) PyObject_NEW( BPy_Radio, &Radio_Type );

      if( !py_radio )
            return NULL;

      if( !scene->radio )
            add_radio(  );    /* adds to G.scene */

      py_radio->radio = scene->radio;
      py_radio->scene = scene;

      return ( ( PyObject * ) py_radio );
}

int Radio_CheckPyObject( PyObject * pyob )
{
      return ( pyob->ob_type == &Radio_Type );
}

static PyObject *Radio_collectMeshes( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      disable_where_script( 1 );    /* used to avoid error popups */
      rad_collect_meshes(  );
      disable_where_script( 0 );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_freeData( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      delete_radio(  );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_go( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( rad_phase(  ) == RAD_PHASE_PATCHES )
            rad_go(  );
      else
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "you need to call radio.collectMeshes() first." );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_replaceMeshes( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( rad_phase(  ) & RAD_PHASE_FACES )
            rad_replacemesh(  );
      else
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "you need to call radio.collectMeshes() and radio.go() first." );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_addMesh( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( rad_phase(  ) & RAD_PHASE_FACES )
            rad_addmesh(  );
      else
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "you need to call radio.collectMeshes() and radio.go() first." );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_filterFaces( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( rad_phase(  ) & RAD_PHASE_FACES )
            filterFaces(  );
      else
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "you need to call radio.collectMeshes() and radio.go() first." );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_filterElems( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( rad_phase(  ) & RAD_PHASE_FACES ) {
            set_radglobal(  );
            filterNodes(  );
            make_face_tab(  );
      } else
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "you need to call radio.collectMeshes() and radio.go() first." );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_limitSubdivide( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( rad_phase(  ) == RAD_PHASE_PATCHES )
            rad_limit_subdivide(  );
      else
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "you need to call this before calculating the radiosity simulation." );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_subdividePatches( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( rad_phase(  ) == RAD_PHASE_PATCHES )
            rad_subdivshootpatch(  );
      else
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "you need to call this before calculating the radiosity simulation." );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_subdivideElems( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( rad_phase(  ) == RAD_PHASE_PATCHES )
            rad_subdivshootelem(  );
      else
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "you need to call radio.collectMeshes() and radio.go() first." );

      return EXPP_incr_ret( Py_None );
}

static PyObject *Radio_removeDoubles( BPy_Radio * self )
{
      if( !EXPP_check_scene( self->scene ) )
            return NULL;

      if( rad_phase(  ) == RAD_PHASE_FACES ) {
            set_radglobal(  );
            removeEqualNodes( self->scene->radio->nodelim );
            make_face_tab(  );
      } else
            return EXPP_ReturnPyObjError( PyExc_RuntimeError,
                                    "you need to call radio.collectMeshes() and radio.go() first." );

      return EXPP_incr_ret( Py_None );
}

static PyMethodDef M_Radio_methods[] = { {NULL, NULL, 0, NULL} };

PyObject *Radio_Init( void )
{
      PyObject *submodule, *Modes, *DrawTypes;

      if( PyType_Ready( &Radio_Type ) < 0 )
            return NULL;

      submodule = Py_InitModule3( "Blender.Scene.Radio", M_Radio_methods,
                            "The Blender Radiosity submodule" );

      Modes = M_constant_New(  );
      DrawTypes = M_constant_New(  );

      if( Modes ) {
            BPy_constant *d = ( BPy_constant * ) Modes;

            constant_insert( d, "ShowLimits",
                         PyInt_FromLong( EXPP_RADIO_flag_SHOWLIM ) );
            constant_insert( d, "Z", PyInt_FromLong( EXPP_RADIO_flag_Z ) );

            PyModule_AddObject( submodule, "Modes", Modes );
      }

      if( DrawTypes ) {
            BPy_constant *d = ( BPy_constant * ) DrawTypes;

            constant_insert( d, "Wire",
                         PyInt_FromLong( EXPP_RADIO_drawtype_WIRE ) );
            constant_insert( d, "Solid",
                         PyInt_FromLong( EXPP_RADIO_drawtype_SOLID ) );
            constant_insert( d, "Gouraud",
                         PyInt_FromLong
                         ( EXPP_RADIO_drawtype_GOURAUD ) );

            PyModule_AddObject( submodule, "DrawTypes", DrawTypes );
      }

      return submodule;
}

Generated by  Doxygen 1.6.0   Back to index