diff options
author | Willian Padovani Germano <wpgermano@gmail.com> | 2005-05-22 11:22:34 +0400 |
---|---|---|
committer | Willian Padovani Germano <wpgermano@gmail.com> | 2005-05-22 11:22:34 +0400 |
commit | 2f3dbcc5b75922bdb0847fce5ce8a15d35443314 (patch) | |
tree | 189bc4fcd2a90f7c3085c68dd1f10051ce4cd797 /source | |
parent | ae2acbf49bf4370c07f165f30ea38f4a9c825fe4 (diff) |
BPython bug fixes:
- bug #2033 reported by Ken Hughes: Vertices of mesh parented to lattice is scaled incorrectly:
https://projects.blender.org/tracker/?func=detail&aid=2033&group_id=9&atid=125
- bug #2211 reported by German Alonso Tamayo (servivo): Add a vertex to a mesh with groups using a script and then edit that mesh hangs blender:
https://projects.blender.org/tracker/index.php?func=detail&aid=2211&group_id=9&atid=125
(#2211's hang was already fixed with previous commit, but this way should work better)
- doc updates (Ken reported missing info about Render slinks, thanks).
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/python/api2_2x/Lattice.c | 32 | ||||
-rw-r--r-- | source/blender/python/api2_2x/NMesh.c | 44 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Object.c | 11 | ||||
-rw-r--r-- | source/blender/python/api2_2x/Scene.c | 2 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Camera.py | 4 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Lamp.py | 4 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Lattice.py | 14 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Object.py | 7 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/Scene.py | 4 | ||||
-rw-r--r-- | source/blender/python/api2_2x/doc/World.py | 4 |
10 files changed, 103 insertions, 23 deletions
diff --git a/source/blender/python/api2_2x/Lattice.c b/source/blender/python/api2_2x/Lattice.c index 87d9520798b..3bd11bed727 100644 --- a/source/blender/python/api2_2x/Lattice.c +++ b/source/blender/python/api2_2x/Lattice.c @@ -96,7 +96,7 @@ static PyObject *Lattice_setMode( BPy_Lattice * self, PyObject * args ); static PyObject *Lattice_getMode( BPy_Lattice * self, PyObject * args ); static PyObject *Lattice_setPoint( BPy_Lattice * self, PyObject * args ); static PyObject *Lattice_getPoint( BPy_Lattice * self, PyObject * args ); -static PyObject *Lattice_applyDeform( BPy_Lattice * self ); +static PyObject *Lattice_applyDeform( BPy_Lattice * self, PyObject *args ); static PyObject *Lattice_insertKey( BPy_Lattice * self, PyObject * args ); /*****************************************************************************/ @@ -132,7 +132,12 @@ static char Lattice_getPoint_doc[] = "(str) - Get the coordinates of a point on the lattice"; static char Lattice_applyDeform_doc[] = - "(str) - Apply the new lattice deformation to children"; + "(force = False) - Apply the new lattice deformation to children\n\n\ +(force = False) - if given and True, children of mesh type are not ignored.\n\ +Meshes are treated differently in Blender, deformation is stored directly in\n\ +their vertices when first redrawn (ex: with Blender.Redraw) after getting a\n\ +Lattice parent, without needing this method (except for command line bg\n\ +mode). If forced, the deformation will be applied over any previous one(s)."; static char Lattice_insertKey_doc[] = "(str) - Set a new key for the lattice at specified frame"; @@ -162,7 +167,7 @@ static PyMethodDef BPy_Lattice_methods[] = { Lattice_setPoint_doc}, {"getPoint", ( PyCFunction ) Lattice_getPoint, METH_VARARGS, Lattice_getPoint_doc}, - {"applyDeform", ( PyCFunction ) Lattice_applyDeform, METH_NOARGS, + {"applyDeform", ( PyCFunction ) Lattice_applyDeform, METH_VARARGS, Lattice_applyDeform_doc}, {"insertKey", ( PyCFunction ) Lattice_insertKey, METH_VARARGS, Lattice_insertKey_doc}, @@ -675,22 +680,35 @@ static PyObject *Lattice_getPoint( BPy_Lattice * self, PyObject * args ) } //This function will not do anything if there are no children -static PyObject *Lattice_applyDeform( BPy_Lattice * self ) +static PyObject *Lattice_applyDeform( BPy_Lattice * self, PyObject *args ) { //Object* ob; unused Base *base; Object *par; + int forced = 0; if( !Lattice_IsLinkedToObject( self ) ) return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "Lattice must be linked to an object to apply it's deformation!" ) ); + if( !PyArg_ParseTuple( args, "|i", &forced ) ) + return ( EXPP_ReturnPyObjError( PyExc_TypeError, + "expected nothing or True or False argument" ) ); + /* deform children */ base = FIRSTBASE; while( base ) { - if( ( par = base->object->parent ) ) { /* checking if object has a parent, assigning if so */ - if((par->type == OB_LATTICE) && (self->Lattice == par->data)) { - object_deform( base->object ); + if( ( par = base->object->parent ) ) { /* check/assign if ob has parent */ + /* meshes have their mverts deformed, others ob types use displist, + * so we're not doing meshes here (unless forced), or else they get + * deformed twice, since parenting a Lattice to an object and redrawing + * already applies lattice deformation. 'forced' is useful for + * command line background mode, when no redraws occur and so this + * method is needed. Or for users who actually want to apply the + * deformation n times. */ + if((self->Lattice == par->data)) { + if ((base->object->type != OB_MESH) || forced) + object_deform( base->object ); } } base = base->next; diff --git a/source/blender/python/api2_2x/NMesh.c b/source/blender/python/api2_2x/NMesh.c index 234aa4833e5..b735204613e 100644 --- a/source/blender/python/api2_2x/NMesh.c +++ b/source/blender/python/api2_2x/NMesh.c @@ -93,6 +93,7 @@ static PyObject *g_nmeshmodule = NULL; static int unlink_existingMeshData( Mesh * mesh ); static int convert_NMeshToMesh( Mesh *mesh, BPy_NMesh *nmesh, int store_edges ); +static void check_dverts(Mesh *me, int old_totverts); static PyObject *NMesh_printDebug( PyObject * self ); static PyObject *NMesh_addEdge( PyObject * self, PyObject * args ); static PyObject *NMesh_findEdge( PyObject * self, PyObject * args ); @@ -1292,6 +1293,7 @@ static PyObject *NMesh_update( PyObject *self, PyObject *a, PyObject *kwd ) static char *kwlist[] = {"recalc_normals", "store_edges", "vertex_shade", NULL}; int needs_redraw = 1; + int old_totvert = 0; if (!PyArg_ParseTupleAndKeywords(a, kwd, "|iii", kwlist, &recalc_normals, &store_edges, &vertex_shade ) ) @@ -1299,8 +1301,10 @@ static PyObject *NMesh_update( PyObject *self, PyObject *a, PyObject *kwd ) "expected nothing or one to three bool(s) (0 or 1) as argument" ); if( mesh ) { + old_totvert = mesh->totvert; unlink_existingMeshData( mesh ); convert_NMeshToMesh( mesh, nmesh, store_edges ); + if (mesh->dvert) check_dverts(mesh, old_totvert); } else { nmesh->mesh = Mesh_fromNMesh( nmesh, store_edges ); mesh = nmesh->mesh; @@ -2411,8 +2415,6 @@ static int unlink_existingMeshData( Mesh * mesh ) { freedisplist( &mesh->disp ); EXPP_unlink_mesh( mesh ); - if( mesh->dvert ) - free_dverts( mesh->dvert, mesh->totvert ); if( mesh->mvert ) MEM_freeN( mesh->mvert ); if( mesh->medge ) { @@ -2601,6 +2603,39 @@ static void fill_medge_from_nmesh(Mesh * mesh, BPy_NMesh * nmesh) MEM_freeN( faces_edges ); } +/* this should ensure meshes don't end up with wrongly sized + * me->dvert arrays, which can cause hangs; it's not ideal, + * it's better to wrap dverts in NMesh, but it should do for now + * since there are also methods in NMesh to edit dverts in the actual + * mesh in Blender and anyway this is memory friendly */ +static void check_dverts(Mesh *me, int old_totvert) +{ + int totvert = me->totvert; + + /* if vert count didn't change or there are no dverts, all is fine */ + if ((totvert == old_totvert) || (!me->dvert)) return; + /* if all verts have been deleted, free old dverts */ + else if (totvert == 0) free_dverts(me->dvert, old_totvert); + /* if verts have been added, expand me->dvert */ + else if (totvert > old_totvert) { + MDeformVert *mdv = me->dvert; + me->dvert = NULL; + create_dverts(me); + copy_dverts(me->dvert, mdv, old_totvert); + free_dverts(mdv, old_totvert); + } + /* if verts have been deleted, shrink me->dvert */ + else { + MDeformVert *mdv = me->dvert; + me->dvert = NULL; + create_dverts(me); + copy_dverts(me->dvert, mdv, totvert); + free_dverts(mdv, old_totvert); + } + + return; +} + static int convert_NMeshToMesh( Mesh * mesh, BPy_NMesh * nmesh, int store_edges) { MFace *newmf; @@ -2782,6 +2817,7 @@ static PyObject *M_NMesh_PutRaw( PyObject * self, PyObject * args ) BPy_NMesh *nmesh; int recalc_normals = 1; int store_edges = 0; + int old_totvert = 0; if( !PyArg_ParseTuple( args, "O!|sii", &NMesh_Type, &nmesh, &name, &recalc_normals, &store_edges ) ) @@ -2830,10 +2866,14 @@ static PyObject *M_NMesh_PutRaw( PyObject * self, PyObject * args ) new_id( &( G.main->mesh ), &mesh->id, PyString_AsString( nmesh->name ) ); + old_totvert = mesh->totvert; + unlink_existingMeshData( mesh ); convert_NMeshToMesh( mesh, nmesh, store_edges ); nmesh->mesh = mesh; + if (mesh->dvert) check_dverts(mesh, old_totvert); + if( recalc_normals ) vertexnormals_mesh( mesh, 0 ); diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index 78b66b683bc..2f92aef0505 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -1553,6 +1553,12 @@ static PyObject *Object_makeParent( BPy_Object * self, PyObject * args ) "expected a list of objects" ) ); } + parent = ( Object * ) self->object; + + if (parent->id.us == 0) + return EXPP_ReturnPyObjError (PyExc_RuntimeError, + "object must be linked to a scene before it can become a parent"); + /* Check if the PyObject passed in list is a Blender object. */ for( i = 0; i < PySequence_Length( list ); i++ ) { child = NULL; @@ -1561,12 +1567,13 @@ static PyObject *Object_makeParent( BPy_Object * self, PyObject * args ) child = ( Object * ) Object_FromPyObject( py_child ); if( child == NULL ) { + Py_DECREF (py_child); return ( EXPP_ReturnPyObjError( PyExc_TypeError, "Object Type expected" ) ); } - parent = ( Object * ) self->object; if( test_parent_loop( parent, child ) ) { + Py_DECREF (py_child); return ( EXPP_ReturnPyObjError( PyExc_RuntimeError, "parenting loop detected - parenting failed" ) ); } @@ -1587,7 +1594,7 @@ static PyObject *Object_makeParent( BPy_Object * self, PyObject * args ) sort_baselist( G.scene ); } // We don't need the child object anymore. - //Py_DECREF ((PyObject *) child); + Py_DECREF (py_child); } return EXPP_incr_ret( Py_None ); } diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c index 2010129ae6b..d4a24656bf4 100644 --- a/source/blender/python/api2_2x/Scene.c +++ b/source/blender/python/api2_2x/Scene.c @@ -752,7 +752,7 @@ static PyObject *Scene_link( BPy_Scene * self, PyObject * args ) /* not linked, go get mem for a new base object */ - base = MEM_callocN( sizeof( Base ), "newbase" ); + base = MEM_callocN( sizeof( Base ), "pynewbase" ); if( !base ) return EXPP_ReturnPyObjError( PyExc_MemoryError, diff --git a/source/blender/python/api2_2x/doc/Camera.py b/source/blender/python/api2_2x/doc/Camera.py index 9dc382a2ba8..ac0319f8fff 100644 --- a/source/blender/python/api2_2x/doc/Camera.py +++ b/source/blender/python/api2_2x/doc/Camera.py @@ -205,7 +205,7 @@ class Camera: """ Get a list with this Camera's script links of type 'event'. @type event: string - @param event: "FrameChanged" or "Redraw". + @param event: "FrameChanged", "Redraw" or "Render". @rtype: list @return: a list with Blender L{Text} names (the script links of the given 'event' type) or None if there are no script links at all. @@ -225,7 +225,7 @@ class Camera: @type text: string @param text: the name of an existing Blender L{Text}. @type event: string - @param event: "FrameChanged" or "Redraw". + @param event: "FrameChanged", "Redraw" or "Render". """ def insertIpoKey(keytype): diff --git a/source/blender/python/api2_2x/doc/Lamp.py b/source/blender/python/api2_2x/doc/Lamp.py index 824e43eaad2..7c8aa9dedc7 100644 --- a/source/blender/python/api2_2x/doc/Lamp.py +++ b/source/blender/python/api2_2x/doc/Lamp.py @@ -329,7 +329,7 @@ class Lamp: """ Get a list with this Lamp's script links of type 'event'. @type event: string - @param event: "FrameChanged" or "Redraw". + @param event: "FrameChanged", "Redraw" or "Render". @rtype: list @return: a list with Blender L{Text} names (the script links of the given 'event' type) or None if there are no script links at all. @@ -349,7 +349,7 @@ class Lamp: @type text: string @param text: the name of an existing Blender L{Text}. @type event: string - @param event: "FrameChanged" or "Redraw". + @param event: "FrameChanged", "Redraw" or "Render". """ def getIpo(): diff --git a/source/blender/python/api2_2x/doc/Lattice.py b/source/blender/python/api2_2x/doc/Lattice.py index 56f4ee71150..9f8bf76c336 100644 --- a/source/blender/python/api2_2x/doc/Lattice.py +++ b/source/blender/python/api2_2x/doc/Lattice.py @@ -171,10 +171,22 @@ class Lattice: @param position: The x,y,z coordinates that you want the point to be: [x,y,z] """ - def applyDeform(): + def applyDeform(force = False): """ + @type force: bool + @param force: if True, meshes are not ignored. Applies the current Lattice deformation to any child objects that have this Lattice as the parent. + @note: simply parenting to a Lattice and redrawing the screen is enough to + get the deformation done, this applyDeform method is useful when the + script won't call a redraw, like in command line background (GUI-less) + mode. + @note: by default, this method doesn't apply deformations to meshes. This + is because unlike other kinds of objects, meshes store lattice + deformation directly in their vertices and calling this applyDeform + method will apply the deformation a second time, giving double + deformation, which can be a feature (set force = True if you want it) or + much probably an undesired effect. """ def insertKey(frame): diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index e75c2cc4234..ef8e31aa415 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -443,6 +443,9 @@ class Object: 0 - update scene hierarchy automatically 1 - don't update scene hierarchy (faster). In this case, you must explicitely update the Scene hierarchy. + @warn: objects must first be linked to a scene before they can become + parents of other objects. Calling this makeParent method for an + unlinked object will result in an error. """ def setDeltaLocation(delta_location): @@ -595,7 +598,7 @@ class Object: """ Get a list with this Object's script links of type 'event'. @type event: string - @param event: "FrameChanged" or "Redraw". + @param event: "FrameChanged", "Redraw" or "Render". @rtype: list @return: a list with Blender L{Text} names (the script links of the given 'event' type) or None if there are no script links at all. @@ -615,7 +618,7 @@ class Object: @type text: string @param text: the name of an existing Blender L{Text}. @type event: string - @param event: "FrameChanged" or "Redraw". + @param event: "FrameChanged", "Redraw" or "Render". """ def makeTrack (tracked, fast = 0): diff --git a/source/blender/python/api2_2x/doc/Scene.py b/source/blender/python/api2_2x/doc/Scene.py index f722b772184..d9846086317 100644 --- a/source/blender/python/api2_2x/doc/Scene.py +++ b/source/blender/python/api2_2x/doc/Scene.py @@ -236,7 +236,7 @@ class Scene: """ Get a list with this Scene's script links of type 'event'. @type event: string - @param event: "FrameChanged", "OnLoad", "OnSave" or "Redraw". + @param event: "FrameChanged", "OnLoad", "OnSave", "Redraw" or "Render". @rtype: list @return: a list with Blender L{Text} names (the script links of the given 'event' type) or None if there are no script links at all. @@ -256,7 +256,7 @@ class Scene: @type text: string @param text: the name of an existing Blender L{Text}. @type event: string - @param event: "FrameChanged", "OnLoad", "OnSave" or "Redraw". + @param event: "FrameChanged", "OnLoad", "OnSave", "Redraw" or "Render". """ def play (mode = 0, win = '<VIEW3D>'): diff --git a/source/blender/python/api2_2x/doc/World.py b/source/blender/python/api2_2x/doc/World.py index 2aa333b6610..8dbf8dfb951 100644 --- a/source/blender/python/api2_2x/doc/World.py +++ b/source/blender/python/api2_2x/doc/World.py @@ -293,7 +293,7 @@ class World: """ Get a list with this World's script links of type 'event'. @type event: string - @param event: "FrameChanged" or "Redraw". + @param event: "FrameChanged", "Redraw", "Render". @rtype: list @return: a list with Blender L{Text} names (the script links of the given 'event' type) or None if there are no script links at all. @@ -313,7 +313,7 @@ class World: @type text: string @param text: the name of an existing Blender L{Text}. @type event: string - @param event: "FrameChanged" or "Redraw". + @param event: "FrameChanged", "Redraw" or "Render". """ def setCurrent (): |