Moved Object.Join() into a function of an object.
eg. ret_val = ob.join(objects) Now it dosent depend on the current selection, or change the selection context. Made respective join_* functions return 0 if the join was not mode, 1 when it workes.
This commit is contained in:
@@ -115,7 +115,6 @@ 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, PyObject *kwd);
|
||||
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);
|
||||
@@ -144,8 +143,6 @@ 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: */
|
||||
@@ -159,8 +156,6 @@ struct PyMethodDef M_Object_methods[] = {
|
||||
M_Object_GetSelected_doc},
|
||||
{"Duplicate", ( PyCFunction ) M_Object_Duplicate, METH_VARARGS | METH_KEYWORDS,
|
||||
M_Object_Duplicate_doc},
|
||||
{"Join", ( PyCFunction ) M_Object_Join, METH_VARARGS,
|
||||
M_Object_Join_doc},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
@@ -198,6 +193,7 @@ static PyObject *Object_isSelected( BPy_Object * self );
|
||||
static PyObject *Object_makeDisplayList( BPy_Object * self );
|
||||
static PyObject *Object_link( BPy_Object * self, PyObject * args );
|
||||
static PyObject *Object_makeParent( BPy_Object * self, PyObject * args );
|
||||
static PyObject *Object_join( BPy_Object * self, PyObject * args );
|
||||
static PyObject *Object_makeParentDeform( BPy_Object * self, PyObject * args );
|
||||
static PyObject *Object_makeParentVertex( BPy_Object * self, PyObject * args );
|
||||
static PyObject *Object_materialUsage( void );
|
||||
@@ -463,6 +459,8 @@ mode:\n\t0: make parent with inverse\n\t1: without inverse\n\
|
||||
fast:\n\t0: update scene hierarchy automatically\n\t\
|
||||
don't update scene hierarchy (faster). In this case, you must\n\t\
|
||||
explicitely update the Scene hierarchy."},
|
||||
{"join", ( PyCFunction ) Object_join, METH_VARARGS,
|
||||
"(object_list) - Joins the objects in object list of the same type, into this object."},
|
||||
{"makeParentDeform", ( PyCFunction ) Object_makeParentDeform, METH_VARARGS,
|
||||
"Makes the object the deformation parent of the objects provided in the \n\
|
||||
argument which must be a list of valid Objects. Optional extra arguments:\n\
|
||||
@@ -853,73 +851,6 @@ static PyObject *M_Object_Duplicate( PyObject * self, PyObject * args, PyObject
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* 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 */
|
||||
/*****************************************************************************/
|
||||
@@ -1875,6 +1806,125 @@ static PyObject *Object_makeParent( BPy_Object * self, PyObject * args )
|
||||
return EXPP_incr_ret( Py_None );
|
||||
}
|
||||
|
||||
|
||||
static PyObject *Object_join( BPy_Object * self, PyObject * args )
|
||||
{
|
||||
PyObject *list;
|
||||
PyObject *py_child;
|
||||
Object *parent;
|
||||
Object *child;
|
||||
Scene *temp_scene;
|
||||
Scene *orig_scene;
|
||||
Base *temp_base;
|
||||
short type;
|
||||
int i, ok=0, ret_value=0, list_length=0;
|
||||
|
||||
/* cant join in editmode */
|
||||
if( G.obedit )
|
||||
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
||||
"can't join objects while in edit mode" );
|
||||
|
||||
/* Check if the arguments passed to makeParent are valid. */
|
||||
if( !PyArg_ParseTuple( args, "O", &list ) )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
|
||||
"expected a list of objects and one or two integers as arguments" ) );
|
||||
|
||||
if( !PySequence_Check( list ) )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"expected a list of objects" ) );
|
||||
|
||||
list_length = PySequence_Length( list ); /* if there are no objects to join then exit silently */
|
||||
|
||||
if( !list_length )
|
||||
return EXPP_incr_ret( Py_None );
|
||||
|
||||
|
||||
parent = ( Object * ) self->object;
|
||||
type = parent->type;
|
||||
|
||||
if (type==OB_MESH || type==OB_MESH || type==OB_CURVE || type==OB_SURF || type==OB_ARMATURE);
|
||||
else
|
||||
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"Base object is not a type blender can join" ) );
|
||||
|
||||
temp_scene = add_scene( "Scene" ); /* make the new scene */
|
||||
temp_scene->lay= 2097151; /* all layers on */
|
||||
|
||||
/* Check if the PyObject passed in list is a Blender object. */
|
||||
for( i = 0; i < list_length; i++ ) {
|
||||
child = NULL;
|
||||
py_child = PySequence_GetItem( list, i );
|
||||
if( !Object_CheckPyObject( py_child ) ) {
|
||||
/* Cleanup */
|
||||
free_libblock( &G.main->scene, temp_scene );
|
||||
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
|
||||
"expected a list of objects, one or more of the list items is not a Blender Object." ) );
|
||||
} else {
|
||||
/* List item is an object, is it the same type? */
|
||||
child = ( Object * ) Object_FromPyObject( py_child );
|
||||
if (parent->type == child->type) {
|
||||
ok =1;
|
||||
/* Add a new base, then link the base to the temp_scene */
|
||||
temp_base = MEM_callocN( sizeof( Base ), "pynewbase" );
|
||||
/*we know these types are the same, link to the temp scene for joining*/
|
||||
temp_base->object = child; /* link object to the new base */
|
||||
temp_base->flag |= SELECT;
|
||||
temp_base->lay = 1; /*1 layer on */
|
||||
|
||||
BLI_addhead( &temp_scene->base, temp_base ); /* finally, link new base to scene */
|
||||
/*child->id.us += 1;*/ /*Would useually increase user count but in this case its ok not to */
|
||||
} else {
|
||||
child->id.us -= 1; /* python object user oddness */
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
orig_scene = G.scene; /* backup our scene */
|
||||
|
||||
/* Add the main object into the temp_scene */
|
||||
temp_base = MEM_callocN( sizeof( Base ), "pynewbase" );
|
||||
temp_base->object = parent; /* link object to the new base */
|
||||
temp_base->flag |= SELECT;
|
||||
temp_base->lay = 1; /*1 layer on */
|
||||
BLI_addhead( &temp_scene->base, temp_base ); /* finally, link new base to scene */
|
||||
parent->id.us += 1;
|
||||
|
||||
/* all objects in the scene, set it active and the active object */
|
||||
set_scene( temp_scene );
|
||||
set_active_base( temp_base );
|
||||
|
||||
/* Do the joining now we know everythings OK. */
|
||||
if(type == OB_MESH)
|
||||
ret_value = join_mesh();
|
||||
else if(type == OB_CURVE)
|
||||
ret_value = join_curve(OB_CURVE);
|
||||
else if(type == OB_SURF)
|
||||
ret_value = join_curve(OB_SURF);
|
||||
else if(type == OB_ARMATURE)
|
||||
ret_value = join_armature ();
|
||||
/* May use for correcting object user counts */
|
||||
/*
|
||||
if (!ret_value) {
|
||||
temp_base = temp_scene->base.first;
|
||||
while( base ) {
|
||||
object = base->object;
|
||||
object->id.us +=1
|
||||
base = base->next;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
/* remove old scene */
|
||||
set_scene( orig_scene );
|
||||
free_libblock( &G.main->scene, temp_scene );
|
||||
|
||||
if (!ok) /* no objects were of the correct type, return 0 */
|
||||
return ( PyInt_FromLong(0) );
|
||||
|
||||
return ( PyInt_FromLong(ret_value) );
|
||||
}
|
||||
|
||||
static PyObject *internal_makeParent(Object *parent, PyObject *py_child,
|
||||
int partype, /* parenting type */
|
||||
int noninverse, int fast, /* parenting arguments */
|
||||
|
@@ -156,7 +156,7 @@ def Duplicate (mesh=0, surface=0, curve=0, text=0, metaball=0, armature=0, lamp=
|
||||
activeObject.LocX += 1
|
||||
Blender.Redraw()
|
||||
"""
|
||||
|
||||
'''
|
||||
def Join ():
|
||||
"""
|
||||
Joins selected objects on visible layers from Blenders current scene.
|
||||
@@ -168,7 +168,7 @@ def Join ():
|
||||
@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:
|
||||
"""
|
||||
@@ -560,6 +560,20 @@ class Object:
|
||||
unlinked object will result in an error.
|
||||
"""
|
||||
|
||||
def join(objects):
|
||||
"""
|
||||
Uses the object as a base for all of the objects in the provided list to join into.
|
||||
|
||||
@type objects: Sequence of Blender Object
|
||||
@param objects: A list of objects matching the objects type.
|
||||
@note: Objects in the list will not be removed, to avoid duplicate data you may want to remove them manualy after joining.
|
||||
@note: Join modifies the object in place so that other objects are joined into it. no new object or data is created.
|
||||
@note: Join will only work for object types Mesh, Armature, Curve and Surface, an error will be raised if the object is not of this type.
|
||||
@note: objects in the list will be ignored if they to not match the base object.
|
||||
@rtype: int
|
||||
@return: 0 is returned if the join is not successfull, otherwise 1 will be returned.
|
||||
"""
|
||||
|
||||
def makeParentDeform(objects, noninverse = 0, fast = 0):
|
||||
"""
|
||||
Makes the object the deformation parent of the objects provided in the argument
|
||||
|
Reference in New Issue
Block a user