[MOAB-dev] r2878 - in MOAB/trunk/tools/iMesh: . python python/itaps python/test

jvporter at wisc.edu jvporter at wisc.edu
Wed May 6 14:32:15 CDT 2009


Author: jvporter
Date: 2009-05-06 14:32:15 -0500 (Wed, 06 May 2009)
New Revision: 2878

Added:
   MOAB/trunk/tools/iMesh/python/
   MOAB/trunk/tools/iMesh/python/README
   MOAB/trunk/tools/iMesh/python/common.h
   MOAB/trunk/tools/iMesh/python/errors.h
   MOAB/trunk/tools/iMesh/python/iBase.c
   MOAB/trunk/tools/iMesh/python/iBase_Python.h
   MOAB/trunk/tools/iMesh/python/iBase_module.h
   MOAB/trunk/tools/iMesh/python/iMesh.c
   MOAB/trunk/tools/iMesh/python/iMesh_Python.h
   MOAB/trunk/tools/iMesh/python/iMesh_entSet.c
   MOAB/trunk/tools/iMesh/python/iMesh_iter.c
   MOAB/trunk/tools/iMesh/python/iMesh_tag.c
   MOAB/trunk/tools/iMesh/python/itaps/
   MOAB/trunk/tools/iMesh/python/itaps/__init__.py
   MOAB/trunk/tools/iMesh/python/setup.py
   MOAB/trunk/tools/iMesh/python/test/
   MOAB/trunk/tools/iMesh/python/test/adj.py
   MOAB/trunk/tools/iMesh/python/test/all.py
   MOAB/trunk/tools/iMesh/python/test/basic.py
   MOAB/trunk/tools/iMesh/python/test/core.py
   MOAB/trunk/tools/iMesh/python/test/entset.py
   MOAB/trunk/tools/iMesh/python/test/iter.py
   MOAB/trunk/tools/iMesh/python/test/tags.py
Log:
Initial revision.
* Python bindings to iBase/iMesh interface more-or-less feature complete
* Basic unit tests written


Added: MOAB/trunk/tools/iMesh/python/README
===================================================================
--- MOAB/trunk/tools/iMesh/python/README	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/README	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,36 @@
+PyTAPS
+Jim Porter, jvporter at wisc.edu
+Revision 0.1, May 6, 2009
+
+== Installation ==
+
+PyTAPS requires the following to be installed on your system:
+ * Python (2.2+)
+ * Numpy
+ * MOAB (or other iBase/iMesh interface)
+ * HDF5
+
+If the include files and libraries are in the default paths for your C 
+compiler, then typing `python setup.py install' should be sufficient. If not,
+create a file named `setup.cfg' and enter the appropriate paths, like so:
+
+----- Begin setup.cfg -----
+
+[build_ext]
+include_dirs = folder1:folder2
+library_dirs = folder3:folder4
+
+----- End setup.cfg -----
+
+
+== Usage ==
+
+For usage examples, consult the files in test/*. For help with using the iMesh
+interface, run `help(itaps.iMesh)' from the Python interpreter.
+
+
+== Testing ==
+
+Basic tests of the interface may be run from test/. To run all tests (excluding
+iterator tests), run all.py. If the tests fail to import the package properly,
+consult test/core.py and adjust the sys.path setting as needed.
\ No newline at end of file

Added: MOAB/trunk/tools/iMesh/python/common.h
===================================================================
--- MOAB/trunk/tools/iMesh/python/common.h	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/common.h	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,64 @@
+#pragma once
+
+#include <Python.h>
+
+#define SIMPLE_TYPE(name,type,name_str,doc)		\
+  static PyTypeObject type = {				\
+    PyObject_HEAD_INIT(NULL)				\
+    0,                         /*ob_size*/		\
+    (name_str),                /*tp_name*/		\
+    sizeof(name),              /*tp_basicsize*/		\
+    0,                         /*tp_itemsize*/		\
+    0,                         /*tp_dealloc*/		\
+    0,                         /*tp_print*/		\
+    0,                         /*tp_getattr*/		\
+    0,                         /*tp_setattr*/		\
+    0,                         /*tp_compare*/		\
+    0,                         /*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,        /*tp_flags*/		\
+    (doc),                     /* tp_doc */		\
+}
+
+#define ENUM_TYPE(name,namestr,docstr)			\
+  typedef struct					\
+  {							\
+    PyObject_HEAD					\
+  } name ## _Object;					\
+  SIMPLE_TYPE(name ## _Object,name ## _Type,		\
+		     namestr,docstr)
+
+#define ADD_ENUM(type,name,value)                       \
+  do {                                                  \
+    PyObject *o = Py_BuildValue("i",(value));           \
+    PyDict_SetItemString((type)->tp_dict,(name),o);     \
+    Py_DECREF(o);                                       \
+  } while(0)
+
+#define REGISTER_SIMPLE(m,name)				\
+  do {							\
+    name ## _Type.tp_new = PyType_GenericNew;		\
+    if(PyType_Ready(&name ## _Type) < 0)		\
+      return;						\
+    Py_INCREF(&name ## _Type);				\
+    PyModule_AddObject(m,#name,				\
+		       (PyObject *)&name ## _Type);	\
+  } while(0)
+
+#define REGISTER_SIMPLE_SUB(base,name)			\
+  do {                                                  \
+    name ## _Type.tp_new = PyType_GenericNew;           \
+    if(PyType_Ready(&name ## _Type) < 0)                \
+      return;                                           \
+    Py_INCREF(&name ## _Type);                          \
+    PyDict_SetItemString(base.tp_dict,#name,		\
+			 (PyObject *)&name ## _Type);	\
+  } while(0)

Added: MOAB/trunk/tools/iMesh/python/errors.h
===================================================================
--- MOAB/trunk/tools/iMesh/python/errors.h	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/errors.h	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,9 @@
+#pragma once
+
+#define ERR_STORAGE_ORDER "storage order expected"
+#define ERR_ENT_OR_ENTARR "entity or entity array expected"
+#define ERR_ENT_OR_ENTSET "entity or entity set expected"
+#define ERR_ANY_ENT       "entity, entity array, or entity set expected"
+#define ERR_ARR_SIZE      "unexpected array size"
+#define ERR_ARR_DIMS      "1- or 2-dimensional array expected"
+#define ERR_TYPE_CODE     "invalid type code"

Added: MOAB/trunk/tools/iMesh/python/iBase.c
===================================================================
--- MOAB/trunk/tools/iMesh/python/iBase.c	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/iBase.c	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,335 @@
+#define _IBASE_MODULE
+#include "iBase_Python.h"
+
+#include <numpy/arrayobject.h>
+
+SIMPLE_TYPE(iBaseEntity_Object,iBaseEntity_Type,"itaps.iBase.iBaseEntity","");
+SIMPLE_TYPE(iBaseEntitySet_Object,iBaseEntitySet_Type,
+	    "itaps.iBase.iBaseEntitySet","");
+SIMPLE_TYPE(iBaseTag_Object,iBaseTag_Type,"itaps.iBase.iBaseTag","");
+
+static PyObject *
+iBaseEntity_FromHandle(iBase_EntityHandle h)
+{
+  iBaseEntity_Object *o = iBaseEntity_New();
+  o->handle = h;
+  return (PyObject*)o;
+}
+static int NPY_IBASEENT;
+
+static PyObject *
+iBaseEntitySet_FromHandle(iBase_EntitySetHandle h)
+{
+  iBaseEntitySet_Object *o = iBaseEntitySet_New();
+  o->handle = h;
+  return (PyObject*)o;
+}
+static int NPY_IBASEENTSET;
+
+static PyObject *
+iBaseTag_FromHandle(iBase_TagHandle h)
+{
+  iBaseTag_Object *o = iBaseTag_New();
+  o->handle = h;
+  return (PyObject*)o;
+}
+static int NPY_IBASETAG;
+
+ENUM_TYPE(type,         "iBase.type",         "");
+ENUM_TYPE(adjCost,      "iBase.adjCost",      "");
+ENUM_TYPE(storageOrder, "iBase.storageOrder", "");
+
+static PyMethodDef module_methods[] = {
+  {0}
+};
+
+
+static PyObject *
+iBaseEntArr_getitem(void *data,void *arr)
+{
+  return iBaseEntity_FromHandle(*(iBase_EntityHandle*)data);
+}
+
+static int
+iBaseEntArr_setitem(PyObject *item,void *data,void *arr)
+{
+  if(!iBaseEntity_Check(item))
+    return -1;
+  *(iBase_EntityHandle*)data = iBaseEntity_GetHandle(item);
+  return 0;
+}
+
+static void
+iBaseEntArr_copyswapn(void *dest,npy_intp dstride,void *src,npy_intp sstride,
+		      npy_intp n,int swap,void *arr)
+{}
+
+static void
+iBaseEntArr_copyswap(void *dest,void *src,int swap,void *arr)
+{}
+
+static npy_bool
+iBaseEntArr_nonzero(void *data,void *arr)
+{
+  printf("nonzero");
+  return *(iBase_EntityHandle*)data != 0;
+}
+
+static PyObject *
+iBaseEntObj_repr(iBaseEntity_Object *self)
+{
+  char foo[64];
+  snprintf(foo,64,"<iBase_EntityHandle %p>",self->handle);
+  return Py_BuildValue("s",foo);
+}
+
+static PyObject *
+iBaseEntObj_richcompare(iBaseEntity_Object *lhs,iBaseEntity_Object *rhs,int op)
+{
+  switch(op)
+  {
+  case Py_EQ:
+    return PyBool_FromLong(lhs->handle == rhs->handle);
+  case Py_NE:
+    return PyBool_FromLong(lhs->handle != rhs->handle);
+  default:
+    return Py_NotImplemented;
+  }
+}
+
+static PyArray_ArrFuncs iBaseEntArr_funcs = {
+  {0},
+  iBaseEntArr_getitem,
+  iBaseEntArr_setitem,
+  iBaseEntArr_copyswapn,
+  iBaseEntArr_copyswap,
+  0,
+  0,
+  0,
+  0,
+  0,
+  iBaseEntArr_nonzero
+};
+
+
+static PyObject *
+iBaseEntSetArr_getitem(void *data,void *arr)
+{
+  return iBaseEntitySet_FromHandle(*(iBase_EntitySetHandle*)data);
+}
+
+static int
+iBaseEntSetArr_setitem(PyObject *item,void *data,void *arr)
+{
+  return 0;
+}
+
+static void
+iBaseEntSetArr_copyswapn(void *dest,npy_intp dstride,void *src,
+			 npy_intp sstride,npy_intp n,int swap,void *arr)
+{}
+
+static void
+iBaseEntSetArr_copyswap(void *dest,void *src,int swap,void *arr)
+{}
+
+static npy_bool
+iBaseEntSetArr_nonzero(void *data,void *arr)
+{
+  return *(iBase_EntitySetHandle*)data != 0;
+}
+
+static PyObject *
+iBaseEntSetObj_repr(iBaseEntitySet_Object *self)
+{
+  char foo[64];
+  snprintf(foo,64,"<iBase_EntitySetHandle %p>",self->handle);
+  return Py_BuildValue("s",foo);
+}
+
+static PyObject *
+iBaseEntSetObj_richcompare(iBaseEntitySet_Object *lhs,
+			   iBaseEntitySet_Object *rhs,int op)
+{
+  switch(op)
+  {
+  case Py_EQ:
+    return PyBool_FromLong(lhs->handle == rhs->handle);
+  case Py_NE:
+    return PyBool_FromLong(lhs->handle != rhs->handle);
+  default:
+    return Py_NotImplemented;
+  }
+}
+
+static PyArray_ArrFuncs iBaseEntSetArr_funcs = {
+  {0},
+  iBaseEntSetArr_getitem,
+  iBaseEntSetArr_setitem,
+  iBaseEntSetArr_copyswapn,
+  iBaseEntSetArr_copyswap,
+  0,
+  0,
+  0,
+  0,
+  0,
+  iBaseEntSetArr_nonzero
+};
+
+
+
+static PyObject *
+iBaseTagArr_getitem(void *data,void *arr)
+{
+  return iBaseTag_FromHandle(*(iBase_TagHandle*)data);
+}
+
+static int
+iBaseTagArr_setitem(PyObject *item,void *data,void *arr)
+{
+  return 0;
+}
+
+static void
+iBaseTagArr_copyswapn(void *dest,npy_intp dstride,void *src,npy_intp sstride,
+                      npy_intp n,int swap,void *arr)
+{}
+
+static void
+iBaseTagArr_copyswap(void *dest,void *src,int swap,void *arr)
+{}
+
+static npy_bool
+iBaseTagArr_nonzero(void *data,void *arr)
+{
+  return *(iBase_TagHandle*)data != 0;
+}
+
+static PyArray_ArrFuncs iBaseTagArr_funcs = {
+  {0},
+  iBaseTagArr_getitem,
+  iBaseTagArr_setitem,
+  iBaseTagArr_copyswapn,
+  iBaseTagArr_copyswap,
+  0,
+  0,
+  0,
+  0,
+  0,
+  iBaseTagArr_nonzero
+};
+
+
+
+PyMODINIT_FUNC initiBase(void)
+{
+  PyArray_Descr *descr;
+  PyObject *m = Py_InitModule("iBase",module_methods);
+  import_array();
+
+  /* register C API */
+  static void *IBase_API[6];
+  PyObject *api_obj;
+
+  /* Initialize the C API pointer array */
+  IBase_API[0] = &iBaseEntity_Type;
+  IBase_API[1] = &NPY_IBASEENT;
+  IBase_API[2] = &iBaseEntitySet_Type;
+  IBase_API[3] = &NPY_IBASEENTSET;
+  IBase_API[4] = &iBaseTag_Type;
+  IBase_API[5] = &NPY_IBASETAG;
+
+  /* Create a CObject containing the API pointer array's address */
+  api_obj = PyCObject_FromVoidPtr(IBase_API,NULL);
+
+  if(api_obj != NULL)
+    PyModule_AddObject(m, "_C_API", api_obj);
+
+  /***** initialize type enum *****/
+  REGISTER_SIMPLE(m,type);
+
+  ADD_ENUM(&type_Type,"vertex", iBase_VERTEX);
+  ADD_ENUM(&type_Type,"edge",   iBase_EDGE);
+  ADD_ENUM(&type_Type,"face",   iBase_FACE);
+  ADD_ENUM(&type_Type,"region", iBase_REGION);
+  ADD_ENUM(&type_Type,"all",    iBase_ALL_TYPES);
+
+  /***** initialize adjacency cost enum *****/
+  REGISTER_SIMPLE(m,adjCost);
+
+  ADD_ENUM(&adjCost_Type,"unavailable",     iBase_UNAVAILABLE);
+  ADD_ENUM(&adjCost_Type,"all_order_1",     iBase_ALL_ORDER_1);
+  ADD_ENUM(&adjCost_Type,"all_order_logn",  iBase_ALL_ORDER_LOGN);
+  ADD_ENUM(&adjCost_Type,"all_order_n",     iBase_ALL_ORDER_N);
+  ADD_ENUM(&adjCost_Type,"some_order_1",    iBase_SOME_ORDER_1);
+  ADD_ENUM(&adjCost_Type,"some_order_logn", iBase_SOME_ORDER_LOGN);
+  ADD_ENUM(&adjCost_Type,"some_order_n",    iBase_SOME_ORDER_N);
+
+  /***** initialize storage order enum *****/
+  REGISTER_SIMPLE(m,storageOrder);
+
+  ADD_ENUM(&storageOrder_Type,"blocked",    iBase_BLOCKED);
+  ADD_ENUM(&storageOrder_Type,"interleaved",iBase_INTERLEAVED);
+
+  /***** initialize iBaseEntity handle *****/
+  iBaseEntity_Type.tp_repr = (reprfunc)iBaseEntObj_repr;
+  iBaseEntity_Type.tp_richcompare = (richcmpfunc)iBaseEntObj_richcompare;
+  iBaseEntity_Type.tp_new = PyType_GenericNew;
+  if(PyType_Ready(&iBaseEntity_Type) < 0)
+    return;
+  Py_INCREF(&iBaseEntity_Type);
+  PyModule_AddObject(m,"iBaseEntity",(PyObject *)&iBaseEntity_Type);
+
+  /***** initialize iBaseEntitySet handle *****/
+  iBaseEntitySet_Type.tp_repr = (reprfunc)iBaseEntSetObj_repr;
+  iBaseEntitySet_Type.tp_richcompare = (richcmpfunc)iBaseEntSetObj_richcompare;
+  iBaseEntitySet_Type.tp_new = PyType_GenericNew;
+  if(PyType_Ready(&iBaseEntitySet_Type) < 0)
+    return;
+  Py_INCREF(&iBaseEntitySet_Type);
+  PyModule_AddObject(m,"iBaseEntitySet",(PyObject *)&iBaseEntitySet_Type);
+
+  /***** initialize iBaseTag handle *****/
+  iBaseTag_Type.tp_new = PyType_GenericNew;
+  if(PyType_Ready(&iBaseTag_Type) < 0)
+    return;
+  Py_INCREF(&iBaseTag_Type);
+  PyModule_AddObject(m,"iBaseTag",(PyObject *)&iBaseTag_Type);
+
+
+  /***** initialize iBaseEntity array type *****/
+  descr = PyArray_DescrNewFromType(NPY_INTP);
+  descr->f = &iBaseEntArr_funcs;
+
+  descr->typeobj = &iBaseEntity_Type;
+  descr->kind = 'V';
+  descr->type = 'j';
+  descr->hasobject = NPY_USE_GETITEM|NPY_USE_SETITEM;
+  descr->elsize = sizeof(iBase_EntityHandle);
+
+  NPY_IBASEENT = PyArray_RegisterDataType(descr);
+
+  /***** initialize iBaseEntitySet array type *****/
+  descr = PyArray_DescrNewFromType(NPY_INTP);
+  descr->f = &iBaseEntSetArr_funcs;
+
+  descr->typeobj = &iBaseEntitySet_Type;
+  descr->kind = 'V';
+  descr->type = 'J';
+  descr->hasobject = NPY_USE_GETITEM|NPY_USE_SETITEM;
+  descr->elsize = sizeof(iBase_EntitySetHandle);
+
+  NPY_IBASEENTSET = PyArray_RegisterDataType(descr);
+
+  /***** initialize iBaseTag array type *****/
+  descr = PyArray_DescrNewFromType(NPY_INTP);
+  descr->f = &iBaseTagArr_funcs;
+
+  descr->typeobj = &iBaseTag_Type;
+  descr->kind = 'V';
+  descr->type = 'T';
+  descr->hasobject = NPY_USE_GETITEM|NPY_USE_SETITEM;
+  descr->elsize = sizeof(iBase_TagHandle);
+
+  NPY_IBASETAG = PyArray_RegisterDataType(descr);
+}

Added: MOAB/trunk/tools/iMesh/python/iBase_Python.h
===================================================================
--- MOAB/trunk/tools/iMesh/python/iBase_Python.h	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/iBase_Python.h	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,109 @@
+#pragma once
+
+#include "common.h"
+
+#include <Python.h>
+#include <iBase.h>
+
+typedef struct
+{
+  PyObject_HEAD
+  iBase_EntityHandle handle;
+} iBaseEntity_Object;
+
+#define iBaseEntity_New()			 \
+  (iBaseEntity_Object*)PyObject_CallObject(	 \
+    (PyObject*)&iBaseEntity_Type,NULL)
+
+#define iBaseEntity_Check(o)			 \
+  PyObject_TypeCheck((o),&iBaseEntity_Type)
+
+#define iBaseEntity_GetHandle(o)		 \
+  ((iBaseEntity_Object*)(o))->handle
+
+typedef struct
+{
+  PyObject_HEAD
+  iBase_EntitySetHandle handle;
+} iBaseEntitySet_Object;
+
+#define iBaseEntitySet_New()			\
+  (iBaseEntitySet_Object*)PyObject_CallObject(  \
+    (PyObject*)&iBaseEntitySet_Type,NULL)
+
+#define iBaseEntitySet_Check(o)			\
+  PyObject_TypeCheck((o),&iBaseEntitySet_Type)
+
+#define iBaseEntitySet_GetHandle(o)		\
+  ((iBaseEntitySet_Object*)(o))->handle
+
+typedef struct
+{
+  PyObject_HEAD
+  iBase_TagHandle handle;
+} iBaseTag_Object;
+
+#define iBaseTag_New()				\
+  (iBaseTag_Object*)PyObject_CallObject(	\
+    (PyObject*)&iBaseTag_Type,NULL)
+
+#define iBaseTag_Check(o)			\
+  PyObject_TypeCheck((o),&iBaseTag_Type)
+
+#define iBaseTag_GetHandle(o)			\
+  ((iBaseTag_Object*)(o))->handle
+
+
+
+
+#ifndef _IBASE_MODULE
+
+#if defined(PY_IBASE_UNIQUE_SYMBOL)
+#define IBase_API PY_IBASE_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_IBASE)
+extern void **IBase_API;
+#elif defined(PY_IBASE_UNIQUE_SYMBOL)
+void **IBase_API;
+#else
+static void **IBase_API = NULL;
+#endif
+
+#define iBaseEntity_Type    (*(PyTypeObject*)IBase_API[0])
+#define NPY_IBASEENT        (*(int*)         IBase_API[1])
+#define iBaseEntitySet_Type (*(PyTypeObject*)IBase_API[2])
+#define NPY_IBASEENTSET     (*(int*)         IBase_API[3])
+#define iBaseTag_Type       (*(PyTypeObject*)IBase_API[4])
+#define NPY_IBASETAG        (*(int*)         IBase_API[5])
+
+
+#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
+static int import_iBase(void)
+{
+  PyObject *module = PyImport_ImportModule("itaps.iBase");
+  PyObject *c_api = NULL;
+
+  if(module == NULL)
+    return -1;
+
+  c_api = PyObject_GetAttrString(module,"_C_API");
+  if(c_api == NULL)
+    {
+      Py_DECREF(module);
+      return -1;
+    }
+
+  if(PyCObject_Check(c_api))
+    IBase_API = (void **)PyCObject_AsVoidPtr(c_api);
+
+  Py_DECREF(c_api);
+  Py_DECREF(module);
+
+  if(IBase_API == NULL)
+    return -1;
+  return 0;
+}
+#endif
+
+#endif

Added: MOAB/trunk/tools/iMesh/python/iBase_module.h
===================================================================
--- MOAB/trunk/tools/iMesh/python/iBase_module.h	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/iBase_module.h	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,53 @@
+#pragma once
+
+#ifndef _IBASE_MODULE
+
+#if defined(PY_IBASE_UNIQUE_SYMBOL)
+#define IBase_API PY_IBASE_UNIQUE_SYMBOL
+#endif
+
+#if defined(NO_IMPORT) || defined(NO_IMPORT_IBASE)
+extern void **IBase_API;
+#elif defined(PY_IBASE_UNIQUE_SYMBOL)
+void **IBase_API;
+#else
+static void **IBase_API = NULL;
+#endif
+
+#define iBaseEntity_Type    (*(PyTypeObject*)IBase_API[0])
+#define NPY_IBASEENT        (*(int*)         IBase_API[1])
+#define iBaseEntitySet_Type (*(PyTypeObject*)IBase_API[2])
+#define NPY_IBASEENTSET     (*(int*)         IBase_API[3])
+#define iBaseTag_Type       (*(PyTypeObject*)IBase_API[4])
+#define NPY_IBASETAG        (*(int*)         IBase_API[5])
+
+
+#if !defined(NO_IMPORT_ARRAY) && !defined(NO_IMPORT)
+static int import_iBase(void)
+{
+  PyObject *module = PyImport_ImportModule("itaps.iBase");
+  PyObject *c_api = NULL;
+
+  if(module == NULL)
+    return -1;
+
+  c_api = PyObject_GetAttrString(module,"_C_API");
+  if(c_api == NULL)
+  {
+    Py_DECREF(module);
+    return -1;
+  }
+
+  if(PyCObject_Check(c_api))
+    IBase_API = (void **)PyCObject_AsVoidPtr(c_api);
+
+  Py_DECREF(c_api);
+  Py_DECREF(module);
+
+  if(IBase_API == NULL)
+    return -1;
+  return 0;
+}
+#endif
+
+#endif

Added: MOAB/trunk/tools/iMesh/python/iMesh.c
===================================================================
--- MOAB/trunk/tools/iMesh/python/iMesh.c	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/iMesh.c	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,1623 @@
+#include "errors.h"
+#include "iMesh_Python.h"
+#include "iBase_Python.h"
+
+
+int checkError(iMesh_Instance mesh,int err)
+{
+  if(err)
+  {
+    char descr[512];
+    iMesh_getDescription(mesh,descr,&err,sizeof(descr));
+
+    PyErr_SetString(PyExc_RuntimeError,descr);
+    return 1;
+  }
+  else
+    return 0;
+}
+
+PyObject *
+PyArray_TryFromObject(PyObject *obj,int typenum,int min_depth,int max_depth)
+{
+  PyObject *ret = PyArray_FromAny(obj,PyArray_DescrFromType(typenum),min_depth,
+                                  max_depth,NPY_C_CONTIGUOUS,NULL);
+  PyErr_Clear();
+  return ret;
+}
+
+static int
+iMeshObj_init(iMeshObject *self,PyObject *args,PyObject *kwds)
+{
+  static char *kwlist[] = {"options",0};
+  const char *options = "";
+
+  if( !PyArg_ParseTupleAndKeywords(args,kwds,"|s",kwlist,&options) )
+    return -1;
+
+  int err;
+  iMesh_newMesh(options,&self->mesh,&err,strlen(options));
+  if(checkError(self->mesh,err))
+    return -1;
+
+  return 0;
+}
+
+static void
+iMeshObj_dealloc(iMeshObject *self)
+{
+  if(self->mesh)
+  {
+    int err;
+    iMesh_dtor(self->mesh,&err);
+  }
+
+  self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+iMeshObj_load(iMeshObject *self,PyObject *args)
+{
+  iBaseEntitySet_Object *set;
+  const char *name = 0;
+  const char *options = "";
+  if(!PyArg_ParseTuple(args,"Os|s",&set,&name,&options))
+    return NULL;
+
+  int err;
+  iMesh_load(self->mesh,set->handle,name,options,&err,strlen(name),
+	     strlen(options));
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+iMeshObj_save(iMeshObject *self,PyObject *args)
+{
+  iBaseEntitySet_Object *set;
+  const char *name = 0;
+  const char *options = "";
+  if(!PyArg_ParseTuple(args,"Os|s",&set,&name,&options))
+    return NULL;
+
+  int err;
+  iMesh_save(self->mesh,set->handle,name,options,&err,strlen(name),
+	     strlen(options));
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+iMeshObj_getRootSet(iMeshObject *self,void *closure)
+{
+  iMeshEntitySet_Object *rootset = iMeshEntitySet_New();
+  rootset->mesh = self; /* TODO: incref? */
+
+  int err;
+  iMesh_getRootSet(self->mesh,&rootset->set.handle,&err);
+  if(checkError(self->mesh,err))
+  {
+    Py_DECREF((PyObject*)rootset);
+    return NULL;
+  }
+
+  return (PyObject*)rootset;
+}
+
+
+static PyObject *
+iMeshObj_getGeometricDimension(iMeshObject *self,void *closure)
+{
+  int dim,err;
+  iMesh_getGeometricDimension(self->mesh,&dim,&err);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("i",dim);
+}
+
+static int
+iMeshObj_setGeometricDimension(iMeshObject *self,PyObject *value,void *closure)
+{
+  if (value == NULL) {
+    PyErr_SetString(PyExc_TypeError, "Cannot delete the geometricDimension "
+		    "attribute");
+    return -1;
+  }
+  
+  int dim,err;
+  if(!PyArg_Parse(value,"i",&dim))
+    return -1;
+  iMesh_setGeometricDimension(self->mesh,dim,&err);
+  if(checkError(self->mesh,err))
+    return -1;
+
+  return 0;
+}
+
+static PyObject *
+iMeshObj_getDfltStorage(iMeshObject *self,void *closure)
+{
+  int order,err;
+  iMesh_getDfltStorage(self->mesh,&order,&err);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("i",order);
+}
+
+static PyObject *
+iMeshObj_getAdjTable(iMeshObject *self,void *closure)
+{
+  int *adjtable=0;
+  int alloc=0,size,err;
+
+  iMesh_getAdjTable(self->mesh,&adjtable,&alloc,&size,&err);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  npy_intp dims[] = {4,4};
+  return PyArray_NewFromMallocData(2,dims,NPY_INT,adjtable);
+}
+
+static PyObject *
+iMeshObj_getNumOfType(iMeshObject *self,PyObject *args)
+{
+  iBaseEntitySet_Object *set;
+  enum iBase_EntityType type;
+  int num,err;
+  if(!PyArg_ParseTuple(args,"O!i",&iBaseEntitySet_Type,&set,&type))
+    return NULL;
+
+  iMesh_getNumOfType(self->mesh,set->handle,type,&num,&err);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("i",num);
+}
+
+static PyObject *
+iMeshObj_getNumOfTopo(iMeshObject *self,PyObject *args)
+{
+  iBaseEntitySet_Object *set;
+  enum iMesh_EntityTopology topo;
+  int num,err;
+  if(!PyArg_ParseTuple(args,"O!i",&iBaseEntitySet_Type,&set,&topo))
+    return NULL;
+
+  iMesh_getNumOfTopo(self->mesh,set->handle,topo,&num,&err);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("i",num);
+}
+
+static PyObject *
+iMeshObj_areEHValid(iMeshObject *self,PyObject *args)
+{
+  int doReset,areInv,err;
+  if(!PyArg_ParseTuple(args,"i",&doReset))
+    return NULL;
+
+  iMesh_areEHValid(self->mesh,doReset,&areInv,&err);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("i",areInv);
+}
+
+static PyObject *
+iMeshObj_getEntities(iMeshObject *self,PyObject *args)
+{
+  iBaseEntitySet_Object *set;
+  enum iBase_EntityType type;
+  enum iMesh_EntityTopology topo;
+  iBase_EntityHandle *entities=0;
+  int alloc=0,size,err;
+
+  if(!PyArg_ParseTuple(args,"O!ii",&iBaseEntitySet_Type,&set,&type,&topo))
+    return NULL;
+
+  iMesh_getEntities(self->mesh,set->handle,type,topo,&entities,&alloc,&size,
+		    &err);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  npy_intp dims[] = {size};
+  return PyArray_NewFromMallocData(1,dims,NPY_IBASEENT,entities);
+}
+
+static PyObject *
+iMeshObj_getVtxCoords(iMeshObject *self,PyObject *args)
+{
+  PyObject *obj;
+  int storage_order=-1;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"O|i",&obj,&storage_order))
+    return NULL;
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    if(storage_order == -1)
+    {
+      PyErr_SetString(PyExc_ValueError,ERR_STORAGE_ORDER);
+      return NULL;
+    }
+
+    int size;
+    double *coords=0;
+    int coords_alloc=0,coords_size;
+
+    size = PyArray_SIZE(ents);
+    iBase_EntityHandle *data = PyArray_DATA(ents);
+
+    iMesh_getVtxArrCoords(self->mesh,data,size,storage_order,&coords,
+			  &coords_alloc,&coords_size,&err);
+    Py_DECREF(ents);
+
+    if(checkError(self->mesh,err))
+      return NULL;
+
+    npy_intp outer;
+    if(storage_order == iBase_BLOCKED)
+      outer = 3;
+    else
+      outer = size;
+    npy_intp dims[] = {outer,coords_size/outer}; /* TODO: think about this */
+    return PyArray_NewFromMallocData(2,dims,NPY_DOUBLE,coords);
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    double *v = malloc(3*sizeof(double));
+    iMesh_getVtxCoord(self->mesh,iBaseEntity_GetHandle(obj), v+0,v+1,v+2,
+		      &err);
+    if(checkError(self->mesh,err))
+      return NULL;
+
+    npy_intp dims[] = {3};
+    return PyArray_NewFromMallocData(1,dims,NPY_DOUBLE,v);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ENT_OR_ENTARR);
+    return NULL;
+  }
+}
+
+static PyObject *
+iMeshObj_getEntTopo(iMeshObject *self,PyObject *args)
+{
+  PyObject *obj;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"O",&obj))
+    return NULL;
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int size;
+    iBase_EntityHandle *data;
+    int *topos=0;
+    int topo_alloc=0,topo_size;
+
+    size = PyArray_SIZE(ents);
+    data = PyArray_DATA(ents);
+
+    iMesh_getEntArrTopo(self->mesh,data,size,&topos,&topo_alloc,&topo_size,
+			&err);
+    Py_DECREF(ents);
+    if(checkError(self->mesh,err))
+      return NULL;
+
+    npy_intp dims[] = {topo_size};
+    return PyArray_NewFromMallocData(1,dims,NPY_UINT,topos);
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    int topo;
+    iBase_EntityHandle handle = ((iBaseEntity_Object*)obj)->handle;
+
+    iMesh_getEntTopo(self->mesh,handle,&topo,&err);
+    if(checkError(self->mesh,err))
+      return NULL;
+
+    return PyInt_FromLong(topo);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ENT_OR_ENTARR);
+    return NULL;
+  }
+}
+
+static PyObject *
+iMeshObj_getEntType(iMeshObject *self,PyObject *args)
+{
+  PyObject *obj;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"O",&obj))
+    return NULL;
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int size;
+    iBase_EntityHandle *data;
+    int *types=0;
+    int type_alloc=0,type_size;
+    
+    size = PyArray_SIZE(ents);
+    data = PyArray_DATA(ents);
+      
+    iMesh_getEntArrType(self->mesh,data,size,&types,&type_alloc,&type_size,
+			&err);
+    Py_DECREF(ents);
+    if(checkError(self->mesh,err))
+      return NULL;
+    
+    npy_intp dims[] = {type_size};
+    return PyArray_NewFromMallocData(1,dims,NPY_UINT,types);
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    int type;
+    iBase_EntityHandle handle = ((iBaseEntity_Object*)obj)->handle;
+    iMesh_getEntType(self->mesh,handle,&type,&err);
+    if(checkError(self->mesh,err))
+      return NULL;
+    
+    return PyInt_FromLong(type);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ENT_OR_ENTARR);
+    return NULL;
+  }
+}
+
+static PyObject *
+iMeshObj_getEntAdj(iMeshObject *self,PyObject *args)
+{
+  PyObject *obj;
+  int type_req;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"Oi",&obj,&type_req))
+    return NULL;
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int size;
+    iBase_EntityHandle *data;
+    iBase_EntityHandle *adj=0;
+    int adj_alloc=0,adj_size;
+    int *offsets;
+    int offsets_alloc=0,offsets_size;
+    
+    size = PyArray_SIZE(ents);
+    data = PyArray_DATA(ents);
+
+    iMesh_getEntArrAdj(self->mesh,data,size,type_req,&adj,&adj_alloc,&adj_size,
+		       &offsets,&offsets_alloc,&offsets_size,&err);
+    Py_DECREF(ents);
+    if(checkError(self->mesh,err))
+      return NULL;
+
+    /* TODO: this is clunky */
+    PyObject *pair = PyTuple_New(2);
+    npy_intp dims[1];
+
+    dims[0] = adj_size;
+    PyTuple_SET_ITEM(pair, 0, PyArray_NewFromMallocData(
+      1,dims,NPY_IBASEENT,adj));
+
+    dims[0] = offsets_size;
+    PyTuple_SET_ITEM(pair, 1, PyArray_NewFromMallocData(
+      1,dims,NPY_INT,offsets));
+
+    return pair;
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    iBase_EntityHandle *adj=0;
+    int adj_alloc=0,adj_size;
+    iBase_EntityHandle handle = iBaseEntity_GetHandle(obj);
+
+    iMesh_getEntAdj(self->mesh,handle,type_req,&adj,&adj_alloc,&adj_size,&err);
+    if(checkError(self->mesh,err))
+      return NULL;
+
+    npy_intp dims[] = {adj_size};
+    return PyArray_NewFromMallocData(1,dims,NPY_IBASEENT,adj);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ENT_OR_ENTARR);
+    return NULL;
+  }
+}
+
+static PyObject *
+iMeshObj_getEnt2ndAdj(iMeshObject *self,PyObject *args)
+{
+  PyObject *obj;
+  int bridge_type,type_req;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"Oii",&obj,&bridge_type,&type_req))
+    return NULL;
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int size;
+    iBase_EntityHandle *data;
+    iBase_EntityHandle *adj=0;
+    int adj_alloc=0,adj_size;
+    int *offsets;
+    int offsets_alloc=0,offsets_size;
+
+    size = PyArray_SIZE(ents);
+    data = PyArray_DATA(ents);
+
+    iMesh_getEntArr2ndAdj(self->mesh,data,size,bridge_type,type_req,&adj,
+			  &adj_alloc,&adj_size,&offsets,&offsets_alloc,
+			  &offsets_size,&err);
+    Py_DECREF(ents);
+    if(checkError(self->mesh,err))
+      return NULL;
+
+    /* TODO: this is clunky */
+    PyObject *pair = PyTuple_New(2);
+    npy_intp dims[1];
+
+    dims[0] = adj_size;
+    PyTuple_SET_ITEM(pair, 0, PyArray_NewFromMallocData(
+      1,dims,NPY_IBASEENT,adj));
+
+    dims[0] = offsets_size;
+    PyTuple_SET_ITEM(pair, 1, PyArray_NewFromMallocData(
+      1,dims,NPY_INT,offsets));
+
+    return pair;
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    iBase_EntityHandle *adj=0;
+    int adj_alloc=0,adj_size;
+    iBase_EntityHandle handle = iBaseEntity_GetHandle(obj);
+
+    iMesh_getEnt2ndAdj(self->mesh,handle,bridge_type,type_req,&adj,&adj_alloc,
+		       &adj_size,&err);
+    if(checkError(self->mesh,err))
+      return NULL;
+
+    npy_intp dims[] = {adj_size};
+    return PyArray_NewFromMallocData(1,dims,NPY_IBASEENT,adj);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ENT_OR_ENTARR);
+    return NULL;
+  }
+}
+
+static PyObject *
+iMeshObj_getAdjEntIndices(iMeshObject *self,PyObject *args)
+{
+  iBaseEntitySet_Object *set;
+  int type_requestor,topo_requestor,type_requested;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"O!iii",&iBaseEntitySet_Type,&set,
+		       &type_requestor,&topo_requestor,&type_requested))
+    return NULL;
+
+  iBase_EntityHandle *entities=0;
+  int ent_alloc=0,ent_size;
+  iBase_EntityHandle *adj_ents=0;
+  int adj_alloc=0,adj_size;
+  int *indices=0;
+  int ind_alloc=0,ind_size;
+  int *offsets=0;
+  int off_alloc=0,off_size;
+
+  iMesh_getAdjEntIndices(self->mesh,set->handle,type_requestor,topo_requestor,
+			 type_requested,
+			 &entities,&ent_alloc,&ent_size,
+			 &adj_ents,&adj_alloc,&adj_size,
+			 &indices, &ind_alloc,&ind_size,
+			 &offsets, &off_alloc,&off_size,
+			 &err);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  /* TODO: this is clunky */
+  PyObject *tup = PyTuple_New(4);
+  npy_intp dims[1];
+
+  dims[0] = ent_size;
+  PyTuple_SET_ITEM(tup, 0, PyArray_NewFromMallocData(
+    1,dims,NPY_IBASEENT,entities));
+
+  dims[0] = adj_size;
+  PyTuple_SET_ITEM(tup, 1, PyArray_NewFromMallocData(
+    1,dims,NPY_IBASEENT,adj_ents));
+
+  dims[0] = ind_size;
+  PyTuple_SET_ITEM(tup, 2, PyArray_NewFromMallocData(
+    1,dims,NPY_INT,indices));
+
+  dims[0] = off_size;
+  PyTuple_SET_ITEM(tup, 3, PyArray_NewFromMallocData(
+    1,dims,NPY_INT,offsets));
+
+  return tup;
+}
+
+static PyObject *
+iMeshObj_createEntSet(iMeshObject *self,PyObject *args)
+{
+  int isList,err;
+  PyObject *obj;
+  iMeshEntitySet_Object *set;
+
+  if(!PyArg_ParseTuple(args,"O!",&PyBool_Type,&obj))
+    return NULL;
+
+  set = iMeshEntitySet_New();
+  set->mesh = self;
+  /*Py_INCREF(self); TODO?? */
+
+  isList = (obj == Py_True);
+  
+  iMesh_createEntSet(self->mesh,isList,&set->set.handle,&err);
+  if(checkError(self->mesh,err))
+  {
+    Py_DECREF((PyObject*)set);
+    return NULL;
+  }
+
+  return (PyObject*)set;  
+}
+
+static PyObject *
+iMeshObj_destroyEntSet(iMeshObject *self,PyObject *args)
+{
+  int err;
+  iBaseEntitySet_Object *set;
+
+  if(!PyArg_ParseTuple(args,"O!",&iBaseEntitySet_Type,&set))
+    return NULL;
+
+  iMesh_destroyEntSet(self->mesh,set->handle,&err);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+iMeshObj_setVtxCoords(iMeshObject *self,PyObject *args)
+{
+  PyObject *obj;
+  int storage_order=-1;
+  PyObject *data;
+  PyObject *ents = 0;
+  PyObject *verts = 0;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"OO|i",&obj,&data,&storage_order))
+    return NULL;
+
+  ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    if(storage_order == -1)
+    {
+      PyErr_SetString(PyExc_ValueError,ERR_STORAGE_ORDER);
+      goto err;
+    }
+
+    verts = PyArray_FROMANY(data,NPY_DOUBLE,2,2,NPY_C_CONTIGUOUS);
+    if(verts == NULL)
+      goto err;
+
+    int ent_size = PyArray_SIZE(ents);
+    iBase_EntityHandle *entities = PyArray_DATA(ents);
+    int coord_size = PyArray_SIZE(verts);
+    double *coords = PyArray_DATA(verts);
+
+    iMesh_setVtxArrCoords(self->mesh,entities,ent_size,storage_order,coords,
+			  coord_size,&err);
+    Py_DECREF(ents);
+    Py_DECREF(verts);
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    verts = PyArray_FROMANY(data,NPY_DOUBLE,1,1,NPY_C_CONTIGUOUS);
+    if(verts == NULL)
+      goto err;
+
+    if(PyArray_SIZE(verts) != 3)
+    {
+      PyErr_SetString(PyExc_ValueError,ERR_ARR_SIZE);
+      goto err;
+    }
+
+    double *v = PyArray_DATA(verts);
+    iBase_EntityHandle entity = iBaseEntity_GetHandle(obj);
+
+    iMesh_setVtxCoord(self->mesh,entity, v[0],v[1],v[2], &err);
+    Py_DECREF(verts);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ENT_OR_ENTARR);
+    return NULL;
+  }
+
+  if(checkError(self->mesh,err))
+    return NULL;
+  Py_RETURN_NONE;
+
+ err:
+  Py_XDECREF(ents);
+  Py_XDECREF(verts);
+  return NULL;
+}
+
+static PyObject *
+iMeshObj_createVtx(iMeshObject *self,PyObject *args)
+{
+  int storage_order=-1;
+  PyObject *data;
+  PyObject *vertices;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"O|i",&data,&storage_order))
+    return NULL;
+
+  if( (vertices = PyArray_TryFromObject(data,NPY_DOUBLE,2,2)) != NULL)
+  {
+    if(storage_order == -1)
+    {
+      Py_DECREF(vertices);
+      PyErr_SetString(PyExc_ValueError,ERR_STORAGE_ORDER);
+      return NULL;
+    }
+
+    int index = storage_order == iBase_BLOCKED;
+    int count = PyArray_DIM(vertices,index); /* this is a bit odd! */
+    int coord_size = PyArray_SIZE(vertices);
+    double *coords = PyArray_DATA(vertices);
+    iBase_EntityHandle *entities=0;
+    int ent_alloc=0,ent_size;
+
+    iMesh_createVtxArr(self->mesh,count,storage_order,coords,coord_size,
+		       &entities,&ent_alloc,&ent_size,&err);
+    Py_DECREF(vertices);
+    if(checkError(self->mesh,err))
+      return NULL;
+
+    npy_intp dims[] = {ent_size};
+    return PyArray_NewFromMallocData(1,dims,NPY_IBASEENT,entities);
+  }
+  else if( (vertices = PyArray_TryFromObject(data,NPY_DOUBLE,1,1)) != NULL)
+  {
+    if(PyArray_SIZE(vertices) != 3)
+    {
+      Py_DECREF(vertices);
+      PyErr_SetString(PyExc_ValueError,ERR_ARR_SIZE);
+      return NULL;
+    }
+
+    double *v = PyArray_DATA(vertices);
+
+    iBaseEntity_Object *entity = iBaseEntity_New();
+    iMesh_createVtx(self->mesh, v[0],v[1],v[2], &entity->handle,&err);
+    Py_DECREF(vertices);
+
+    if(checkError(self->mesh,err))
+    {
+      Py_DECREF((PyObject*)entity);
+      return NULL;
+    }
+    return (PyObject*)entity;
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ARR_DIMS);
+    return NULL;
+  }
+}
+
+static PyObject *
+iMeshObj_createEnt(iMeshObject *self,PyObject *args)
+{
+  int topo,status,err;
+  PyObject *obj;
+
+  if(!PyArg_ParseTuple(args,"iO",&topo,&obj))
+    return NULL;
+
+  PyObject *ents = PyArray_FROMANY(obj,NPY_IBASEENT,1,1,NPY_C_CONTIGUOUS);
+  if(ents == NULL)
+    return NULL;
+
+  int lower_size = PyArray_SIZE(ents);
+  iBase_EntityHandle *lower = PyArray_DATA(ents);
+
+  PyObject *pair = PyTuple_New(2);
+  iBaseEntity_Object *entity = iBaseEntity_New();
+
+  iMesh_createEnt(self->mesh,topo,lower,lower_size,&entity->handle,&status,
+		  &err);
+  Py_DECREF(ents);
+  if(checkError(self->mesh,err))
+  {
+    Py_DECREF(pair);
+    Py_DECREF((PyObject*)entity);
+    return NULL;
+  }
+
+  PyTuple_SET_ITEM(pair,0,(PyObject*)entity);
+  PyTuple_SET_ITEM(pair,1,Py_BuildValue("i",status));
+  return pair;
+}
+
+static PyObject *
+iMeshObj_createEntArr(iMeshObject *self,PyObject *args)
+{
+  int topo,err;
+  PyObject *obj;
+
+  if(!PyArg_ParseTuple(args,"iO",&topo,&obj))
+    return NULL;
+
+  PyObject *ents = PyArray_FROMANY(obj,NPY_IBASEENT,1,1,NPY_C_CONTIGUOUS);
+  if(ents == NULL)
+    return NULL;
+
+  int lower_size = PyArray_SIZE(ents);
+  iBase_EntityHandle *lower = PyArray_DATA(ents);
+
+  iBase_EntityHandle *entities=0;
+  int ent_alloc=0,ent_size;
+  int *status;
+  int stat_alloc=0,stat_size;
+
+  iMesh_createEntArr(self->mesh,topo,lower,lower_size,&entities,&ent_alloc,
+		     &ent_size,&status,&stat_alloc,&stat_size,&err);
+  Py_DECREF(ents);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  PyObject *pair = PyTuple_New(2);
+  npy_intp dims[1];
+
+  dims[0] = ent_size;
+  PyTuple_SET_ITEM(pair, 0, PyArray_NewFromMallocData(
+    1,dims,NPY_IBASEENT,entities));
+
+  dims[0] = stat_size;
+  PyTuple_SET_ITEM(pair, 1, PyArray_NewFromMallocData(
+    1,dims,NPY_INT,status));
+
+  return pair;
+}
+
+
+static PyObject *
+iMeshObj_deleteEnt(iMeshObject *self,PyObject *args)
+{
+  PyObject *obj;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"O",&obj))
+    return NULL;
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int size = PyArray_SIZE(ents);
+    iBase_EntityHandle *entities = PyArray_DATA(ents);
+    iMesh_deleteEntArr(self->mesh,entities,size,&err);
+    Py_DECREF(ents);
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    iBase_EntityHandle entity = iBaseEntity_GetHandle(obj);
+    iMesh_deleteEnt(self->mesh,entity,&err);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ENT_OR_ENTARR);
+    return NULL;
+  }
+
+  if(checkError(self->mesh,err))
+    return NULL;
+  Py_RETURN_NONE;
+}
+
+
+static PyObject *
+iMeshObj_createTag(iMeshObject *self,PyObject *args)
+{
+  char *name;
+  char typechar;
+  int size,type,err;
+  iMeshTag_Object *tag;
+
+  if(!PyArg_ParseTuple(args,"sic",&name,&size,&typechar))
+    return NULL;
+
+  type = char_to_type(typechar);
+  if(type == -1)
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_TYPE_CODE);
+    return NULL;
+  }
+
+  tag = iMeshTag_New();
+  tag->mesh = self;
+  /*Py_INCREF(self); TODO?? */
+
+  iMesh_createTag(self->mesh,name,size,type,&tag->tag.handle,&err,
+		  strlen(name));
+  if(checkError(self->mesh,err))
+  {
+    Py_DECREF((PyObject*)tag);
+    return NULL;
+  }
+
+  return (PyObject*)tag;
+}
+
+static PyObject *
+iMeshObj_destroyTag(iMeshObject *self,PyObject *args)
+{
+  int forced,err;
+  iBaseTag_Object *tag;
+  PyObject *obj;
+
+  if(!PyArg_ParseTuple(args,"O!O!",&iBaseTag_Type,&tag,
+		       &PyBool_Type,&obj))
+    return NULL;
+
+  forced = (obj == Py_True);
+
+  iMesh_destroyTag(self->mesh,tag->handle,forced,&err);
+  if(checkError(self->mesh,err))
+    return NULL;
+
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+iMeshObj_getTagHandle(iMeshObject *self,PyObject *args)
+{
+  char *name;
+  iMeshTag_Object *tag;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"s",&name))
+    return NULL;
+
+  tag = iMeshTag_New();
+  tag->mesh = self;
+  /*Py_INCREF(self); TODO?? */
+
+  iMesh_getTagHandle(self->mesh,name,&tag->tag.handle,&err,strlen(name));
+  if(checkError(self->mesh,err))
+  {
+    Py_DECREF((PyObject*)tag);
+    return NULL;
+  }
+
+  return (PyObject*)tag;
+}
+
+static PyObject *
+iMeshObj_setData(iMeshObject *self,PyObject *args)
+{
+  PyObject *obj;
+  iBaseTag_Object *tag;
+  PyObject *data_obj;
+  char typechar=0;
+  int type;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"OO!O|c",&obj,&iBaseTag_Type,&tag,&data_obj,
+		       &typechar))
+    return NULL;
+
+  if(typechar == 0)
+  {
+    /* infer the type of the data */
+    iMesh_getTagType(self->mesh,tag->handle,&type,&err);
+    if(checkError(self->mesh,err))
+      return NULL;
+  }
+  else
+  {
+    type = char_to_type(typechar);
+    if(type == -1)
+    {
+      PyErr_SetString(PyExc_ValueError,ERR_TYPE_CODE);
+      return NULL;
+    }
+  }
+ 
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int ent_size;
+    iBase_EntityHandle *entities;
+    int data_size;
+    PyObject *data_arr=0;
+
+    ent_size = PyArray_SIZE(ents);
+    entities = PyArray_DATA(ents);
+
+    if(type == iBase_INTEGER)
+    {
+      data_arr = PyArray_FROMANY(data_obj,NPY_INT,1,1,NPY_C_CONTIGUOUS);
+      if(data_arr == NULL)
+	return NULL;
+
+      data_size = PyArray_SIZE(data_arr);
+      int *data = PyArray_DATA(data_arr);
+      iMesh_setIntArrData(self->mesh,entities,ent_size,tag->handle,data,
+                          data_size,&err);
+    }
+    else if(type == iBase_DOUBLE)
+    {
+      data_arr = PyArray_FROMANY(data_obj,NPY_DOUBLE,1,1,NPY_C_CONTIGUOUS);
+      if(data_arr == NULL)
+        return NULL;
+
+      data_size = PyArray_SIZE(data_arr);
+      double *data = PyArray_DATA(data_arr);
+      iMesh_setDblArrData(self->mesh,entities,ent_size,tag->handle,data,
+                          data_size,&err);
+    }
+    else if(type == iBase_ENTITY_HANDLE)
+    {
+      data_arr = PyArray_FROMANY(data_obj,NPY_IBASEENT,1,1,NPY_C_CONTIGUOUS);
+      if(data_arr == NULL)
+        return NULL;
+
+      data_size = PyArray_SIZE(data_arr);
+      iBase_EntityHandle *data = PyArray_DATA(data_arr);
+      iMesh_setEHArrData(self->mesh,entities,ent_size,tag->handle,data,
+                         data_size,&err);
+    }
+    else /* iBase_BYTES */
+    {
+      /* TODO: I have no idea if this is right */
+      data_arr = PyArray_FROMANY(data_obj,NPY_BYTE,1,1,NPY_C_CONTIGUOUS);
+      if(data_arr == NULL)
+        return NULL;
+
+      data_size = PyArray_SIZE(data_arr);
+      char *data = PyArray_DATA(data_arr);
+      iMesh_setArrData(self->mesh,entities,ent_size,tag->handle,data,
+                       data_size,&err);
+    }
+
+    Py_DECREF(ents);
+    Py_XDECREF(data_arr);
+  }
+  else if(iBaseEntitySet_Check(obj))
+  {
+    iBase_EntitySetHandle set = iBaseEntitySet_GetHandle(obj);
+
+    if(type == iBase_INTEGER)
+    {
+      PyObject *o = PyNumber_Int(data_obj);
+      if(o == NULL)
+	return NULL;
+      iMesh_setEntSetIntData(self->mesh,set,tag->handle,PyInt_AsLong(o),&err);
+      Py_DECREF(o);
+    }
+    else if(type == iBase_DOUBLE)
+    {
+      PyObject *o = PyNumber_Float(data_obj);
+      if(o == NULL)
+        return NULL;
+      iMesh_setEntSetDblData(self->mesh,set,tag->handle,PyFloat_AsDouble(o),
+			     &err);
+      Py_DECREF(o);
+    }
+    else if(type == iBase_ENTITY_HANDLE)
+    {
+      if(!iBaseEntity_Check(data_obj))
+	return NULL;
+      iMesh_setEntSetEHData(self->mesh,set,tag->handle,
+                            iBaseEntity_GetHandle(data_obj),&err);
+    }
+    else /* iBase_BYTES */
+    {
+      PyObject *data_arr = PyArray_FROMANY(data_obj,NPY_BYTE,1,1,
+					   NPY_C_CONTIGUOUS);
+      if(data_arr == NULL)
+	return NULL;
+
+      char *data = PyArray_DATA(data_arr);
+      int data_size = PyArray_SIZE(data_arr);
+      iMesh_setEntSetData(self->mesh,set,tag->handle,data,data_size,&err);
+      Py_DECREF(data_arr);
+    }
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    iBase_EntityHandle entity = iBaseEntity_GetHandle(obj);
+
+    if(type == iBase_INTEGER)
+    {
+      PyObject *o = PyNumber_Int(data_obj);
+      if(o == NULL)
+	return NULL;
+      iMesh_setIntData(self->mesh,entity,tag->handle,PyInt_AsLong(o),&err);
+      Py_DECREF(o);
+    }
+    else if(type == iBase_DOUBLE)
+    {
+      PyObject *o = PyNumber_Float(data_obj);
+      if(o == NULL)
+	return NULL;
+      iMesh_setDblData(self->mesh,entity,tag->handle,PyFloat_AsDouble(o),&err);
+      Py_DECREF(o);
+    }
+    else if(type == iBase_ENTITY_HANDLE)
+    {
+      if(!iBaseEntity_Check(data_obj))
+	return NULL;
+      iMesh_setEHData(self->mesh,entity,tag->handle,
+		      iBaseEntity_GetHandle(data_obj),&err);
+    }
+    else /* iBase_BYTES */
+    {
+      PyObject *data_arr = PyArray_FROMANY(data_obj,NPY_BYTE,1,1,
+					   NPY_C_CONTIGUOUS);
+      if(data_arr == NULL)
+	return NULL;
+
+      char *data = PyArray_DATA(data_arr);
+      int data_size = PyArray_SIZE(data_arr);
+      iMesh_setData(self->mesh,entity,tag->handle,data,data_size,&err);
+      Py_DECREF(data_arr);
+    }
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ANY_ENT);
+    return NULL;
+  }
+
+  if(checkError(self->mesh,err))
+    return NULL;
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+iMeshObj_getData(iMeshObject *self,PyObject *args)
+{
+  PyObject *obj;
+  iBaseTag_Object *tag;
+  char typechar=0;
+  int type;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"OO!|c",&obj,&iBaseTag_Type,&tag,&typechar))
+    return NULL;
+
+  if(typechar == 0)
+  {
+    /* infer the type of the data */
+    iMesh_getTagType(self->mesh,tag->handle,&type,&err);
+    if(checkError(self->mesh,err))
+      return NULL;
+  }
+  else
+  {
+    type = char_to_type(typechar);
+    if(type == -1)
+    {
+      PyErr_SetString(PyExc_ValueError,"invalid type code");
+      return NULL;
+    }
+  }
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int ent_size = PyArray_SIZE(ents);
+    iBase_EntityHandle *entities = PyArray_DATA(ents);
+    PyObject *ret = 0;
+
+    if(type == iBase_INTEGER)
+    {
+      int *data=0;
+      int alloc=0,size;
+
+      iMesh_getIntArrData(self->mesh,entities,ent_size,tag->handle,&data,
+			  &alloc,&size,&err);
+      if(!checkError(self->mesh,err))
+      {
+	npy_intp dims[] = {size};
+	ret = PyArray_NewFromMallocData(1,dims,NPY_INT,data);
+      }
+    }
+    else if(type == iBase_DOUBLE)
+    {
+      double *data=0;
+      int alloc=0,size;
+
+      iMesh_getDblArrData(self->mesh,entities,ent_size,tag->handle,&data,
+                          &alloc,&size,&err);
+      if(!checkError(self->mesh,err))
+      {
+	npy_intp dims[] = {size};
+	ret = PyArray_NewFromMallocData(1,dims,NPY_DOUBLE,data);
+      }
+    }
+    else if(type == iBase_ENTITY_HANDLE)
+    {
+      iBase_EntityHandle *data=0;
+      int alloc=0,size;
+
+      iMesh_getEHArrData(self->mesh,entities,ent_size,tag->handle,&data,
+			 &alloc,&size,&err);
+      if(!checkError(self->mesh,err))
+      {
+	npy_intp dims[] = {size};
+	ret = PyArray_NewFromMallocData(1,dims,NPY_IBASEENT,data);
+      }
+    }
+    else /* iBase_BYTES */
+    {
+      char *data=0;
+      int alloc=0,size;
+
+      iMesh_getArrData(self->mesh,entities,ent_size,tag->handle,&data,
+		       &alloc,&size,&err);
+      if(!checkError(self->mesh,err))
+      {
+	npy_intp dims[] = {size};
+	ret = PyArray_NewFromMallocData(1,dims,NPY_BYTE,data);
+      }
+    }
+
+    Py_DECREF(ents);
+    return ret;
+  }
+  else if(iBaseEntitySet_Check(obj))
+  {
+    iBase_EntitySetHandle set = iBaseEntitySet_GetHandle(obj);
+
+    if(type == iBase_INTEGER)
+    {
+      int data;
+      iMesh_getEntSetIntData(self->mesh,set,tag->handle,&data,&err);
+      if(checkError(self->mesh,err))
+	return NULL;
+      return Py_BuildValue("i",data);
+    }
+    else if(type == iBase_DOUBLE)
+    {
+      double data;
+      iMesh_getEntSetDblData(self->mesh,set,tag->handle,&data,&err);
+      if(checkError(self->mesh,err))
+        return NULL;
+      return Py_BuildValue("d",data);
+    }
+    else if(type == iBase_ENTITY_HANDLE)
+    {
+      iBaseEntity_Object *data = iBaseEntity_New();
+      iMesh_getEntSetEHData(self->mesh,set,tag->handle,&data->handle,&err);
+      if(checkError(self->mesh,err))
+      {
+	Py_DECREF(data);
+	return NULL;
+      }
+      return (PyObject*)data;
+    }
+    else /* iBase_BYTES */
+    {
+      char *data=0;
+      int alloc=0,size;
+      iMesh_getEntSetData(self->mesh,set,tag->handle,&data,&alloc,&size,&err);
+      if(checkError(self->mesh,err))
+        return NULL;
+      npy_intp dims[] = {size};
+      return PyArray_NewFromMallocData(1,dims,NPY_BYTE,data);
+    }
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    iBase_EntityHandle entity = iBaseEntity_GetHandle(obj);
+
+    if(type == iBase_INTEGER)
+    {
+      int data;
+      iMesh_getIntData(self->mesh,entity,tag->handle,&data,&err);
+      if(checkError(self->mesh,err))
+        return NULL;
+      return Py_BuildValue("i",data);
+    }
+    else if(type == iBase_DOUBLE)
+    {
+      double data;
+      iMesh_getDblData(self->mesh,entity,tag->handle,&data,&err);
+      if(checkError(self->mesh,err))
+        return NULL;
+      return Py_BuildValue("d",data);
+    }
+    else if(type == iBase_ENTITY_HANDLE)
+    {
+      iBaseEntity_Object *data = iBaseEntity_New();
+      iMesh_getEHData(self->mesh,entity,tag->handle,&data->handle,&err);
+      if(checkError(self->mesh,err))
+      {
+	Py_DECREF(data);
+	return NULL;
+      }
+      return (PyObject*)data;
+    }
+    else /* iBase_BYTES */
+    {
+      char *data=0;
+      int alloc=0,size;
+      iMesh_getData(self->mesh,entity,tag->handle,&data,&alloc,&size,&err);
+      if(checkError(self->mesh,err))
+	return NULL;
+      npy_intp dims[] = {size};
+      return PyArray_NewFromMallocData(1,dims,NPY_BYTE,data);
+    }
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ANY_ENT);
+    return NULL;
+  }
+}
+
+static PyObject *
+iMeshObj_getAllTags(iMeshObject *self,PyObject *args)
+{
+  PyObject *ents;
+  iBase_TagHandle *tags=0;
+  int alloc=0,size;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"O",&ents))
+    return NULL;
+
+  if(iBaseEntitySet_Check(ents))
+  {
+    iBase_EntitySetHandle set = iBaseEntitySet_GetHandle(ents);
+
+    iMesh_getAllEntSetTags(self->mesh,set,&tags,&alloc,&size,&err);
+    if(checkError(self->mesh,err))
+      return NULL;
+  }
+  else if(iBaseEntity_Check(ents))
+  {
+    iBase_EntityHandle entity = iBaseEntity_GetHandle(ents);
+
+    iMesh_getAllTags(self->mesh,entity,&tags,&alloc,&size,&err);
+    if(checkError(self->mesh,err))
+      return NULL;
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ENT_OR_ENTSET);
+    return NULL;
+  }
+
+  npy_intp dims[] = {size};
+  PyObject *arr = PyArray_NewFromMallocData(1,dims,NPY_IMESHTAG,tags);
+  Py_INCREF(self);
+  PyArray_BASE(arr) = (PyObject*)self;
+  return arr;
+}
+
+static PyObject *
+iMeshObj_rmvTag(iMeshObject *self,PyObject *args)
+{
+  PyObject *obj;
+  iBaseTag_Object *tag;
+  int err;
+
+  if(!PyArg_ParseTuple(args,"OO!",&obj,&iBaseTag_Type,&tag))
+    return NULL;
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int ent_size = PyArray_SIZE(ents);
+    iBase_EntityHandle *entities = PyArray_DATA(ents);
+    iMesh_rmvArrTag(self->mesh,entities,ent_size,tag->handle,&err);
+    Py_DECREF(ents);
+  }
+  else if(iBaseEntitySet_Check(obj))
+  {
+    iBase_EntitySetHandle set = iBaseEntitySet_GetHandle(obj);
+    iMesh_rmvEntSetTag(self->mesh,set,tag->handle,&err);
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    iBase_EntityHandle entity =iBaseEntity_GetHandle(obj);
+    iMesh_rmvTag(self->mesh,entity,tag->handle,&err);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ANY_ENT);
+    return NULL;
+  }
+
+  if(checkError(self->mesh,err))
+    return NULL;
+  Py_RETURN_NONE;
+}
+
+
+static PyMethodDef iMesh_methods[] = {
+  { "load", (PyCFunction)iMeshObj_load, METH_VARARGS,
+    "Load a mesh"
+  },
+  { "save", (PyCFunction)iMeshObj_save, METH_VARARGS,
+    "Save the mesh"
+  },
+  { "getNumOfType", (PyCFunction)iMeshObj_getNumOfType, METH_VARARGS,
+    "Get the number of entities with the specified type in the instance or set"
+  },
+  { "getNumOfTopo", (PyCFunction)iMeshObj_getNumOfTopo, METH_VARARGS,
+    "Get the number of entities with the specified topology in the instance "
+    "or set"
+  },
+  { "areEHValid", (PyCFunction)iMeshObj_areEHValid, METH_VARARGS,
+    "Return whether entity handles have changed since last reset or since "
+    "instance construction"
+  },
+  { "getEntities", (PyCFunction)iMeshObj_getEntities, METH_VARARGS,
+    "Get entities of specific type and/or topology in set or instance"
+  },
+  { "getVtxCoords", (PyCFunction)iMeshObj_getVtxCoords, METH_VARARGS,
+    "Get coordinates of specified vertex(ices)"
+  },
+  { "getEntTopo", (PyCFunction)iMeshObj_getEntTopo, METH_VARARGS,
+    "Get the entity topology(ies) for the specified entity(ies)"
+  },
+  { "getEntType", (PyCFunction)iMeshObj_getEntType, METH_VARARGS,
+    "Get the entity type(s) for the specified entity(ies)"
+  },
+  { "getEntAdj", (PyCFunction)iMeshObj_getEntAdj, METH_VARARGS,
+    "Get entities of specified type adjacent to entity(ies)"
+  },
+  { "getEnt2ndAdj", (PyCFunction)iMeshObj_getEnt2ndAdj, METH_VARARGS,
+    "Get \"2nd order\" adjacencies to entity(ies)"
+  },
+  { "getAdjEntIndices", (PyCFunction)iMeshObj_getAdjEntIndices, METH_VARARGS,
+    "Get indexed representation of mesh or subset of mesh"
+  },
+  { "createEntSet", (PyCFunction)iMeshObj_createEntSet, METH_VARARGS,
+    "Create an entity set"
+  },
+  { "destroyEntSet", (PyCFunction)iMeshObj_destroyEntSet, METH_VARARGS,
+    "Destroy an entity set"
+  },
+  { "setVtxCoords", (PyCFunction)iMeshObj_setVtxCoords, METH_VARARGS,
+    "Set coordinates for a vertex or array of vertices"
+  },
+  { "createVtx", (PyCFunction)iMeshObj_createVtx, METH_VARARGS,
+    "Create a new vertex or array of vertices at specified coordinates"
+  },
+  { "createEnt", (PyCFunction)iMeshObj_createEnt, METH_VARARGS,
+    "Create a new entity with specified lower-order topology"
+  },
+  { "createEntArr", (PyCFunction)iMeshObj_createEntArr, METH_VARARGS,
+    "Create an array of entities with specified lower-order topology"
+  },
+  { "deleteEnt", (PyCFunction)iMeshObj_deleteEnt, METH_VARARGS,
+    "Delete specified entity(ies)"
+  },
+  { "createTag", (PyCFunction)iMeshObj_createTag, METH_VARARGS,
+    "Create a tag with specified name, size, and type"
+  },
+  { "destroyTag", (PyCFunction)iMeshObj_destroyTag, METH_VARARGS,
+    "Destroy a tag"
+  },
+  { "getTagHandle", (PyCFunction)iMeshObj_getTagHandle, METH_VARARGS,
+    "Get the handle of an existing tag with the specified name"
+  },
+  { "setData", (PyCFunction)iMeshObj_setData, METH_VARARGS,
+    "Set tag values on an entity (or array/set of entities)"
+  },
+  { "getData", (PyCFunction)iMeshObj_getData, METH_VARARGS,
+    "Get tag values on an entity (or array/set of entities)"
+  },
+  { "getAllTags", (PyCFunction)iMeshObj_getAllTags, METH_VARARGS,
+    "Get all the tags associated with a specified entity handle (or "
+    "array/set of entities)"
+  },
+  { "rmvTag", (PyCFunction)iMeshObj_rmvTag, METH_VARARGS,
+    "Remove a tag value from an entity (or array/set of entities)"
+  },
+  {0}
+};
+
+static PyGetSetDef iMesh_getset[] = {
+  { "rootSet", (getter)iMeshObj_getRootSet, 0, "root set", 0 },
+  { "geometricDimension", (getter)iMeshObj_getGeometricDimension,
+    (setter)iMeshObj_setGeometricDimension, "geometric dimension", 0 },
+  { "dfltStorage",(getter)iMeshObj_getDfltStorage, 0, "default storage order",
+    0 },
+  { "adjTable",(getter)iMeshObj_getAdjTable, 0, "get adjacency table", 0},
+  {0}
+};
+
+static PyTypeObject iMeshType = {
+  PyObject_HEAD_INIT(NULL)
+  0,                            /* ob_size */
+  "itaps.iMesh",                /* tp_name */
+  sizeof(iMeshObject),          /* tp_basicsize */
+  0,                            /* tp_itemsize */
+  (destructor)iMeshObj_dealloc, /* tp_dealloc */
+  0,                            /* tp_print */
+  0,                            /* tp_getattr */
+  0,                            /* tp_setattr */
+  0,                            /* tp_compare */
+  0,                            /* 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 */
+  "iMesh objects",              /* tp_doc */
+  0,                            /* tp_traverse */
+  0,                            /* tp_clear */
+  0,                            /* tp_richcompare */
+  0,                            /* tp_weaklistoffset */
+  0,                            /* tp_iter */
+  0,                            /* tp_iternext */
+  iMesh_methods,                /* tp_methods */
+  0,                            /* tp_members */
+  iMesh_getset,                 /* tp_getset */
+  0,                            /* tp_base */
+  0,                            /* tp_dict */
+  0,                            /* tp_descr_get */
+  0,                            /* tp_descr_set */
+  0,                            /* tp_dictoffset */
+  (initproc)iMeshObj_init,      /* tp_init */
+  0,                            /* tp_alloc */
+  0,                            /* tp_new */
+};
+
+
+static PyMethodDef module_methods[] = {
+  {0}
+};
+
+static PyObject *
+iMeshEntSetArr_getitem(void *data,void *arr)
+{
+  iMeshObject *mesh = (iMeshObject*)PyArray_BASE(arr);
+  iMeshEntitySet_Object *o = iMeshEntitySet_New();
+
+  o->set.handle = *(iBase_EntitySetHandle*)data;
+  o->mesh = mesh; /* TODO: incref? */
+
+  return (PyObject*)o;
+}
+
+static PyObject *
+iMeshTagArr_getitem(void *data,void *arr)
+{
+  iMeshObject *mesh = (iMeshObject*)PyArray_BASE(arr);
+  iMeshTag_Object *o = iMeshTag_New();
+
+  o->tag.handle = *(iBase_TagHandle*)data;
+  o->mesh = mesh; /* TODO: incref? */
+
+  return (PyObject*)o;
+}
+
+static PyArray_ArrFuncs iMeshEntSetArr_Funcs;
+int NPY_IMESHENTSET;
+
+static PyArray_ArrFuncs iMeshTagArr_Funcs;
+int NPY_IMESHTAG;
+
+ENUM_TYPE(topology,"iMesh.topology","");
+
+PyMODINIT_FUNC initiMesh(void)
+{
+  PyObject *m;
+  PyArray_Descr *descr;
+
+  m = Py_InitModule("iMesh",module_methods);
+  import_array();
+  import_iBase();
+
+  iMeshType.tp_new = PyType_GenericNew;
+  if(PyType_Ready(&iMeshType) < 0)
+    return;
+  Py_INCREF(&iMeshType);
+  PyModule_AddObject(m,"iMesh",(PyObject *)&iMeshType);
+
+  /***** initialize topology enum *****/
+  REGISTER_SIMPLE_SUB(iMeshType,topology);
+
+  ADD_ENUM(&topology_Type,"point",          iMesh_POINT);
+  ADD_ENUM(&topology_Type,"line_segment",   iMesh_LINE_SEGMENT);
+  ADD_ENUM(&topology_Type,"polygon",        iMesh_POLYGON);
+  ADD_ENUM(&topology_Type,"triangle",       iMesh_TRIANGLE);
+  ADD_ENUM(&topology_Type,"quadrilateral",  iMesh_QUADRILATERAL);
+  ADD_ENUM(&topology_Type,"polyhedron",     iMesh_POLYHEDRON);
+  ADD_ENUM(&topology_Type,"tetrahedron",    iMesh_TETRAHEDRON);
+  ADD_ENUM(&topology_Type,"hexahedron",     iMesh_HEXAHEDRON);
+  ADD_ENUM(&topology_Type,"prism",          iMesh_PRISM);
+  ADD_ENUM(&topology_Type,"pyramid",        iMesh_PYRAMID);
+  ADD_ENUM(&topology_Type,"septahedron",    iMesh_SEPTAHEDRON);
+  ADD_ENUM(&topology_Type,"all",            iMesh_ALL_TOPOLOGIES);
+
+  iMeshIter_Type.tp_new = PyType_GenericNew;
+  if(PyType_Ready(&iMeshIter_Type) < 0)
+    return;
+  PyDict_SetItemString(iMeshType.tp_dict,"iterator",
+                       (PyObject *)&iMeshIter_Type);
+
+  iMeshEntitySet_Type.tp_base = &iBaseEntitySet_Type;
+  if(PyType_Ready(&iMeshEntitySet_Type) < 0)
+    return;
+  PyDict_SetItemString(iMeshType.tp_dict,"entitySet",
+		       (PyObject *)&iMeshEntitySet_Type);
+
+  iMeshTag_Type.tp_base = &iBaseTag_Type;
+  if(PyType_Ready(&iMeshTag_Type) < 0)
+    return;
+  PyDict_SetItemString(iMeshType.tp_dict,"tag",
+		       (PyObject *)&iMeshTag_Type);
+
+
+  /***** initialize iMeshEntitySet array *****/
+  descr = PyArray_DescrNewFromType(NPY_IBASEENTSET);
+  memcpy(&iMeshEntSetArr_Funcs,descr->f,sizeof(PyArray_ArrFuncs));
+  descr->f = &iMeshEntSetArr_Funcs;
+
+  descr->typeobj = &iMeshEntitySet_Type;
+  descr->type = 'M';
+  descr->f->getitem = iMeshEntSetArr_getitem;
+
+  NPY_IMESHENTSET = PyArray_RegisterDataType(descr);
+
+  /***** initialize iMeshTag array *****/
+  descr = PyArray_DescrNewFromType(NPY_IBASETAG);
+  memcpy(&iMeshTagArr_Funcs,descr->f,sizeof(PyArray_ArrFuncs));
+  descr->f = &iMeshTagArr_Funcs;
+
+  descr->typeobj = &iMeshTag_Type;
+  descr->type = 'M';
+  descr->f->getitem = iMeshTagArr_getitem;
+
+  NPY_IMESHTAG = PyArray_RegisterDataType(descr);
+}

Added: MOAB/trunk/tools/iMesh/python/iMesh_Python.h
===================================================================
--- MOAB/trunk/tools/iMesh/python/iMesh_Python.h	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/iMesh_Python.h	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,83 @@
+#pragma once
+
+#include "common.h"
+
+#include <Python.h>
+#include <iMesh.h>
+
+#define PY_IBASE_UNIQUE_SYMBOL itaps_IBASE_API
+#include "iBase_Python.h"
+
+#define PY_ARRAY_UNIQUE_SYMBOL itaps_ARRAY_API
+#include <numpy/arrayobject.h>
+
+#define PyArray_NewFromMallocData(nd, dims, typenum, data)      \
+  PyArray_New(&PyArray_Type, nd, dims, typenum, NULL,           \
+              data, 0, NPY_CARRAY|NPY_OWNDATA, NULL)
+
+PyObject *
+PyArray_TryFromObject(PyObject *obj,int typenum,int min_depth,int max_depth);
+
+
+int checkError(iMesh_Instance mesh,int err);
+enum iBase_TagValueType char_to_type(char c);
+char type_to_char(enum iBase_TagValueType t);
+
+typedef struct
+{
+  PyObject_HEAD
+  iMesh_Instance mesh;
+} iMeshObject;
+
+
+typedef struct
+{
+  PyObject_HEAD
+  iMesh_Instance mesh;
+  int is_arr;
+  union
+  {
+    iMesh_EntityIterator    iter;
+    iMesh_EntityArrIterator arr_iter;
+  };
+} iMeshIter_Object;
+
+extern PyTypeObject iMeshIter_Type;
+
+typedef struct
+{
+  iBaseEntitySet_Object set;
+  iMeshObject *mesh;
+} iMeshEntitySet_Object;
+
+extern PyTypeObject iMeshEntitySet_Type;
+extern int NPY_IMESHENTSET;
+
+#define iMeshEntitySet_New()                    \
+  (iMeshEntitySet_Object*)PyObject_CallObject(  \
+    (PyObject*)&iMeshEntitySet_Type,NULL)
+
+#define iMeshEntitySet_Check(o)                 \
+  PyObject_TypeCheck((o),&iMeshEntitySet_Type)
+
+#define iMeshEntitySet_GetMesh(o)               \
+  ((iMeshEntitySet_Object*)(o))->mesh
+
+typedef struct
+{
+  iBaseTag_Object tag;
+  iMeshObject *mesh;
+} iMeshTag_Object;
+
+extern PyTypeObject iMeshTag_Type;
+extern int NPY_IMESHTAG;
+
+#define iMeshTag_New()				\
+  (iMeshTag_Object*)PyObject_CallObject(	\
+    (PyObject*)&iMeshTag_Type,NULL)
+
+#define iMeshTag_Check(o)			\
+  PyObject_TypeCheck((o),&iMeshTag_Type)
+
+#define iMeshTag_GetMesh(o)			\
+  ((iMeshTag_Object*)(o))->mesh

Added: MOAB/trunk/tools/iMesh/python/iMesh_entSet.c
===================================================================
--- MOAB/trunk/tools/iMesh/python/iMesh_entSet.c	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/iMesh_entSet.c	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,551 @@
+#define NO_IMPORT_ARRAY
+#define NO_IMPORT_IBASE
+
+#include "errors.h"
+#include "iMesh_Python.h"
+#include "iBase_Python.h"
+
+static PyObject *
+iMeshEntSetObj_isList(iMeshEntitySet_Object *self,void *closure)
+{
+  int is_list,err;
+  iMesh_isList(self->mesh->mesh,self->set.handle,&is_list,&err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  return PyBool_FromLong(is_list);
+}
+
+static PyObject *
+iMeshEntSetObj_getNumEntSets(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int num_hops,num_sets,err;
+
+  if(!PyArg_ParseTuple(args,"i",&num_hops))
+    return NULL;
+
+  iMesh_getNumEntSets(self->mesh->mesh,self->set.handle,num_hops,&num_sets,
+		      &err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("i",num_sets);
+}
+
+static PyObject *
+iMeshEntSetObj_getEntSets(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int num_hops,sets_alloc=0,sets_size,err;
+  iBase_EntitySetHandle *sets;
+  
+  if(!PyArg_ParseTuple(args,"i",&num_hops))
+    return NULL;
+
+  iMesh_getEntSets(self->mesh->mesh,self->set.handle,num_hops,&sets,
+		   &sets_alloc,&sets_size,&err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  npy_intp dims[] = {sets_size};
+  return PyArray_NewFromMallocData(1,dims,NPY_IBASEENTSET,sets);
+}
+
+static PyObject *
+iMeshEntSetObj_add(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int err;
+  PyObject *obj;
+
+  if(!PyArg_ParseTuple(args,"O",&obj))
+    return NULL;
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int size = PyArray_SIZE(ents);
+    iBase_EntityHandle *data = PyArray_DATA(ents);
+    iMesh_addEntArrToSet(self->mesh->mesh,data,size,self->set.handle,&err);
+    Py_DECREF(ents);
+  }
+  else if(iBaseEntitySet_Check(obj))
+  {
+    iBaseEntitySet_Object *set = (iBaseEntitySet_Object*)obj;
+    iMesh_addEntSet(self->mesh->mesh,set->handle,self->set.handle,&err);
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    iBaseEntity_Object *ent = (iBaseEntity_Object*)obj;
+    iMesh_addEntToSet(self->mesh->mesh,ent->handle,self->set.handle,&err);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ANY_ENT);
+    return NULL;
+  }
+
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+iMeshEntSetObj_remove(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int err;
+  PyObject *obj;
+
+  if(!PyArg_ParseTuple(args,"O",&obj))
+    return NULL;
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int size = PyArray_SIZE(ents);
+    iBase_EntityHandle *data = PyArray_DATA(ents);
+    iMesh_rmvEntArrFromSet(self->mesh->mesh,data,size,self->set.handle,&err);
+    Py_DECREF(ents);
+  }
+  else if(iBaseEntitySet_Check(obj))
+  {
+    iBaseEntitySet_Object *set = (iBaseEntitySet_Object*)obj;
+    iMesh_rmvEntSet(self->mesh->mesh,set->handle,self->set.handle,&err);
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    iBaseEntity_Object *ent = (iBaseEntity_Object*)obj;
+    iMesh_rmvEntFromSet(self->mesh->mesh,ent->handle,self->set.handle,&err);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ANY_ENT);
+    return NULL;
+  }
+
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+iMeshEntSetObj_contains(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int err;
+  PyObject *obj;
+
+  if(!PyArg_ParseTuple(args,"O",&obj))
+    return NULL;
+
+  PyObject *ents = PyArray_TryFromObject(obj,NPY_IBASEENT,1,1);
+  if(ents)
+  {
+    int *contains=0;
+    int contains_alloc=0,contains_size;
+
+    int size = PyArray_SIZE(ents);
+    iBase_EntityHandle *data = PyArray_DATA(ents);
+    iMesh_isEntArrContained(self->mesh->mesh,self->set.handle,data,size,
+			    &contains,&contains_alloc,&contains_size,&err);
+    Py_DECREF(ents);
+    if(checkError(self->mesh->mesh,err))
+      return NULL;
+
+    npy_intp dims[] = {contains_size};
+    npy_intp strides[] = {sizeof(int)/sizeof(npy_bool)};
+    return PyArray_New(&PyArray_Type,1,dims,NPY_BOOL,strides,contains,
+		       0,NPY_CARRAY|NPY_OWNDATA,NULL); /* TODO: careful! */
+  }
+  else if(iBaseEntitySet_Check(obj))
+  {
+    int contains;
+    iBaseEntitySet_Object *set = (iBaseEntitySet_Object*)obj;
+    iMesh_isEntSetContained(self->mesh->mesh,self->set.handle,set->handle,
+			    &contains,&err);
+    if(checkError(self->mesh->mesh,err))
+      return NULL;
+
+    return PyBool_FromLong(contains);
+  }
+  else if(iBaseEntity_Check(obj))
+  {
+    int contains;
+    iBaseEntity_Object *ent = (iBaseEntity_Object*)obj;
+    iMesh_isEntContained(self->mesh->mesh,self->set.handle,ent->handle,
+			 &contains,&err);
+    if(checkError(self->mesh->mesh,err))
+      return NULL;
+
+    return PyBool_FromLong(contains);
+  }
+  else
+  {
+    PyErr_SetString(PyExc_ValueError,ERR_ANY_ENT);
+    return NULL;
+  }
+}
+
+/* TODO: add/removeParent? */
+
+static PyObject *
+iMeshEntSetObj_addChild(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int err;
+  iBaseEntitySet_Object *set;
+
+  if(!PyArg_ParseTuple(args,"O!",&iBaseEntitySet_Type,&set))
+    return NULL;
+
+  iMesh_addPrntChld(self->mesh->mesh,self->set.handle,set->handle,&err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+iMeshEntSetObj_removeChild(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int err;
+  iBaseEntitySet_Object *set;
+
+  if(!PyArg_ParseTuple(args,"O!",&iBaseEntitySet_Type,&set))
+    return NULL;
+
+  iMesh_rmvPrntChld(self->mesh->mesh,self->set.handle,set->handle,&err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  Py_RETURN_NONE;
+}
+
+static PyObject *
+iMeshEntSetObj_isChild(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int is_child,err;
+  iBaseEntitySet_Object *set;
+
+  if(!PyArg_ParseTuple(args,"O!",&iBaseEntitySet_Type,&set))
+    return NULL;
+
+  iMesh_isChildOf(self->mesh->mesh,self->set.handle,set->handle,&is_child,
+		  &err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  return PyBool_FromLong(is_child);
+}
+
+static PyObject *
+iMeshEntSetObj_getNumChildren(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int num_hops,num_children,err;
+
+  if(!PyArg_ParseTuple(args,"i",&num_hops))
+    return NULL;
+
+  iMesh_getNumChld(self->mesh->mesh,self->set.handle,num_hops,&num_children,
+		   &err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("i",num_children);
+}
+
+static PyObject *
+iMeshEntSetObj_getNumParents(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int num_hops,num_parents,err;
+
+  if(!PyArg_ParseTuple(args,"i",&num_hops))
+    return NULL;
+
+  iMesh_getNumPrnt(self->mesh->mesh,self->set.handle,num_hops,&num_parents,
+		   &err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("i",num_parents);
+}
+
+static PyObject *
+iMeshEntSetObj_getChildren(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int num_hops,sets_alloc=0,sets_size,err;
+  iBase_EntitySetHandle *sets;
+
+  if(!PyArg_ParseTuple(args,"i",&num_hops))
+    return NULL;
+
+  iMesh_getChldn(self->mesh->mesh,self->set.handle,num_hops,&sets,&sets_alloc,
+                   &sets_size,&err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  npy_intp dims[] = {sets_size};
+  PyObject *o = PyArray_NewFromMallocData(1,dims,NPY_IMESHENTSET,sets);
+  Py_INCREF(self->mesh);
+  PyArray_BASE(o) = (PyObject*)self->mesh;
+  return o;
+}
+
+static PyObject *
+iMeshEntSetObj_getParents(iMeshEntitySet_Object *self,PyObject *args)
+{
+  int num_hops,sets_alloc=0,sets_size,err;
+  iBase_EntitySetHandle *sets;
+
+  if(!PyArg_ParseTuple(args,"i",&num_hops))
+    return NULL;
+
+  iMesh_getPrnts(self->mesh->mesh,self->set.handle,num_hops,&sets,&sets_alloc,
+		 &sets_size,&err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  npy_intp dims[] = {sets_size};
+  PyObject *o = PyArray_NewFromMallocData(1,dims,NPY_IMESHENTSET,sets);
+  Py_INCREF(self->mesh);
+  PyArray_BASE(o) = (PyObject*)self->mesh;
+  return o;
+}
+
+static PyObject *
+iMeshEntSetObj_iterate(iMeshEntitySet_Object *self,PyObject *args)
+{
+  Py_ssize_t size = PyTuple_Size(args);
+  PyObject *type,*topo,*count,*tuple,*ret;
+
+  if(!PyArg_UnpackTuple(args,"iterate",2,3,&type,&topo,&count))
+    return NULL;
+  tuple = PyTuple_Pack(size+2,self->mesh,self,type,topo,count);
+
+  ret = PyObject_CallObject((PyObject*)&iMeshIter_Type,tuple);
+  Py_DECREF(tuple);
+  return ret;
+}
+
+
+static PyObject *
+iMeshEntSetObj_sub(iMeshEntitySet_Object *lhs,iMeshEntitySet_Object *rhs)
+{
+  int err;
+  iMeshEntitySet_Object *result;
+
+  if(lhs->mesh->mesh != rhs->mesh->mesh)
+    return NULL;
+
+  result = iMeshEntitySet_New();
+  result->mesh = lhs->mesh; /* TODO: incref? */
+  iMesh_subtract(lhs->mesh->mesh,lhs->set.handle,rhs->set.handle,
+		 &result->set.handle,&err);
+  if(checkError(lhs->mesh->mesh,err))
+  {
+    Py_DECREF((PyObject*)result);
+    return NULL;
+  }
+
+  return (PyObject*)result;
+}
+
+static PyObject *
+iMeshEntSetObj_bitand(iMeshEntitySet_Object *lhs,iMeshEntitySet_Object *rhs)
+{
+  int err;
+  iMeshEntitySet_Object *result;
+
+  if(lhs->mesh->mesh != rhs->mesh->mesh)
+    return NULL;
+
+  result = iMeshEntitySet_New();
+  result->mesh = lhs->mesh; /* TODO: incref? */
+  iMesh_intersect(lhs->mesh->mesh,lhs->set.handle,rhs->set.handle,
+		  &result->set.handle,&err);
+  if(checkError(lhs->mesh->mesh,err))
+  {
+    Py_DECREF((PyObject*)result);
+    return NULL;
+  }
+
+  return (PyObject*)result;
+}
+
+static PyObject *
+iMeshEntSetObj_bitor(iMeshEntitySet_Object *lhs,iMeshEntitySet_Object *rhs)
+{
+  int err;
+  iMeshEntitySet_Object *result;
+
+  if(lhs->mesh->mesh != rhs->mesh->mesh)
+    return NULL;
+
+  result = iMeshEntitySet_New();
+  result->mesh = lhs->mesh; /* TODO: incref? */
+  iMesh_unite(lhs->mesh->mesh,lhs->set.handle,rhs->set.handle,
+	      &result->set.handle,&err);
+  if(checkError(lhs->mesh->mesh,err))
+  {
+    Py_DECREF((PyObject*)result);
+    return NULL;
+  }
+
+  return (PyObject*)result;
+}
+
+
+static PyObject *
+iMeshEntSetObj_difference(iMeshEntitySet_Object *self,PyObject *args)
+{
+  iMeshEntitySet_Object *rhs;
+  if(!PyArg_ParseTuple(args,"O!",&iMeshEntitySet_Type,&rhs))
+    return NULL;
+
+  return iMeshEntSetObj_sub(self,rhs);
+}
+
+static PyObject *
+iMeshEntSetObj_intersection(iMeshEntitySet_Object *self,PyObject *args)
+{
+  iMeshEntitySet_Object *rhs;
+  if(!PyArg_ParseTuple(args,"O!",&iMeshEntitySet_Type,&rhs))
+    return NULL;
+
+  return iMeshEntSetObj_bitand(self,rhs);
+}
+
+static PyObject *
+iMeshEntSetObj_union(iMeshEntitySet_Object *self,PyObject *args)
+{
+  iMeshEntitySet_Object *rhs;
+  if(!PyArg_ParseTuple(args,"O!",&iMeshEntitySet_Type,&rhs))
+    return NULL;
+
+  return iMeshEntSetObj_bitor(self,rhs);
+}
+
+
+static PyMethodDef iMeshEntSetObj_methods[] = {
+  { "getNumEntSets", (PyCFunction)iMeshEntSetObj_getNumEntSets, METH_VARARGS,
+    "Get the number of entity sets contained in the set or interface"
+  },
+  { "getEntSets", (PyCFunction)iMeshEntSetObj_getEntSets, METH_VARARGS,
+    "Get the entity sets contained in the set or interface"
+  },
+  { "add", (PyCFunction)iMeshEntSetObj_add, METH_VARARGS,
+    "Add an entity (or array of entities or entity set) to the set"
+  },
+  { "remove", (PyCFunction)iMeshEntSetObj_remove, METH_VARARGS,
+    "Remove an entity (or array of entities or entity set) from the set"
+  },
+  { "contains", (PyCFunction)iMeshEntSetObj_contains, METH_VARARGS,
+    "Return whether an entity (or array of entities or entity set) are "
+    "contained in the set"
+  },
+  { "addChild", (PyCFunction)iMeshEntSetObj_addChild, METH_VARARGS,
+    "Add parent/child links between two sets"
+  },
+  { "removeChild", (PyCFunction)iMeshEntSetObj_removeChild, METH_VARARGS,
+    "Remove parent/child links between two sets"
+  },
+  { "isChild", (PyCFunction)iMeshEntSetObj_isChild, METH_VARARGS,
+    "Return whether a set is a child of this set"
+  },
+  { "getNumChildren", (PyCFunction)iMeshEntSetObj_getNumChildren, METH_VARARGS,
+    "Get the number of child sets linked from this set"
+  },
+  { "getNumParents", (PyCFunction)iMeshEntSetObj_getNumParents, METH_VARARGS,
+    "Get the number of parent sets linked from this set"
+  },
+  { "getChildren", (PyCFunction)iMeshEntSetObj_getChildren, METH_VARARGS,
+    "Get the child sets linked from this set"
+  },
+  { "getParents", (PyCFunction)iMeshEntSetObj_getParents, METH_VARARGS,
+    "Get the parent sets linked from this set"
+  },
+  { "iterate", (PyCFunction)iMeshEntSetObj_iterate, METH_VARARGS,
+    "Initialize an iterator over specified entity type, topology, and size"
+  },
+  { "difference", (PyCFunction)iMeshEntSetObj_difference, METH_VARARGS,
+    "Get the difference of the two sets"
+  },
+  { "intersection", (PyCFunction)iMeshEntSetObj_intersection, METH_VARARGS,
+    "Get the intersection of the two sets"
+  },
+  { "union", (PyCFunction)iMeshEntSetObj_union, METH_VARARGS,
+    "Get the union of the two sets"
+  },
+  {0}
+};
+
+static PyGetSetDef iMeshEntSetObj_getset[] = {
+  { "isList", (getter)iMeshEntSetObj_isList, 0,
+    "Return whether a specified set is ordered or unordered", 0 },
+  {0}
+};
+
+static PyNumberMethods iMeshEntSetObj_num = {
+  0,                                   /* nb_add */
+  (binaryfunc)iMeshEntSetObj_sub,      /* nb_subtract */
+  0,                                   /* nb_multiply */
+  0,                                   /* nb_divide */
+  0,                                   /* nb_remainder */
+  0,                                   /* nb_divmod */
+  0,                                   /* nb_power */
+  0,                                   /* nb_negative */
+  0,                                   /* nb_positive */
+  0,                                   /* nb_absolute */
+  0,                                   /* nb_nonzero */
+  0,                                   /* nb_invert */
+  0,                                   /* nb_lshift */
+  0,                                   /* nb_rshift */
+  (binaryfunc)iMeshEntSetObj_bitand,   /* nb_and */
+  0,                                   /* nb_xor */
+  (binaryfunc)iMeshEntSetObj_bitor,    /* nb_or */
+  0,                                   /* nb_coerce */
+  0,                                   /* nb_int */
+  0,                                   /* nb_long */
+  0,                                   /* nb_float */
+  0,                                   /* nb_oct */
+  0,                                   /* nb_hex */
+};
+
+PyTypeObject iMeshEntitySet_Type = {
+  PyObject_HEAD_INIT(NULL)
+  0,                                   /* ob_size */
+  "itaps.iMesh.entitySet",             /* tp_name */
+  sizeof(iMeshEntitySet_Object),       /* tp_basicsize */
+  0,                                   /* tp_itemsize */
+  0,                                   /* tp_dealloc */
+  0,                                   /* tp_print */
+  0,                                   /* tp_getattr */
+  0,                                   /* tp_setattr */
+  0,                                   /* tp_compare */
+  0,                                   /* tp_repr */
+  &iMeshEntSetObj_num,                 /* 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 */
+  "iMesh entity set object",           /* tp_doc */
+  0,                                   /* tp_traverse */
+  0,                                   /* tp_clear */
+  0,                                   /* tp_richcompare */
+  0,                                   /* tp_weaklistoffset */
+  0,                                   /* tp_iter */
+  0,                                   /* tp_iternext */
+  iMeshEntSetObj_methods,              /* tp_methods */
+  0,                                   /* tp_members */
+  iMeshEntSetObj_getset,               /* 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 */
+};

Added: MOAB/trunk/tools/iMesh/python/iMesh_iter.c
===================================================================
--- MOAB/trunk/tools/iMesh/python/iMesh_iter.c	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/iMesh_iter.c	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,151 @@
+#define NO_IMPORT_ARRAY
+#define NO_IMPORT_ITER
+
+#include "iMesh_Python.h"
+#include "iBase_Python.h"
+
+static int
+iMeshIterObj_init(iMeshIter_Object *self,PyObject *args,PyObject *kwds)
+{
+  static char *kwlist[] = {"mesh","entity_set","type","topology",
+                           "array_size",0};
+  iMeshObject *mesh;
+  iBaseEntitySet_Object *set;
+  int type,topo,array_size=1,err;
+
+  if( !PyArg_ParseTupleAndKeywords(args,kwds,"OOii|i",kwlist,&mesh,&set,&type,
+                                   &topo,&array_size) )
+    return -1;
+
+  self->mesh = mesh->mesh;
+  if(array_size == 1)
+  {
+    self->is_arr = 0;
+    iMesh_initEntIter(self->mesh,set->handle,type,topo,&self->iter,&err);
+  }
+  else
+  {
+    self->is_arr = 1;
+    iMesh_initEntArrIter(self->mesh,set->handle,type,topo,array_size,
+			 &self->arr_iter,&err);
+  }
+  if(checkError(self->mesh,err))
+    return -1;
+
+  return 0;
+}
+
+static void
+iMeshIterObj_dealloc(iMeshIter_Object *self)
+{
+  if(self->mesh && self->iter)
+  {
+    int err;
+    if(self->is_arr)
+      iMesh_endEntArrIter(self->mesh,self->arr_iter,&err);
+    else
+      iMesh_endEntIter(self->mesh,self->iter,&err);
+  }
+
+  self->ob_type->tp_free((PyObject*)self);
+}
+
+static PyObject *
+iMeshIterObj_reset(iMeshIter_Object *self,PyObject *args)
+{
+  int err;
+  if(self->is_arr)
+    iMesh_resetEntArrIter(self->mesh,self->arr_iter,&err);
+  else
+    iMesh_resetEntIter(self->mesh,self->iter,&err);
+
+  if(checkError(self->mesh,err))
+    return NULL;
+  Py_RETURN_NONE;
+}
+
+static PyMethodDef iMeshIter_methods[] = {
+  { "reset", (PyCFunction)iMeshIterObj_reset, METH_NOARGS,
+    "Reset the iterator"
+  },
+  {0}
+};
+
+static PyObject *
+iMeshIterObj_iternext(iMeshIter_Object *self)
+{
+  int has_data,err;
+
+  if(self->is_arr)
+  {
+    iBase_EntityHandle *entities=0;
+    int alloc=0,size;
+
+    iMesh_getNextEntArrIter(self->mesh,self->arr_iter,&entities,&alloc,&size,
+			    &has_data,&err);
+    if(checkError(self->mesh,err))
+      return NULL;
+    if(!has_data)
+      return NULL;
+
+    npy_intp dims[] = {size};
+    return PyArray_NewFromMallocData(1,dims,NPY_IBASEENT,entities);
+  }
+  else
+  {
+    iBase_EntityHandle entity;
+    iMesh_getNextEntIter(self->mesh,self->iter,&entity,&has_data,&err);
+    if(checkError(self->mesh,err))
+      return NULL;
+    if(!has_data)
+      return NULL;
+
+    iBaseEntity_Object *o = iBaseEntity_New();
+    o->handle = entity;
+    return (PyObject*)o;
+  }
+}
+
+PyTypeObject iMeshIter_Type = {
+  PyObject_HEAD_INIT(NULL)
+  0,                                   /* ob_size */
+  "itaps.iMesh.iterator",              /* tp_name */
+  sizeof(iMeshIter_Object),            /* tp_basicsize */
+  0,                                   /* tp_itemsize */
+  (destructor)iMeshIterObj_dealloc,    /* tp_dealloc */
+  0,                                   /* tp_print */
+  0,                                   /* tp_getattr */
+  0,                                   /* tp_setattr */
+  0,                                   /* tp_compare */
+  0,                                   /* 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_HAVE_ITER |
+  Py_TPFLAGS_BASETYPE,                 /* tp_flags */
+  "iMesh iterator object",             /* tp_doc */
+  0,                                   /* tp_traverse */
+  0,                                   /* tp_clear */
+  0,                                   /* tp_richcompare */
+  0,                                   /* tp_weaklistoffset */
+  PyObject_SelfIter,                   /* tp_iter */
+  (iternextfunc)iMeshIterObj_iternext, /* tp_iternext */
+  iMeshIter_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 */
+  (initproc)iMeshIterObj_init,         /* tp_init */
+  0,                                   /* tp_alloc */
+  0,                                   /* tp_new */
+};

Added: MOAB/trunk/tools/iMesh/python/iMesh_tag.c
===================================================================
--- MOAB/trunk/tools/iMesh/python/iMesh_tag.c	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/iMesh_tag.c	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,137 @@
+#define NO_IMPORT_ARRAY
+#define NO_IMPORT_IBASE
+
+#include "iMesh_Python.h"
+#include "iBase_Python.h"
+
+static char typechars[] = {'i','d','E','b'};
+
+enum iBase_TagValueType
+char_to_type(char c)
+{
+  int i;
+  for(i=0; i<sizeof(typechars); i++)
+    {
+      if(typechars[i] == c)
+	return i;
+    }
+  return -1;
+}
+
+char
+type_to_char(enum iBase_TagValueType t)
+{
+  return typechars[t];
+}
+
+
+static PyObject *
+iMeshTagObj_getName(iMeshTag_Object *self,void *closure)
+{
+  char name[512];
+  int err;
+  iMesh_getTagName(self->mesh->mesh,self->tag.handle,name,&err,sizeof(name));
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("s",name);
+}
+
+static PyObject *
+iMeshTagObj_getSizeValues(iMeshTag_Object *self,void *closure)
+{
+  int size,err;
+  iMesh_getTagSizeValues(self->mesh->mesh,self->tag.handle,&size,&err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("i",size);
+}
+
+static PyObject *
+iMeshTagObj_getSizeBytes(iMeshTag_Object *self,void *closure)
+{
+  int size,err;
+  iMesh_getTagSizeBytes(self->mesh->mesh,self->tag.handle,&size,&err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("i",size);
+}
+
+static PyObject *
+iMeshTagObj_getType(iMeshTag_Object *self,void *closure)
+{
+  int type,err;
+  iMesh_getTagType(self->mesh->mesh,self->tag.handle,&type,&err);
+  if(checkError(self->mesh->mesh,err))
+    return NULL;
+
+  return Py_BuildValue("c",type_to_char(type));
+}
+
+
+static PyMethodDef iMeshTagObj_methods[] = {
+  {0}
+};
+
+static PyGetSetDef iMeshTagObj_getset[] = {
+  { "name", (getter)iMeshTagObj_getName, 0,
+      "Get the name for a given tag handle", 0
+  },
+  { "sizeValues", (getter)iMeshTagObj_getSizeValues, 0,
+    "Get size of a tag in units of numbers of tag data type", 0
+  },
+  { "sizeBytes", (getter)iMeshTagObj_getSizeBytes, 0,
+    "Get size of a tag in units of bytes", 0
+  },
+  { "type", (getter)iMeshTagObj_getType, 0,
+    "Get the data type of the specified tag handle", 0
+  },
+  {0}
+};
+
+
+PyTypeObject iMeshTag_Type = {
+  PyObject_HEAD_INIT(NULL)
+  0,                                   /* ob_size */
+  "itaps.iMesh.tag",                   /* tp_name */
+  sizeof(iMeshTag_Object),             /* tp_basicsize */
+  0,                                   /* tp_itemsize */
+  0,                                   /* tp_dealloc */
+  0,                                   /* tp_print */
+  0,                                   /* tp_getattr */
+  0,                                   /* tp_setattr */
+  0,                                   /* tp_compare */
+  0,                                   /* 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 */
+  "iMesh tag object",                  /* tp_doc */
+  0,                                   /* tp_traverse */
+  0,                                   /* tp_clear */
+  0,                                   /* tp_richcompare */
+  0,                                   /* tp_weaklistoffset */
+  0,                                   /* tp_iter */
+  0,                                   /* tp_iternext */
+  iMeshTagObj_methods,                 /* tp_methods */
+  0,                                   /* tp_members */
+  iMeshTagObj_getset,                  /* 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 */
+};
+

Added: MOAB/trunk/tools/iMesh/python/itaps/__init__.py
===================================================================
--- MOAB/trunk/tools/iMesh/python/itaps/__init__.py	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/itaps/__init__.py	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,2 @@
+import iBase
+from iMesh import *

Added: MOAB/trunk/tools/iMesh/python/setup.py
===================================================================
--- MOAB/trunk/tools/iMesh/python/setup.py	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/setup.py	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,23 @@
+from distutils.core import setup, Extension
+
+iBase = Extension('itaps.iBase',
+                  depends = ['common.h', 'iBase_Python.h'],
+                  sources = ['iBase.c']
+                  )
+
+iMesh = Extension('itaps.iMesh',
+                  libraries = ['iMesh', 'm', 'gcc_s', 'c', 'MOAB',
+                               'netcdf_c++', 'netcdf', 'hdf5', 'stdc++'],
+                  depends = ['common.h', 'iMesh_Python.h', 'iBase_Python.h',
+                             'errors.h'],
+                  sources = ['iMesh.c', 'iMesh_iter.c', 'iMesh_entSet.c',
+                             'iMesh_tag.c']
+                  )
+
+
+setup(name = 'PyTAPS',
+      version = '0.1',
+      description = 'Python bindings for iBase and iMesh interfaces',
+      packages = ['itaps'],
+      ext_modules = [iBase, iMesh]
+      )

Added: MOAB/trunk/tools/iMesh/python/test/adj.py
===================================================================
--- MOAB/trunk/tools/iMesh/python/test/adj.py	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/test/adj.py	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,97 @@
+from core import *
+
+topo = iMesh.topology # shorthand
+
+class TestAdj(unittest.TestCase):
+    def setUp(self):
+        self.mesh = iMesh()
+        self.verts = [[0,0,0], [0,0,1], [0,1,0], [0,1,1]]
+        self.ents = self.mesh.createVtx(self.verts,
+                                        iBase.storageOrder.interleaved)
+
+        self.lines = [ 
+            self.mesh.createEnt(topo.line_segment, self.ents[0:2] )[0],
+            self.mesh.createEnt(topo.line_segment, self.ents[1:3] )[0],
+            self.mesh.createEnt(topo.line_segment, self.ents[2:4] )[0],
+            self.mesh.createEnt(topo.line_segment, self.ents[::-3])[0] ]
+
+    def tearDown(self):
+        self.mesh  = None
+        self.verts = None
+        self.ents  = None
+        self.root  = None
+        self.lines = None
+
+    @staticmethod
+    def jaggify(arr,offsets):
+        prev = offsets[0]
+        jag = []
+        for i in offsets[1:]:
+            jag.append(arr[prev:i].tolist())
+            prev = i
+        return jag
+
+    def testSquare(self):
+        quad = self.mesh.createEnt(topo.quadrilateral, self.lines)[0]
+        root = self.mesh.rootSet
+
+        self.assertEqual(self.mesh.getNumOfType(root, iBase.type.vertex),  4)
+        self.assertEqual(self.mesh.getNumOfType(root, iBase.type.edge),    4)
+        self.assertEqual(self.mesh.getNumOfType(root, iBase.type.face),    1)
+
+        self.assertEqual(self.mesh.getNumOfTopo(root, topo.point),         4)
+        self.assertEqual(self.mesh.getNumOfTopo(root, topo.line_segment),  4)
+        self.assertEqual(self.mesh.getNumOfTopo(root, topo.quadrilateral), 1)
+
+        self.mesh.deleteEnt(quad)
+        self.assertEqual(self.mesh.getNumOfType(root, iBase.type.face),    0)
+        self.assertEqual(self.mesh.getNumOfTopo(root, topo.quadrilateral), 0)
+
+        self.mesh.deleteEnt(self.lines)
+        self.assertEqual(self.mesh.getNumOfType(root, iBase.type.edge),    0)
+        self.assertEqual(self.mesh.getNumOfTopo(root, topo.line_segment),  0)
+
+        self.mesh.deleteEnt(self.ents)
+        self.assertEqual(self.mesh.getNumOfType(root, iBase.type.vertex),  0)
+        self.assertEqual(self.mesh.getNumOfTopo(root, topo.point),         0)
+
+    def testAdj(self):
+        adj = self.mesh.getEntAdj(self.ents[1], iBase.type.all)
+        self.assertEqual(adj.tolist(), self.lines[0:2])
+
+        adj = self.mesh.getEntAdj(self.ents, iBase.type.all)
+        self.assertEqual(TestAdj.jaggify(adj[0],adj[1]),
+                         [ self.lines[::3],
+                           self.lines[0:2],
+                           self.lines[1:3],
+                           self.lines[2:4] ])
+
+    def test2ndAdj(self):
+        quad = self.mesh.createEnt(topo.quadrilateral, self.lines)[0]
+
+        adj = self.mesh.getEnt2ndAdj(self.ents[1], iBase.type.edge,
+                                     iBase.type.vertex)
+        self.assertEqual(adj.tolist(), self.ents[0:3:2].tolist())
+
+        adj = self.mesh.getEnt2ndAdj(self.ents, iBase.type.edge,
+                                     iBase.type.vertex)
+        self.assertEqual(TestAdj.jaggify(adj[0],adj[1]),
+                         [ self.ents[1::2].tolist(),
+                           self.ents[0::2].tolist(),
+                           self.ents[1::2].tolist(),
+                           self.ents[0::2].tolist() ])
+
+    def testAdjIndices(self):
+        set = self.mesh.createEntSet(True)
+        set.add(self.ents)
+        adj = self.mesh.getAdjEntIndices(set, iBase.type.all, topo.all,
+                                         iBase.type.all)
+
+        self.assertEqual(adj[0].tolist(), self.ents.tolist())
+        self.assertEqual(adj[1].tolist(), self.lines)
+        self.assertEqual(TestAdj.jaggify(adj[2],adj[3]),
+                         [ [0,3], [0,1], [1,2], [2,3] ])
+
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestAdj)
+unittest.TextTestRunner(verbosity=2).run(suite)

Added: MOAB/trunk/tools/iMesh/python/test/all.py
===================================================================
--- MOAB/trunk/tools/iMesh/python/test/all.py	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/test/all.py	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,6 @@
+import basic
+import entset
+import tags
+import adj
+# import iter
+

Added: MOAB/trunk/tools/iMesh/python/test/basic.py
===================================================================
--- MOAB/trunk/tools/iMesh/python/test/basic.py	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/test/basic.py	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,94 @@
+from core import *
+
+class TestBasic(unittest.TestCase):
+    def testMinimal(self):
+        mesh = iMesh("hello there")
+
+        mesh.geometricDimension = 2
+        self.assertEqual(mesh.geometricDimension, 2)
+        root = mesh.rootSet
+        mesh.dfltStorage
+
+        self.assert_(mesh.areEHValid(True))
+        self.assertEqual(mesh.getNumOfType(root, iBase.type.all), 0)
+        self.assertEqual(mesh.getNumOfTopo(root, iMesh.topology.all), 0)
+        self.assertEqual(mesh.adjTable.shape, (4,4))
+
+    def testVertex(self):
+        mesh = iMesh()
+        ent = mesh.createVtx([1,2,3])
+        root = mesh.rootSet
+
+        self.assertEqual(mesh.getNumOfType(root, iBase.type.vertex), 1)
+        self.assertEqual(mesh.getNumOfTopo(root, iMesh.topology.point), 1)
+
+        self.assert_( (mesh.getVtxCoords(ent) == [1,2,3]).all() )
+        self.assert_( (mesh.getVtxCoords([ent], iBase.storageOrder.interleaved)
+                       == [[1,2,3]]).all() )
+
+        self.assertEqual(mesh.getEntType(ent), iBase.type.vertex)
+        self.assertEqual(mesh.getEntTopo(ent), iMesh.topology.point)
+
+        mesh.setVtxCoords(ent,[4,5,6])
+        self.assert_( (mesh.getVtxCoords(ent) == [4,5,6]).all() )
+
+    def testVertices(self):
+        mesh = iMesh()
+        verts = [[1,2,3], [4,5,6], [7,8,9], [10,11,12]]
+        ents = mesh.createVtx(verts, iBase.storageOrder.interleaved)
+        root = mesh.rootSet
+
+        self.assertEqual(mesh.getNumOfType(root, iBase.type.vertex), 4)
+        self.assertEqual(mesh.getNumOfTopo(root, iMesh.topology.point), 4)
+
+        coords = mesh.getVtxCoords(ents, iBase.storageOrder.interleaved)
+        self.assert_( (coords == verts).all())
+
+        self.assertEqual(mesh.getEntType(ents[0]), iBase.type.vertex)
+        self.assert_( (mesh.getEntType(ents) == 4*[iBase.type.vertex]).all() )
+
+        self.assertEqual(mesh.getEntTopo(ents[0]), iMesh.topology.point)
+        self.assert_( (mesh.getEntTopo(ents) == 
+                       4*[iMesh.topology.point]).all() )
+
+        verts = [[12,11,10], [9,8,7], [6,5,4], [3,2,1]]
+        mesh.setVtxCoords(ents, verts, iBase.storageOrder.interleaved)
+        
+        coords = mesh.getVtxCoords(ents, iBase.storageOrder.interleaved)
+        self.assert_( (coords == verts).all())
+
+    def testCreateEntArr(self):
+        mesh = iMesh()
+        verts = [[0,0,0], [0,0,1], [0,1,0], [0,1,1]]
+        ents = mesh.createVtx(verts, iBase.storageOrder.interleaved)
+        root = mesh.rootSet
+        topo = iMesh.topology
+
+        lines = mesh.createEntArr(topo.line_segment,ents)[0]
+        self.assertEqual(mesh.getNumOfType(root, iBase.type.vertex),  4)
+        self.assertEqual(mesh.getNumOfType(root, iBase.type.edge),    2)
+
+        self.assertEqual(mesh.getNumOfTopo(root, topo.point),         4)
+        self.assertEqual(mesh.getNumOfTopo(root, topo.line_segment),  2)
+
+    def testSave(self):
+        mesh = iMesh()
+        verts = [1,2,3]
+        mesh.createVtx(verts)
+        
+        mesh.save(mesh.rootSet,'test')
+        
+        mesh = iMesh()
+        root = mesh.rootSet
+        mesh.load(root,'test')
+        ents = mesh.getEntities(root,iBase.type.all,iMesh.topology.all)
+
+        self.assertEqual(mesh.getNumOfType(root, iBase.type.vertex), 1)
+        self.assertEqual(mesh.getNumOfTopo(root, iMesh.topology.point), 1)
+
+        coords = mesh.getVtxCoords(ents,iBase.storageOrder.interleaved)
+        self.assert_( (coords == [1,2,3]).all() )
+
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestBasic)
+unittest.TextTestRunner(verbosity=2).run(suite)

Added: MOAB/trunk/tools/iMesh/python/test/core.py
===================================================================
--- MOAB/trunk/tools/iMesh/python/test/core.py	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/test/core.py	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,5 @@
+import sys
+sys.path.append('/home/porterj/python-ext/build/lib.linux-x86_64-2.5/')
+
+import unittest
+from itaps import *

Added: MOAB/trunk/tools/iMesh/python/test/entset.py
===================================================================
--- MOAB/trunk/tools/iMesh/python/test/entset.py	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/test/entset.py	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,123 @@
+from core import *
+
+class TestEntSet(unittest.TestCase):
+    def setUp(self):
+        self.mesh = iMesh()
+        self.set = self.mesh.createEntSet(True)
+
+    def tearDown(self):
+        self.mesh = None
+
+    def testCreation(self):
+        self.assertEqual(self.set.isList, True)
+        self.assertEqual(self.set.getNumEntSets(1), 0)
+        self.assertEqual(self.mesh.rootSet.getNumEntSets(0), 1)
+
+        foo = self.mesh.rootSet.getEntSets(0)[0]
+        self.assertEqual(self.set, foo)
+
+        self.mesh.destroyEntSet(self.set)
+        self.assertEqual(self.mesh.rootSet.getNumEntSets(0), 0)
+
+    def testEnt(self):
+        ent = self.mesh.createVtx([1,2,3])
+
+        self.assertFalse(self.set.contains(ent))
+
+        self.set.add(ent)
+        self.assert_(self.set.contains(ent))
+
+        self.set.remove(ent)
+        self.assertFalse(self.set.contains(ent))
+
+    def testEntArr(self):
+        ents = self.mesh.createVtx([[1,2,3], [4,5,6], [7,8,9]],
+                                   iBase.storageOrder.interleaved)
+        
+        self.assertFalse(self.set.contains(ents).any())
+
+        self.set.add(ents)
+        self.assert_(self.set.contains(ents).all())
+
+        self.set.remove(ents)
+        self.assertFalse(self.set.contains(ents).any())
+
+    def testEntSet(self):
+        sub = self.mesh.createEntSet(True)
+
+        self.assertFalse(self.set.contains(sub))
+
+        self.set.add(sub)
+        self.assert_(self.set.contains(sub))
+
+        self.set.remove(sub)
+        self.assertFalse(self.set.contains(sub))
+
+    def testChildren(self):
+        sub = self.mesh.createEntSet(True)
+        self.set.addChild(sub)
+
+        self.assert_(self.set.isChild(sub))
+        self.assertEqual(self.set.getNumChildren(1), 1)
+        self.assertEqual(sub.getNumParents(1),  1)
+
+        self.assertEqual(self.set.getChildren(1)[0], sub)
+        self.assertEqual(sub.getParents(1)[0], self.set)
+
+        self.set.removeChild(sub)
+
+        self.assert_(not self.set.isChild(sub))
+        self.assertEqual(self.set.getNumChildren(1), 0)
+        self.assertEqual(sub.getNumParents(1),  0)
+
+    def testSubtract(self):
+        set2 = self.mesh.createEntSet(True)
+        ents = self.mesh.createVtx([[1,2,3], [4,5,6]],
+                                   iBase.storageOrder.interleaved)
+        self.set.add(ents)
+        set2.add(ents[0])
+
+        diff = self.set - set2
+        self.assertFalse(diff.contains(ents[0]))
+        self.assertTrue (diff.contains(ents[1]))
+
+        diff = self.set.difference(set2)
+        self.assertFalse(diff.contains(ents[0]))
+        self.assertTrue (diff.contains(ents[1]))
+
+    def testIntersect(self):
+        set2 = self.mesh.createEntSet(True)
+        ents = self.mesh.createVtx([[1,2,3], [4,5,6], [7,8,9]],
+                                   iBase.storageOrder.interleaved)
+        self.set.add(ents[0:2])
+        set2.add(ents[1:3])
+
+        sect = self.set & set2
+        self.assertFalse(sect.contains(ents[0]))
+        self.assertTrue (sect.contains(ents[1]))
+        self.assertFalse(sect.contains(ents[2]))
+
+        sect = self.set.intersection(set2)
+        self.assertFalse(sect.contains(ents[0]))
+        self.assertTrue (sect.contains(ents[1]))
+        self.assertFalse(sect.contains(ents[2]))
+
+    def testUnite(self):
+        set2 = self.mesh.createEntSet(True)
+        ents = self.mesh.createVtx([[1,2,3], [4,5,6]],
+                                   iBase.storageOrder.interleaved)
+        self.set.add(ents[0])
+        set2.add(ents[1])
+
+        union = self.set | set2
+        self.assertTrue(union.contains(ents[0]))
+        self.assertTrue(union.contains(ents[1]))
+
+        union = self.set.union(set2)
+        self.assertTrue(union.contains(ents[0]))
+        self.assertTrue(union.contains(ents[1]))
+
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestEntSet)
+unittest.TextTestRunner(verbosity=2).run(suite)
+

Added: MOAB/trunk/tools/iMesh/python/test/iter.py
===================================================================
--- MOAB/trunk/tools/iMesh/python/test/iter.py	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/test/iter.py	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,47 @@
+from core import *
+
+class TestIter(unittest.TestCase):
+    def setUp(self):
+        self.mesh = iMesh()
+        self.empty = self.mesh.createEntSet(True)
+
+        self.ent = self.mesh.createVtx([1,2,3])
+        self.set = self.mesh.createEntSet(True)
+        self.set.add(self.ent)
+
+    def testEmpty(self):
+        for i in self.empty.iterate(iBase.type.all, iMesh.topology.all):
+            self.fail('empty iterator has >0 elements')
+        iter.reset()
+
+    def testArrEmpty(self):
+        for i in self.empty.iterate(iBase.type.all, iMesh.topology.all, 16):
+            self.fail('empty iterator has >0 elements')
+        iter.reset()
+
+    def testSingle(self):
+        count = 0
+        for i in self.set.iterate(iBase.type.all, iMesh.topology.all):
+            count += 1
+            self.assertEqual(i, self.ent)
+        self.assertEqual(count, 1)
+
+    def testArr(self):
+        count = 0
+        for i in self.set.iterate(iBase.type.all, iMesh.topology.all, 16):
+            count += 1
+            self.assertEqual(i, self.ent) # TODO
+        self.assertEqual(count,1)
+
+    def testAlternate(self):
+        count = 0
+        iter = iMesh.iterator(self.mesh, self.set, iBase.type.all,
+                              iMesh.topology.all)
+        for i in iter:
+            count += 1
+            self.assertEqual(i, self.ent)
+        self.assertEqual(count, 1)
+
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestIter)
+unittest.TextTestRunner(verbosity=2).run(suite)

Added: MOAB/trunk/tools/iMesh/python/test/tags.py
===================================================================
--- MOAB/trunk/tools/iMesh/python/test/tags.py	                        (rev 0)
+++ MOAB/trunk/tools/iMesh/python/test/tags.py	2009-05-06 19:32:15 UTC (rev 2878)
@@ -0,0 +1,176 @@
+from core import *
+from numpy import *
+
+class TestTags(unittest.TestCase):
+    def setUp(self):
+        self.mesh = iMesh()
+
+        self.itag = self.mesh.createTag('int',    1, 'i')
+        self.dtag = self.mesh.createTag('double', 1, 'd')
+        self.etag = self.mesh.createTag('handle', 1, 'E')
+        self.btag = self.mesh.createTag('bytes',  3, 'b')
+
+        self.ents = self.mesh.createVtx([[1,2,3], [4,5,6], [7,8,9]],
+                                        iBase.storageOrder.interleaved)
+        self.ent = self.ents[0]
+        self.set = self.mesh.createEntSet(True)
+
+    def testCreation(self):
+        self.assertEqual(self.itag.name, 'int')
+        self.assertEqual(self.itag.type, 'i')
+        self.assertEqual(self.itag.sizeValues, 1)
+        self.assertEqual(self.itag.sizeBytes, 4)
+
+    def testFind(self):
+        t = self.mesh.getTagHandle('int')
+        self.assertEqual(t.name, self.itag.name)
+
+        self.assertRaises(RuntimeError, self.mesh.getTagHandle, 'potato')
+
+    def testIntData(self):
+        self.mesh.setData(self.ent, self.itag, 42)
+        self.assertEqual(self.mesh.getData(self.ent, self.itag), 42)
+        self.assertEqual(self.mesh.getData(self.ent, self.itag, 'i'), 42)
+
+        self.mesh.rmvTag(self.ent, self.itag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.ent,self.itag)
+
+    def testDblData(self):
+        self.mesh.setData(self.ent, self.dtag, 42.0)
+        self.assertEqual(self.mesh.getData(self.ent, self.dtag), 42.0)
+        self.assertEqual(self.mesh.getData(self.ent, self.dtag, 'd'), 42.0)
+
+        self.mesh.rmvTag(self.ent, self.dtag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.ent,self.dtag)
+
+    def testEHData(self):
+        self.mesh.setData(self.ent, self.etag, self.ent)
+        self.assertEqual(self.mesh.getData(self.ent, self.etag), self.ent)
+        self.assertEqual(self.mesh.getData(self.ent, self.etag, 'E'), self.ent)
+
+        self.mesh.rmvTag(self.ent, self.etag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.ent,self.etag)        
+
+    def testRawData(self):
+        data = array([1,2,3], int8)
+        self.mesh.setData(self.ent, self.btag, data)
+        self.assert_( (self.mesh.getData(self.ent, self.btag) == data).all() )
+        self.assert_( (self.mesh.getData(self.ent, self.btag, 'b') == data)
+                      .all() )
+
+        self.mesh.rmvTag(self.ent, self.btag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.ent,self.btag)
+
+    def testGetAll(self):
+        self.mesh.setData(self.ent, self.itag, 42)
+        self.mesh.setData(self.ent, self.dtag, 42)
+
+        tags = self.mesh.getAllTags(self.ent)
+        self.assertEqual(tags[0].name, self.itag.name) # TODO: ignore order?
+        self.assertEqual(tags[1].name, self.dtag.name)
+
+
+    def testIntArrData(self):
+        self.mesh.setData(self.ents, self.itag, 3*[42])
+
+        self.assert_((self.mesh.getData(self.ents, self.itag, 'i') ==
+                      3*[42]).all())
+        self.assertEqual(self.mesh.getData(self.ents[0], self.itag, 'i'), 42)
+
+        self.mesh.rmvTag(self.ents, self.itag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.ents,self.itag)
+
+    def testDblArrData(self):
+        self.mesh.setData(self.ents, self.dtag, 3*[42.0])
+
+        self.assert_((self.mesh.getData(self.ents, self.dtag, 'd') ==
+                      3*[42.0]).all())
+        self.assertEqual(self.mesh.getData(self.ents[0], self.dtag, 'd'), 42.0)
+
+        self.mesh.rmvTag(self.ents, self.dtag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.ents,self.dtag)
+
+    def testEHArrData(self):
+        self.mesh.setData(self.ents, self.etag, self.ents)
+
+        self.assertEqual(str(self.mesh.getData(self.ents, self.etag, 'E')),
+                         str(self.ents))
+        self.assertEqual(self.mesh.getData(self.ents[0], self.etag, 'E'),
+                         self.ents[0])
+
+        self.mesh.rmvTag(self.ents, self.etag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.ents,self.etag)
+
+    def testRawArrData(self):
+        data = array([1,2,3], int8)
+        self.mesh.setData(self.ents, self.btag, data)
+
+        cmp = array([1,2,3, 0,0,0, 0,0,0], int8) # Huh??
+        self.assert_((self.mesh.getData(self.ents, self.btag, 'b') ==
+                      cmp).all())
+        self.assert_((self.mesh.getData(self.ents[0], self.btag, 'b') == data).
+                     all())
+
+        self.mesh.rmvTag(self.ents, self.btag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.ents,self.btag)
+
+
+
+    def testIntSetData(self):
+        self.mesh.setData(self.set, self.itag, 42)
+        self.assertEqual(self.mesh.getData(self.set, self.itag), 42)
+        self.assertEqual(self.mesh.getData(self.set, self.itag, 'i'), 42)
+
+        self.mesh.rmvTag(self.set, self.itag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.set,self.itag)
+
+    def testDblSetData(self):
+        self.mesh.setData(self.set, self.dtag, 42)
+        self.assertEqual(self.mesh.getData(self.set, self.dtag), 42)
+        self.assertEqual(self.mesh.getData(self.set, self.dtag, 'd'), 42)
+
+        self.mesh.rmvTag(self.set, self.dtag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.set,self.dtag)
+        
+    def testEHSetData(self):
+        self.mesh.setData(self.set, self.etag, self.ent)
+        self.assertEqual(self.mesh.getData(self.set, self.etag), self.ent)
+        self.assertEqual(self.mesh.getData(self.set, self.etag, 'd'), self.ent)
+
+        self.mesh.rmvTag(self.set, self.etag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.set,self.etag)
+
+    def testRawSetData(self):
+        data = array([1,2,3], int8)
+        self.mesh.setData(self.set, self.btag, data)
+
+        self.assert_((self.mesh.getData(self.set, self.btag) == data).all())
+        self.assert_((self.mesh.getData(self.set, self.btag, 'b') == data)
+                     .all())
+
+        self.mesh.rmvTag(self.set, self.btag)
+        self.assertRaises(RuntimeError, self.mesh.getData,
+                          self.set,self.btag)
+
+    def testGetAllSet(self):
+        self.mesh.setData(self.set, self.itag, 42)
+        self.mesh.setData(self.set, self.dtag, 42)
+
+        tags = self.mesh.getAllTags(self.set)
+        self.assertEqual(tags[0].name, self.itag.name) # TODO: ignore order?
+        self.assertEqual(tags[1].name, self.dtag.name)
+        
+
+suite = unittest.TestLoader().loadTestsFromTestCase(TestTags)
+unittest.TextTestRunner(verbosity=2).run(suite)



More information about the moab-dev mailing list