===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)
This commit is contained in:
@@ -80,6 +80,7 @@
|
||||
#include "Image.h"
|
||||
#include "Material.h"
|
||||
#include "Mathutils.h"
|
||||
#include "meshPrimitive.h"
|
||||
#include "constant.h"
|
||||
#include "gen_utils.h"
|
||||
|
||||
@@ -7378,6 +7379,9 @@ PyObject *Mesh_Init( void )
|
||||
|
||||
submodule =
|
||||
Py_InitModule3( "Blender.Mesh", M_Mesh_methods, M_Mesh_doc );
|
||||
PyDict_SetItemString( PyModule_GetDict( submodule ),
|
||||
"Primitives", MeshPrimitives_Init( ) );
|
||||
|
||||
if( Modes )
|
||||
PyModule_AddObject( submodule, "Modes", Modes );
|
||||
if( FaceFlags )
|
||||
|
||||
160
source/blender/python/api2_2x/doc/MeshPrimitives.py
Normal file
160
source/blender/python/api2_2x/doc/MeshPrimitives.py
Normal file
@@ -0,0 +1,160 @@
|
||||
# Blender.Mesh.Primitives module
|
||||
|
||||
"""
|
||||
The Blender.Mesh.Primitives submodule.
|
||||
|
||||
B{New}:
|
||||
|
||||
Mesh Primitive Data
|
||||
===================
|
||||
|
||||
This submodule provides access Blender's mesh primitives. Each module
|
||||
function returns a BPy_Mesh object which wraps the mesh data. This data can
|
||||
then be manipulated using the L{Mesh} API.
|
||||
|
||||
Example::
|
||||
|
||||
from Blender import *
|
||||
|
||||
me = Mesh.Primitives.Cube(2.0) # create a new cube of size 2
|
||||
ob = Object.New('Mesh') # create a new mesh-type object
|
||||
ob.link(me) # link mesh datablock with object
|
||||
sc = Scene.GetCurrent() # get current scene
|
||||
sc.link(ob) # add object to the scene
|
||||
Window.RedrawAll() # update windows
|
||||
"""
|
||||
|
||||
|
||||
def Plane(size=2.0):
|
||||
"""
|
||||
Construct a filled planar mesh with 4 vertices. The default size
|
||||
creates a 2 by 2 Blender unit plane, identical to the Blender UI.
|
||||
@type size: float
|
||||
@param size: optional size of the plane.
|
||||
@rtype: L{BPy_Mesh<Mesh>}
|
||||
@return: returns a mesh object.
|
||||
"""
|
||||
|
||||
def Cube(size=2.0):
|
||||
"""
|
||||
Construct a cube mesh. The default size creates a cube with each face
|
||||
2 by 2 Blender units, identical to the Blender UI.
|
||||
@type size: float
|
||||
@param size: optional size of the cube.
|
||||
@rtype: L{BPy_Mesh<Mesh>}
|
||||
@return: returns a mesh object.
|
||||
"""
|
||||
|
||||
def Circle(verts=32,diameter=2.8284):
|
||||
"""
|
||||
Construct a circle mesh. The defaults create a circle with a
|
||||
diameter of 2*sqrt(2) Blender units, identical to the Blender UI.
|
||||
@type verts: int
|
||||
@param verts: optional number of vertices for the circle.
|
||||
Value must be in the range [3,100].
|
||||
@type diameter: float
|
||||
@param diameter: optional diameter of the circle.
|
||||
@rtype: L{BPy_Mesh<Mesh>}
|
||||
@return: returns a mesh object.
|
||||
"""
|
||||
|
||||
def Cylinder(verts=32, diameter=2.8284, length=1.0):
|
||||
"""
|
||||
Construct a cylindrical mesh (ends filled). The defaults create a
|
||||
cylinder with a diameter of 2*sqrt(2) Blender units and length 1 unit,
|
||||
identical to the Blender UI.
|
||||
@type verts: int
|
||||
@param verts: optional number of vertices in the cylinder's perimeter.
|
||||
Value must be in the range [3,100].
|
||||
@type diameter: float
|
||||
@param diameter: optional diameter of the cylinder.
|
||||
@type length: float
|
||||
@param length: optional length of the cylinder.
|
||||
@rtype: L{BPy_Mesh<Mesh>}
|
||||
@return: returns a mesh object.
|
||||
"""
|
||||
|
||||
def Tube(verts=32, diameter=2.8284, length=1.0):
|
||||
"""
|
||||
Construct a cylindrical mesh (ends not filled). The defaults create a
|
||||
cylinder with a diameter of 2*sqrt(2) Blender units and length 1 unit, identical
|
||||
to the Blender UI.
|
||||
@type verts: int
|
||||
@param verts: optional number of vertices in the tube's perimeter.
|
||||
Value must be in the range [3,100].
|
||||
@type diameter: float
|
||||
@param diameter: optional diameter of the tube.
|
||||
@type length: float
|
||||
@param length: optional length of the tube.
|
||||
@rtype: L{BPy_Mesh<Mesh>}
|
||||
@return: returns a mesh object.
|
||||
"""
|
||||
|
||||
def Cone(verts=32, diameter=2.8284, length=1.0):
|
||||
"""
|
||||
Construct a conic mesh (ends filled). The defaulte create a cone with a
|
||||
base diameter of 2*sqrt(2) Blender units and length 1 unit, identical to the Blender
|
||||
UI.
|
||||
@type verts: int
|
||||
@param verts: optional number of vertices in the cone's perimeter.
|
||||
Value must be in the range [3,100].
|
||||
@type diameter: float
|
||||
@param diameter: optional diameter of the cone.
|
||||
@type length: float
|
||||
@param length: optional length of the cone.
|
||||
@rtype: L{BPy_Mesh<Mesh>}
|
||||
@return: returns a mesh object.
|
||||
"""
|
||||
|
||||
def Grid(xres=32, yres=32, size=2.0):
|
||||
"""
|
||||
Construct a grid mesh. The defaults create a 32 by 32 mesh of size 2
|
||||
Blender units, identical to the Blender UI.
|
||||
@type xres: int
|
||||
@param xres: optional grid size in the x direction.
|
||||
Value must be in the range [2,100].
|
||||
@type yres: int
|
||||
@param yres: optional grid size in the y direction.
|
||||
Value must be in the range [2,100].
|
||||
@type size: float
|
||||
@param size: optional size of the grid.
|
||||
@rtype: L{BPy_Mesh<Mesh>}
|
||||
@return: returns a mesh object.
|
||||
"""
|
||||
|
||||
def UVsphere(segments=32, rings=32, diameter=2.8284):
|
||||
"""
|
||||
Construct a UV sphere mesh. The defaults create a 32 by 32 sphere with
|
||||
a diameter of 2*sqrt(2) Blender units, identical to the Blender UI.
|
||||
@type segments: int
|
||||
@param segments: optional number of longitudinal divisions.
|
||||
Value must be in the range [3,100].
|
||||
@type rings: int
|
||||
@param rings: optional number of latitudinal divisions.
|
||||
Value must be in the range [3,100].
|
||||
@type diameter: float
|
||||
@param diameter: optional diameter of the sphere.
|
||||
@rtype: L{BPy_Mesh<Mesh>}
|
||||
@return: returns a mesh object.
|
||||
"""
|
||||
|
||||
def Icosphere(subdivisions=2, diameter=2.82824):
|
||||
"""
|
||||
Construct a Icosphere mesh. The defaults create sphere with 2 subdivisions
|
||||
and diameter of 2*sqrt(2) Blender units, identical to the Blender UI.
|
||||
@type subdivisions: int
|
||||
@param subdivisions: optional number of subdivisions.
|
||||
Value must be in the range [2,5].
|
||||
@type diameter: float
|
||||
@param diameter: optional diameter of the sphere.
|
||||
@rtype: L{BPy_Mesh<Mesh>}
|
||||
@return: returns a mesh object.
|
||||
"""
|
||||
|
||||
def Monkey():
|
||||
"""
|
||||
Construct a Suzanne mesh.
|
||||
@rtype: L{BPy_Mesh<Mesh>}
|
||||
@return: returns a mesh object.
|
||||
"""
|
||||
|
||||
280
source/blender/python/api2_2x/meshPrimitive.c
Normal file
280
source/blender/python/api2_2x/meshPrimitive.c
Normal file
@@ -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 );
|
||||
}
|
||||
|
||||
46
source/blender/python/api2_2x/meshPrimitive.h
Normal file
46
source/blender/python/api2_2x/meshPrimitive.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* $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.
|
||||
*
|
||||
* Contributor(s): Ken Hughes
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef EXPP_MESHPRIMITIVES_H
|
||||
#define EXPP_MESHPRIMITIVES_H
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
/* PROTOS */
|
||||
|
||||
PyObject *MeshPrimitives_Init( void );
|
||||
|
||||
#endif /* EXPP_MESHPRIMITIVES_H */
|
||||
Reference in New Issue
Block a user