diff options
author | Ken Hughes <khughes@pacific.edu> | 2006-05-25 20:45:24 +0400 |
---|---|---|
committer | Ken Hughes <khughes@pacific.edu> | 2006-05-25 20:45:24 +0400 |
commit | 48033e00c44c0ff5aab055f6ecfe833b7f688856 (patch) | |
tree | 18262846584b26a0c53612e1d5bce719041b940b /source/blender/python/api2_2x/meshPrimitive.c | |
parent | 1b2d9b5ade184d26679b3b4f2e09f27d84b9fd39 (diff) |
===Python API===
Fulfilling a very old feature request: a new Mesh Primitives module is
introduced, which gives script writers access to the Blender mesh datablocks
created from the "Add->Mesh" menu. You can now do this:
from Blender import *
me = Mesh.Primitives.UVsphere(10,20,3) # 10 segments, 20 rings, diameter 3
ob = Object.New('Mesh','mySphere')
ob.link(me)
sc = Scene.GetCurrent()
sc.link(ob)
Diffstat (limited to 'source/blender/python/api2_2x/meshPrimitive.c')
-rw-r--r-- | source/blender/python/api2_2x/meshPrimitive.c | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/source/blender/python/api2_2x/meshPrimitive.c b/source/blender/python/api2_2x/meshPrimitive.c new file mode 100644 index 00000000000..6182159afc2 --- /dev/null +++ b/source/blender/python/api2_2x/meshPrimitive.c @@ -0,0 +1,280 @@ +/* + * $Id$ + * + * ***** 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, partially based on NMesh.c API. + * + * Contributor(s): Ken Hughes + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "Mesh.h" /*This must come first*/ + +#include "DNA_scene_types.h" +#include "BDR_editobject.h" +#include "BIF_editmesh.h" +#include "BKE_global.h" +#include "BKE_object.h" +#include "BKE_scene.h" +#include "BKE_library.h" +#include "blendef.h" + +#include "gen_utils.h" + +/* + * local helper procedure which does the dirty work of messing with the + * edit mesh, active objects, etc. + */ + +static PyObject *make_mesh( int type, char *name, short tot, short seg, + short subdiv, float dia, float height, short ext, short fill ) +{ + float cent[3] = {0,0,0}; + float imat[3][3]={{1,0,0},{0,1,0},{0,0,1}}; + Mesh *me; + BPy_Mesh *obj; + Object *ob; + Base *base; + + /* remember active object (if any) for later, so we can re-activate */ + base = BASACT; + + /* make a new object, "copy" to the editMesh structure */ + ob = add_object(OB_MESH); + me = (Mesh *)ob->data; + G.obedit = BASACT->object; + make_editMesh( ); + + /* create the primitive in the edit mesh */ + + make_prim( type, imat, /* mesh type, transform matrix */ + tot, seg, /* total vertices, segments */ + subdiv, /* subdivisions (for Icosphere only) */ + dia, -height, /* diameter-ish, height */ + ext, fill, /* extrude, fill end faces */ + cent ); /* location of center */ + + /* copy primitive back to the real mesh */ + load_editMesh( ); + free_editMesh( G.editMesh ); + G.obedit = NULL; + + /* remove object link to the data, then delete the object */ + ob->data = NULL; + me->id.us = 0; + free_and_unlink_base(BASACT); + + /* if there was an active object, reactivate it */ + if( base ) + scene_select_base(G.scene, base); + + /* create the BPy_Mesh that wraps this mesh */ + obj = (BPy_Mesh *)PyObject_NEW( BPy_Mesh, &Mesh_Type ); + + rename_id( &me->id, name ); + obj->mesh = me; + obj->object = NULL; + obj->new = 1; + return (PyObject *) obj; +} + +static PyObject *M_MeshPrim_Plane( PyObject *self_unused, PyObject *args ) +{ + float size = 2.0; + + if( !PyArg_ParseTuple( args, "|f", &size ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected optional float arg" ); + + size *= sqrt(2.0)/2.0; + return make_mesh( 0, "Plane", 4, 0, 0, size, -size, 0, 1 ); +} + +static PyObject *M_MeshPrim_Cube( PyObject *self_unused, PyObject *args ) +{ + float size = 2.0; + + if( !PyArg_ParseTuple( args, "|f", &size ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected optional float arg" ); + + size *= sqrt(2.0)/2.0; + return make_mesh( 1, "Cube", 4, 0, 0, size, -size, 1, 1 ); +} + +static PyObject *M_MeshPrim_Circle( PyObject *self_unused, PyObject *args ) +{ + int tot = 32; + float size = 2.0*sqrt(2.0); + + if( !PyArg_ParseTuple( args, "|if", &tot, &size ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected int and optional float arg" ); + if( tot < 3 || tot > 100 ) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "number of vertices must be in the range [3:100]" ); + + size /= 2.0; + return make_mesh( 4, "Circle", tot, 0, 0, size, -size, 0, 0 ); +} + +static PyObject *M_MeshPrim_Cylinder( PyObject *self_unused, PyObject *args ) +{ + int tot = 32; + float size = 2.0*sqrt(2.0); + float len = 1.0; + + if( !PyArg_ParseTuple( args, "|iff", &tot, &size, &len ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected int and optional float arg" ); + if( tot < 3 || tot > 100 ) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "number of vertices must be in the range [3:100]" ); + + size /= 2.0; + return make_mesh( 5, "Cylinder", tot, 0, 0, size, -len, 1, 1 ); +} + +static PyObject *M_MeshPrim_Tube( PyObject *self_unused, PyObject *args ) +{ + int tot = 32; + float size = 2.0*sqrt(2.0); + float len = 1.0; + + if( !PyArg_ParseTuple( args, "|iff", &tot, &size, &len ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected int and optional float arg" ); + if( tot < 3 || tot > 100 ) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "number of vertices must be in the range [3:100]" ); + + size /= 2.0; + return make_mesh( 6, "Tube", tot, 0, 0, size, -len, 1, 0 ); +} + +static PyObject *M_MeshPrim_Cone( PyObject *self_unused, PyObject *args ) +{ + int tot = 32; + float size = 2.0*sqrt(2.0); + float len = 1.0; + + if( !PyArg_ParseTuple( args, "|iff", &tot, &size, &len ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected int and optional float arg" ); + if( tot < 3 || tot > 100 ) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "number of vertices must be in the range [3:100]" ); + + size /= 2.0; + return make_mesh( 7, "Cone", tot, 0, 0, size, -len, 0, 1 ); +} + +static PyObject *M_MeshPrim_Grid( PyObject *self_unused, PyObject *args ) +{ + int xres = 32; + int yres = 32; + float size = 2.0; + + if( !PyArg_ParseTuple( args, "|iif", &xres, &yres, &size ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected two ints and an optional float arg" ); + if( xres < 2 || xres > 100 || yres < 2 || yres > 100 ) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "resolution must be in the range [2:100]" ); + + size /= 2.0; + return make_mesh( 10, "Grid", xres, yres, 0, size, -size, 0, 0 ); +} + +static PyObject *M_MeshPrim_UVsphere( PyObject *self_unused, PyObject *args ) +{ + int segs = 32; + int rings = 32; + float size = 2.0*sqrt(2.0); + + if( !PyArg_ParseTuple( args, "|iif", &segs, &rings, &size ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected two ints and an optional float arg" ); + if( segs < 3 || segs > 100 || rings < 3 || rings > 100 ) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "segments and rings must be in the range [3:100]" ); + + size /= 2.0; + return make_mesh( 11, "UVsphere", segs, rings, 0, size, -size, 0, 0 ); +} + +static PyObject *M_MeshPrim_Icosphere( PyObject *self_unused, PyObject *args ) +{ + int subdiv = 2; + float size = 2.0*sqrt(2.0); + + if( !PyArg_ParseTuple( args, "|if", &subdiv, &size ) ) + return EXPP_ReturnPyObjError( PyExc_TypeError, + "expected int and an optional float arg" ); + if( subdiv < 1 || subdiv > 5 ) + return EXPP_ReturnPyObjError( PyExc_ValueError, + "subdivisions must be in the range [1:5]" ); + + size /= 2.0; + return make_mesh( 12, "Icosphere", 0, 0, subdiv, size, -size, 0, 0 ); +} + +static PyObject *M_MeshPrim_Suzanne( PyObject *self_unused, PyObject *args ) +{ + return make_mesh( 13, "Monkey", 0, 0, 0, 0, 0, 0, 0 ); +} + +static struct PyMethodDef M_MeshPrim_methods[] = { + {"Plane", (PyCFunction)M_MeshPrim_Plane, METH_VARARGS, + "Create a plane mesh"}, + {"Cube", (PyCFunction)M_MeshPrim_Cube, METH_VARARGS, + "Create a cube mesh"}, + {"Circle", (PyCFunction)M_MeshPrim_Circle, METH_VARARGS, + "Create a circle mesh"}, + {"Cylinder", (PyCFunction)M_MeshPrim_Cylinder, METH_VARARGS, + "Create a cylindrical mesh"}, + {"Tube", (PyCFunction)M_MeshPrim_Tube, METH_VARARGS, + "Create a tube mesh"}, + {"Cone", (PyCFunction)M_MeshPrim_Cone, METH_VARARGS, + "Create a conic mesh"}, + {"Grid", (PyCFunction)M_MeshPrim_Grid, METH_VARARGS, + "Create a 2D grid mesh"}, + {"UVsphere", (PyCFunction)M_MeshPrim_UVsphere, METH_VARARGS, + "Create a UV sphere mesh"}, + {"Icosphere", (PyCFunction)M_MeshPrim_Icosphere, METH_VARARGS, + "Create a Ico sphere mesh"}, + {"Monkey", (PyCFunction)M_MeshPrim_Suzanne, METH_NOARGS, + "Create a Suzanne mesh"}, + {NULL, NULL, 0, NULL}, +}; + +static char M_MeshPrim_doc[] = "The Blender.Mesh.Primitives submodule"; + +PyObject *MeshPrimitives_Init( void ) +{ + return Py_InitModule3( "Blender.Mesh.Primitives", + M_MeshPrim_methods, M_MeshPrim_doc ); +} + |