From c0303d78b4c25a095208d33a7d809ebb3db79404 Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Sat, 20 Sep 2003 03:40:16 +0000 Subject: Exppython: - Object: implemented getBoundBox and makeDisplayList methods - NMesh and Object: small internal changes for nicer behavior - Draw: added function PupMenu - Docs: updated for the additions above Auto build tiny fix: added the imbuf include dir to source/creator/Makefile.am --- source/blender/python/api2_2x/Draw.c | 21 +++ source/blender/python/api2_2x/Draw.h | 23 ++- source/blender/python/api2_2x/NMesh.c | 163 ++++++++++++++++--- source/blender/python/api2_2x/NMesh.h | 20 ++- source/blender/python/api2_2x/Object.c | 244 ++++++++++++++++++---------- source/blender/python/api2_2x/Object.h | 2 + source/blender/python/api2_2x/doc/Draw.py | 7 +- source/blender/python/api2_2x/doc/NMesh.py | 31 +++- source/blender/python/api2_2x/doc/Object.py | 31 ++++ source/blender/python/api2_2x/modules.h | 2 +- 10 files changed, 420 insertions(+), 124 deletions(-) (limited to 'source') diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c index 4dc866b368f..3a824aa9f6b 100644 --- a/source/blender/python/api2_2x/Draw.c +++ b/source/blender/python/api2_2x/Draw.c @@ -670,6 +670,27 @@ static PyObject *Method_Text (PyObject *self, PyObject *args) return PyInt_FromLong (BMF_GetStringWidth (font, text)); } +static PyObject *Method_PupMenu (PyObject *self, PyObject *args) +{ + char *text; + int maxrow = -1; + PyObject *ret; + + if (!PyArg_ParseTuple(args, "s|i", &text, &maxrow)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected a string and optionally an int as arguments"); + + if (maxrow >= 0) + ret = PyInt_FromLong (pupmenu_col (text, maxrow)); + else + ret = PyInt_FromLong (pupmenu (text)); + + if (ret) return ret; + + return EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create a PyInt"); +} + PyObject *Draw_Init (void) { PyObject *submodule, *dict; diff --git a/source/blender/python/api2_2x/Draw.h b/source/blender/python/api2_2x/Draw.h index c84cc91ff58..3fbac1de12e 100644 --- a/source/blender/python/api2_2x/Draw.h +++ b/source/blender/python/api2_2x/Draw.h @@ -123,8 +123,9 @@ static void exit_pydraw(SpaceText *st); static void exec_callback(SpaceText *st, PyObject *callback, PyObject *args); void BPY_spacetext_do_pywin_draw(SpaceText *st); static void spacetext_do_pywin_buttons(SpaceText *st, unsigned short event); -void BPY_spacetext_do_pywin_event(SpaceText *st, unsigned short event, short val); -int BPY_spacetext_is_pywin(SpaceText *st); +void BPY_spacetext_do_pywin_event(SpaceText *st, + unsigned short event, short val); +int BPY_spacetext_is_pywin(SpaceText *sc); static char Method_Exit_doc[] = "() - Exit the windowing interface"; @@ -278,6 +279,20 @@ NEW! - This function now returns the width of the drawn string."; static PyObject *Method_GetStringWidth (PyObject *self, PyObject *args); static PyObject *Method_Text (PyObject *self, PyObject *args); +static char Method_PupMenu_doc[] = +"(string, maxrow = None) - Display a pop-up menu at the screen.\n\ +The contents of the pop-up are specified through the 'string' argument,\n\ +like with Draw.Menu.\n\ +'maxrow' is an optional int to control how many rows the pop-up should have.\n\ +Options are followed by a format code and separated\n\ +by the '|' (pipe) character.\n\ +Valid format codes are\n\ + %t - The option should be used as the title\n\ + %xN - The option should set the integer N in the button value.\n\n\ +Ex: Draw.PupMenu('OK?%t|QUIT BLENDER') # should be familiar ..."; + +static PyObject *Method_PupMenu (PyObject *self, PyObject *args); + #define _MethodDef(func, prefix) \ {#func, prefix##_##func, METH_VARARGS, prefix##_##func##_doc} @@ -296,11 +311,9 @@ static struct PyMethodDef Draw_methods[] = { MethodDef(Scrollbar), MethodDef(Number), MethodDef(String), - MethodDef(GetStringWidth), - MethodDef(Text), - + MethodDef(PupMenu), MethodDef(Exit), MethodDef(Redraw), MethodDef(Draw), diff --git a/source/blender/python/api2_2x/NMesh.c b/source/blender/python/api2_2x/NMesh.c index db090b21462..a0ab4c668e6 100644 --- a/source/blender/python/api2_2x/NMesh.c +++ b/source/blender/python/api2_2x/NMesh.c @@ -886,12 +886,14 @@ static PyObject *NMesh_getVertexInfluences(PyObject *self, PyObject *args) Mesh *Mesh_fromNMesh(BPy_NMesh *nmesh) { Mesh *mesh = NULL; - mesh = add_mesh(); /* us == 1, should we zero it for all added objs ? */ + mesh = add_mesh(); if (!mesh) EXPP_ReturnPyObjError(PyExc_RuntimeError, "FATAL: could not create mesh object"); + mesh->id.us = 0; /* no user yet */ + G.totmesh++; convert_NMeshToMesh(mesh, nmesh); return mesh; @@ -905,11 +907,54 @@ PyObject *NMesh_link(PyObject *self, PyObject *args) return EXPP_ReturnPyErrorObj (PyExc_TypeError, "NMesh can only be linked to Objects"); - bl_obj->data = (PyObject *)self; do this function later */ + bl_obj->data = (PyObject *)self;*/ + +/* Better use object.link(nmesh), no need for this nmesh.link(object) */ return EXPP_incr_ret(Py_None); } +static PyObject *NMesh_getMode (BPy_NMesh *self) +{ + PyObject *attr = PyInt_FromLong (self->mode); + + if (attr) return attr; + + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "couldn't get NMesh.mode attribute"); +} + +static PyObject *NMesh_setMode (PyObject *self, PyObject *args) +{ + BPy_NMesh *nmesh = (BPy_NMesh *)self; + char *m[4] = {NULL, NULL, NULL, NULL}; + short i, mode = 0; + + if (!PyArg_ParseTuple(args, "|ssss", &m[0], &m[1], &m[2], &m[3])) + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "expected from none to 4 strings as argument(s)"); + + for (i = 0; i < 4; i++) { + if (!m[i]) break; + if (strcmp(m[i], "NoVNormalsFlip") == 0) + mode |= EXPP_NMESH_MODE_NOPUNOFLIP; + else if (strcmp(m[i], "TwoSided") == 0) + mode |= EXPP_NMESH_MODE_TWOSIDED; + else if (strcmp(m[i], "AutoSmooth") == 0) + mode |= EXPP_NMESH_MODE_AUTOSMOOTH; + else if (strcmp(m[i], "SubSurf") == 0) + mode |= EXPP_NMESH_MODE_SUBSURF; + else + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "unknown NMesh mode"); + } + + nmesh->mode = mode; + + Py_INCREF (Py_None); + return Py_None; +} + #undef MethodDef #define MethodDef(func) {#func, NMesh_##func, METH_VARARGS, NMesh_##func##_doc} @@ -925,6 +970,8 @@ static struct PyMethodDef NMesh_methods[] = MethodDef(insertKey), MethodDef(removeAllKeys), MethodDef(update), + {"getMode", (PyCFunction)NMesh_getMode, METH_NOARGS, NMesh_getMode_doc}, + MethodDef(setMode), {NULL, NULL} }; @@ -935,7 +982,10 @@ static PyObject *NMesh_getattr(PyObject *self, char *name) if (strcmp(name, "name") == 0) return EXPP_incr_ret(me->name); - else if (strcmp(name, "block_type") == 0) + else if (strcmp(name, "mode") == 0) + return PyInt_FromLong(me->mode); + + else if (strcmp(name, "block_type") == 0) /* for compatibility */ return PyString_FromString("NMesh"); else if (strcmp(name, "materials") == 0) @@ -948,7 +998,7 @@ static PyObject *NMesh_getattr(PyObject *self, char *name) if (me->mesh) { return PyInt_FromLong(me->mesh->id.us); } - else { // it's a free mesh: + else { /* it's a free mesh: */ return Py_BuildValue("i", 0); } } @@ -977,6 +1027,20 @@ static int NMesh_setattr(PyObject *self, char *name, PyObject *v) me->name = EXPP_incr_ret(v); } + else if (!strcmp(name, "mode")) { + short mode; + + if (!PyInt_Check(v)) + return EXPP_ReturnIntError (PyExc_TypeError, + "expected int argument"); + + mode = (short)PyInt_AsLong(v); + if (mode >= 0) me->mode = mode; + else + return EXPP_ReturnIntError (PyExc_ValueError, + "expected positive int argument"); + } + else if (!strcmp(name, "verts") || !strcmp(name, "faces") || !strcmp(name, "materials")) { @@ -1058,7 +1122,7 @@ static BPy_NMFace *nmface_from_data(BPy_NMesh *mesh, int vidxs[4], newf->image = NULL; newf->uv = PyList_New(0); } - + newf->mat_nr = mat_nr; newf->smooth = flag & ME_SMOOTH; @@ -1142,7 +1206,7 @@ static PyObject *new_NMesh_internal(Mesh *oldmesh, { BPy_NMesh *me = PyObject_NEW (BPy_NMesh, &NMesh_Type); me->flags = 0; - me->object = NULL; /* not linked to any object in particular yet */ + me->object = NULL; /* not linked to any object yet */ if (!oldmesh) { me->name = EXPP_incr_ret(Py_None); @@ -1177,7 +1241,8 @@ static PyObject *new_NMesh_internal(Mesh *oldmesh, else { me->name = PyString_FromString(oldmesh->id.name+2); me->mesh = oldmesh; - + me->mode = oldmesh->flag; /* yes, we save the mesh flags in nmesh->mode */ + mfaceints = NULL; msticky = oldmesh->msticky; mverts = oldmesh->mvert; @@ -1235,7 +1300,22 @@ PyObject *new_NMesh(Mesh *oldmesh) static PyObject *M_NMesh_New(PyObject *self, PyObject *args) { - return new_NMesh(NULL); + char *name = NULL; + PyObject *ret = NULL; + + if (!PyArg_ParseTuple(args, "|s", &name)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected nothing or a string as argument"); + + ret = new_NMesh(NULL); + + if (ret && name) { + BPy_NMesh *nmesh = (BPy_NMesh *)ret; + Py_DECREF (nmesh->name); + nmesh->name = PyString_FromString(name); + } + + return ret; } static PyObject *M_NMesh_GetRaw(PyObject *self, PyObject *args) @@ -1256,6 +1336,8 @@ static PyObject *M_NMesh_GetRaw(PyObject *self, PyObject *args) return new_NMesh(oldmesh); } +/* Note: NMesh.GetRawFromObject gets the display list mesh from Blender: + * the vertices are already transformed / deformed. */ static PyObject *M_NMesh_GetRawFromObject(PyObject *self, PyObject *args) { char *name; @@ -1285,7 +1367,7 @@ static PyObject *M_NMesh_GetRawFromObject(PyObject *self, PyObject *args) nmesh = new_NMesh(me); } -/* hack: to mark that (deformed) mesh is readonly, so the update function +/* @hack: to mark that (deformed) mesh is readonly, so the update function * will not try to write it. */ ((BPy_NMesh *) nmesh)->mesh = 0; @@ -1586,6 +1668,9 @@ static int convert_NMeshToMesh (Mesh *mesh, BPy_NMesh *nmesh) mesh->tface = NULL; mesh->mat = NULL; + /* Minor note: we used 'mode' because 'flag' was already used internally by nmesh */ + mesh->flag = nmesh->mode; + /*@ material assignment moved to PutRaw */ mesh->totvert = PySequence_Length(nmesh->verts); if (mesh->totvert) { @@ -1723,18 +1808,30 @@ static PyObject *M_NMesh_PutRaw(PyObject *self, PyObject *args) if (name) mesh = (Mesh *)GetIdFromList(&(G.main->mesh), name); - - if(!mesh || mesh->id.us == 0) { + + if (!mesh) { ob = add_object(OB_MESH); + if (!ob) { PyErr_SetString(PyExc_RuntimeError, - "Fatal: could not create mesh object"); + "Fatal: could not create mesh object"); + return 0; + } + + mesh = (Mesh *)ob->data; + } + + else if (mesh->id.us == 0) { + ob = add_object(OB_EMPTY); /* we already have a mesh */ + + if (!ob) { + PyErr_SetString(PyExc_RuntimeError, + "Fatal: could not create mesh object"); return 0; } - if (mesh) - set_mesh(ob, mesh); - else - mesh = (Mesh *)ob->data; + + ob->type = OB_MESH; + set_mesh(ob, mesh); /* also does id.us++ */ } if (name) new_id(&(G.main->mesh), &mesh->id, name); @@ -1752,7 +1849,7 @@ static PyObject *M_NMesh_PutRaw(PyObject *self, PyObject *args) if (!during_script()) allqueue(REDRAWVIEW3D, 0); - // OK...this requires some explanation: + // @OK...this requires some explanation: // Materials can be assigned two ways: // a) to the object data (in this case, the mesh) // b) to the Object @@ -1791,8 +1888,6 @@ static PyObject *M_NMesh_PutRaw(PyObject *self, PyObject *args) {#func, M_NMesh_##func, METH_VARARGS, M_NMesh_##func##_doc} static struct PyMethodDef M_NMesh_methods[] = { -/*@ These should be: Mesh.Col, Mesh.Vert, Mesh.Face in fure */ -/* -- for ownership reasons */ MethodDef(Col), MethodDef(Vert), MethodDef(Face), @@ -1803,6 +1898,23 @@ static struct PyMethodDef M_NMesh_methods[] = { {NULL, NULL} }; +static PyObject *M_NMesh_Modes (void) +{ + PyObject *Modes = M_constant_New(); + + if (Modes) { + BPy_constant *d = (BPy_constant *)Modes; + + constant_insert(d, "NOVNORMALSFLIP", + PyInt_FromLong(EXPP_NMESH_MODE_NOPUNOFLIP)); + constant_insert(d, "TWOSIDED", PyInt_FromLong(EXPP_NMESH_MODE_TWOSIDED)); + constant_insert(d, "AUTOSMOOTH",PyInt_FromLong(EXPP_NMESH_MODE_AUTOSMOOTH)); + constant_insert(d, "SUBSURF", PyInt_FromLong(EXPP_NMESH_MODE_SUBSURF)); + } + + return Modes; +} + #undef EXPP_ADDCONST #define EXPP_ADDCONST(dict, name) \ constant_insert(dict, #name, PyInt_FromLong(TF_##name)) @@ -1868,6 +1980,7 @@ PyObject *NMesh_Init (void) { PyObject *submodule; + PyObject *Modes = M_NMesh_Modes (); PyObject *FaceFlags = M_NMesh_FaceFlagsDict (); PyObject *FaceModes = M_NMesh_FaceModesDict (); PyObject *FaceTranspModes = M_NMesh_FaceTranspModesDict (); @@ -1879,10 +1992,11 @@ PyObject *NMesh_Init (void) submodule = Py_InitModule3("Blender.NMesh", M_NMesh_methods, M_NMesh_doc); - if (FaceFlags) PyModule_AddObject (submodule, "FaceFlags" , FaceFlags); - if (FaceModes) PyModule_AddObject (submodule, "FaceModes" , FaceModes); + if (Modes) PyModule_AddObject (submodule, "Modes", Modes); + if (FaceFlags) PyModule_AddObject (submodule, "FaceFlags", FaceFlags); + if (FaceModes) PyModule_AddObject (submodule, "FaceModes", FaceModes); if (FaceTranspModes) - PyModule_AddObject (submodule, "FaceTranspModes" , FaceTranspModes); + PyModule_AddObject (submodule, "FaceTranspModes", FaceTranspModes); g_nmeshmodule = submodule; return submodule; @@ -1904,7 +2018,7 @@ int NMesh_CheckPyObject (PyObject *pyobj) return (pyobj->ob_type == &NMesh_Type); } -Mesh *NMesh_FromPyObject (PyObject *pyobj, Object *ob) +Mesh *Mesh_FromPyObject (PyObject *pyobj, Object *ob) { if (pyobj->ob_type == &NMesh_Type) { Mesh *mesh; @@ -1922,6 +2036,9 @@ Mesh *NMesh_FromPyObject (PyObject *pyobj, Object *ob) nmesh->object = ob; /* linking for vgrouping methods */ + if (nmesh->name && nmesh->name != Py_None) + new_id(&(G.main->mesh), &mesh->id, PyString_AsString(nmesh->name)); + mesh_update(mesh); return mesh; } diff --git a/source/blender/python/api2_2x/NMesh.h b/source/blender/python/api2_2x/NMesh.h index 88c06cd042f..e0b9f54fe5e 100644 --- a/source/blender/python/api2_2x/NMesh.h +++ b/source/blender/python/api2_2x/NMesh.h @@ -69,6 +69,12 @@ #include "gen_utils.h" #include "modules.h" +/* EXPP Mesh defines */ + +#define EXPP_NMESH_MODE_NOPUNOFLIP ME_NOPUNOFLIP +#define EXPP_NMESH_MODE_TWOSIDED ME_TWOSIDED +#define EXPP_NMESH_MODE_AUTOSMOOTH ME_AUTOSMOOTH +#define EXPP_NMESH_MODE_SUBSURF ME_SUBSURF /* EXPP PyType Objects */ @@ -151,11 +157,14 @@ bone name and the weight."; static char NMesh_update_doc[] = "(recalc_normals = 0) - updates the Mesh.\n\ if recalc_normals is given and is equal to 1, normal vectors are recalculated."; -/* -static char NMesh_asMesh_doc[] = "returns free Mesh datablock object from NMesh"; -static char NMesh_link_doc[] = "(object) - Links NMesh data with Object 'object'"; -*/ +static char NMesh_getMode_doc[] = +"() - get the mode flags of this nmesh as an or'ed int value."; + +static char NMesh_setMode_doc[] = +"(none to 4 strings) - set the mode flags of this nmesh.\n\ +() - unset all flags."; + static char M_NMesh_New_doc[] = "() - returns a new, empty NMesh mesh object\n"; @@ -213,12 +222,13 @@ typedef struct { typedef struct { PyObject_HEAD Mesh *mesh; - Object *object; /* object the mesh is linked to (can be NULL) */ + Object *object; /* for vertex grouping info, since it's stored on the object */ PyObject *name; PyObject *materials; PyObject *verts; PyObject *faces; int sel_face; /*@ XXX remove */ + short mode; /* see the EXPP_NMESH_* defines in the beginning of this file */ char flags; #define NMESH_HASMCOL 1<<0 diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 7f2cbe13ce3..c9dc788b45a 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -97,6 +97,8 @@ static PyObject *Object_getName (BPy_Object *self); static PyObject *Object_getParent (BPy_Object *self); static PyObject *Object_getTracked (BPy_Object *self); static PyObject *Object_getType (BPy_Object *self); +static PyObject *Object_getBoundBox (BPy_Object *self); +static PyObject *Object_makeDisplayList (BPy_Object *self); static PyObject *Object_link (BPy_Object *self, PyObject *args); static PyObject *Object_makeParent (BPy_Object *self, PyObject *args); static PyObject *Object_materialUsage (BPy_Object *self, PyObject *args); @@ -148,6 +150,12 @@ e.g. Mesh"}, "Returns the object's tracked object"}, {"getType", (PyCFunction)Object_getType, METH_NOARGS, "Returns type of string of Object"}, + {"getBoundBox", (PyCFunction)Object_getBoundBox, METH_NOARGS, + "Returns the object's bounding box"}, + {"makeDisplayList", (PyCFunction)Object_makeDisplayList, METH_NOARGS, + "Update this object's Display List. Some changes like turning \n\ +'SubSurf' on for a mesh need this method (followed by a Redraw) to \n\ +show the changes on the 3d window."}, {"link", (PyCFunction)Object_link, METH_VARARGS, "Links Object with data provided in the argument. The data must \n\ match the Object's type, so you cannot link a Lamp to a Mesh type object."}, @@ -320,55 +328,6 @@ PyObject *M_Object_New(PyObject *self, PyObject *args) object->gameflag = OB_PROP; object->lay = 1; // Layer, by default visible - - switch(type) - { - case OB_ARMATURE: - /* TODO: Do we need to add something to G? (see the OB_LAMP case) */ - object->data = add_armature(); - break; - case OB_CAMERA: - /* TODO: Do we need to add something to G? (see the OB_LAMP case) */ - object->data = add_camera(); - break; - case OB_CURVE: - object->data = add_curve(OB_CURVE); - G.totcurve++; - break; - case OB_LAMP: - object->data = add_lamp(); - G.totlamp++; - break; - case OB_MESH: - object->data = add_mesh(); - G.totmesh++; - break; - - /* TODO the following types will be supported later - case OB_SURF: - object->data = add_curve(OB_SURF); - G.totcurve++; - break; - case OB_FONT: - object->data = add_curve(OB_FONT); - break; - case OB_MBALL: - object->data = add_mball(); - break; - case OB_IKA: - object->data = add_ika(); - object->dt = OB_WIRE; - break; - case OB_LATTICE: - object->data = (void *)add_lattice(); - object->dt = OB_WIRE; - break; - case OB_WAVE: - object->data = add_wave(); - break; - */ - } - G.totobj++; /* Create a Python object from it. */ @@ -534,8 +493,8 @@ PyObject *Object_Init (void) static PyObject *Object_buildParts (BPy_Object *self) { void build_particle_system(Object *ob); - struct Object *obj = self->object; - build_particle_system( obj); + struct Object *obj = self->object; + build_particle_system( obj); Py_INCREF (Py_None); return (Py_None); } @@ -572,49 +531,98 @@ static PyObject *Object_clrParent (BPy_Object *self, PyObject *args) static PyObject *Object_getData (BPy_Object *self) { PyObject * data_object; + Object * object = self->object; /* If there's no data associated to the Object, then there's nothing to */ /* return. */ - if (self->object->data == NULL) + if (object->data == NULL) { - Py_INCREF (Py_None); - return (Py_None); + switch(object->type) + { + case OB_ARMATURE: + /* TODO: Do we need to add something to G? (see the OB_LAMP case) */ + object->data = add_armature(); + break; + case OB_CAMERA: + /* TODO: Do we need to add something to G? (see the OB_LAMP case) */ + object->data = add_camera(); + break; + case OB_CURVE: + object->data = add_curve(OB_CURVE); + G.totcurve++; + break; + case OB_LAMP: + object->data = add_lamp(); + G.totlamp++; + break; + case OB_MESH: + object->data = add_mesh(); + G.totmesh++; + break; + + /* TODO the following types will be supported later + case OB_SURF: + object->data = add_curve(OB_SURF); + G.totcurve++; + break; + case OB_FONT: + object->data = add_curve(OB_FONT); + break; + case OB_MBALL: + object->data = add_mball(); + break; + case OB_IKA: + object->data = add_ika(); + object->dt = OB_WIRE; + break; + case OB_LATTICE: + object->data = (void *)add_lattice(); + object->dt = OB_WIRE; + break; + case OB_WAVE: + object->data = add_wave(); + break; + */ + default: + Py_INCREF (Py_None); + return (Py_None); + } } data_object = NULL; - switch (self->object->type) + switch (object->type) { case OB_ARMATURE: - data_object = Armature_CreatePyObject (self->object->data); + data_object = Armature_CreatePyObject (object->data); break; case OB_CAMERA: - data_object = Camera_CreatePyObject (self->object->data); + data_object = Camera_CreatePyObject (object->data); break; case OB_CURVE: - data_object = Curve_CreatePyObject (self->object->data); + data_object = Curve_CreatePyObject (object->data); break; case ID_IM: - data_object = Image_CreatePyObject (self->object->data); + data_object = Image_CreatePyObject (object->data); break; case ID_IP: - data_object = Ipo_CreatePyObject (self->object->data); + data_object = Ipo_CreatePyObject (object->data); break; case OB_LAMP: - data_object = Lamp_CreatePyObject (self->object->data); + data_object = Lamp_CreatePyObject (object->data); break; case ID_MA: break; case OB_MESH: - data_object = NMesh_CreatePyObject (self->object->data, self->object); + data_object = NMesh_CreatePyObject (object->data, object); break; case ID_OB: - data_object = Object_CreatePyObject (self->object->data); + data_object = Object_CreatePyObject (object->data); break; case ID_SCE: break; case ID_TXT: - data_object = Text_CreatePyObject (self->object->data); + data_object = Text_CreatePyObject (object->data); break; case ID_WO: break; @@ -781,6 +789,70 @@ static PyObject *Object_getType (BPy_Object *self) } } +static PyObject *Object_getBoundBox (BPy_Object *self) +{ + int i; + float *vec = NULL; + PyObject *vector, *bbox; + + if (!self->object->data) + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "This object isn't linked to any object data (mesh, curve, etc) yet"); + + if (!self->object->bb) { + Mesh *me; + Curve *curve; + switch (self->object->type) { + case OB_MESH: + me = self->object->data; + if (!me->bb) tex_space_mesh(me); + vec = (float *)me->bb->vec; + break; + case OB_CURVE: + case OB_FONT: + case OB_SURF: + curve = self->object->data; + if (!curve->bb) tex_space_curve(curve); + vec = (float *)curve->bb->vec; + break; + default: + Py_INCREF (Py_None); + return Py_None; + } + } + else vec = (float *)self->object->bb->vec; + + if (!vec) + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "couldn't retrieve bounding box data"); + + bbox = PyList_New(8); + + if (!bbox) + return EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create pylist"); + + for (i = 0; i < 8; i++) { + vector = newVectorObject(vec, 3); + PyList_SET_ITEM(bbox, i, vector); + vec += 3; + } + + return bbox; +} + +static PyObject *Object_makeDisplayList (BPy_Object *self) +{ + Object *ob = self->object; + + if (ob->type == OB_FONT) text_to_curve(ob, 0); + + makeDispList(ob); + + Py_INCREF (Py_None); + return Py_None; +} + static PyObject *Object_link (BPy_Object *self, PyObject *args) { PyObject * py_data; @@ -801,7 +873,7 @@ static PyObject *Object_link (BPy_Object *self, PyObject *args) if (Curve_CheckPyObject (py_data)) data = (void *)Curve_FromPyObject (py_data); if (NMesh_CheckPyObject (py_data)) - data = (void *)NMesh_FromPyObject (py_data, self->object); + data = (void *)Mesh_FromPyObject (py_data, self->object); /* have we set data to something good? */ if( !data ) @@ -1216,20 +1288,20 @@ struct Object* Object_FromPyObject (PyObject *py_obj) /*****************************************************************************/ Object * GetObjectByName (char * name) { - Object * obj_iter; - - obj_iter = G.main->object.first; - while (obj_iter) - { - if (StringEqual (name, GetIdName (&(obj_iter->id)))) - { - return (obj_iter); - } - obj_iter = obj_iter->id.next; - } - - /* There is no object with the given name */ - return (NULL); + Object * obj_iter; + + obj_iter = G.main->object.first; + while (obj_iter) + { + if (StringEqual (name, GetIdName (&(obj_iter->id)))) + { + return (obj_iter); + } + obj_iter = obj_iter->id.next; + } + + /* There is no object with the given name */ + return (NULL); } /*****************************************************************************/ @@ -1329,22 +1401,22 @@ static PyObject* Object_getAttr (BPy_Object *obj, char *name) return (NULL); } if (StringEqual (name, "Layer")) - return (PyInt_FromLong(object->lay)); + return (PyInt_FromLong(object->lay)); if (StringEqual (name, "parent")) { if (object->parent) return (Object_CreatePyObject (object->parent)); else - { - Py_INCREF (Py_None); - return (Py_None); - } + { + Py_INCREF (Py_None); + return (Py_None); + } } if (StringEqual (name, "track")) - return (Object_CreatePyObject (object->track)); + return (Object_CreatePyObject (object->track)); if (StringEqual (name, "data")) - return (Object_getData (obj)); + return (Object_getData (obj)); if (StringEqual (name, "ipo")) { if (object->ipo == NULL) diff --git a/source/blender/python/api2_2x/Object.h b/source/blender/python/api2_2x/Object.h index c12a94c758e..43ef17caef5 100644 --- a/source/blender/python/api2_2x/Object.h +++ b/source/blender/python/api2_2x/Object.h @@ -43,6 +43,8 @@ #include #include #include +#include /* for makeDispList */ +#include /* for text_to_font */ #include #include #include diff --git a/source/blender/python/api2_2x/doc/Draw.py b/source/blender/python/api2_2x/doc/Draw.py index 17c363efb60..db29cf95d67 100644 --- a/source/blender/python/api2_2x/doc/Draw.py +++ b/source/blender/python/api2_2x/doc/Draw.py @@ -152,13 +152,14 @@ def PupMenu(name, maxrow = None): L{Menu}: options are followed by a format code and separated by the '|' character. Valid format codes are: - %t - The option should be used as the title of the pop-up; - - %l - insert a separating line; + - %l - insert a separating line (only works if 'maxrow' isn't given); - %xB{N} - Chosen this option, PupMenu should return the integer B{N}. Example:: - name = "OK?%t|QUIT BLENDER" # if no %xN integer is set, indices start from 1 + name = "OK?%t|QUIT BLENDER" # if no %xN int is set, indices start from 1 result = Draw.PupMenu(name) - if result: Draw.PupMenu("Do you really think we'd let scripts close Blender?%t|Yes|No") + if result: + Draw.PupMenu("Really?%t|Yes|No") @type name: string @param name: The format string to define the contents of the button. diff --git a/source/blender/python/api2_2x/doc/NMesh.py b/source/blender/python/api2_2x/doc/NMesh.py index d5a1de54f81..a07af9ae615 100644 --- a/source/blender/python/api2_2x/doc/NMesh.py +++ b/source/blender/python/api2_2x/doc/NMesh.py @@ -28,9 +28,15 @@ Example:: v.co[2] *= 2.5 me.update() # update the real mesh in Blender +@type Modes: readonly dictionary @type FaceFlags: readonly dictionary @type FaceModes: readonly dictionary @type FaceTranspModes: readonly dictionary +@var Modes: The available mesh modes. + - NOVNORMALSFLIP - no flipping of vertex normals during render. + - TWOSIDED - double sided mesh. + - AUTOSMOOTH - turn auto smoothing of faces "on". + - SUBSURF - turn Catmull-Clark subdivision of surfaces "on". @var FaceFlags: The available face selection flags. - SELECT - selected. - HIDE - hidden. @@ -89,9 +95,11 @@ def Face(vertexList = None): @return: A new NMFace object. """ -def New(): +def New(name = 'Mesh'): """ Create a new mesh object. + @type name: string + @param name: An optional name for the created mesh. rtype: NMesh @return: A new (B{empty}) NMesh object. """ @@ -223,6 +231,7 @@ class NMesh: @cvar verts: The list of NMesh vertices (NMVerts). @cvar users: The number of Objects using (linked to) this mesh. @cvar faces: The list of NMesh faces (NMFaces). + @cvar mode: The mode flags for this mesh. See L{setMode} """ def addMaterial(material): @@ -348,3 +357,23 @@ class NMesh: @param recalc_normals: If given and equal to 1, the vertex normals are recalculated. """ + + def getMode(): + """ + Get this mesh's mode flags. + @rtype: int + @return: Or'ed value. See L{Modes}. + """ + + def setMode(m = None, m1=None, m2=None, m3=None): + """ + Set the mode flags for this mesh. Given mode strings turn the mode "on". + Modes not passed in are turned "off", so setMode() (without arguments) + unsets all mode flags. + @type m: string + @param m: mode string. From none to 4 can be given: + - "NoVNormalsFlip" + - "TwoSided" + - "AutoSmooth" + - "SubSurf" + """ diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index 1c1838eb250..19fb6448e61 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -409,3 +409,34 @@ class Object: @type object: Blender Object @param object: A Blender Object of the same type. """ + + def getBoundBox(): + """ + Returns the bounding box of this object. This works for meshes (out of + edit mode) and curves. + @rtype: list of 8 (x,y,z) float coordinate vectors + @return: The coordinates of the 8 corners of the bounding box. + """ + + def makeDisplayList(): + """ + Updates this object's display list. Blender uses display lists to store + already transformed data (like a mesh with its vertices already modified + by coordinate transformations and armature deformation). If the object + isn't modified, there's no need to recalculate this data. This method is + here for the *few cases* where a script may need it, like when toggling + the "SubSurf" mode for a mesh: + Example:: + object = Blender.Object.Get("Sphere") + nmesh = object.getData() + nmesh.setMode("SubSurf") + nmesh.update() # don't forget to update! + object.makeDisplayList() + Blender.Window.RedrawAll() # and don't forget to redraw + + If you try this example without the line to update the display list, the + object will disappear from the screen until you press "SubSurf". + @warn: If after running your script objects disappear from the screen or + are not displayed correctly, try this method function. But if the script + works properly without it, there's no reason to use it. + """ diff --git a/source/blender/python/api2_2x/modules.h b/source/blender/python/api2_2x/modules.h index f2c7229d5cf..328a47eff52 100644 --- a/source/blender/python/api2_2x/modules.h +++ b/source/blender/python/api2_2x/modules.h @@ -86,7 +86,7 @@ PyObject * Types_Init (void); /* NMesh Data */ PyObject * NMesh_Init (void); PyObject * NMesh_CreatePyObject (Mesh *me, Object *ob); -Mesh * NMesh_FromPyObject (PyObject *pyobj, Object *ob); +Mesh * Mesh_FromPyObject (PyObject *pyobj, Object *ob); int NMesh_CheckPyObject (PyObject *pyobj); /* Material */ -- cgit v1.2.3