From fe07b232b7e7e80569733de2b42e391874de6477 Mon Sep 17 00:00:00 2001 From: Willian Padovani Germano Date: Wed, 30 Jul 2003 21:15:41 +0000 Subject: * got rid of a warning in editipo.c: changed "get_ipo(key, ..." to "get_ipo((ID *)key, ..." in line 107. * changed insert_meshkey(Mesh *me) to insert_meshkey(Mesh *me, short offline): To call this function from a script, so that it doesn't pop the "relative / absolute" dialog window when the "offline" arg is non-zero. Exppython: * NMesh module: - Added method NMesh.addMaterial(mat) to the NMesh module: alternative safer (aka slower) way to add materials. - Added optional arg to NMesh_update(): if given and equal to 1, the mesh normals are recalculated. - Fixed NMesh.getVertexInfluences: it was segfaulting when a NULL bone was linked to the vertex. Thanks to Jiba on the bf-python mailing list for bug report and sample .blend file. Also made this method give an IndexError when the vertex index is out of range. * Material module: Added specR, specG, specB vars for compatibility with the 2.25 API. Pointed by Manuel Bastioni. * Image module: Exposed image width, height and depth parameters. From a suggestion by jms. * BPython Ref Doc: - Small updates to reflect the above additions. - Added info for the Bone type in the Armature doc. --- source/blender/include/BIF_editkey.h | 2 +- source/blender/python/api2_2x/Bone.c | 2 +- source/blender/python/api2_2x/Image.c | 57 +++++++++- source/blender/python/api2_2x/Material.c | 28 +++++ source/blender/python/api2_2x/Material.h | 1 + source/blender/python/api2_2x/NMesh.c | 103 ++++++++++++++---- source/blender/python/api2_2x/NMesh.h | 17 ++- source/blender/python/api2_2x/doc/Armature.py | 147 ++++++++++++++++++++++++++ source/blender/python/api2_2x/doc/Image.py | 18 +++- source/blender/python/api2_2x/doc/NMesh.py | 29 ++++- source/blender/src/editipo.c | 2 +- source/blender/src/editkey.c | 12 ++- 12 files changed, 376 insertions(+), 42 deletions(-) diff --git a/source/blender/include/BIF_editkey.h b/source/blender/include/BIF_editkey.h index 0a9b14dee16..46f9d8e2aa4 100644 --- a/source/blender/include/BIF_editkey.h +++ b/source/blender/include/BIF_editkey.h @@ -42,7 +42,7 @@ struct Curve; void mesh_to_key(struct Mesh *me, struct KeyBlock *kb); void key_to_mesh(struct KeyBlock *kb, struct Mesh *me); -void insert_meshkey(struct Mesh *me); +void insert_meshkey(struct Mesh *me, short offline); void latt_to_key(struct Lattice *lt, struct KeyBlock *kb); void key_to_latt(struct KeyBlock *kb, struct Lattice *lt); diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c index c088662b750..d94623f5e3f 100644 --- a/source/blender/python/api2_2x/Bone.c +++ b/source/blender/python/api2_2x/Bone.c @@ -109,7 +109,7 @@ static PyMethodDef BPy_Bone_methods[] = { {"getQuat", (PyCFunction)Bone_getQuat, METH_NOARGS, "() - return Bone quat"}, {"getParent", (PyCFunction)Bone_hasParent, METH_NOARGS, "() - return the parent bone of this one if it exists." - " Otherwise raise an error. Check this condition with the " + " None if not found. You can check this condition with the " "hasParent() method."}, {"hasParent", (PyCFunction)Bone_hasParent, METH_NOARGS, "() - return true if bone has a parent"}, diff --git a/source/blender/python/api2_2x/Image.c b/source/blender/python/api2_2x/Image.c index a93de2ede5a..0a99c781e4d 100644 --- a/source/blender/python/api2_2x/Image.c +++ b/source/blender/python/api2_2x/Image.c @@ -34,7 +34,7 @@ #include #include #include - +#include /* for the IB_rect define */ #include "gen_utils.h" #include "Image.h" @@ -226,6 +226,8 @@ PyObject *Image_Init (void) /*****************************************************************************/ static PyObject *Image_getName(BPy_Image *self); static PyObject *Image_getFilename(BPy_Image *self); +static PyObject *Image_getSize(BPy_Image *self); +static PyObject *Image_getDepth(BPy_Image *self); static PyObject *Image_getXRep(BPy_Image *self); static PyObject *Image_getYRep(BPy_Image *self); static PyObject *Image_setName(BPy_Image *self, PyObject *args); @@ -241,6 +243,10 @@ static PyMethodDef BPy_Image_methods[] = { "() - Return Image object name"}, {"getFilename", (PyCFunction)Image_getFilename, METH_NOARGS, "() - Return Image object filename"}, + {"getSize", (PyCFunction)Image_getSize, METH_NOARGS, + "() - Return Image object [width, height] dimension in pixels"}, + {"getDepth", (PyCFunction)Image_getDepth, METH_NOARGS, + "() - Return Image object pixel depth"}, {"getXRep", (PyCFunction)Image_getXRep, METH_NOARGS, "() - Return Image object x repetition value"}, {"getYRep", (PyCFunction)Image_getYRep, METH_NOARGS, @@ -354,6 +360,47 @@ static PyObject *Image_getFilename(BPy_Image *self) "couldn't get Image.filename attribute")); } +static PyObject *Image_getSize(BPy_Image *self) +{ + PyObject *attr; + Image *image = self->image; + + if (!image->ibuf) /* if no image data available */ + load_image(image, IB_rect, "", 0); /* loading it */ + + if (!image->ibuf) /* didn't work */ + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "couldn't load image data in Blender"); + + attr = Py_BuildValue("[hh]", image->ibuf->x, image->ibuf->y); + + if (attr) return attr; + + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "couldn't get Image.size attribute"); +} + +static PyObject *Image_getDepth(BPy_Image *self) +{ + PyObject *attr; + Image *image = self->image; + + if (!image->ibuf) /* if no image data available */ + load_image(image, IB_rect, "", 0); /* loading it */ + + if (!image->ibuf) /* didn't work */ + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "couldn't load image data in Blender"); + + attr = Py_BuildValue("h", image->ibuf->depth); + + if (attr) return attr; + + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "couldn't get Image.depth attribute"); +} + + static PyObject *Image_getXRep(BPy_Image *self) { PyObject *attr = PyInt_FromLong(self->image->xrep); @@ -441,14 +488,18 @@ static PyObject *Image_getAttr (BPy_Image *self, char *name) attr = PyString_FromString(self->image->id.name+2); else if (strcmp(name, "filename") == 0) attr = PyString_FromString(self->image->name); + else if (strcmp(name, "size") == 0) + attr = Image_getSize(self); + else if (strcmp(name, "depth") == 0) + attr = Image_getDepth(self); else if (strcmp(name, "xrep") == 0) attr = PyInt_FromLong(self->image->xrep); else if (strcmp(name, "yrep") == 0) attr = PyInt_FromLong(self->image->yrep); else if (strcmp(name, "__members__") == 0) - attr = Py_BuildValue("[s,s,s,s]", - "name", "filename", "xrep", "yrep"); + attr = Py_BuildValue("[s,s,s,s,s,s]", + "name", "filename", "size", "depth", "xrep", "yrep"); if (!attr) return (EXPP_ReturnPyObjError (PyExc_MemoryError, diff --git a/source/blender/python/api2_2x/Material.c b/source/blender/python/api2_2x/Material.c index ee66097994f..f51fd7c4b32 100644 --- a/source/blender/python/api2_2x/Material.c +++ b/source/blender/python/api2_2x/Material.c @@ -583,6 +583,16 @@ int Material_CheckPyObject (PyObject *pyobj) return (pyobj->ob_type == &Material_Type); } +/*****************************************************************************/ +/* Function: Material_FromPyObject */ +/* Description: This function returns the Blender material from the given */ +/* PyObject. */ +/*****************************************************************************/ +Material *Material_FromPyObject (PyObject *pyobj) +{ + return ((BPy_Material *)pyobj)->material; +} + /*****************************************************************************/ /* Description: Returns the object with the name specified by the argument */ /* name. Note that the calling function has to remove the first */ @@ -988,6 +998,12 @@ static PyObject *Material_setColorComponent(BPy_Material *self, char *key, self->material->g = value; else if (!strcmp(key, "B")) self->material->b = value; + else if (!strcmp(key, "specR")) + self->material->specr = value; + else if (!strcmp(key, "specG")) + self->material->specg = value; + else if (!strcmp(key, "specB")) + self->material->specb = value; return EXPP_incr_ret (Py_None); } @@ -1287,6 +1303,12 @@ static PyObject *Material_getAttr (BPy_Material *self, char *name) attr = PyFloat_FromDouble((double)self->material->g); else if (strcmp(name, "B") == 0) attr = PyFloat_FromDouble((double)self->material->b); + else if (strcmp(name, "specR") == 0) + attr = PyFloat_FromDouble((double)self->material->specr); + else if (strcmp(name, "specG") == 0) + attr = PyFloat_FromDouble((double)self->material->specg); + else if (strcmp(name, "specB") == 0) + attr = PyFloat_FromDouble((double)self->material->specb); else if (strcmp(name, "amb") == 0) attr = PyFloat_FromDouble((double)self->material->amb); else if (strcmp(name, "emit") == 0) @@ -1389,6 +1411,12 @@ static int Material_setAttr (BPy_Material *self, char *name, PyObject *value) error = Material_setColorComponent (self, "G", valtuple); else if (strcmp (name, "B") == 0) error = Material_setColorComponent (self, "B", valtuple); + else if (strcmp (name, "specR") == 0) + error = Material_setColorComponent (self, "specR", valtuple); + else if (strcmp (name, "specG") == 0) + error = Material_setColorComponent (self, "specG", valtuple); + else if (strcmp (name, "specB") == 0) + error = Material_setColorComponent (self, "specB", valtuple); else if (strcmp (name, "amb") == 0) error = Material_setAmb (self, valtuple); else if (strcmp (name, "emit") == 0) diff --git a/source/blender/python/api2_2x/Material.h b/source/blender/python/api2_2x/Material.h index 6fd4c596618..b5ce6a113ab 100644 --- a/source/blender/python/api2_2x/Material.h +++ b/source/blender/python/api2_2x/Material.h @@ -58,6 +58,7 @@ extern PyTypeObject Material_Type; /* The Material PyType Object */ /*****************************************************************************/ PyObject *M_Material_Init (void); PyObject *Material_CreatePyObject (Material *mat); +Material *Material_FromPyObject (PyObject *pyobj); int Material_CheckPyObject (PyObject *pyobj); /* Some functions needed by NMesh.c */ diff --git a/source/blender/python/api2_2x/NMesh.c b/source/blender/python/api2_2x/NMesh.c index 8dfa75a8566..aa7eeea0f6f 100644 --- a/source/blender/python/api2_2x/NMesh.c +++ b/source/blender/python/api2_2x/NMesh.c @@ -29,11 +29,10 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ -/* This file is opy_nmesh.c from bpython modified to work with the new - * implementation of the Blender Python API */ - #include "NMesh.h" +#define NMESH_FRAME_MAX 18000 + void mesh_update(Mesh *mesh) { edge_drawflags_mesh(mesh); @@ -551,10 +550,42 @@ static void NMesh_dealloc(PyObject *self) Py_DECREF(me->name); Py_DECREF(me->verts); Py_DECREF(me->faces); - + Py_DECREF(me->materials); + PyObject_DEL(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; + + 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); + + 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"); + } + + PyList_Append(me->materials, (PyObject *)pymat); + + return EXPP_incr_ret (Py_None); +} + static PyObject *NMesh_removeAllKeys (PyObject *self, PyObject *args) { BPy_NMesh *nm = (BPy_NMesh *)self; @@ -575,14 +606,25 @@ 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; BPy_NMesh *nm = (BPy_NMesh *)self; Mesh *mesh = nm->mesh; - if (!PyArg_ParseTuple(args, "|i", &fra)) + if (!PyArg_ParseTuple(args, "|is", &fra, &type)) return EXPP_ReturnPyObjError (PyExc_TypeError, - "expected int argument (or nothing)"); + "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; + 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); oldfra = G.scene->r.cfra; G.scene->r.cfra = fra; } @@ -591,7 +633,7 @@ static PyObject *NMesh_insertKey(PyObject *self, PyObject *args) return EXPP_ReturnPyObjError (PyExc_RuntimeError, "update this NMesh first with its .update() method"); - insert_meshkey(mesh); + insert_meshkey(mesh, typenum); if (fra > 0) G.scene->r.cfra = oldfra; @@ -710,17 +752,26 @@ static PyObject *NMesh_hasVertexColours(PyObject *self, PyObject *args) static PyObject *NMesh_update(PyObject *self, PyObject *args) { + int recalc_normals = 0; BPy_NMesh *nmesh = (BPy_NMesh *)self; Mesh *mesh = nmesh->mesh; + if (!PyArg_ParseTuple(args, "|i", &recalc_normals)) + return EXPP_ReturnPyObjError (PyExc_AttributeError, + "expected nothing or an int (0 or 1) as argument"); + if (mesh) { unlink_existingMeshData(mesh); convert_NMeshToMesh(mesh, nmesh); - mesh_update(mesh); - } else { + } else { nmesh->mesh = Mesh_fromNMesh(nmesh); } + if(recalc_normals == 1) + vertexnormals_mesh(mesh, 0); + + mesh_update(mesh); + nmesh_updateMaterials(nmesh); /**@ This is another ugly fix due to the weird material handling of blender. * it makes sure that object material lists get updated (by their length) @@ -737,7 +788,7 @@ static PyObject *NMesh_update(PyObject *self, PyObject *args) /** Implementation of the python method getVertexInfluence for an NMesh object. - * This method returns a list of pairs (string,float) with bone nemaes and + * This method returns a list of pairs (string,float) with bone names and * influences that this vertex receives. * @author Jordi Rovira i Bonet */ @@ -765,29 +816,36 @@ static PyObject *NMesh_getVertexInfluences(PyObject *self, PyObject *args) int i; MDeformWeight *sweight = NULL; - /* Number of bones influencig the vertex */ + /* Number of bones influencing the vertex */ int totinfluences=me->dvert[index].totweight; /* Build the list only with weights and names of the influent bones */ - influence_list = PyList_New(totinfluences); + /*influence_list = PyList_New(totinfluences);*/ + influence_list = PyList_New(0); - /* Get the reference of the first wwight structure */ + /* Get the reference of the first weight structure */ sweight = me->dvert[index].dw; for (i=0; idata);*/ - /*Add the weight and the name of the bone, which is used to identify it*/ - 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, + Py_BuildValue("[Of]", Py_None, sweight->weight));*/ + PyList_Append(influence_list, Py_BuildValue("[sf]", sweight->data->name, sweight->weight)); /* Next weight */ sweight++; } } - else influence_list = PyList_New(0); + else //influence_list = PyList_New(0); + return EXPP_ReturnPyObjError (PyExc_IndexError, + "vertex index out of range"); } else influence_list = PyList_New(0); @@ -804,7 +862,6 @@ Mesh *Mesh_fromNMesh(BPy_NMesh *nmesh) "FATAL: could not create mesh object"); convert_NMeshToMesh(mesh, nmesh); - mesh_update(mesh); return mesh; } @@ -833,6 +890,7 @@ static struct PyMethodDef NMesh_methods[] = MethodDef(getActiveFace), MethodDef(getSelectedFaces), MethodDef(getVertexInfluences), + MethodDef(addMaterial), MethodDef(insertKey), MethodDef(removeAllKeys), MethodDef(update), @@ -1811,8 +1869,11 @@ int NMesh_CheckPyObject (PyObject *pyobj) Mesh *NMesh_FromPyObject (PyObject *pyobj) { - if (pyobj->ob_type == &NMesh_Type) - return Mesh_fromNMesh ((BPy_NMesh *)pyobj); + if (pyobj->ob_type == &NMesh_Type) { + Mesh *me = Mesh_fromNMesh ((BPy_NMesh *)pyobj); + mesh_update(me); + return me; + } return NULL; } diff --git a/source/blender/python/api2_2x/NMesh.h b/source/blender/python/api2_2x/NMesh.h index 6f1fbf59596..088cca164f3 100644 --- a/source/blender/python/api2_2x/NMesh.h +++ b/source/blender/python/api2_2x/NMesh.h @@ -55,10 +55,12 @@ #include "BIF_space.h" #include "DNA_mesh_types.h" #include "DNA_key_types.h" +#include "DNA_listBase.h" #include "DNA_object_types.h" #include "DNA_material_types.h" #include "DNA_armature_types.h" #include "mydevice.h" +#include "BIF_editkey.h" /* insert_meshkey */ #include "Material.h" #include "Image.h" @@ -68,8 +70,6 @@ #include "modules.h" -void insert_meshkey(Mesh *me); /* defined in editkey.c */ - /* EXPP PyType Objects */ PyTypeObject NMesh_Type; @@ -107,9 +107,15 @@ static char M_NMesh_Vert_doc[] = "([x, y, z]) - Get a new vertice\n\n\ [x, y, z] Specify new coordinates"; +static char NMesh_addMaterial_doc[] = +"(material) - add a new Blender Material 'material' to this Mesh's materials\n\ +list."; + static char NMesh_insertKey_doc[] = -"(frame = None) - inserts a Mesh key at the given frame\n\ -if called without arguments, it inserts the key at the current Scene frame"; +"(frame = None, type = 'relative') - inserts a Mesh key at the given frame\n\ +if called without arguments, it inserts the key at the current Scene frame.\n\ +(type) - 'relative' or 'absolute'. Only relevant on the first call to this\n\ +function for each nmesh."; static char NMesh_removeAllKeys_doc[] = "() - removes all keys from this mesh\n\ @@ -141,7 +147,8 @@ specified by index. The list contains pairs with the \n\ bone name and the weight."; -static char NMesh_update_doc[] = "updates the Mesh"; +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"; diff --git a/source/blender/python/api2_2x/doc/Armature.py b/source/blender/python/api2_2x/doc/Armature.py index b57dc43a562..31c0833b4d6 100644 --- a/source/blender/python/api2_2x/doc/Armature.py +++ b/source/blender/python/api2_2x/doc/Armature.py @@ -74,3 +74,150 @@ class Armature: Set the Armature root bones (still unimplemented). @warn: This method wasn't implemented yet. """ + +class Bone: + """ + The Bone object + =============== + This object gives access to Bone-specific data in Blender. + @cvar name: The name of this Bone. + @cvar roll: This Bone's roll value. + @cvar head: This Bone's "head" ending position when in rest state. + @cvar tail: This Bone's "tail" ending position when in rest state. + @cvar loc: This Bone's location. + @cvar size: This Bone's size. + @cvar quat: This Bone's quaternion. + @cvar parent: The parent Bone. + @cvar children: The children bones. + """ + + def getName(): + """ + Get the name of this Bone. + @rtype: string + """ + + def getRoll(): + """ + Get the roll value. + @rtype: float + """ + + def getHead(): + """ + Get the "head" ending position. + @rtype: list of three floats + """ + + def getTail(): + """ + Get the "tail" ending position. + @rtype: list of three floats + """ + + def getLoc(): + """ + Get the location of this Bone. + @rtype: list of three floats + """ + + def getSize(): + """ + Get the size attribute. + @rtype: list of three floats + """ + + def getQuat(): + """ + Get this Bone's quaternion. + @rtype: list of four floats. + """ + + def hasParent(): + """ + True if this Bone has a parent Bone. + @rtype: true or false + """ + + def getParent(): + """ + Get this Bone's parent Bone, if available. + @rtype: Blender Bone + """ + + def getChildren(): + """ + Get this Bone's children Bones, if available. + @rtype: list of Blender Bones + """ + + def setName(name): + """ + Rename this Bone. + @type name: string + @param name: The new name. + """ + + def setRoll(roll): + """ + Set the roll value. + @type roll: float + @param roll: The new value. + """ + + def setHead(x,y,z): + """ + Set the "head" ending position. + @type x: float + @type y: float + @type z: float + @param x: The new x value. + @param y: The new y value. + @param z: The new z value. + """ + + def setTail(x,y,z): + """ + Set the "tail" ending position. + @type x: float + @type y: float + @type z: float + @param x: The new x value. + @param y: The new y value. + @param z: The new z value. + """ + + def setLoc(x,y,z): + """ + Set the new location for this Bone. + @type x: float + @type y: float + @type z: float + @param x: The new x value. + @param y: The new y value. + @param z: The new z value. + """ + + def setSize(x,y,z): + """ + Set the new size for this Bone. + @type x: float + @type y: float + @type z: float + @param x: The new x value. + @param y: The new y value. + @param z: The new z value. + """ + + def setQuat(real,imag_i,imag_j,imag_k): + """ + Set the new quaternion orientation for this Bone. + @type real: float + @type imag_i: float + @type imag_j: float + @type imag_k: float + @param real: The new quat[0] value. + @param imag_i: The new quat[1] value. + @param imag_j: The new quat[2] value. + @param imag_k: The new quat[3] value. + """ diff --git a/source/blender/python/api2_2x/doc/Image.py b/source/blender/python/api2_2x/doc/Image.py index 96f75496540..40ca9328617 100644 --- a/source/blender/python/api2_2x/doc/Image.py +++ b/source/blender/python/api2_2x/doc/Image.py @@ -55,11 +55,12 @@ class Image: """ The Image object ================ - This object gives access to Images in Blender. In the future it will allow - direct read/write access to their pixel buffers, too. + This object gives access to Images in Blender. @cvar name: The name of this Image object. @cvar filename: The filename (path) to the image file loaded into this Image object. + @cvar size: The [width, height] dimensions of the image (in pixels). + @cvar depth: The pixel depth of the image. @cvar xrep: Texture tiling: the number of repetitions in the x (horizontal) axis. @cvar yrep: Texture tiling: the number of repetitions in the y (vertical) @@ -78,6 +79,18 @@ class Image: @rtype: string """ + def getSize(): + """ + Get the [width, height] dimensions (in pixels) of this image. + @rtype: list of 2 ints + """ + + def getDepth(): + """ + Get the pixel depth of this image. + @rtype: int + """ + def getXRep(): """ Get the number of repetitions in the x (horizontal) axis for this Image. @@ -112,4 +125,3 @@ class Image: @type yrep: int @param yrep: The new value in [1, 16]. """ - diff --git a/source/blender/python/api2_2x/doc/NMesh.py b/source/blender/python/api2_2x/doc/NMesh.py index c8fe8390a1e..f631726029b 100644 --- a/source/blender/python/api2_2x/doc/NMesh.py +++ b/source/blender/python/api2_2x/doc/NMesh.py @@ -110,11 +110,15 @@ def GetRaw(name = None): def GetRawFromObject(name): """ - Get the mesh data object from the Object in Blender called I{name}. + Get the raw mesh data object from the Object in Blender called I{name}. @type name: string @param name: The name of an Object of type "Mesh". @rtype: NMesh @return: The NMesh wrapper of the mesh data from the Object called I{name}. + @warn: This function gets I{deformed} mesh data, already modified for + rendering (think "display list"). It also doesn't let you overwrite the + original mesh in Blender, so if you try to update it, a new mesh will + be created. """ def PutRaw(nmesh, name = None, recalculate_normals = 1): @@ -187,7 +191,7 @@ class NMFace: @param vertex: An NMVert object. """ -class NMesh : +class NMesh: """ The NMesh Data object ===================== @@ -201,6 +205,16 @@ class NMesh : @cvar faces: The list of NMesh faces (NMFaces). """ + def addMaterial(material): + """ + Add a new material to this NMesh's list of materials. This method is the + slower but safer way to add materials, since it checks if the argument + given is really a material, imposes a limit of 16 materials and only adds + the material if it wasn't already in the list. + @type material: Blender Material + @param material: A Blender Material. + """ + def hasVertexColours(flag = None): """ Get (and optionally set) if this NMesh has vertex colours. @@ -272,14 +286,18 @@ class NMesh : and its weight is a float value. """ - def insertKey(frame = None): + def insertKey(frame = None, type = 'relative'): """ Insert a mesh key at the given frame. Remember to L{update} the nmesh before doing this, or changes in the vertices won't be updated in the Blender mesh. @type frame: int + @type type: string @param frame: The Scene frame where the mesh key should be inserted. If None, the current frame is used. + @param type: The mesh key type: 'relative' or 'absolute'. This is only + relevant on the first call to insertKey for each nmesh (and after all + keys were removed with L{removeAllKeys}, of course). @warn: This and L{removeAllKeys} were included in this release only to make accessing vertex keys possible, but may not be a proper solution and may be substituted by something better later. For example, it @@ -301,9 +319,12 @@ class NMesh : add them. """ - def update(): + def update(recalc_normals = 0): """ Update the mesh in Blender. The changes made are put back to the mesh in Blender, if available, or put in a newly created mesh object if this NMesh wasn't linked to one, yet. + @type recalc_normals: int + @param recalc_normals: If given and equal to 1, the vertex normals are + recalculated. """ diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index b799d9d99f0..fb483365cd5 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -3839,7 +3839,7 @@ void common_insertkey() if(event== -1) return; if(event==7) { - if(ob->type==OB_MESH) insert_meshkey(ob->data); + if(ob->type==OB_MESH) insert_meshkey(ob->data, 0); else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(ob->data); else if(ob->type==OB_LATTICE) insert_lattkey(ob->data); diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c index 5d9492d9af7..0edc47ad9c8 100644 --- a/source/blender/src/editkey.c +++ b/source/blender/src/editkey.c @@ -104,7 +104,7 @@ static IpoCurve *get_key_icu(Key *key, int keynum) { */ IpoCurve *icu; if (!(key->ipo)) { - key->ipo = get_ipo(key, ID_KE, 1); + key->ipo = get_ipo((ID *)key, ID_KE, 1); return NULL; } @@ -356,7 +356,7 @@ void key_to_mesh(KeyBlock *kb, Mesh *me) -void insert_meshkey(Mesh *me) +void insert_meshkey(Mesh *me, short offline) { Key *key; KeyBlock *kb, *kkb; @@ -365,7 +365,13 @@ void insert_meshkey(Mesh *me) if(me->key==0) { me->key= add_key( (ID *)me); - rel = pupmenu("Insert Vertex Keys %t|Relative keys %x1|Absolute keys %x2"); + + if (!offline) /* interactive */ + rel = pupmenu("Insert Vertex Keys %t|" + "Relative keys %x1|Absolute keys %x2"); + else /* we were called from a script */ + rel = offline; + switch (rel) { case 1: me->key->type = KEY_RELATIVE; -- cgit v1.2.3