Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorKen Hughes <khughes@pacific.edu>2006-05-25 20:45:24 +0400
committerKen Hughes <khughes@pacific.edu>2006-05-25 20:45:24 +0400
commit48033e00c44c0ff5aab055f6ecfe833b7f688856 (patch)
tree18262846584b26a0c53612e1d5bce719041b940b /source
parent1b2d9b5ade184d26679b3b4f2e09f27d84b9fd39 (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')
-rw-r--r--source/blender/include/BIF_editmesh.h3
-rw-r--r--source/blender/python/api2_2x/Mesh.c4
-rw-r--r--source/blender/python/api2_2x/doc/MeshPrimitives.py160
-rw-r--r--source/blender/python/api2_2x/meshPrimitive.c280
-rw-r--r--source/blender/python/api2_2x/meshPrimitive.h46
-rw-r--r--source/blender/src/editmesh_add.c555
6 files changed, 784 insertions, 264 deletions
diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h
index 8711c21b3a8..5cf5f6c8f8a 100644
--- a/source/blender/include/BIF_editmesh.h
+++ b/source/blender/include/BIF_editmesh.h
@@ -65,6 +65,9 @@ extern void separate_mesh(void);
extern void separate_mesh_loose(void);
/* ******************* editmesh_add.c */
+extern void make_prim(int type, float imat[3][3], short tot, short seg,
+ short subdiv, float dia, float d, short ext, short fill,
+ float cent[3]);
extern void add_primitiveMesh(int type);
extern void adduplicate_mesh(void);
extern void add_click_mesh(void);
diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c
index 5f1f8b8314f..ba383fd4068 100644
--- a/source/blender/python/api2_2x/Mesh.c
+++ b/source/blender/python/api2_2x/Mesh.c
@@ -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 )
diff --git a/source/blender/python/api2_2x/doc/MeshPrimitives.py b/source/blender/python/api2_2x/doc/MeshPrimitives.py
new file mode 100644
index 00000000000..a6a0365b9c0
--- /dev/null
+++ b/source/blender/python/api2_2x/doc/MeshPrimitives.py
@@ -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.
+ """
+
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 );
+}
+
diff --git a/source/blender/python/api2_2x/meshPrimitive.h b/source/blender/python/api2_2x/meshPrimitive.h
new file mode 100644
index 00000000000..1aa60c31eb4
--- /dev/null
+++ b/source/blender/python/api2_2x/meshPrimitive.h
@@ -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 */
diff --git a/source/blender/src/editmesh_add.c b/source/blender/src/editmesh_add.c
index 5ae47c078c1..7a3003a01f9 100644
--- a/source/blender/src/editmesh_add.c
+++ b/source/blender/src/editmesh_add.c
@@ -734,15 +734,293 @@ int confirm_objectExists( Mesh **me, float mat[][3] )
return newob;
}
-void add_primitiveMesh(int type)
+void make_prim(int type, float imat[3][3], short tot, short seg,
+ short subdiv, float dia, float d, short ext, short fill,
+ float cent[3])
{
EditMesh *em = G.editMesh;
- Mesh *me;
EditVert *eve, *v1=NULL, *v2, *v3, *v4=NULL, *vtop, *vdown;
- float *curs, d, dia, phi, phid, cent[3], vec[3], imat[3][3], mat[3][3];
+ float phi, phid, vec[3];
float q[4], cmat[3][3], nor[3]= {0.0, 0.0, 0.0};
+ short a, b;
+
+ phid= 2*M_PI/tot;
+ phi= .25*M_PI;
+
+ switch(type) {
+ case 10: /* grid */
+ /* clear flags */
+ eve= em->verts.first;
+ while(eve) {
+ eve->f= 0;
+ eve= eve->next;
+ }
+ /* one segment first: the X axis */
+ phi= 1.0;
+ phid= 2.0/((float)tot-1);
+ for(a=0;a<tot;a++) {
+ vec[0]= cent[0]+dia*phi;
+ vec[1]= cent[1]- dia;
+ vec[2]= cent[2];
+ Mat3MulVecfl(imat,vec);
+ eve= addvertlist(vec);
+ eve->f= 1+2+4;
+ if (a) {
+ addedgelist(eve->prev, eve, NULL);
+ }
+ phi-=phid;
+ }
+ /* extrude and translate */
+ vec[0]= vec[2]= 0.0;
+ vec[1]= dia*phid;
+ Mat3MulVecfl(imat, vec);
+ for(a=0;a<seg-1;a++) {
+ extrudeflag_vert(2, nor); // nor unused
+ translateflag(2, vec);
+ }
+ break;
+ case 11: /* UVsphere */
+
+ /* clear all flags */
+ eve= em->verts.first;
+ while(eve) {
+ eve->f= 0;
+ eve= eve->next;
+ }
+
+ /* one segment first */
+ phi= 0;
+ phid/=2;
+ for(a=0; a<=tot; a++) {
+ vec[0]= dia*sin(phi);
+ vec[1]= 0.0;
+ vec[2]= dia*cos(phi);
+ eve= addvertlist(vec);
+ eve->f= 1+2+4;
+ if(a==0) v1= eve;
+ else addedgelist(eve->prev, eve, NULL);
+ phi+= phid;
+ }
+
+ /* extrude and rotate */
+ phi= M_PI/seg;
+ q[0]= cos(phi);
+ q[3]= sin(phi);
+ q[1]=q[2]= 0;
+ QuatToMat3(q, cmat);
+
+ for(a=0; a<seg; a++) {
+ extrudeflag_vert(2, nor); // nor unused
+ rotateflag(2, v1->co, cmat);
+ }
+
+ removedoublesflag(4, 0.0001);
+
+ /* and now do imat */
+ eve= em->verts.first;
+ while(eve) {
+ if(eve->f & SELECT) {
+ VecAddf(eve->co,eve->co,cent);
+ Mat3MulVecfl(imat,eve->co);
+ }
+ eve= eve->next;
+ }
+ break;
+ case 12: /* Icosphere */
+ {
+ EditVert *eva[12];
+ EditEdge *eed;
+
+ /* clear all flags */
+ eve= em->verts.first;
+ while(eve) {
+ eve->f= 0;
+ eve= eve->next;
+ }
+ dia/=200;
+ for(a=0;a<12;a++) {
+ vec[0]= dia*icovert[a][0];
+ vec[1]= dia*icovert[a][1];
+ vec[2]= dia*icovert[a][2];
+ eva[a]= addvertlist(vec);
+ eva[a]->f= 1+2;
+ }
+ for(a=0;a<20;a++) {
+ EditFace *evtemp;
+ v1= eva[ icoface[a][0] ];
+ v2= eva[ icoface[a][1] ];
+ v3= eva[ icoface[a][2] ];
+ evtemp = addfacelist(v1, v2, v3, 0, NULL, NULL);
+ evtemp->e1->f = 1+2;
+ evtemp->e2->f = 1+2;
+ evtemp->e3->f = 1+2;
+ }
+
+ dia*=200;
+ for(a=1; a<subdiv; a++) esubdivideflag(2, dia, 0,1,0);
+ /* and now do imat */
+ eve= em->verts.first;
+ while(eve) {
+ if(eve->f & 2) {
+ VecAddf(eve->co,eve->co,cent);
+ Mat3MulVecfl(imat,eve->co);
+ }
+ eve= eve->next;
+ }
+
+ // Clear the flag 2 from the edges
+ for(eed=em->edges.first;eed;eed=eed->next){
+ if(eed->f & 2){
+ eed->f &= !2;
+ }
+ }
+ }
+ break;
+ case 13: /* Monkey */
+ {
+ extern int monkeyo, monkeynv, monkeynf;
+ extern signed char monkeyf[][4];
+ extern signed char monkeyv[][3];
+ EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv");
+ EditFace *efa;
+ int i;
+
+ for (i=0; i<monkeynv; i++) {
+ float v[3];
+ v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0;
+ tv[i]= addvertlist(v);
+ tv[i]->f |= SELECT;
+ tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(v);
+ tv[monkeynv+i]->f |= SELECT;
+ }
+ for (i=0; i<monkeynf; i++) {
+ efa= addfacelist(tv[monkeyf[i][0]+i-monkeyo], tv[monkeyf[i][1]+i-monkeyo], tv[monkeyf[i][2]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeyf[i][3]+i-monkeyo]:NULL, NULL, NULL);
+ efa= addfacelist(tv[monkeynv+monkeyf[i][2]+i-monkeyo], tv[monkeynv+monkeyf[i][1]+i-monkeyo], tv[monkeynv+monkeyf[i][0]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeynv+monkeyf[i][3]+i-monkeyo]:NULL, NULL, NULL);
+ }
+
+ MEM_freeN(tv);
+
+ /* and now do imat */
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if(eve->f & SELECT) {
+ VecAddf(eve->co,eve->co,cent);
+ Mat3MulVecfl(imat,eve->co);
+ }
+ }
+ recalc_editnormals();
+ }
+ break;
+ default: /* all types except grid, sphere... */
+ if(ext==0 && type!=7) d= 0;
+
+ /* vertices */
+ vtop= vdown= v1= v2= 0;
+ for(b=0; b<=ext; b++) {
+ for(a=0; a<tot; a++) {
+
+ vec[0]= cent[0]+dia*sin(phi);
+ vec[1]= cent[1]+dia*cos(phi);
+ vec[2]= cent[2]+d;
+
+ Mat3MulVecfl(imat, vec);
+ eve= addvertlist(vec);
+ eve->f= SELECT;
+ if(a==0) {
+ if(b==0) v1= eve;
+ else v2= eve;
+ }
+ phi+=phid;
+ }
+ d= -d;
+ }
+ /* centre vertices */
+ if(fill && type>1) {
+ VECCOPY(vec,cent);
+ vec[2]-= -d;
+ Mat3MulVecfl(imat,vec);
+ vdown= addvertlist(vec);
+ if(ext || type==7) {
+ VECCOPY(vec,cent);
+ vec[2]-= d;
+ Mat3MulVecfl(imat,vec);
+ vtop= addvertlist(vec);
+ }
+ } else {
+ vdown= v1;
+ vtop= v2;
+ }
+ if(vtop) vtop->f= SELECT;
+ if(vdown) vdown->f= SELECT;
+
+ /* top and bottom face */
+ if(fill) {
+ if(tot==4 && (type==0 || type==1)) {
+ v3= v1->next->next;
+ if(ext) v4= v2->next->next;
+
+ addfacelist(v3, v1->next, v1, v3->next, NULL, NULL);
+ if(ext) addfacelist(v2, v2->next, v4, v4->next, NULL, NULL);
+
+ }
+ else {
+ v3= v1;
+ v4= v2;
+ for(a=1; a<tot; a++) {
+ addfacelist(vdown, v3, v3->next, 0, NULL, NULL);
+ v3= v3->next;
+ if(ext) {
+ addfacelist(vtop, v4, v4->next, 0, NULL, NULL);
+ v4= v4->next;
+ }
+ }
+ if(type>1) {
+ addfacelist(vdown, v3, v1, 0, NULL, NULL);
+ if(ext) addfacelist(vtop, v4, v2, 0, NULL, NULL);
+ }
+ }
+ }
+ else if(type==4) { /* we need edges for a circle */
+ v3= v1;
+ for(a=1;a<tot;a++) {
+ addedgelist(v3, v3->next, NULL);
+ v3= v3->next;
+ }
+ addedgelist(v3, v1, NULL);
+ }
+ /* side faces */
+ if(ext) {
+ v3= v1;
+ v4= v2;
+ for(a=1; a<tot; a++) {
+ addfacelist(v3, v3->next, v4->next, v4, NULL, NULL);
+ v3= v3->next;
+ v4= v4->next;
+ }
+ addfacelist(v3, v1, v2, v4, NULL, NULL);
+ }
+ else if(type==7) { /* cone */
+ v3= v1;
+ for(a=1; a<tot; a++) {
+ addfacelist(vtop, v3->next, v3, 0, NULL, NULL);
+ v3= v3->next;
+ }
+ addfacelist(vtop, v1, v3, 0, NULL, NULL);
+ }
+ }
+ /* simple selection flush OK, based on fact it's a single model */
+ EM_select_flush(); /* flushes vertex -> edge -> face selection */
+
+ if(type!=0 && type!=13)
+ righthandfaces(1); /* otherwise monkey has eyes in wrong direction */
+}
+
+void add_primitiveMesh(int type)
+{
+ Mesh *me;
+ float *curs, d, dia, phi, phid, cent[3], imat[3][3], mat[3][3];
+ float cmat[3][3];
static short tot=32, seg=32, subdiv=2;
- short a, b, ext=0, fill=0, totoud, newob=0;
+ short ext=0, fill=0, totoud, newob=0;
char *undostr="Add Primitive";
char *name=NULL;
@@ -864,272 +1142,21 @@ void add_primitiveMesh(int type)
Mat3Inv(imat, mat);
}
- dia= sqrt(2.0)*G.vd->grid;
+ dia= G.vd->grid;
+ if(type != 10)
+ dia *= sqrt(2.0);
+
d= -G.vd->grid;
phid= 2*M_PI/tot;
phi= .25*M_PI;
- if(type<10) { /* all types except grid, sphere... */
- if(ext==0 && type!=7) d= 0;
-
- /* vertices */
- vtop= vdown= v1= v2= 0;
- for(b=0; b<=ext; b++) {
- for(a=0; a<tot; a++) {
-
- vec[0]= cent[0]+dia*sin(phi);
- vec[1]= cent[1]+dia*cos(phi);
- vec[2]= cent[2]+d;
-
- Mat3MulVecfl(imat, vec);
- eve= addvertlist(vec);
- eve->f= SELECT;
- if(a==0) {
- if(b==0) v1= eve;
- else v2= eve;
- }
- phi+=phid;
- }
- d= -d;
- }
- /* centre vertices */
- if(fill && type>1) {
- VECCOPY(vec,cent);
- vec[2]-= -d;
- Mat3MulVecfl(imat,vec);
- vdown= addvertlist(vec);
- if(ext || type==7) {
- VECCOPY(vec,cent);
- vec[2]-= d;
- Mat3MulVecfl(imat,vec);
- vtop= addvertlist(vec);
- }
- } else {
- vdown= v1;
- vtop= v2;
- }
- if(vtop) vtop->f= SELECT;
- if(vdown) vdown->f= SELECT;
-
- /* top and bottom face */
- if(fill) {
- if(tot==4 && (type==0 || type==1)) {
- v3= v1->next->next;
- if(ext) v4= v2->next->next;
-
- addfacelist(v3, v1->next, v1, v3->next, NULL, NULL);
- if(ext) addfacelist(v2, v2->next, v4, v4->next, NULL, NULL);
-
- }
- else {
- v3= v1;
- v4= v2;
- for(a=1; a<tot; a++) {
- addfacelist(vdown, v3, v3->next, 0, NULL, NULL);
- v3= v3->next;
- if(ext) {
- addfacelist(vtop, v4, v4->next, 0, NULL, NULL);
- v4= v4->next;
- }
- }
- if(type>1) {
- addfacelist(vdown, v3, v1, 0, NULL, NULL);
- if(ext) addfacelist(vtop, v4, v2, 0, NULL, NULL);
- }
- }
- }
- else if(type==4) { /* we need edges for a circle */
- v3= v1;
- for(a=1;a<tot;a++) {
- addedgelist(v3, v3->next, NULL);
- v3= v3->next;
- }
- addedgelist(v3, v1, NULL);
- }
- /* side faces */
- if(ext) {
- v3= v1;
- v4= v2;
- for(a=1; a<tot; a++) {
- addfacelist(v3, v3->next, v4->next, v4, NULL, NULL);
- v3= v3->next;
- v4= v4->next;
- }
- addfacelist(v3, v1, v2, v4, NULL, NULL);
- }
- else if(type==7) { /* cone */
- v3= v1;
- for(a=1; a<tot; a++) {
- addfacelist(vtop, v3->next, v3, 0, NULL, NULL);
- v3= v3->next;
- }
- addfacelist(vtop, v1, v3, 0, NULL, NULL);
- }
-
- if(type<2) tot= totoud;
-
- }
- else if(type==10) { /* grid */
- /* clear flags */
- eve= em->verts.first;
- while(eve) {
- eve->f= 0;
- eve= eve->next;
- }
- dia= G.vd->grid;
- /* one segment first: the X axis */
- phi= 1.0;
- phid= 2.0/((float)tot-1);
- for(a=0;a<tot;a++) {
- vec[0]= cent[0]+dia*phi;
- vec[1]= cent[1]- dia;
- vec[2]= cent[2];
- Mat3MulVecfl(imat,vec);
- eve= addvertlist(vec);
- eve->f= 1+2+4;
- if (a) {
- addedgelist(eve->prev, eve, NULL);
- }
- phi-=phid;
- }
- /* extrude and translate */
- vec[0]= vec[2]= 0.0;
- vec[1]= dia*phid;
- Mat3MulVecfl(imat, vec);
- for(a=0;a<seg-1;a++) {
- extrudeflag_vert(2, nor); // nor unused
- translateflag(2, vec);
- }
- }
- else if(type==11) { /* UVsphere */
-
- /* clear all flags */
- eve= em->verts.first;
- while(eve) {
- eve->f= 0;
- eve= eve->next;
- }
-
- /* one segment first */
- phi= 0;
- phid/=2;
- for(a=0; a<=tot; a++) {
- vec[0]= dia*sin(phi);
- vec[1]= 0.0;
- vec[2]= dia*cos(phi);
- eve= addvertlist(vec);
- eve->f= 1+2+4;
- if(a==0) v1= eve;
- else addedgelist(eve->prev, eve, NULL);
- phi+= phid;
- }
-
- /* extrude and rotate */
- phi= M_PI/seg;
- q[0]= cos(phi);
- q[3]= sin(phi);
- q[1]=q[2]= 0;
- QuatToMat3(q, cmat);
-
- for(a=0; a<seg; a++) {
- extrudeflag_vert(2, nor); // nor unused
- rotateflag(2, v1->co, cmat);
- }
+ make_prim(type, imat,
+ tot, seg, subdiv, dia, d,
+ ext, fill,
+ cent);
- removedoublesflag(4, 0.0001);
+ if(type<2) tot = totoud;
- /* and now do imat */
- eve= em->verts.first;
- while(eve) {
- if(eve->f & SELECT) {
- VecAddf(eve->co,eve->co,cent);
- Mat3MulVecfl(imat,eve->co);
- }
- eve= eve->next;
- }
- }
- else if(type==12) { /* Icosphere */
- EditVert *eva[12];
- EditEdge *eed;
-
- /* clear all flags */
- eve= em->verts.first;
- while(eve) {
- eve->f= 0;
- eve= eve->next;
- }
- dia/=200;
- for(a=0;a<12;a++) {
- vec[0]= dia*icovert[a][0];
- vec[1]= dia*icovert[a][1];
- vec[2]= dia*icovert[a][2];
- eva[a]= addvertlist(vec);
- eva[a]->f= 1+2;
- }
- for(a=0;a<20;a++) {
- EditFace *evtemp;
- v1= eva[ icoface[a][0] ];
- v2= eva[ icoface[a][1] ];
- v3= eva[ icoface[a][2] ];
- evtemp = addfacelist(v1, v2, v3, 0, NULL, NULL);
- evtemp->e1->f = 1+2;
- evtemp->e2->f = 1+2;
- evtemp->e3->f = 1+2;
- }
-
- dia*=200;
- for(a=1; a<subdiv; a++) esubdivideflag(2, dia, 0,1,0);
- /* and now do imat */
- eve= em->verts.first;
- while(eve) {
- if(eve->f & 2) {
- VecAddf(eve->co,eve->co,cent);
- Mat3MulVecfl(imat,eve->co);
- }
- eve= eve->next;
- }
-
- // Clear the flag 2 from the edges
- for(eed=em->edges.first;eed;eed=eed->next){
- if(eed->f & 2){
- eed->f &= !2;
- }
- }
-
-
- } else if (type==13) { /* Monkey */
- extern int monkeyo, monkeynv, monkeynf;
- extern signed char monkeyf[][4];
- extern signed char monkeyv[][3];
- EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv");
- EditFace *efa;
- int i;
-
- for (i=0; i<monkeynv; i++) {
- float v[3];
- v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0;
- tv[i]= addvertlist(v);
- tv[i]->f |= SELECT;
- tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(v);
- tv[monkeynv+i]->f |= SELECT;
- }
- for (i=0; i<monkeynf; i++) {
- efa= addfacelist(tv[monkeyf[i][0]+i-monkeyo], tv[monkeyf[i][1]+i-monkeyo], tv[monkeyf[i][2]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeyf[i][3]+i-monkeyo]:NULL, NULL, NULL);
- efa= addfacelist(tv[monkeynv+monkeyf[i][2]+i-monkeyo], tv[monkeynv+monkeyf[i][1]+i-monkeyo], tv[monkeynv+monkeyf[i][0]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeynv+monkeyf[i][3]+i-monkeyo]:NULL, NULL, NULL);
- }
-
- MEM_freeN(tv);
-
- /* and now do imat */
- for(eve= em->verts.first; eve; eve= eve->next) {
- if(eve->f & SELECT) {
- VecAddf(eve->co,eve->co,cent);
- Mat3MulVecfl(imat,eve->co);
- }
- }
- recalc_editnormals();
- }
-
// simple selection flush OK, based on fact it's a single model
EM_select_flush(); // flushes vertex -> edge -> face selection