Added a python hook to Joining objects
authorCampbell Barton <ideasman42@gmail.com>
Fri, 30 Dec 2005 14:17:15 +0000 (14:17 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 30 Dec 2005 14:17:15 +0000 (14:17 +0000)
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
source/blender/python/api2_2x/Object.c
source/blender/python/api2_2x/doc/Object.py
source/blender/src/editarmature.c
source/blender/src/editcurve.c
source/blender/src/header_view3d.c
source/blender/src/meshtools.c
source/blender/src/space.c

index b51d844403c80878143bf854ccc017055a928e2f..189adc0a20ae563bec70616d86c2a7f9906c74d9 100644 (file)
@@ -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);
index f5937a3712933ac4b2b2a6b1e1ebfa1d846bd458..d996e119c19f74f01ba52981ac72d1becfeeb6cb 100644 (file)
@@ -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                                             */
 /*****************************************************************************/
index d1b83b45484a61434772fd3d5a60d49566a264b3..a3dc5c397f3d5acf798bed034478e152a9f8f3a0 100644 (file)
@@ -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
index b8630a4ea5a4a08372e7dd1436f3f312d6bfe3c0..6983f19093b69fb149814cc3419572ad35bbaf44 100644 (file)
@@ -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();
index d87450e7a7271179460e614e06ad8ebf9c5a79c0..6c3bbd18df43a8a528ae3b6646ee9e6114991573 100644 (file)
@@ -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);
        
index c3b91f937e8ac6e6f24370ce7d456b1f24151c89..d71f6365198013a5257cb5f628bb57a35b715962 100644 (file)
@@ -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();
index 1ef7320763c0b2c933a1b7bb9cbc02b642fe3d38..8211bcaf8afdb45d74d0a26a496194af0e2c124e 100644 (file)
@@ -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 */
index b89be1ad43699b0cd8bca49b2ad60d2f880857ec..6db820a88e54d34d3cf13084fcf3a35cee9f52ea 100644 (file)
@@ -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();