diff --git a/source/blender/python/api2_2x/NMesh.c b/source/blender/python/api2_2x/NMesh.c index 62607ebe855..8c25aac01ab 100644 --- a/source/blender/python/api2_2x/NMesh.c +++ b/source/blender/python/api2_2x/NMesh.c @@ -255,37 +255,37 @@ static PyObject *NMFace_getattr(PyObject *self, char *name) return Py_BuildValue("i", mf->transp); else if (strcmp(name, "uv") == 0) return Py_BuildValue("O", mf->uv); - else if (strcmp(name, "normal") == 0) - { - if(EXPP_check_sequence_consistency(mf->v, &NMVert_Type)) - { + + else if ((strcmp(name, "normal") == 0) || (strcmp(name, "no") == 0)) { + + if (EXPP_check_sequence_consistency(mf->v, &NMVert_Type)) { + float fNormal[3] = {0.0,0.0,0.0}; + float *vco[4] = {NULL, NULL, NULL, NULL}; int nSize = PyList_Size(mf->v); - if(nSize == 4) - { - CalcNormFloat4( &((BPy_NMVert*)(PyList_GetItem(mf->v, 0)))->co, - &((BPy_NMVert*)(PyList_GetItem(mf->v, 1)))->co, - &((BPy_NMVert*)(PyList_GetItem(mf->v, 2)))->co, - &((BPy_NMVert*)(PyList_GetItem(mf->v, 3)))->co, - &fNormal); - return Py_BuildValue("[f,f,f]",fNormal[0],fNormal[1],fNormal[2]); - } - else if(nSize == 3) - { - CalcNormFloat( &((BPy_NMVert*)(PyList_GetItem(mf->v, 0)))->co, - &((BPy_NMVert*)(PyList_GetItem(mf->v, 1)))->co, - &((BPy_NMVert*)(PyList_GetItem(mf->v, 2)))->co, - &fNormal); - return Py_BuildValue("[f,f,f]",fNormal[0],fNormal[1],fNormal[2]); - } - else + int loop; + + if (nSize != 3 && nSize != 4) return EXPP_ReturnPyObjError (PyExc_AttributeError, "face must contain either 3 or 4 verts"); + + for (loop = 0; loop < nSize; loop++) { + BPy_NMVert *v = (BPy_NMVert *)PyList_GetItem(mf->v, loop); + vco[loop] = (float *)v->co; + } + + if (nSize == 4) + CalcNormFloat4(vco[0], vco[1], vco[2], vco[3], fNormal); + else + CalcNormFloat(vco[0], vco[1], vco[2], fNormal); + + return Py_BuildValue("[f,f,f]",fNormal[0],fNormal[1],fNormal[2]); } - else + else // EXPP_check_sequence_consistency failed return EXPP_ReturnPyObjError (PyExc_AttributeError, - "this face does not contain a series of NMVerts"); + "this face does not contain a series of NMVerts"); } + else if (strcmp(name, "__members__") == 0) return Py_BuildValue("[s,s,s,s,s,s,s,s,s,s,s]", "v", "col", "mat", "materialIndex", "smooth", @@ -994,7 +994,7 @@ static struct PyMethodDef NMesh_methods[] = MethodDef(removeVertGroup), MethodDef(assignVertsToGroup), MethodDef(removeVertsFromGroup), - MethodDef(returnVertsFromGroup), + MethodDef(getVertsFromGroup), MethodDef(hasVertexColours), MethodDef(hasFaceUV), MethodDef(hasVertexUV), @@ -1844,7 +1844,7 @@ static PyObject *M_NMesh_PutRaw(PyObject *self, PyObject *args) if (name) mesh = (Mesh *)GetIdFromList(&(G.main->mesh), name); - if (!mesh) { + if (!mesh || mesh->id.us == 0) { ob = add_object(OB_MESH); if (!ob) { PyErr_SetString(PyExc_RuntimeError, @@ -1852,19 +1852,8 @@ static PyObject *M_NMesh_PutRaw(PyObject *self, PyObject *args) return 0; } - mesh = (Mesh *)ob->data; - } - - else if (mesh->id.us == 0) { - ob = add_object(OB_MESH); // we already have a mesh - if (!ob) { - PyErr_SetString(PyExc_RuntimeError, - "Fatal: could not create mesh object"); - return 0; - } - - ob->type = OB_MESH; - set_mesh(ob, mesh); // also does id.us++ + if (!mesh) mesh = (Mesh *)ob->data; + else set_mesh(ob, mesh); // also does id.us++ } if (name) @@ -2085,14 +2074,12 @@ static PyObject *NMesh_addVertGroup (PyObject *self, PyObject *args) { char* groupStr; struct Object* object; - //int nIndex; XXX unused - //bDeformGroup* pGroup; XXX unused if (!PyArg_ParseTuple(args, "s", &groupStr)) - return EXPP_ReturnPyObjError (PyExc_TypeError, - "expected string argument"); + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string argument"); - if(((BPy_NMesh*)self)->object == NULL) + if (( (BPy_NMesh*)self )->object == NULL) return EXPP_ReturnPyObjError (PyExc_AttributeError, "mesh must be linked to an object first..."); @@ -2116,7 +2103,7 @@ static PyObject *NMesh_removeVertGroup (PyObject *self, PyObject *args) return EXPP_ReturnPyObjError (PyExc_TypeError, "expected string argument"); - if(((BPy_NMesh*)self)->object == NULL) + if (( (BPy_NMesh*)self )->object == NULL) return EXPP_ReturnPyObjError (PyExc_AttributeError, "mesh must be linked to an object first..."); @@ -2137,7 +2124,7 @@ static PyObject *NMesh_removeVertGroup (PyObject *self, PyObject *args) del_defgroup(object); allqueue (REDRAWBUTSALL, 1); - + return EXPP_incr_ret (Py_None); } @@ -2151,32 +2138,31 @@ static PyObject *NMesh_assignVertsToGroup (PyObject *self, PyObject *args) // - remove group influence from this vertex char* groupStr; - char* assignmodeStr; + char* assignmodeStr = NULL; int nIndex; int assignmode; - float weight; + float weight = 1.0; struct Object* object; bDeformGroup* pGroup; PyObject* listObject; int tempInt; int x; - if (!PyArg_ParseTuple(args, "sO!fs", &groupStr, &PyList_Type, &listObject, - &weight, &assignmodeStr)) - { - return EXPP_ReturnPyObjError (PyExc_TypeError, - "expected string & type_List & float & string argument"); - } - - if (((BPy_NMesh*)self)->object == NULL) + if (( (BPy_NMesh*)self )->object == NULL) return EXPP_ReturnPyObjError (PyExc_AttributeError, "mesh must be linked to an object first..."); + if (!PyArg_ParseTuple(args, "sO!fs", &groupStr, &PyList_Type, &listObject, + &weight, &assignmodeStr)) { + return EXPP_ReturnPyObjError (PyExc_TypeError, + "expected string, list, float, string arguments"); + } + object = ((BPy_NMesh*)self)->object; - if(object->data == NULL) + if (object->data == NULL) return EXPP_ReturnPyObjError (PyExc_AttributeError, - "object contains no data..."); + "object contains no data..."); pGroup = get_named_vertexgroup(object, groupStr); if(pGroup == NULL) @@ -2187,7 +2173,9 @@ static PyObject *NMesh_assignVertsToGroup (PyObject *self, PyObject *args) return EXPP_ReturnPyObjError (PyExc_AttributeError, "no deform groups assigned to mesh"); - if(STREQ(assignmodeStr, "replace")) + if(assignmodeStr == NULL) + assignmode = 1; /* default */ + else if(STREQ(assignmodeStr, "replace")) assignmode = 1; else if(STREQ(assignmodeStr, "add")) assignmode = 2; @@ -2196,7 +2184,6 @@ static PyObject *NMesh_assignVertsToGroup (PyObject *self, PyObject *args) else return EXPP_ReturnPyObjError (PyExc_ValueError, "bad assignment mode"); - //makes a set of dVerts corresponding to the mVerts if (!((Mesh*)object->data)->dvert) { create_dverts((Mesh*)object->data); @@ -2216,8 +2203,7 @@ static PyObject *NMesh_assignVertsToGroup (PyObject *self, PyObject *args) } //enter editmode - if((G.obedit == 0)) - { + if((G.obedit == 0)) { BASACT->object = object; G.obedit= BASACT->object; } @@ -2244,39 +2230,44 @@ static PyObject *NMesh_removeVertsFromGroup (PyObject *self, PyObject *args) bDeformGroup* pGroup; PyObject* listObject; int tempInt; - int x; + int x, argc; - listObject = (void*)-2054456; //uninitialized + /* argc is the number of parameters passed in: 1 (no list given) or 2: */ + argc = PyObject_Length(args); + + //listObject = (void*)-2054456; //uninitialized if (!PyArg_ParseTuple(args, "s|O!", &groupStr, &PyList_Type, &listObject)) return EXPP_ReturnPyObjError (PyExc_TypeError, - "expected string & optional type_List argument"); + "expected string and optional list argument"); - if (((BPy_NMesh*)self)->object == NULL) + if (( (BPy_NMesh*)self )->object == NULL) return EXPP_ReturnPyObjError (PyExc_AttributeError, "mesh must be linked to an object first..."); object = ((BPy_NMesh*)self)->object; - if(object->data == NULL) + if (object->data == NULL) return EXPP_ReturnPyObjError (PyExc_AttributeError, - "object contains no data..."); + "object contains no data..."); if ((!((Mesh*)object->data)->dvert)) return EXPP_ReturnPyObjError (PyExc_AttributeError, - "this mesh contains no deform vertices...'"); + "this mesh contains no deform vertices...'"); pGroup = get_named_vertexgroup(object, groupStr); if(pGroup == NULL) return EXPP_ReturnPyObjError (PyExc_AttributeError, - "group does not exist!"); + "group does not exist!"); nIndex = get_defgroup_num(object, pGroup); if(nIndex == -1) return EXPP_ReturnPyObjError (PyExc_AttributeError, - "no deform groups assigned to mesh"); + "no deform groups assigned to mesh"); - if(listObject == (void*)-2054456) /*if uninitialized*/ { +// if (listObject == (void*)-2054456) /*if uninitialized*/ { + + if (argc == 1) /* no list given */ { //enter editmode if((G.obedit == 0)) { @@ -2296,7 +2287,7 @@ static PyObject *NMesh_removeVertsFromGroup (PyObject *self, PyObject *args) } else { - if(G.obedit != 0) //remove_vert_def_nr doesn't like it if your in editmode + if(G.obedit != 0) //remove_vert_def_nr doesn't like it if your in editmode G.obedit = 0; //loop list adding verts to group @@ -2316,7 +2307,7 @@ static PyObject *NMesh_removeVertsFromGroup (PyObject *self, PyObject *args) return EXPP_incr_ret (Py_None); } -static PyObject *NMesh_returnVertsFromGroup (PyObject *self, PyObject *args) +static PyObject *NMesh_getVertsFromGroup (PyObject *self, PyObject *args) { //not passing a list will return all verts from group //passing indecies not part of the group will not return data in pyList @@ -2328,7 +2319,6 @@ static PyObject *NMesh_returnVertsFromGroup (PyObject *self, PyObject *args) struct Object* object; bDeformGroup* pGroup; MVert *mvert; - //MDeformWeight *newdw; XXX unused MDeformVert *dvert; float weight; int i, k, l1, l2, count; @@ -2348,7 +2338,7 @@ static PyObject *NMesh_returnVertsFromGroup (PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s|iO!", &groupStr, &weightRet, &PyList_Type, &listObject)) return EXPP_ReturnPyObjError (PyExc_TypeError, - "expected string & optional int and optional type_List argument"); + "expected string and optional int and list arguments"); if (weightRet < 0 || weightRet > 1) return EXPP_ReturnPyObjError (PyExc_ValueError, @@ -2412,10 +2402,12 @@ static PyObject *NMesh_returnVertsFromGroup (PyObject *self, PyObject *args) for(x = 0; x < PyList_Size(listObject); x++) { if(!(PyArg_Parse((PyList_GetItem(listObject, x)), "i", &tempInt))) - return EXPP_ReturnPyObjError (PyExc_TypeError, "python list integer not parseable"); + return EXPP_ReturnPyObjError (PyExc_TypeError, + "python list integer not parseable"); if(tempInt < 0 || tempInt >= ((Mesh*)object->data)->totvert) - return EXPP_ReturnPyObjError (PyExc_ValueError, "bad vertex index in list"); + return EXPP_ReturnPyObjError (PyExc_ValueError, + "bad vertex index in list"); num = tempInt; dvert = ((Mesh*)object->data)->dvert + num; @@ -2430,11 +2422,13 @@ static PyObject *NMesh_returnVertsFromGroup (PyObject *self, PyObject *args) weight = dvert->dw[i].weight; //printf("index =%3d weight:%10f\n", num, weight); - if(weightRet == 1) - PyList_SetItem(tempVertexList, count, Py_BuildValue("(i,f)", num, weight)); + if(weightRet == 1) { + PyList_SetItem(tempVertexList, count, + Py_BuildValue("(i,f)", num, weight)); + } else if (weightRet == 0) PyList_SetItem(tempVertexList, count, Py_BuildValue("i", num)); - + count++; } if(l2 == FALSE) diff --git a/source/blender/python/api2_2x/NMesh.h b/source/blender/python/api2_2x/NMesh.h index 3ab7c477ee7..492760b02a9 100644 --- a/source/blender/python/api2_2x/NMesh.h +++ b/source/blender/python/api2_2x/NMesh.h @@ -135,7 +135,7 @@ static char NMesh_removeVertsFromGroup_doc[] = mesh that has been linked to an object. If no list is given this will remove\n\ all vertex point associations with the group passed"; -static char NMesh_returnVertsFromGroup_doc[] = +static char NMesh_getVertsFromGroup_doc[] = "By passing a python list of vertex indices and a named group, this will\n\ return a python list representing the indeces that are a part of this vertex.\n\ group. If no association was found for the index passed nothing will be\n\ @@ -295,7 +295,7 @@ static PyObject *NMesh_addVertGroup(PyObject *self, PyObject *args); static PyObject *NMesh_removeVertGroup(PyObject *self, PyObject *args); static PyObject *NMesh_assignVertsToGroup(PyObject *self, PyObject *args); static PyObject *NMesh_removeVertsFromGroup(PyObject *self, PyObject *args); -static PyObject *NMesh_returnVertsFromGroup(PyObject *self, PyObject *args); +static PyObject *NMesh_getVertsFromGroup(PyObject *self, PyObject *args); #endif /* EXPP_NMESH_H */ diff --git a/source/blender/python/api2_2x/doc/NMesh.py b/source/blender/python/api2_2x/doc/NMesh.py index ce7ae272b51..0fc0e434a7d 100644 --- a/source/blender/python/api2_2x/doc/NMesh.py +++ b/source/blender/python/api2_2x/doc/NMesh.py @@ -201,7 +201,7 @@ class NMFace: @cvar transp: Transparency mode bit vector (see L{NMesh.FaceTranspModes}). @cvar uv: List of per-face UV coordinates: [(u0, v0), (u1, v1), ...]. - @cvar normal: The normalized vector for this face: [x,y,z]. + @cvar normal: (or just B{no}) The normal vector for this face: [x,y,z]. @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). @@ -379,45 +379,40 @@ class NMesh: - "SubSurf" """ - def addVertGroup(groupName): + def addVertGroup(group): """ - Add a named and empty vertex (deform) group to a mesh that has been linked - to an object. - @type groupName: string + Add a named and empty vertex (deform) group to the object this nmesh is + linked to. If this nmesh was newly created or accessed with GetRaw, it must + first be linked to an object (with object.link or NMesh.PutRaw) so the + method knows which object to update.\n + This is because vertex groups in Blender are stored in I{the object} -- + not in the mesh, which may be linked to more than one object. For this + reason, it's better to use "mesh = object.getData()" than + "mesh = NMesh.GetRaw(meshName)" to access an existing mesh. + @type group: string + @param group: the name for the new group. """ - def removeVertGroup(groupName): + def removeVertGroup(group): """ - Remove a named vertex (deform)group from a mesh that has been linked to - an object. Will remove all verts assigned to group, if any. - @type groupName: string + Remove a named vertex (deform) group from the object linked to this nmesh. + All vertices assigned to the group will be removed (just from the group, + not deleted from the mesh), if any. If this nmesh was newly created, it + must first be linked to an object (read the comment in L{addVertGroup} for + more info). + @type group: string + @param group: the name of a vertex group. """ - def assignVertsToGroup(groupName, vertList, weight, assignmode): + def assignVertsToGroup(group, vertList, weight, assignmode = 'replace'): """ - Adds an array (a python list) of vertex points to a named vertex group associated - with a mesh. The vertex list is a list of vertex indeces from the mesh. The vertex list - will have an associated wieght assigned to them. This weight represents the amount of - influence this group has over these vertex points. Weights should be in the range of - 0.0 - 1.0. The assignmode can be either 'add', 'subtract', or 'replace'. If the vertex - in the list is not assigned to the group already, 'add' creates a new association with - between this vertex and the group with the weight specified, otherwise the weight given - is added to the current weight of an existing association between the vertex and group. - 'subtract' will attempt to subtract the weight passed from a vertex already associated - with a group, else it does nothing. 'replace' attempts to replace a weight with the - new weight value for an already associated vertex/group, else it does nothing. You should - assign vertex points to groups only when the mesh has all its vertex points add to it. - @type groupName: string - @type vertList: python list (integers) - @type weight: float - @type assignmode: string - @param assignmode: Three choices: - - 'add' - - 'substract' - - 'replace' + Adds an array (a python list) of vertex points to a named vertex group + associated with a mesh. The vertex list is a list of vertex indices from + the mesh. You should assign vertex points to groups only when the mesh has + all its vertex points added to it and is already linked to an object. - I{B{Example:}} - The example here adds a new set of vertex indeces to a sphere primative:: + I{B{Example:}} + The example here adds a new set of vertex indices to a sphere primitive:: import Blender sphere = Blender.Object.Get('Sphere') mesh = sphere.getData() @@ -427,35 +422,65 @@ class NMesh: if x % 3 == 0: vertList.append(x) mesh.assignVertsToGroup('firstGroup', vertList, 0.5, 'add') + + @type group: string + @param group: the name of the group. + @type vertList: list of ints + @param vertList: a list of vertex indices. + @type weight: float + @param weight: the deform weight for (which means: the amount of influence + the group has over) the given vertices. It should be in the range + [0.0, 1.0]. If weight <= 0, the given vertices are removed from the + group. If weight > 1, it is clamped. + @type assignmode: string + @param assignmode: Three choices: + - 'add' + - 'substract' + - 'replace'\n + + 'B{add}': if the vertex in the list is not assigned to the group + already, this creates a new association between this vertex and the + group with the weight specified, otherwise the weight given is added to + the current weight of an existing association between the vertex and + group.\n + 'B{subtract}' will attempt to subtract the weight passed from a vertex + already associated with a group, else it does nothing.\n + 'B{replace}' attempts to replace a weight with the new weight value + for an already associated vertex/group, else it does nothing. + """ + + def removeVertsFromGroup(group, vertList = None): + """ + Remove a list of vertices from the given group. If this nmesh was newly + created, it must first be linked to an object (check L{addVertGroup}). + @type group: string + @param group: the name of a vertex group + @type vertList: list of ints + @param vertList: a list of vertex indices to be removed from the given + 'group'. If None, all vertices are removed -- the group is emptied. """ - def removeVertsFromGroup(groupName, (optional)vertList): - """ - Will remove an array (a python list) of vertex points from a named group in a mesh - that has been linked to an object. If no list is given this will remove all vertex - point associations with the group passed. - @type groupName: string - @type vertList: python list (integers) + def getVertsFromGroup(group, weightsFlag = 0, vertList = None): """ + Return a list of vertex indices associated with the passed group. This + method can be used to test whether a vertex index is part of a group and + if so, what its weight is. - def returnVertsFromGroup(groupName, (optional)weightsFlag, (optional)vertList): - """ - The function will return a list of vertex indeces associated with the passed group. - The weightsFlag should be either 0 or 1. The default is 0, however if 1 is passed the - weight is returned along with the index. A vertex list can also be passed as a 3rd - parameter. In this case only those vertex points that are both in the list passed and - in the group passed are returned. The method can be used to test whether a vertex index - is part of a group and if so, what it's weight is. - @type groupName: string - @type weightsFlag: int - @type vertList: python list (integers) + I{B{Example:}} + Append this to the example from L{assignVertsToGroup}:: + # ... + print "Vertex indices from group %s :" % groupName + print mesh.getVertsFromGroup('firstGroup') + print "Again, with weights:" + print mesh.getVertsFromGroup('firstGroup',1) + print "Again, with weights and restricted to the given indices:" + print mesh.getVertsFromGroup('firstGroup',1,[1,2,3,4,5,6]) - I{B{Examples:}} - Here is an example:: - ...same as example in assignVertsToGroup... - returnVertList = mesh.returnVertsFromGroup('firstGroup') - or - returnVertList = mesh.returnVertsFromGroup('firstGroup',1) - or - returnVertList = mesh.returnVertsFromGroup('firstGorup',1,[1,2,3,4,5,6]) - """ + @type group: string + @param group: the group name. + @type weightsFlag: bool + @param weightsFlag: if 1, the weight is returned along with the index. + @type vertList: list of ints + @param vertList: if given, only those vertex points that are both in the + list and group passed in are returned. + """