diff options
-rw-r--r-- | source/blender/python/BPY_interface.c | 30 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Lamp.h | 2 | ||||
-rw-r--r-- | source/blender/python/api2_2x/NMesh.c | 166 | ||||
-rw-r--r-- | source/blender/python/api2_2x/NMesh.h | 5 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Object.c | 4 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Scene.c | 6 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Window.c | 81 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Window.h | 18 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Draw.py | 29 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/NMesh.py | 16 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Window.py | 22 | ||||
-rw-r--r-- | source/blender/python/api2_2x/modules.h | 4 | ||||
-rw-r--r-- | source/blender/python/api2_2x/vector.c | 41 |
13 files changed, 329 insertions, 95 deletions
diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c index 684b5bdc520..7bf5351731b 100644 --- a/source/blender/python/BPY_interface.c +++ b/source/blender/python/BPY_interface.c @@ -24,7 +24,7 @@ * * This is a new part of Blender. * - * Contributor(s): Michel Selten, Willian P. Germano + * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -199,6 +199,30 @@ void init_syspath(void) syspath_append(p); /* append to module search path */ } + /* sds */ + /* bring in the site module so we can add site-package dirs to sys.path */ + mod = PyImport_ImportModule("site"); /* new ref */ + + if (mod) { + PyObject* item; + int size, index; + + /* get the value of 'sitedirs' from the module */ + d = PyModule_GetDict (mod); /* borrowed ref */ + p = PyDict_GetItemString (d, "sitedirs"); /* borrowed ref */ + + /* append each item in sitedirs list to path */ + size = PyList_Size (p); + + for (index = 0; index < size; index++) { + item = PySequence_GetItem (p, index); /* new ref */ + syspath_append (item); + } + + Py_DECREF(mod); + } + else PyErr_Clear(); + /* set sys.executable to the Blender exe */ mod = PyImport_ImportModule("sys"); /* new ref */ @@ -280,7 +304,9 @@ void BPY_Err_Handle(Text *text) v = PyObject_GetAttrString(err, "lineno"); g_script_error.lineno = PyInt_AsLong(v); Py_XDECREF(v); - return; + /* this avoids an abort in Python 2.3's garbage collecting: */ + PyErr_Clear(); + return; } else { PyErr_NormalizeException(&exception, &err, &tb); PyErr_Restore(exception, err, tb); // takes away reference! diff --git a/source/blender/python/api2_2x/Lamp.h b/source/blender/python/api2_2x/Lamp.h index 71f146247c7..cc3fe9e76b8 100644 --- a/source/blender/python/api2_2x/Lamp.h +++ b/source/blender/python/api2_2x/Lamp.h @@ -249,6 +249,8 @@ static PyMethodDef BPy_Lamp_methods[] = { "(int) - change Lamp halo step value"}, {"setEnergy", (PyCFunction)Lamp_setEnergy, METH_VARARGS, "(float) - change Lamp energy value"}, + {"setDist", (PyCFunction)Lamp_setDist, METH_VARARGS, + "(float) - change Lamp clipping distance value"}, {"setSpotSize", (PyCFunction)Lamp_setSpotSize, METH_VARARGS, "(float) - change Lamp spot size value"}, {"setSpotBlend", (PyCFunction)Lamp_setSpotBlend, METH_VARARGS, diff --git a/source/blender/python/api2_2x/NMesh.c b/source/blender/python/api2_2x/NMesh.c index b0a3233490c..db090b21462 100644 --- a/source/blender/python/api2_2x/NMesh.c +++ b/source/blender/python/api2_2x/NMesh.c @@ -150,30 +150,30 @@ static void NMFace_dealloc (PyObject *self) static PyObject *new_NMFace(PyObject *vertexlist) { BPy_NMFace *mf = PyObject_NEW (BPy_NMFace, &NMFace_Type); - PyObject *vlcopy; + PyObject *vlcopy; - if (vertexlist) { /* create a copy of the given vertex list */ - PyObject *item; - int i, len = PyList_Size(vertexlist); + if (vertexlist) { /* create a copy of the given vertex list */ + PyObject *item; + int i, len = PyList_Size(vertexlist); - vlcopy = PyList_New(len); + vlcopy = PyList_New(len); - if (!vlcopy) - return EXPP_ReturnPyObjError(PyExc_MemoryError, - "couldn't create PyList"); + if (!vlcopy) + return EXPP_ReturnPyObjError(PyExc_MemoryError, + "couldn't create PyList"); - for (i = 0; i < len; i++) { - item = PySequence_GetItem(vertexlist, i); /* PySequence increfs */ + for (i = 0; i < len; i++) { + item = PySequence_GetItem(vertexlist, i); /* PySequence increfs */ - if (item) - PyList_SET_ITEM(vlcopy, i, item); - else - return EXPP_ReturnPyObjError(PyExc_RuntimeError, - "couldn't get vertex from a PyList"); - } - } - else /* create an empty vertex list */ - vlcopy = PyList_New(0); + if (item) + PyList_SET_ITEM(vlcopy, i, item); + else + return EXPP_ReturnPyObjError(PyExc_RuntimeError, + "couldn't get vertex from a PyList"); + } + } + else /* create an empty vertex list */ + vlcopy = PyList_New(0); mf->v = vlcopy; mf->uv = PyList_New(0); @@ -581,33 +581,33 @@ static void NMesh_dealloc(PyObject *self) static PyObject *NMesh_addMaterial (PyObject *self, PyObject *args) { - BPy_NMesh *me = (BPy_NMesh *)self; - BPy_Material *pymat; - Material *mat; - PyObject *iter; - int i, len = 0; + BPy_NMesh *me = (BPy_NMesh *)self; + BPy_Material *pymat; + Material *mat; + PyObject *iter; + int i, len = 0; - if (!PyArg_ParseTuple (args, "O!", &Material_Type, &pymat)) - return EXPP_ReturnPyObjError (PyExc_TypeError, - "expected Blender Material PyObject"); + if (!PyArg_ParseTuple (args, "O!", &Material_Type, &pymat)) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected Blender Material PyObject"); - mat = pymat->material; - len = PyList_Size(me->materials); + mat = pymat->material; + len = PyList_Size(me->materials); - if (len >= 16) - return EXPP_ReturnPyObjError (PyExc_RuntimeError, - "object data material lists can't have more than 16 materials"); + if (len >= 16) + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "object data material lists can't have more than 16 materials"); - for (i = 0; i < len; i++) { - iter = PyList_GetItem(me->materials, i); - if (mat == Material_FromPyObject(iter)) - return EXPP_ReturnPyObjError (PyExc_AttributeError, - "material already in the list"); - } + for (i = 0; i < len; i++) { + iter = PyList_GetItem(me->materials, i); + if (mat == Material_FromPyObject(iter)) + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "material already in the list"); + } - PyList_Append(me->materials, (PyObject *)pymat); + PyList_Append(me->materials, (PyObject *)pymat); - return EXPP_incr_ret (Py_None); + return EXPP_incr_ret (Py_None); } static PyObject *NMesh_removeAllKeys (PyObject *self, PyObject *args) @@ -630,8 +630,8 @@ static PyObject *NMesh_removeAllKeys (PyObject *self, PyObject *args) static PyObject *NMesh_insertKey(PyObject *self, PyObject *args) { int fra = -1, oldfra = -1; - char *type = NULL; - short typenum; + char *type = NULL; + short typenum; BPy_NMesh *nm = (BPy_NMesh *)self; Mesh *mesh = nm->mesh; @@ -639,16 +639,16 @@ static PyObject *NMesh_insertKey(PyObject *self, PyObject *args) return EXPP_ReturnPyObjError (PyExc_TypeError, "expected nothing or an int and optionally a string as arguments"); - if (!type || !strcmp(type, "relative")) - typenum = 1; - else if (!strcmp(type, "absolute")) - typenum = 2; + if (!type || !strcmp(type, "relative")) + typenum = 1; + else if (!strcmp(type, "absolute")) + typenum = 2; else return EXPP_ReturnPyObjError (PyExc_AttributeError, "if given, type should be 'relative' or 'absolute'"); if (fra > 0) { - fra = EXPP_ClampInt(fra, 1, NMESH_FRAME_MAX); + fra = EXPP_ClampInt(fra, 1, NMESH_FRAME_MAX); oldfra = G.scene->r.cfra; G.scene->r.cfra = fra; } @@ -776,7 +776,7 @@ static PyObject *NMesh_hasVertexColours(PyObject *self, PyObject *args) static PyObject *NMesh_update(PyObject *self, PyObject *args) { - int recalc_normals = 0; + int recalc_normals = 0; BPy_NMesh *nmesh = (BPy_NMesh *)self; Mesh *mesh = nmesh->mesh; @@ -784,7 +784,7 @@ static PyObject *NMesh_update(PyObject *self, PyObject *args) return EXPP_ReturnPyObjError (PyExc_AttributeError, "expected nothing or an int (0 or 1) as argument"); - if (recalc_normals && recalc_normals != 1) + if (recalc_normals && recalc_normals != 1) return EXPP_ReturnPyObjError (PyExc_ValueError, "expected 0 or 1 as argument"); @@ -793,8 +793,8 @@ static PyObject *NMesh_update(PyObject *self, PyObject *args) convert_NMeshToMesh(mesh, nmesh); } else { nmesh->mesh = Mesh_fromNMesh(nmesh); - mesh = nmesh->mesh; - } + mesh = nmesh->mesh; + } if (recalc_normals) vertexnormals_mesh(mesh, 0); @@ -808,8 +808,8 @@ static PyObject *NMesh_update(PyObject *self, PyObject *args) */ test_object_materials((ID *)mesh); - if (nmesh->name && nmesh->name != Py_None) - new_id(&(G.main->mesh), &mesh->id, PyString_AsString(nmesh->name)); + if (nmesh->name && nmesh->name != Py_None) + new_id(&(G.main->mesh), &mesh->id, PyString_AsString(nmesh->name)); if (!during_script()) allqueue(REDRAWVIEW3D, 0); @@ -831,9 +831,9 @@ static PyObject *NMesh_getVertexInfluences(PyObject *self, PyObject *args) /* Get a reference to the mesh object wrapped in here. */ Mesh *me = ((BPy_NMesh*)self)->mesh; - if (!me) - return EXPP_ReturnPyObjError (PyExc_RuntimeError, - "unlinked nmesh: call its .update() method first"); + if (!me) + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "unlinked nmesh: call its .update() method first"); /* Parse the parameters: only on integer (vertex index) */ if (!PyArg_ParseTuple(args, "i", &index)) @@ -861,13 +861,13 @@ static PyObject *NMesh_getVertexInfluences(PyObject *self, PyObject *args) /*Add the weight and the name of the bone, which is used to identify it*/ - if (sweight->data) /* valid bone: return its name */ -/* PyList_SetItem(influence_list, i, + if (sweight->data) /* valid bone: return its name */ +/* PyList_SetItem(influence_list, i, Py_BuildValue("[sf]", sweight->data->name, sweight->weight)); - else // NULL bone: return Py_None instead - PyList_SetItem(influence_list, i, + else // NULL bone: return Py_None instead + PyList_SetItem(influence_list, i, Py_BuildValue("[Of]", Py_None, sweight->weight));*/ - PyList_Append(influence_list, + PyList_Append(influence_list, Py_BuildValue("[sf]", sweight->data->name, sweight->weight)); /* Next weight */ @@ -876,7 +876,7 @@ static PyObject *NMesh_getVertexInfluences(PyObject *self, PyObject *args) } else //influence_list = PyList_New(0); return EXPP_ReturnPyObjError (PyExc_IndexError, - "vertex index out of range"); + "vertex index out of range"); } else influence_list = PyList_New(0); @@ -1142,6 +1142,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 */ if (!oldmesh) { me->name = EXPP_incr_ret(Py_None); @@ -1289,7 +1290,7 @@ static PyObject *M_NMesh_GetRawFromObject(PyObject *self, PyObject *args) ((BPy_NMesh *) nmesh)->mesh = 0; - return nmesh; + return nmesh; } static void mvert_from_data(MVert *mv, MSticky *st, BPy_NMVert *from) @@ -1478,7 +1479,7 @@ void EXPP_unlink_mesh(Mesh *me) /* ... here we want to preserve mesh keys */ /* if users want to get rid of them, they can use mesh.removeAllKeys() */ /* - if(me->key) me->key->id.us--; + if(me->key) me->key->id.us--; me->key= 0; */ if(me->texcomesh) me->texcomesh= 0; @@ -1737,8 +1738,8 @@ static PyObject *M_NMesh_PutRaw(PyObject *self, PyObject *args) } if (name) new_id(&(G.main->mesh), &mesh->id, name); - else if (nmesh->name && nmesh->name != Py_None) - new_id(&(G.main->mesh), &mesh->id, PyString_AsString(nmesh->name)); + else if (nmesh->name && nmesh->name != Py_None) + new_id(&(G.main->mesh), &mesh->id, PyString_AsString(nmesh->name)); unlink_existingMeshData(mesh); convert_NMeshToMesh(mesh, nmesh); @@ -1773,6 +1774,7 @@ static PyObject *M_NMesh_PutRaw(PyObject *self, PyObject *args) // each bit indicates the binding PER MATERIAL if (ob) { // we created a new object + nmesh->object = ob; /* linking so vgrouping methods know which obj to work on */ NMesh_assignMaterials_toObject(nmesh, ob); EXPP_synchronizeMaterialLists (ob, ob->data); return Object_CreatePyObject(ob); @@ -1888,9 +1890,13 @@ PyObject *NMesh_Init (void) /* These are needed by Object.c */ -PyObject *NMesh_CreatePyObject (Mesh *me) +PyObject *NMesh_CreatePyObject (Mesh *me, Object *ob) { - return new_NMesh (me); + BPy_NMesh *nmesh = (BPy_NMesh *)new_NMesh (me); + + if (nmesh) nmesh->object = ob; /* linking nmesh and object for vgrouping methods */ + + return (PyObject *)nmesh; } int NMesh_CheckPyObject (PyObject *pyobj) @@ -1898,13 +1904,27 @@ int NMesh_CheckPyObject (PyObject *pyobj) return (pyobj->ob_type == &NMesh_Type); } -Mesh *NMesh_FromPyObject (PyObject *pyobj) +Mesh *NMesh_FromPyObject (PyObject *pyobj, Object *ob) { if (pyobj->ob_type == &NMesh_Type) { - Mesh *me = Mesh_fromNMesh ((BPy_NMesh *)pyobj); - mesh_update(me); - return me; - } + Mesh *mesh; + BPy_NMesh *nmesh = (BPy_NMesh *)pyobj; + + if (nmesh->mesh) { + mesh = nmesh->mesh; + unlink_existingMeshData(mesh); + convert_NMeshToMesh(mesh, nmesh); + } + else { + nmesh->mesh = Mesh_fromNMesh(nmesh); + mesh = nmesh->mesh; + } + + nmesh->object = ob; /* linking for vgrouping methods */ + + mesh_update(mesh); + return mesh; + } return NULL; } diff --git a/source/blender/python/api2_2x/NMesh.h b/source/blender/python/api2_2x/NMesh.h index 088cca164f3..88c06cd042f 100644 --- a/source/blender/python/api2_2x/NMesh.h +++ b/source/blender/python/api2_2x/NMesh.h @@ -79,6 +79,8 @@ PyTypeObject NMCol_Type; extern PyTypeObject Image_Type; +struct BPy_Object; + /* Globals */ static PyObject *g_nmeshmodule = NULL; @@ -211,11 +213,12 @@ typedef struct { typedef struct { PyObject_HEAD Mesh *mesh; + Object *object; /* object the mesh is linked to (can be NULL) */ PyObject *name; PyObject *materials; PyObject *verts; PyObject *faces; - int sel_face; /*@ XXX remove */ + int sel_face; /*@ XXX remove */ 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 9bc043b63c9..7f2cbe13ce3 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -606,7 +606,7 @@ static PyObject *Object_getData (BPy_Object *self) case ID_MA: break; case OB_MESH: - data_object = NMesh_CreatePyObject (self->object->data); + data_object = NMesh_CreatePyObject (self->object->data, self->object); break; case ID_OB: data_object = Object_CreatePyObject (self->object->data); @@ -801,7 +801,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); + data = (void *)NMesh_FromPyObject (py_data, self->object); /* have we set data to something good? */ if( !data ) diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index b6b55c2d50b..919fb1fb7a4 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -152,7 +152,7 @@ static PyMethodDef BPy_Scene_methods[] = { {"currentFrame", (PyCFunction)Scene_currentFrame, METH_VARARGS, "(frame) - If frame is given, the current frame is set and" "\nreturned in any case"}, - {"frameSettings", (PyCFunction)Scene_frameSettings, METH_NOARGS, + {"frameSettings", (PyCFunction)Scene_frameSettings, METH_VARARGS, "(start, end, current) - Sets or retrieves the Scene's frame" " settings.\nIf the frame arguments are specified, they are set. " "A tuple (start, end, current) is returned in any case."}, @@ -539,6 +539,10 @@ static PyObject *Scene_update (BPy_Scene *self, PyObject *args) return EXPP_ReturnPyObjError (PyExc_TypeError, "expected nothing or int (0 or 1) argument"); +/* Under certain circunstances, sort_baselist *here* can crash Blender. + * A "RuntimeError: max recursion limit" happens when a scriptlink + * on frame change has scene.update(1). + * Investigate better how to avoid this. */ if (!full) sort_baselist (scene); diff --git a/source/blender/python/api2_2x/Window.c b/source/blender/python/api2_2x/Window.c index 02279db25d5..ad92b7d02ff 100644 --- a/source/blender/python/api2_2x/Window.c +++ b/source/blender/python/api2_2x/Window.c @@ -30,6 +30,7 @@ */ #include "Window.h" +#include "vector.h" /* Many parts of the code here come from the older bpython implementation * (file opy_window.c) */ @@ -210,6 +211,86 @@ static PyObject *M_Window_GetCursorPos(PyObject *self) } /*****************************************************************************/ +/* Function: M_Window_SetCursorPos */ +/* Python equivalent: Blender.Window.SetCursorPos */ +/*****************************************************************************/ +static PyObject *M_Window_SetCursorPos(PyObject *self, PyObject *args) +{ + int ok = 0; + float val[3]; + + if (PyObject_Length (args) == 3) + ok = PyArg_ParseTuple (args, "fff", &val[0], &val[1], &val[2]); + else + ok = PyArg_ParseTuple(args, "(fff)", &val[0], &val[1], &val[2]); + + if (!ok) + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected [f,f,f] or f,f,f as arguments"); + + if (G.vd && G.vd->localview) { + G.vd->cursor[0] = val[0]; + G.vd->cursor[1] = val[1]; + G.vd->cursor[2] = val[2]; + } + else { + G.scene->cursor[0] = val[0]; + G.scene->cursor[1] = val[1]; + G.scene->cursor[2] = val[2]; + } + + Py_INCREF (Py_None); + return Py_None; +} + +/*****************************************************************************/ +/* Function: M_Window_GetViewVector */ +/* Python equivalent: Blender.Window.GetViewVector */ +/*****************************************************************************/ +static PyObject *M_Window_GetViewVector(PyObject *self) +{ + float *vec = NULL; + PyObject *pylist; + + if (!G.vd) { + Py_INCREF (Py_None); + return Py_None; + } + + vec = G.vd->viewinv[2]; + + pylist = Py_BuildValue("[fff]", vec[0], vec[1], vec[2]); + + if (!pylist) + return (EXPP_ReturnPyObjError (PyExc_MemoryError, + "GetViewVector: couldn't create pylist")); + + return pylist; +} + +/*****************************************************************************/ +/* Function: M_Window_GetViewMatrix */ +/* Python equivalent: Blender.Window.GetViewMatrix */ +/*****************************************************************************/ +static PyObject *M_Window_GetViewMatrix(PyObject *self) +{ + PyObject *viewmat; + + if (!G.vd) { + Py_INCREF (Py_None); + return Py_None; + } + + viewmat = newMatrixObject (G.vd->viewmat); + + if (!viewmat) + return (EXPP_ReturnPyObjError (PyExc_MemoryError, + "GetViewMatrix: couldn't create matrix pyobject")); + + return viewmat; +} + +/*****************************************************************************/ /* Function: Window_Init */ /*****************************************************************************/ PyObject *Window_Init (void) diff --git a/source/blender/python/api2_2x/Window.h b/source/blender/python/api2_2x/Window.h index 525701228fe..c7b631a703a 100644 --- a/source/blender/python/api2_2x/Window.h +++ b/source/blender/python/api2_2x/Window.h @@ -69,6 +69,9 @@ static PyObject *M_Window_FileSelector (PyObject *self, PyObject *args); static PyObject *M_Window_ImageSelector (PyObject *self, PyObject *args); static PyObject *M_Window_DrawProgressBar (PyObject *self, PyObject *args); static PyObject *M_Window_GetCursorPos (PyObject *self); +static PyObject *M_Window_SetCursorPos (PyObject *self, PyObject *args); +static PyObject *M_Window_GetViewVector (PyObject *self); +static PyObject *M_Window_GetViewMatrix (PyObject *self); /*****************************************************************************/ /* The following string definitions are used for documentation strings. */ @@ -115,6 +118,15 @@ currently being done."; char M_Window_GetCursorPos_doc[] = "() - Get the current 3d cursor position as a list of three floats."; +char M_Window_SetCursorPos_doc[] = +"([f,f,f]) - Set the current 3d cursor position from a list of three floats."; + +char M_Window_GetViewVector_doc[] = +"() - Get the current 3d view vector as a list of three floats [x,y,z]."; + +char M_Window_GetViewMatrix_doc[] = +"() - Get the current 3d view matrix."; + /*****************************************************************************/ /* Python method structure definition for Blender.Window module: */ /*****************************************************************************/ @@ -132,6 +144,12 @@ struct PyMethodDef M_Window_methods[] = { M_Window_DrawProgressBar_doc}, {"GetCursorPos", (PyCFunction)M_Window_GetCursorPos, METH_NOARGS, M_Window_GetCursorPos_doc}, + {"SetCursorPos", M_Window_SetCursorPos, METH_VARARGS, + M_Window_SetCursorPos_doc}, + {"GetViewVector", (PyCFunction)M_Window_GetViewVector, METH_NOARGS, + M_Window_GetViewVector_doc}, + {"GetViewMatrix", (PyCFunction)M_Window_GetViewMatrix, METH_NOARGS, + M_Window_GetViewMatrix_doc}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/python/api2_2x/doc/Draw.py b/source/blender/python/api2_2x/doc/Draw.py index ffba6863213..17c363efb60 100644 --- a/source/blender/python/api2_2x/doc/Draw.py +++ b/source/blender/python/api2_2x/doc/Draw.py @@ -3,6 +3,8 @@ """ The Blender.Draw submodule. +B{New}: L{PupMenu}. + Draw ==== @@ -142,6 +144,30 @@ def Button(name, event, x, y, width, height, tooltip = None): is kept over the button). """ +def PupMenu(name, maxrow = None): + """ + Create a pop-up menu. + + The menu options are specified through the 'name' parameter, like with + 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; + - %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 + result = Draw.PupMenu(name) + if result: Draw.PupMenu("Do you really think we'd let scripts close Blender?%t|Yes|No") + + @type name: string + @param name: The format string to define the contents of the button. + @type maxrow: int + @param maxrow: The maximum number of rows for each column in the pop-up. + @rtype: int + @return: the chosen entry number or -1 if none was chosen. + """ + def Menu(name, event, x, y, width, height, default, tooltip = None): """ Create a new Menu Button object. @@ -150,6 +176,7 @@ def Menu(name, event, x, y, width, height, default, tooltip = None): I{followed} by a format code and separated by the '|' (pipe) character. Valid format codes are: - %t - The option should be used as the title; + - %l - Insert a separating line; - %xB{N} - The option should set the integer B{N} in the button value. Example:: @@ -159,7 +186,7 @@ def Menu(name, event, x, y, width, height, default, tooltip = None): # will appear as the default choice in the Menu. @type name: string - @param name: The string to display on the button. + @param name: The format string to define the contents of the button. @type event: int @param event: The event number to pass to the button event function when activated. diff --git a/source/blender/python/api2_2x/doc/NMesh.py b/source/blender/python/api2_2x/doc/NMesh.py index 99dbe9f3790..d5a1de54f81 100644 --- a/source/blender/python/api2_2x/doc/NMesh.py +++ b/source/blender/python/api2_2x/doc/NMesh.py @@ -164,6 +164,13 @@ class NMVert: @cvar uvco: The vertex texture "sticky" coordinates. @type index: int @cvar index: The vertex index, if owned by a mesh. + @warn: There are two kinds of uv texture coordinates in Blender: per vertex + ("sticky") and per face vertex (uv in L{NMFace}). In the first, there's + only one uv pair of coordinates for each vertex in the mesh. In the + second, for each face it belongs to, a vertex can have different uv + coordinates. This makes the per face option more flexible, since two + adjacent faces won't have to be mapped to a continuous region in an image: + each face can be independently mapped to any part of its texture. """ class NMFace: @@ -186,6 +193,15 @@ class NMFace: @cvar transp: Transparency mode bit vector (see L{NMesh.FaceTranspModes<FaceTranspModes>}). @cvar uv: List of per-face UV coordinates: [(u0, v0), (u1, v1), ...]. + @warn: Assigning uv textures to mesh faces in Blender works like this: + 1. Select your mesh. + 2. Enter face select mode (press f) and select at least some face(s). + 3. In the UV/Image Editor window, load / select an image. + 4. Play in both windows (better split the screen to see both at the same + time) until the uv coordinates are where you want them. Hint: in the + 3d window, the 'u' key opens a menu of default uv choices and the 'r' + key lets you rotate the uv coords. + 5. Leave face select mode (press f). """ def append(vertex): diff --git a/source/blender/python/api2_2x/doc/Window.py b/source/blender/python/api2_2x/doc/Window.py index bbdb28f4247..cac7c5d5e36 100644 --- a/source/blender/python/api2_2x/doc/Window.py +++ b/source/blender/python/api2_2x/doc/Window.py @@ -139,3 +139,25 @@ def GetCursorPos (): @rtype: list of three floats @return: the current position: [x, y, z]. """ +def SetCursorPos (coords): + """ + Change the 3d cursor position. Note: if visible, the 3d window must be + redrawn to display the change. This can be done with + L{Redraw}(L{Types}['VIEW3D']), for example. + @type coords: 3 floats or a list of 3 floats + @param coords: The new x, y, z coordinates. + """ + +def GetViewVector (): + """ + Get the current 3d view vector. + @rtype: list of three floats + @return: the current vector: [x, y, z]. + """ + +def GetViewMatrix (): + """ + Get the current 3d view matrix. + @rtype: 4x4 float matrix + @return: the current matrix. + """ diff --git a/source/blender/python/api2_2x/modules.h b/source/blender/python/api2_2x/modules.h index 28c104a88dd..f2c7229d5cf 100644 --- a/source/blender/python/api2_2x/modules.h +++ b/source/blender/python/api2_2x/modules.h @@ -85,8 +85,8 @@ PyObject * Types_Init (void); /* NMesh Data */ PyObject * NMesh_Init (void); -PyObject * NMesh_CreatePyObject (Mesh *me); -Mesh * NMesh_FromPyObject (PyObject *pyobj); +PyObject * NMesh_CreatePyObject (Mesh *me, Object *ob); +Mesh * NMesh_FromPyObject (PyObject *pyobj, Object *ob); int NMesh_CheckPyObject (PyObject *pyobj); /* Material */ diff --git a/source/blender/python/api2_2x/vector.c b/source/blender/python/api2_2x/vector.c index 1bc8d817cbc..d08775aa6a7 100644 --- a/source/blender/python/api2_2x/vector.c +++ b/source/blender/python/api2_2x/vector.c @@ -146,16 +146,31 @@ static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *se static PyObject *Vector_repr (VectorObject *self) { - char buffer[100]; + int i, maxindex = self->size - 1; + char ftoa[24]; + PyObject *str1, *str2; - if (self->size == 3) - sprintf (buffer, "[%.3f, %.3f, %.3f]\n", - self->vec[0], self->vec[1], self->vec[2]); - else /* assuming size == 4 */ - sprintf (buffer, "[%.3f, %.3f, %.3f, %.3f]\n", - self->vec[0], self->vec[1], self->vec[2], self->vec[3]); + str1 = PyString_FromString ("["); - return PyString_FromString (buffer); + for (i = 0; i < maxindex; i++) { + sprintf(ftoa, "%.3f, ", self->vec[i]); + str2 = PyString_FromString (ftoa); + if (!str1 || !str2) goto error; /* my first goto : ) */ + PyString_ConcatAndDel (&str1, str2); + } + + sprintf(ftoa, "%.3f]\n", self->vec[maxindex]); + str2 = PyString_FromString (ftoa); + if (!str1 || !str2) goto error; /* uh-oh, became a habit */ + PyString_ConcatAndDel (&str1, str2); + + if (str1) return str1; + +error: + Py_XDECREF (str1); + Py_XDECREF (str2); + return EXPP_ReturnPyObjError (PyExc_MemoryError, + "couldn't create PyString!"); } static PySequenceMethods Vector_SeqMethods = @@ -193,10 +208,10 @@ PyObject *newVectorObject(float *vec, int size) vector_Type.ob_type = &PyType_Type; - self= PyObject_NEW(VectorObject, &vector_Type); - - self->vec= vec; - self->size= size; - + self = PyObject_NEW(VectorObject, &vector_Type); + + self->vec = vec; + self->size = size; + return (PyObject*) self; } |