From 625c553e2077ec0a252ddd934d4267c61011d61f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Dec 2005 14:17:15 +0000 Subject: [PATCH] Added a python hook to Joining objects Object.Join() Seperated the join calls from space.c and view3dmenu into join_menu() in space.c, like the select_group_menu(), okee's from join_curve, join_mesh.. etc are in join_menu() so python can call them without UI menu's in the way. this is also a bit neater since there were 2 places that were doing what join_menu() does now. - Cam --- source/blender/include/BIF_space.h | 1 + source/blender/python/api2_2x/Object.c | 73 +++++++++++++++++++++ source/blender/python/api2_2x/doc/Object.py | 13 ++++ source/blender/src/editarmature.c | 5 +- source/blender/src/editcurve.c | 7 +- source/blender/src/header_view3d.c | 7 +- source/blender/src/meshtools.c | 1 - source/blender/src/space.c | 35 +++++++--- 8 files changed, 117 insertions(+), 25 deletions(-) diff --git a/source/blender/include/BIF_space.h b/source/blender/include/BIF_space.h index b51d844403c..189adc0a20a 100644 --- a/source/blender/include/BIF_space.h +++ b/source/blender/include/BIF_space.h @@ -115,6 +115,7 @@ extern void set_rects_butspace(struct SpaceButs *buts); extern void test_butspace(void); extern void start_game(void); extern void select_group_menu(void); +extern void join_menu(void); extern void select_group(short nr); extern void BIF_undo_push(char *str); diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c index f5937a37129..d996e119c19 100644 --- a/source/blender/python/api2_2x/Object.c +++ b/source/blender/python/api2_2x/Object.c @@ -115,6 +115,7 @@ static PyObject *M_Object_New( PyObject * self, PyObject * args ); PyObject *M_Object_Get( PyObject * self, PyObject * args ); static PyObject *M_Object_GetSelected( PyObject * self ); static PyObject *M_Object_Duplicate( PyObject * self, PyObject * args ); +static PyObject *M_Object_Join( PyObject * self ); /* HELPER FUNCTION FOR PARENTING */ static PyObject *internal_makeParent(Object *parent, PyObject *py_child, int partype, int noninverse, int fast, int v1, int v2, int v3); @@ -143,6 +144,9 @@ The active object is the first in the list, if visible"; char M_Object_Duplicate_doc[] = "(linked) - Duplicate all selected, visible objects in the current scene"; +char M_Object_Join_doc[] = + "() - Join all selected objects matching the active objects type."; + /*****************************************************************************/ /* Python method structure definition for Blender.Object module: */ /*****************************************************************************/ @@ -155,6 +159,8 @@ struct PyMethodDef M_Object_methods[] = { M_Object_GetSelected_doc}, {"Duplicate", ( PyCFunction ) M_Object_Duplicate, METH_VARARGS, M_Object_Duplicate_doc}, + {"Join", ( PyCFunction ) M_Object_Join, METH_VARARGS, + M_Object_Join_doc}, {NULL, NULL, 0, NULL} }; @@ -824,6 +830,73 @@ static PyObject *M_Object_Duplicate( PyObject * self, PyObject * args ) } +/*****************************************************************************/ +/* Function: M_Object_Join */ +/* Python equivalent: Blender.Object.Join */ +/*****************************************************************************/ +static PyObject *M_Object_Join( PyObject * self ) +{ + Base *base; + Object *ob= OBACT; + Mesh *me; + int totvert=0, haskey=0; + + if( G.obedit ) + return EXPP_ReturnPyObjError(PyExc_RuntimeError, + "can't join objects while in edit mode" ); + + /* Replicate some of the mesh joining code, should realy spare a baselist loop and communicate + with join_mesh(), will fix later, this will do for now */ + if (ob->type==OB_MESH) { + /* count */ + base= FIRSTBASE; + while(base) { + if TESTBASELIB(base) { + if(base->object->type==OB_MESH) { + me= base->object->data; + totvert+= me->totvert; + + if(me->key) { + haskey= 1; + break; + } + } + } + base= base->next; + } + + if(haskey) { + return EXPP_ReturnPyObjError(PyExc_RuntimeError, + "Can't join meshes with vertex keys" ); + + } + + if(totvert==0) + return EXPP_ReturnPyObjError(PyExc_RuntimeError, + "Can't join meshes, there are no verts to join" ); + if (totvert>MESH_MAX_VERTS) + return EXPP_ReturnPyObjError(PyExc_RuntimeError, + "Can't join meshes, there are too many verts for 1 mesh." ); + } + + + /* Do the actial joining now we know everythings OK. */ + if (ob) { + if(ob->type == OB_MESH) { + join_mesh(); + } else if(ob->type == OB_CURVE) { + join_curve(OB_CURVE); + } else if(ob->type == OB_SURF) { + join_curve(OB_SURF); + } else if(ob->type == OB_ARMATURE) { + join_armature (); + } + } + + Py_RETURN_NONE; +} + + /*****************************************************************************/ /* Function: initObject */ /*****************************************************************************/ diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py index d1b83b45484..a3dc5c397f3 100644 --- a/source/blender/python/api2_2x/doc/Object.py +++ b/source/blender/python/api2_2x/doc/Object.py @@ -140,6 +140,19 @@ def Duplicate (linked=1): """ +def Join (): + """ + Joins selected objects on visible layers from Blenders current scene. + The active object is used as a base for all other objects of the same type to join into - just like pressing Ctrl+J + + @return: None + @note: Being in edit mode, mesh objects with keys and a large number of verts in the + resulting mesh will all raise a RuntimeError. + @note: The join may be unsucsessfull because of the selection or object types and no error raised. + Checking if the number of selected objects has changed is a way to know the join worked. + """ + + class Object: """ The Object object diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index b8630a4ea5a..6983f19093b 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -358,14 +358,11 @@ void join_armature(void) float mat[4][4], imat[4][4]; /* Ensure we're not in editmode and that the active object is an armature*/ - if(G.obedit) return; + /* if(G.obedit) return; */ /* Alredy checked in join_menu() */ ob= OBACT; if(ob->type!=OB_ARMATURE) return; - /* Make sure the user wants to continue*/ - if(okee("Join selected armatures")==0) return; - /* Put the active armature into editmode and join the bones from the other one*/ enter_editmode(); diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c index d87450e7a72..6c3bbd18df4 100644 --- a/source/blender/src/editcurve.c +++ b/source/blender/src/editcurve.c @@ -3289,18 +3289,13 @@ void join_curve(int type) float imat[4][4], cmat[4][4]; int a; - if(G.obedit) return; + /* if(G.obedit) return; */ /* Alredy checked in join_menu() */ ob= OBACT; if(ob->type!=type) return; if(ob->lay & G.vd->lay); else return; tempbase.first= tempbase.last= 0; - if(type==OB_SURF) { - if(okee("Join selected NURBS")==0) return; - } - else if(okee("Join selected curves")==0) return; - /* trasnform all selected curves inverse in obact */ Mat4Invert(imat, ob->obmat); diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index c3b91f937e8..d71f6365198 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -1991,12 +1991,7 @@ static void do_view3d_edit_objectmenu(void *arg, int event) special_editmenu(); break; case 8: /* join objects */ - if( (ob= OBACT) ) { - if(ob->type == OB_MESH) join_mesh(); - else if(ob->type == OB_CURVE) join_curve(OB_CURVE); - else if(ob->type == OB_SURF) join_curve(OB_SURF); - else if(ob->type == OB_ARMATURE) join_armature(); - } + join_menu(); break; case 9: /* convert object type */ convertmenu(); diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index 1ef7320763c..8211bcaf8af 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -166,7 +166,6 @@ void join_mesh(void) if(totvert==0 || totvert>MESH_MAX_VERTS) return; - if(okee("Join selected meshes")==0) return; /* if needed add edges to other meshes */ diff --git a/source/blender/src/space.c b/source/blender/src/space.c index b89be1ad436..6db820a88e5 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -598,6 +598,27 @@ void select_group_menu(void) select_group(nr); } +void join_menu(void) +{ + Object *ob= OBACT; + if (ob && !G.obedit) { + if(ob->type == OB_MESH) { + if(okee("Join selected meshes")==0) return; + join_mesh(); + } else if(ob->type == OB_CURVE) { + if(okee("Join selected curves")==0) return; + join_curve(OB_CURVE); + } else if(ob->type == OB_SURF) { + if(okee("Join selected NURBS")==0) return; + join_curve(OB_SURF); + } else if(ob->type == OB_ARMATURE) { + /* Make sure the user wants to continue*/ + if(okee("Join selected armatures")==0) return; + join_armature (); + } + } +} + void select_group(short nr) { Base *base; @@ -623,6 +644,11 @@ void select_group(short nr) allqueue(REDRAWIPO, 0); } + + + + + static unsigned short convert_for_nonumpad(unsigned short event) { if (event>=ZEROKEY && event<=NINEKEY) { @@ -1366,14 +1392,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) case JKEY: if(G.qual==LR_CTRLKEY) { if( ob ) { - if(ob->type == OB_MESH) - join_mesh(); - else if(ob->type == OB_CURVE) - join_curve(OB_CURVE); - else if(ob->type == OB_SURF) - join_curve(OB_SURF); - else if(ob->type == OB_ARMATURE) - join_armature (); + join_menu(); } else if ((G.obedit) && ELEM(G.obedit->type, OB_CURVE, OB_SURF)) addsegment_nurb();