Orange; merger with bf-blender.

(Merging is *not* fun work, especially not with bugfixes in main branch
for code that got cleaned up in the other! Poor Hos... :)
This commit is contained in:
Ton Roosendaal 2006-01-03 21:43:31 +00:00
commit f47899fc0f
62 changed files with 1093 additions and 363 deletions

@ -43,7 +43,7 @@ extern "C" {
struct ListBase;
struct MemFile;
#define BLENDER_VERSION 239
#define BLENDER_VERSION 240
int BKE_read_file(char *dir, void *type_r);
int BKE_read_file_from_memory(char* filebuf, int filelength, void *type_r);

@ -1550,7 +1550,15 @@ static void dag_object_time_update_flags(Object *ob)
{
if(ob->ipo) ob->recalc |= OB_RECALC_OB;
else if(ob->constraints.first) ob->recalc |= OB_RECALC_OB;
else if(ob->constraints.first) {
bConstraint *con;
for (con = ob->constraints.first; con; con=con->next){
if (constraint_has_target(con)) {
ob->recalc |= OB_RECALC_OB;
break;
}
}
}
else if(ob->scriptlink.totscript) ob->recalc |= OB_RECALC_OB;
else if(ob->parent) {
/* motion path or bone child */

@ -1210,9 +1210,15 @@ static void *booleanModifier_applyModifier(ModifierData *md, Object *ob, void *d
if( ((Mesh *)ob->data)->totface>3 && bmd->object && ((Mesh *)bmd->object->data)->totface>3) {
DispListMesh *dlm= NewBooleanMeshDLM(bmd->object, ob, 1+bmd->operation);
return derivedmesh_from_displistmesh(dlm, NULL);
/* if new mesh returned, get derived mesh; otherwise there was
* an error, so delete the modifier object */
if( dlm )
return derivedmesh_from_displistmesh(dlm, NULL);
else
bmd->object = NULL;
}
else return derivedData;
return derivedData;
}
/***/

@ -625,6 +625,9 @@ static BHeadN *get_bhead(FileData *fd)
}
}
/* make sure people are not trying to pass bad blend files */
if (bhead.len < 0) fd->eof = 1;
// bhead now contains the (converted) bhead structure. Now read
// the associated data and put everything in a BHeadN (creative naming !)
@ -639,6 +642,7 @@ static BHeadN *get_bhead(FileData *fd)
if (readsize != bhead.len) {
fd->eof = 1;
MEM_freeN(new_bhead);
new_bhead = 0;
}
} else {
fd->eof = 1;
@ -5205,12 +5209,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
cam->flag |= CAM_SHOWPASSEPARTOUT;
/* make sure old cameras have title safe on */
/* *** to be uncommented before 2.40 release! *** */
/*
if (!(cam->flag & CAM_SHOWTITLESAFE))
cam->flag |= CAM_SHOWTITLESAFE;
*/
/* set an appropriate camera passepartout alpha */
if (!(cam->passepartalpha)) cam->passepartalpha = 0.2f;
@ -5222,11 +5222,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
ma->mode |= MA_TANGENT_STR;
}
if(ma->mode & MA_TRACEBLE) ma->mode |= MA_SHADBUF;
/* orange stuff, so should be done for 2.40 too */
if(ma->layers.first==NULL) {
ma->ml_flag= ML_RENDER;
}
}
}

@ -303,7 +303,7 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
{
TIFF *image = NULL;
struct ImBuf *ibuf = NULL;
struct ImbTIFFMemFile memFile = { mem, 0, size };
struct ImbTIFFMemFile memFile;
uint32 width, height;
int bytesperpixel;
int success;
@ -312,6 +312,10 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
uint32 pixel;
unsigned char *to = NULL;
memFile.mem = mem;
memFile.offset = 0;
memFile.size = size;
/* check whether or not we have a TIFF file */
assert(size >= IMB_TIFF_NCB);
if (imb_is_a_tiff(mem) == 0)

@ -81,7 +81,7 @@ void selectrow_nurb(void);
void adduplicate_nurb(void);
void delNurb(void);
void nurb_set_smooth(short event);
void join_curve(int type);
int join_curve(int type);
struct Nurb *addNurbprim(int type, int stype, int newname);
void default_curve_ipo(struct Curve *cu);
void add_primitiveCurve(int stype);

@ -92,7 +92,7 @@ void single_tex_users_expand(void);
void single_mat_users_expand(void);
void single_user(void);
void make_local(void);
void adduplicate(int noTrans);
void adduplicate(int mode, int dupflag); /* when the dupflag is 0 no data is duplicated */
void selectlinks_menu(void);
void selectlinks(int nr);
void image_aspect(void);

@ -87,7 +87,7 @@ void subdivide_armature(void);
void free_editArmature(void);
void join_armature(void);
int join_armature(void);
void load_editArmature(void);
void make_bone_parent(void);

@ -36,7 +36,7 @@
struct Object;
struct EditVert;
extern void join_mesh(void);
extern int join_mesh(void);
extern void fasterdraw(void);
extern void slowerdraw(void);

@ -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_grouped(short nr);
extern void join_menu(void);
extern void BIF_undo_push(char *str);
extern void BIF_undo(void);

@ -172,28 +172,25 @@ static int BonesDict_InitEditBones(BPy_BonesDict *self)
//This is the string representation of the object
static PyObject *BonesDict_repr(BPy_BonesDict *self)
{
char buffer[128], str[4096];
char str[4096];
PyObject *key, *value;
int pos = 0;
char *p = str;
p += sprintf(str, "[Bone Dict: {");
BLI_strncpy(str,"",4096);
sprintf(buffer, "[Bone Dict: {");
strcat(str,buffer);
if (self->editmode_flag){
while (PyDict_Next(self->editbonesMap, &pos, &key, &value)) {
sprintf(buffer, "%s : %s, ", PyString_AsString(key),
p += sprintf(p, "%s : %s, ", PyString_AsString(key),
PyString_AsString(value->ob_type->tp_repr(value)));
strcat(str,buffer);
}
}else{
while (PyDict_Next(self->bonesMap, &pos, &key, &value)) {
sprintf(buffer, "%s : %s, ", PyString_AsString(key),
p += sprintf(p, "%s : %s, ", PyString_AsString(key),
PyString_AsString(value->ob_type->tp_repr(value)));
strcat(str,buffer);
}
}
sprintf(buffer, "}]\n");
strcat(str,buffer);
p += sprintf(p, "}]\n");
return PyString_FromString(str);
}

@ -136,43 +136,55 @@ PyTypeObject BezTriple_Type = {
static PyObject *M_BezTriple_New( PyObject* self, PyObject * args )
{
float numbuf[9];
int status, length;
PyObject* in_args = NULL;
int length;
if( !PyArg_ParseTuple( args, "|O", &in_args) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected sequence of 3 or 9 floats or nothing" );
/* accept list, tuple, or 3 or 9 args (which better be floats) */
length = PyTuple_Size( args );
if( length == 3 || length == 9 )
in_args = args;
else if( !PyArg_ParseTuple( args, "|O", &in_args) )
goto TypeError;
if( !in_args ) {
numbuf[0] = 0.0f; numbuf[1] = 0.0f; numbuf[2] = 0.0f;
numbuf[3] = 0.0f; numbuf[4] = 0.0f; numbuf[5] = 0.0f;
numbuf[6] = 0.0f; numbuf[7] = 0.0f; numbuf[8] = 0.0f;
} else {
int i, length;
if( !PySequence_Check( in_args ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected sequence of 3 or 9 floats or nothing" );
goto TypeError;
length = PySequence_Length( in_args );
if( length == 9 )
status = PyArg_ParseTuple( in_args, "fffffffff",
&numbuf[0], &numbuf[1], &numbuf[2],
&numbuf[3], &numbuf[4], &numbuf[5],
&numbuf[6], &numbuf[7], &numbuf[8]);
else if( length == 3 ) {
status = PyArg_ParseTuple( in_args, "fff",
&numbuf[0], &numbuf[1], &numbuf[2]);
if( length != 9 && length != 3 )
goto TypeError;
for(i=0; i<length; i++) {
PyObject *item, *pyfloat;
item=PySequence_ITEM(in_args, i);
if( !item )
goto TypeError;
pyfloat=PyNumber_Float(item);
Py_DECREF(item);
if( !pyfloat )
goto TypeError;
numbuf[i]=(float)PyFloat_AS_DOUBLE(pyfloat);
Py_DECREF(pyfloat);
}
if( length == 3 ) {
numbuf[3] = numbuf[0]; numbuf[6] = numbuf[0];
numbuf[4] = numbuf[1]; numbuf[7] = numbuf[1];
numbuf[5] = numbuf[2]; numbuf[8] = numbuf[2];
} else
return EXPP_ReturnPyObjError( PyExc_TypeError,
"wrong number of points" );
if( !status )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"sequence item not number");
}
}
return newBezTriple( numbuf );
TypeError:
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected sequence of 3 or 9 floats or nothing" );
}
/****************************************************************************

@ -84,6 +84,7 @@
#define EXPP_LAMP_MODE_DEEPSHADOW 1024
#define EXPP_LAMP_MODE_NODIFFUSE 2048
#define EXPP_LAMP_MODE_NOSPECULAR 4096
#define EXPP_LAMP_MODE_SHAD_RAY 8192
/* Lamp MIN, MAX values */
#define EXPP_LAMP_SAMPLES_MIN 1
@ -120,8 +121,8 @@
/* Raytracing settings */
#define EXPP_LAMP_RAYSAMPLES_MIN 1
#define EXPP_LAMP_RAYSAMPLES_MAX 16
#define EXPP_LAMP_AREASIZE_MIN 0.01
#define EXPP_LAMP_AREASIZE_MAX 100.0
#define EXPP_LAMP_AREASIZE_MIN 0.01f
#define EXPP_LAMP_AREASIZE_MAX 100.0f
/* Lamp_setComponent() keys for which color to get/set */
#define EXPP_LAMP_COMP_R 0x00
@ -781,8 +782,8 @@ static PyObject *Lamp_ModesDict( void )
PyInt_FromLong( EXPP_LAMP_MODE_ONLYSHADOW ) );
PyConstant_Insert( c, "NoDiffuse",
PyInt_FromLong( EXPP_LAMP_MODE_NODIFFUSE ) );
PyConstant_Insert( c, "NoSpecular",
PyInt_FromLong( EXPP_LAMP_MODE_NOSPECULAR ) );
PyConstant_Insert( c, "RayShadow",
PyInt_FromLong( EXPP_LAMP_MODE_SHAD_RAY ) );
}
return Modes;
@ -1165,7 +1166,8 @@ static int Lamp_setMode( BPy_Lamp * self, PyObject * value )
| EXPP_LAMP_MODE_SPHERE
| EXPP_LAMP_MODE_SQUARE
| EXPP_LAMP_MODE_NODIFFUSE
| EXPP_LAMP_MODE_NOSPECULAR;
| EXPP_LAMP_MODE_NOSPECULAR
| EXPP_LAMP_MODE_SHAD_RAY;
if( !PyInt_CheckExact ( value ) ) {
char errstr[128];
@ -1550,7 +1552,7 @@ static PyObject *Lamp_insertIpoKey( BPy_Lamp * self, PyObject * args )
static PyObject *Lamp_getModesConst( void )
{
PyObject * attr = Py_BuildValue
( "{s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h}",
( "{s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h,s:h}",
"Shadows", EXPP_LAMP_MODE_SHADOWS, "Halo",
EXPP_LAMP_MODE_HALO, "Layer", EXPP_LAMP_MODE_LAYER,
"Quad", EXPP_LAMP_MODE_QUAD, "Negative",
@ -1559,7 +1561,8 @@ static PyObject *Lamp_getModesConst( void )
EXPP_LAMP_MODE_SPHERE, "Square",
EXPP_LAMP_MODE_SQUARE, "NoDiffuse",
EXPP_LAMP_MODE_NODIFFUSE, "NoSpecular",
EXPP_LAMP_MODE_NOSPECULAR );
EXPP_LAMP_MODE_NOSPECULAR, "RayShadow",
EXPP_LAMP_MODE_SHAD_RAY);
if( !attr )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@ -1804,6 +1807,8 @@ static PyObject *Lamp_oldsetMode( BPy_Lamp * self, PyObject * args )
flag |= ( short ) EXPP_LAMP_MODE_NODIFFUSE;
else if( !strcmp( name, "NoSpecular" ) )
flag |= ( short ) EXPP_LAMP_MODE_NOSPECULAR;
else if( !strcmp( name, "RayShadow" ) )
flag |= ( short ) EXPP_LAMP_MODE_SHAD_RAY;
else
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"unknown lamp flag argument" );

@ -522,6 +522,8 @@ static PyObject *Material_getColorComponent( BPy_Material * self,
static PyObject *Material_getOopsLoc( BPy_Material * self );
static PyObject *Material_getOopsSel( BPy_Material * self );
static PyObject *Material_getUsers( BPy_Material * self );
static int Material_setSeptex( BPy_Material * self, PyObject * value );
static PyObject *Material_getSeptex( BPy_Material * self );
/*****************************************************************************/
/* Python BPy_Material methods declarations: */
@ -2891,17 +2893,20 @@ static PyObject *Matr_oldsetZOffset( BPy_Material * self, PyObject * args )
static PyObject *Matr_oldsetRGBCol( BPy_Material * self, PyObject * args )
{
return EXPP_setterWrapper( (void *)self, args, (setter)Material_setRGBCol );
return EXPP_setterWrapperTuple( (void *)self, args,
(setter)Material_setRGBCol );
}
static PyObject *Matr_oldsetSpecCol( BPy_Material * self, PyObject * args )
{
return EXPP_setterWrapper( (void *)self, args, (setter)Material_setSpecCol );
return EXPP_setterWrapperTuple( (void *)self, args,
(setter)Material_setSpecCol );
}
static PyObject *Matr_oldsetMirCol( BPy_Material * self, PyObject * args )
{
return EXPP_setterWrapper( (void *)self, args, (setter)Material_setMirCol );
return EXPP_setterWrapperTuple( (void *)self, args,
(setter)Material_setMirCol );
}

@ -4084,7 +4084,7 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
/* eliminate new faces already in the mesh */
tmppair = newpair;
for( i = len; i-- ; ) {
for( i = good_faces; i-- ; ) {
if( tmppair->v[1] ) {
if( bsearch( tmppair, oldpair, mesh->totface,
sizeof(SrchFaces), mface_comp ) ) {
@ -4101,6 +4101,16 @@ static PyObject *MFaceSeq_extend( BPy_MEdgeSeq * self, PyObject *args )
if( good_faces ) {
int totface = mesh->totface+good_faces; /* new face count */
/* if mesh has tfaces, reallocate them first */
if( mesh->tface ) {
TFace *tmptface;
tmptface = MEM_callocN(totface*sizeof(TFace), "Mesh_addFaces");
memcpy( tmptface, mesh->tface, mesh->totface*sizeof(TFace));
MEM_freeN( mesh->tface );
mesh->tface = tmptface;
}
/* allocate new face list */
tmpface = MEM_callocN(totface*sizeof(MFace), "Mesh_addFaces");
@ -4761,11 +4771,11 @@ static PyObject *Mesh_getFromObject( BPy_Mesh * self, PyObject * args )
char *name;
ID tmpid;
Mesh *tmpmesh;
Curve *tmpcu;
Curve *tmpcu = NULL;
DispListMesh *dlm;
DerivedMesh *dm;
Object *tmpobj = NULL;
int cage = 0;
int cage = 0, i;
if( !PyArg_ParseTuple( args, "s|i", &name, &cage ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
@ -4839,7 +4849,8 @@ static PyObject *Mesh_getFromObject( BPy_Mesh * self, PyObject * args )
displistmesh_to_mesh( dlm, tmpmesh );
dm->release( dm );
}
/* take control of mesh before object is freed */
tmpobj->data = NULL;
free_libblock_us( &G.main->object, tmpobj );
@ -4855,11 +4866,60 @@ static PyObject *Mesh_getFromObject( BPy_Mesh * self, PyObject * args )
tmpid = self->mesh->id;
memcpy( self->mesh, tmpmesh, sizeof( Mesh ) );
self->mesh->id = tmpid;
/* if mesh has keys, make sure they point back to this mesh */
if( self->mesh->key )
self->mesh->key->from = (ID *)self->mesh;
/* Copy materials to new object */
switch (ob->type) {
case OB_SURF:
self->mesh->totcol = tmpcu->totcol;
/* free old material list (if it exists) and adjust user counts */
if( tmpcu->mat ) {
for( i = tmpcu->totcol; i-- > 0; ) {
self->mesh->mat[i] = tmpcu->mat[i];
if (self->mesh->mat[i]) {
tmpmesh->mat[i]->id.us++;
}
}
}
break;
#if 0
/* Crashes when assigning the new material, not sure why */
case OB_MBALL:
tmpmb = (MetaBall *)ob->data;
self->mesh->totcol = tmpmb->totcol;
/* free old material list (if it exists) and adjust user counts */
if( tmpmb->mat ) {
for( i = tmpmb->totcol; i-- > 0; ) {
self->mesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
if (self->mesh->mat[i]) {
tmpmb->mat[i]->id.us++;
}
}
}
break;
#endif
case OB_MESH:
self->mesh->totcol = tmpmesh->totcol;
if( tmpmesh->mat ) {
for( i = tmpmesh->totcol; i-- > 0; ) {
self->mesh->mat[i] = tmpmesh->mat[i];
/* user count dosent need to change */
}
}
break;
} /* end copy materials */
/* remove the temporary mesh */
BLI_remlink( &G.main->mesh, tmpmesh );
MEM_freeN( tmpmesh );

@ -317,6 +317,77 @@ void mesh_update( Mesh * mesh, Object * ob )
}
}
/*
* before trying to convert NMesh data back to mesh, verify that the
* lists contain the right type of data
*/
static int check_NMeshLists( BPy_NMesh *nmesh )
{
int i;
if( !PySequence_Check( nmesh->verts ) )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh verts are not a sequence" );
if( !PySequence_Check( nmesh->edges ) )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh edges are not a sequence" );
if( !PySequence_Check( nmesh->faces ) )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh faces are not a sequence" );
if( !PySequence_Check( nmesh->materials ) )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh materials are not a sequence" );
if( EXPP_check_sequence_consistency( nmesh->verts, &NMVert_Type ) != 1 )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh vertices must be NMVerts" );
if( EXPP_check_sequence_consistency( nmesh->edges, &NMEdge_Type ) != 1 )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh edges must be NMEdges" );
if( EXPP_check_sequence_consistency( nmesh->faces, &NMFace_Type ) != 1 )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh faces must be NMFaces" );
for( i = 0 ; i < PySequence_Length(nmesh->faces); ++i ) {
int j, err=0;
PyObject *col, *v, *uv;
BPy_NMFace *face=(BPy_NMFace *)PySequence_GetItem(nmesh->faces, i);
col = face->col;
uv = face->uv;
v = face->v;
Py_DECREF( face );
if( EXPP_check_sequence_consistency( face->col, &NMCol_Type ) != 1 ) {
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh face col must be NMCols" );
}
if( EXPP_check_sequence_consistency( face->v, &NMVert_Type ) != 1 )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh face v must be NMVerts" );
for( j = 0 ; !err && j < PySequence_Length( face->uv ); ++j ) {
PyObject *uv = PySequence_GetItem( face->uv, j);
if( PySequence_Check(uv) && PySequence_Length(uv) == 2 ) {
PyObject *p1 = PySequence_GetItem(uv, 0);
PyObject *p2 = PySequence_GetItem(uv, 1);
if( !PyNumber_Check(p1) || !PyNumber_Check(p2) )
err = 1;
Py_DECREF( p1 );
Py_DECREF( p2 );
}
else {
err = 1;
}
Py_DECREF( uv );
}
if( err )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh face uv must contain sequence of 2 floats" );
}
return 0;
}
/*****************************/
/* Mesh Color Object */
@ -602,7 +673,7 @@ static int NMFace_setattr( PyObject * self, char *name, PyObject * v )
if( strcmp( name, "v" ) == 0 ) {
if( PyList_Check( v ) ) {
if( PySequence_Check( v ) ) {
Py_DECREF( mf->v );
mf->v = EXPP_incr_ret( v );
@ -610,7 +681,7 @@ static int NMFace_setattr( PyObject * self, char *name, PyObject * v )
}
} else if( strcmp( name, "col" ) == 0 ) {
if( PyList_Check( v ) ) {
if( PySequence_Check( v ) ) {
Py_DECREF( mf->col );
mf->col = EXPP_incr_ret( v );
@ -642,7 +713,7 @@ static int NMFace_setattr( PyObject * self, char *name, PyObject * v )
} else if( strcmp( name, "uv" ) == 0 ) {
if( PyList_Check( v ) ) {
if( PySequence_Check( v ) ) {
Py_DECREF( mf->uv );
mf->uv = EXPP_incr_ret( v );
@ -1327,6 +1398,9 @@ static PyObject *NMesh_update( PyObject *self, PyObject *a, PyObject *kwd )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected nothing or one to three bool(s) (0 or 1) as argument" );
if( check_NMeshLists( nmesh ) )
return NULL;
if( mesh ) {
old_totvert = mesh->totvert;
unlink_existingMeshData( mesh );
@ -1767,7 +1841,7 @@ static int NMesh_setattr( PyObject * self, char *name, PyObject * v )
else if( !strcmp( name, "verts" ) || !strcmp( name, "faces" ) ||
!strcmp( name, "materials" ) ) {
if( PyList_Check( v ) ) {
if( PySequence_Check( v ) ) {
if( strcmp( name, "materials" ) == 0 ) {
Py_DECREF( me->materials );
@ -2988,6 +3062,10 @@ static int convert_NMeshToMesh( Mesh * mesh, BPy_NMesh * nmesh)
mesh->subdiv = nmesh->subdiv[0];
mesh->subdivr = nmesh->subdiv[1];
/*@ material assignment moved to PutRaw */
mesh->totvert = PySequence_Length( nmesh->verts );
if( mesh->totvert ) {
@ -3144,24 +3222,8 @@ static PyObject *M_NMesh_PutRaw( PyObject * self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected an NMesh object and optionally also a string and two ints" );
if( !PySequence_Check( nmesh->verts ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"nmesh vertices are not a sequence" );
if( !PySequence_Check( nmesh->faces ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"nmesh faces are not a sequence" );
if( !PySequence_Check( nmesh->materials ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"nmesh materials are not a sequence" );
if( EXPP_check_sequence_consistency( nmesh->verts, &NMVert_Type ) !=
1 )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"nmesh vertices must be NMVerts" );
if( EXPP_check_sequence_consistency( nmesh->faces, &NMFace_Type ) !=
1 )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"nmesh faces must be NMFaces" );
if( check_NMeshLists( nmesh ) )
return NULL;
if( name )
mesh = ( Mesh * ) GetIdFromList( &( G.main->mesh ), name );

@ -62,12 +62,16 @@ struct rctf;
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_scene.h"
#include "BSE_editipo.h"
#include "BSE_edit.h"
#include "BIF_space.h"
#include "BIF_editview.h"
#include "BIF_drawscene.h"
#include "BIF_meshtools.h"
#include "BIF_editarmature.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
@ -123,6 +127,7 @@ struct rctf;
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);
/* 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);
@ -148,6 +153,10 @@ char M_Object_GetSelected_doc[] =
"() - Returns a list of selected Objects in the active layer(s)\n\
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";
/*****************************************************************************/
/* Python method structure definition for Blender.Object module: */
/*****************************************************************************/
@ -158,9 +167,12 @@ struct PyMethodDef M_Object_methods[] = {
M_Object_Get_doc},
{"GetSelected", ( PyCFunction ) M_Object_GetSelected, METH_NOARGS,
M_Object_GetSelected_doc},
{"Duplicate", ( PyCFunction ) M_Object_Duplicate, METH_VARARGS | METH_KEYWORDS,
M_Object_Duplicate_doc},
{NULL, NULL, 0, NULL}
};
/*****************************************************************************/
/* Python BPy_Object methods declarations: */
/*****************************************************************************/
@ -195,6 +207,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 );
@ -466,6 +479,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\
@ -779,12 +794,13 @@ static PyObject *M_Object_GetSelected( PyObject * self )
PyObject *list;
Base *base_iter;
if( G.vd == NULL ) {
// No 3d view has been initialized yet, simply return None
Py_INCREF( Py_None );
return Py_None;
}
list = PyList_New( 0 );
if( G.vd == NULL ) {
/* No 3d view has been initialized yet, simply return an empty list */
return list;
}
if( ( G.scene->basact ) &&
( ( G.scene->basact->flag & SELECT ) &&
( G.scene->basact->lay & G.vd->lay ) ) ) {
@ -802,22 +818,66 @@ static PyObject *M_Object_GetSelected( PyObject * self )
base_iter = G.scene->base.first;
while( base_iter ) {
if( ( ( base_iter->flag & SELECT ) &&
( base_iter->lay & G.vd->lay ) ) &&
( base_iter->lay & G.vd->lay ) ) &&
( base_iter != G.scene->basact ) ) {
blen_object = Object_CreatePyObject( base_iter->object );
if( !blen_object ) {
Py_DECREF( list );
Py_RETURN_NONE;
if( blen_object ) {
PyList_Append( list, blen_object );
Py_DECREF( blen_object );
}
PyList_Append( list, blen_object );
Py_DECREF( blen_object );
}
base_iter = base_iter->next;
}
return list;
}
/*****************************************************************************/
/* Function: M_Object_Duplicate */
/* Python equivalent: Blender.Object.Duplicate */
/*****************************************************************************/
static PyObject *M_Object_Duplicate( PyObject * self, PyObject * args, PyObject *kwd )
{
int dupflag= 0; /* this a flag, passed to adduplicate() and used instead of U.dupflag sp python can set what is duplicated */
/* the following variables are bools, if set true they will modify the dupflag to pass to adduplicate() */
int mesh_dupe = 0;
int surface_dupe = 0;
int curve_dupe = 0;
int text_dupe = 0;
int metaball_dupe = 0;
int armature_dupe = 0;
int lamp_dupe = 0;
int material_dupe = 0;
int texture_dupe = 0;
int ipo_dupe = 0;
static char *kwlist[] = {"mesh", "surface", "curve",
"text", "metaball", "armature", "lamp", "material", "texture", "ipo", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwd, "|iiiiiiiiii", kwlist,
&mesh_dupe, &surface_dupe, &curve_dupe, &text_dupe, &metaball_dupe,
&armature_dupe, &lamp_dupe, &material_dupe, &texture_dupe, &ipo_dupe))
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected nothing or bool keywords 'mesh', 'surface', 'curve', 'text', 'metaball', 'armature', 'lamp' 'material', 'texture' and 'ipo' as arguments" );
/* USER_DUP_ACT for actions is not supported in the UI so dont support it here */
if (mesh_dupe) dupflag |= USER_DUP_MESH;
if (surface_dupe) dupflag |= USER_DUP_SURF;
if (curve_dupe) dupflag |= USER_DUP_CURVE;
if (text_dupe) dupflag |= USER_DUP_FONT;
if (metaball_dupe) dupflag |= USER_DUP_MBALL;
if (armature_dupe) dupflag |= USER_DUP_ARM;
if (lamp_dupe) dupflag |= USER_DUP_LAMP;
if (material_dupe) dupflag |= USER_DUP_MAT;
if (texture_dupe) dupflag |= USER_DUP_TEX;
if (ipo_dupe) dupflag |= USER_DUP_IPO;
adduplicate(2, dupflag); /* 2 is a mode with no transform and no redraw, Duplicate the current selection, context sensitive */
Py_RETURN_NONE;
}
/*****************************************************************************/
/* Function: initObject */
/*****************************************************************************/
@ -970,7 +1030,8 @@ int EXPP_add_obdata( struct Object *object )
object->data = add_mball( );
break;
/* TODO the following types will be supported later
/* TODO the following types will be supported later,
be sure to update Scene_link when new types are supported
case OB_SURF:
object->data = add_curve(OB_SURF);
G.totcurve++;
@ -1783,6 +1844,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 */

@ -734,6 +734,7 @@ static PyObject *Scene_link( BPy_Scene * self, PyObject * args )
{
Scene *scene = self->scene;
BPy_Object *bpy_obj;
Object *object = NULL;
if( !scene )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@ -742,9 +743,19 @@ static PyObject *Scene_link( BPy_Scene * self, PyObject * args )
if( !PyArg_ParseTuple( args, "O!", &Object_Type, &bpy_obj ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected Object argument" );
else { /* Ok, all is fine, let's try to link it */
Object *object = bpy_obj->object;
//return EXPP_ReturnPyObjError( PyExc_RuntimeError,
// "Could not create data on demand for this object type!" );
object = bpy_obj->object;
/* Object.c's EXPP_add_obdata does not support these objects */
if (!object->data && (object->type == OB_SURF || object->type == OB_FONT || object->type == OB_WAVE )) {
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Object has no data and new data cant be automaticaly created for Surf, Text or Wave type objects!" );
} else {
/* Ok, all is fine, let's try to link it */
Base *base;
/* We need to link the object to a 'Base', then link this base
@ -766,8 +777,9 @@ static PyObject *Scene_link( BPy_Scene * self, PyObject * args )
"couldn't allocate new Base for object" );
/* check if this object has obdata, case not, try to create it */
if( !object->data && ( object->type != OB_EMPTY ) )
EXPP_add_obdata( object ); /* returns -1 on error, defined in Object.c */
EXPP_add_obdata( object ); /* returns -1 on error, defined in Object.c */
base->object = object; /* link object to the new base */
base->lay = object->lay;
@ -823,7 +835,6 @@ static PyObject *Scene_getChildren( BPy_Scene * self )
PyObject *bpy_obj;
Object *object;
Base *base;
PyObject *name;
if( !scene )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
@ -833,22 +844,16 @@ static PyObject *Scene_getChildren( BPy_Scene * self )
while( base ) {
object = base->object;
name = Py_BuildValue( "(s)", object->id.name + 2 );
if( !name )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Py_BuildValue() failed" );
bpy_obj = M_Object_Get( Py_None, name );
Py_DECREF ( name );
bpy_obj = Object_CreatePyObject( object );
if( !bpy_obj )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't create new object wrapper" );
PyList_Append( pylist, bpy_obj );
Py_XDECREF( bpy_obj ); /* PyList_Append incref'ed it */
base = base->next;
}
@ -869,11 +874,7 @@ static PyObject *Scene_getActiveObject(BPy_Scene *self)
ob = ((scene->basact) ? (scene->basact->object) : 0);
if (ob) {
PyObject *arg = Py_BuildValue("(s)", ob->id.name+2);
pyob = M_Object_Get(Py_None, arg);
Py_DECREF(arg);
pyob = Object_CreatePyObject( ob );
if (!pyob)
return EXPP_ReturnPyObjError(PyExc_MemoryError,
@ -889,8 +890,9 @@ static PyObject *Scene_getActiveObject(BPy_Scene *self)
static PyObject *Scene_getCurrentCamera( BPy_Scene * self )
{
Object *cam_obj;
PyObject *pyob;
Scene *scene = self->scene;
if( !scene )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Blender Scene was deleted!" );
@ -898,16 +900,11 @@ static PyObject *Scene_getCurrentCamera( BPy_Scene * self )
cam_obj = scene->camera;
if( cam_obj ) { /* if found, return a wrapper for it */
PyObject *camera = NULL;
PyObject *name = Py_BuildValue( "(s)", cam_obj->id.name + 2 );
if( !name )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Py_BuildValue() failed" );
camera = M_Object_Get( Py_None, name );
Py_DECREF ( name );
return camera;
pyob = Object_CreatePyObject( cam_obj );
if (!pyob)
return EXPP_ReturnPyObjError(PyExc_MemoryError,
"couldn't create new object wrapper!");
return pyob;
}
Py_INCREF( Py_None ); /* none found */

@ -410,6 +410,17 @@ class BezTriple:
@type hide: int
"""
def __init__(coords):
"""
Create a new BezTriple object.
@type coords: sequence of three or nine floats
@param coords: the coordinate values for the new control point. If three
floats are given, then the handle values are automatically generated.
@rtype: BezTriple
@return: a new BezTriple object
"""
def getPoints():
"""
Returns the xy coordinates of the Bezier knot point.

@ -14,7 +14,7 @@ Example::
from Blender import Lamp
l = Lamp.New('Spot') # create new 'Spot' lamp data
l.setMode('square', 'shadow') # set these two lamp mode flags
l.setMode('Square', 'Shadow') # set these two lamp mode flags
ob = Object.New('Lamp') # create new lamp object
ob.link(l) # link lamp obj with lamp data
@ -36,6 +36,8 @@ Example::
- 'OnlyShadow'
- 'Sphere'
- 'Square'
- 'NoDiffuse'
- 'RayShadow'
"""
def New (type = 'Lamp', name = 'LampData'):

@ -530,9 +530,9 @@ class MFaceSeq:
me = Mesh.Get("Plane") # get the mesh data called "Plane"
v = me.verts # get vertices
if len(v) >= 6: # if there are enough vertices...
me.face.extend(v[1],v[2],v[3]) # add a single edge
me.faces.extend(v[1],v[2],v[3]) # add a single edge
l=[(v[0],v[1]),(v[0],v[2],v[4],v[5])]
me.face.extend(l) # add another face
me.faces.extend(l) # add another face
@type vertseq: tuple(s) of MVerts
@param vertseq: either two to four MVerts, or sequence (list or tuple)
@ -583,6 +583,8 @@ class Mesh:
B{Note}: L{Object.colbits<Object.Object.colbits>} needs to be set correctly
for each object in order for these materials to be used instead of
the object's materials.
B{Note}: Making the material list shorter does not change the faces material indicies,
take care when using the faces material indices to reference a material in the materials list.
@type materials: list of Materials
@ivar degr: The max angle for auto smoothing in [1,80].
@type degr: int
@ -630,6 +632,8 @@ class Mesh:
@note: The mesh coordinates are in I{local space}, not the world space of
its object. For world space vertex coordinates, each vertex location must
be multiplied by the object's 4x4 transform matrix (see L{transform}).
@note: The objects materials will not be copied into the existing mesh,
however the face material indices will match the material list of the original data.
@type name: string
@param name: name of the Blender object which contains the geometry data.
@type cage: int

@ -37,11 +37,12 @@ def New (type, name='type'):
"""
Creates a new Object.
@type type: string
@param type: The Object type: 'Armature', 'Camera', 'Curve', 'Lamp', 'Mesh'
or 'Empty'.
@param type: The Object type: 'Armature', 'Camera', 'Curve', 'Lamp', 'Lattice',
'Mball', 'Mesh', 'Surf' or 'Empty'.
@type name: string
@param name: The name of the object. By default, the name will be the same
as the object type.
If the name is alredy in use, this new object will have a number at the end of the name.
@return: The created Object.
I{B{Example:}}
@ -50,11 +51,11 @@ def New (type, name='type'):
location (0, 0, 0) in the current scene::
import Blender
object = Blender.Object.New ('Lamp')
lamp = Blender.Lamp.New ('Spot')
object.link (lamp)
scene = Blender.Scene.getCurrent ()
scene.link (object)
object = Blender.Object.New('Lamp')
lamp = Blender.Lamp.New('Spot')
object.link(lamp)
scene = Blender.Scene.GetCurrent()
scene.link(object)
Blender.Redraw()
"""
@ -70,8 +71,7 @@ def Get (name = None):
I{B{Example 1:}}
The example below works on the default scene. The script returns the plane
object and prints the location of the plane::
The example below works on the default scene. The script returns the plane object and prints the location of the plane::
import Blender
object = Blender.Object.Get ('plane')
@ -85,12 +85,15 @@ def Get (name = None):
objects = Blender.Object.Get ()
print objects
@note: Get will return objects from all scenes.
Most user tools should only operate on objects from the current scene - Blender.Scene.GetCurrent().getChildren()
"""
def GetSelected ():
"""
Get the selected objects from Blender. If no objects are selected, an empty
Get the selected objects on visible layers from Blenders current scene. If no objects are selected, an empty
list will be returned.
The active object of the current scene will always be the first object in the list (if selected).
@return: A list of all selected Objects in the current scene.
I{B{Example:}}
@ -99,10 +102,74 @@ def GetSelected ():
the script will print the selected objects::
import Blender
objects = Blender.Object.GetSelected ()
objects = Blender.Object.GetSelected()
print objects
"""
def Duplicate (mesh=0, surface=0, curve=0, text=0, metaball=0, armature=0, lamp=0, material=0, texture=0, ipo=0):
"""
Duplicate selected objects on visible layers from Blenders current scene,
de-selecting the currently visible, selected objects and making a copy where all new objects are selected.
By default no data linked to the object is duplicated, use the kayword arguments to change this.
Object.GetSelected() will return the list of objects resulting from duplication.
@type mesh: bool
@param mesh: When non zero, mesh object data will be duplicated with the objects.
@type surface: bool
@param surface: When non zero, surface object data will be duplicated with the objects.
@type curve: bool
@param curve: When non zero, curve object data will be duplicated with the objects.
@type text: bool
@param text: When non zero, text object data will be duplicated with the objects.
@type metaball: bool
@param metaball: When non zero, metaball object data will be duplicated with the objects.
@type armature: bool
@param armature: When non zero, armature object data will be duplicated with the objects.
@type lamp: bool
@param lamp: When non zero, lamp object data will be duplicated with the objects.
@type material: bool
@param material: When non zero, materials used my the object or its object data will be duplicated with the objects.
@type texture: bool
@param texture: When non zero, texture data used by the objects materials will be duplicated with the objects.
@type ipo: bool
@param ipo: When non zero, ipo data linked to the object will be duplicated with the objects.
@return: None
I{B{Example:}}
The example below creates duplicates the active object 10 times
and moves each object 1.0 on the X axis::
import Blender
scn = Scene.GetCurrent()
activeObject = scn.getActiveObject()
# Unselect all
for ob in Blender.Object.GetSelected():
ob.sel = 0
activeObject.sel = 1
for x in xrange(10):
Blender.Object.Duplicate() # Duplicate linked
activeObject = scn.getActiveObject()
activeObject.LocX += 1
Blender.Redraw()
"""
'''
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
@ -187,22 +254,22 @@ class Object:
of: 2 - axis, 4 - texspace, 8 - drawname, 16 - drawimage,
32 - drawwire.
@ivar name: The name of the object.
@ivar sel: The selection state of the object in the current scene, 1 is selected, 0 is unselected.
@ivar sel: The selection state of the object in the current scene, 1 is selected, 0 is unselected. (Selecting makes the object active)
@ivar effects: The list of particle effects associated with the object. (Read-only)
@ivar parentbonename: The string name of the parent bone.
@ivar users: The number of users of the object. Read-only.
@type users: int
@ivar protectFlags: The "transform locking" bitfield flags for the object.
Setting bits lock the following attributes:
- bit 0: X location
- bit 1: Y location
- bit 2: Z location
- bit 3: X rotation
- bit 4: Y rotation
- bit 5: Z rotation
- bit 6: X size
- bit 7: Y size
- bit 8: Z size
- bit 0: X location
- bit 1: Y location
- bit 2: Z location
- bit 3: X rotation
- bit 4: Y rotation
- bit 5: Z rotation
- bit 6: X size
- bit 7: Y size
- bit 8: Z size
@type protectFlags: int
"""
@ -399,7 +466,7 @@ class Object:
For objects parented to bones, this is the name of the bone.
@rtype: String
@return: The parent object sub-name of the object.
If not available, None will be returned.
If not available, None will be returned.
"""
def getTimeOffset():
@ -418,7 +485,8 @@ class Object:
def getType():
"""
Returns the type of the object.
Returns the type of the object in 'Armature', 'Camera', 'Curve', 'Lamp', 'Lattice',
'Mball', 'Mesh', 'Surf', 'Empty', 'Wave' (deprecated) or 'unknown' in exceptional cases.
@return: The type of object.
I{B{Example:}}
@ -491,7 +559,21 @@ class Object:
parents of other objects. Calling this makeParent method for an
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
@ -514,7 +596,7 @@ class Object:
@warn: child objects must be of mesh type to deform correctly. Other object
types will fall back to normal parenting silently.
"""
def makeParentVertex(objects, indices, noninverse = 0, fast = 0):
"""
Makes the object the vertex parent of the objects provided in the argument
@ -620,7 +702,7 @@ class Object:
def setSize(x, y, z):
"""
Sets the object's size, relative to the parent object (if any)
Sets the object's size, relative to the parent object (if any), clamped
@type x: float
@param x: The X size multiplier.
@type y: float
@ -647,6 +729,7 @@ class Object:
def select(boolean):
"""
Sets the object's selection state in the current scene.
setting the selection will make this object the active object of this scene.
@type boolean: Integer
@param boolean:
- 0 - unselected

@ -176,27 +176,29 @@ int EXPP_ReturnIntError( PyObject * type, char *error_msg )
int EXPP_intError(PyObject *type, const char *format, ...)
{
char *error = "";
PyObject *error;
va_list vlist;
va_start(vlist, format);
vsprintf(error, format, vlist);
error = PyString_FromFormatV(format, vlist);
va_end(vlist);
PyErr_SetString(type, error);
PyErr_SetObject(type, error);
Py_DECREF(error);
return -1;
}
//Like EXPP_ReturnPyObjError but takes a printf format string and multiple arguments
PyObject *EXPP_objError(PyObject *type, const char *format, ...)
{
char *error = "";
PyObject *error;
va_list vlist;
va_start(vlist, format);
vsprintf(error, format, vlist);
error = PyString_FromFormatV(format, vlist);
va_end(vlist);
PyErr_SetString(type, error);
PyErr_SetObject(type, error);
Py_DECREF(error);
return NULL;
}

@ -658,8 +658,8 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe
// Now thread safe
if(load_ibuf_lock) SDL_mutexP(load_ibuf_lock);
if(env->ima->ibuf==NULL) ima_ibuf_is_nul(tex, tex->ima);
if(load_ibuf_lock) SDL_mutexV(load_ibuf_lock);
if(env->ima->ok && env->ok==0) envmap_split_ima(env);
if(load_ibuf_lock) SDL_mutexV(load_ibuf_lock);
}
}

@ -838,19 +838,15 @@ int imagewraposa(Tex *tex, Image *ima, float *texvec, float *dxt, float *dyt, Te
boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr);
val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
if(dx>=1.0f) {
texres->nor[0]= (val1-val2);
texres->nor[1]= (val1-val3);
}
else {
texres->nor[0]= (val1-val2); /* vals have been interpolated above! */
texres->nor[1]= (val1-val3);
if(dx<1.0f) {
dy= 1.0f-dx;
texres->tb= dy*texres->tb+ dx*texr.tb;
texres->tg= dy*texres->tg+ dx*texr.tg;
texres->tr= dy*texres->tr+ dx*texr.tr;
texres->ta= dy*texres->ta+ dx*texr.ta;
texres->nor[0]= dy*texres->nor[0] + dx*(val1-val2);
texres->nor[1]= dy*texres->nor[1] + dx*(val1-val3);
}
}
}

@ -1014,8 +1014,10 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float
fy= (t[1] + 1.0) / 2.0;
dxt[0]/= 2.0;
dxt[1]/= 2.0;
dxt[2]/= 2.0;
dyt[0]/= 2.0;
dyt[1]/= 2.0;
dyt[2]/= 2.0;
}
else if ELEM(wrap, MTEX_TUBE, MTEX_SPHERE) {
/* exception: the seam behind (y<0.0) */
@ -1056,19 +1058,25 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float
else proj = cubemap(mtex, vlr, t[0], t[1], t[2], &fx, &fy);
if(proj==1) {
dxt[1]= dxt[2];
dyt[1]= dyt[2];
SWAP(float, dxt[1], dxt[2]);
SWAP(float, dyt[1], dyt[2]);
}
else if(proj==2) {
float f1= dxt[0], f2= dyt[0];
dxt[0]= dxt[1];
dyt[0]= dyt[1];
dxt[1]= dxt[2];
dyt[1]= dyt[2];
dxt[2]= f1;
dyt[2]= f2;
}
dxt[0]/= 2.0;
dxt[1]/= 2.0;
dxt[2]/= 2.0;
dyt[0]/= 2.0;
dyt[1]/= 2.0;
dyt[2]/= 2.0;
}
/* if area, then reacalculate dxt[] and dyt[] */
@ -1083,7 +1091,9 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float
/* repeat */
if(tex->extend==TEX_REPEAT) {
float max= 1.0f;
if(tex->xrepeat>1) {
max= tex->xrepeat;
fx *= tex->xrepeat;
dxt[0]*= tex->xrepeat;
dyt[0]*= tex->xrepeat;
@ -1091,12 +1101,19 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *dxt, float
else if(fx<0.0) fx+= 1-(int)(fx);
}
if(tex->yrepeat>1) {
if(max<tex->yrepeat)
max= tex->yrepeat;
fy *= tex->yrepeat;
dxt[1]*= tex->yrepeat;
dyt[1]*= tex->yrepeat;
if(fy>1.0) fy -= (int)(fy);
else if(fy<0.0) fy+= 1-(int)(fy);
}
if(max!=1.0f) {
dxt[1]*= max;
dyt[2]*= max;
}
}
/* crop */
if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) {
@ -1502,10 +1519,25 @@ void do_material_tex(ShadeInput *shi)
else texvec[2]= 0.0;
if(shi->osatex) {
VECCOPY(dxt, dx);
VECCOPY(dyt, dy);
if(mtex->projx) {
dxt[0]= dx[mtex->projx-1];
dyt[0]= dy[mtex->projx-1];
}
else dxt[0]= dyt[0]= 0.0f;
if(mtex->projy) {
dxt[1]= dx[mtex->projy-1];
dyt[1]= dy[mtex->projy-1];
}
else dxt[1]= dyt[1]= 0.0f;
if(mtex->projz) {
dxt[2]= dx[mtex->projz-1];
dyt[2]= dy[mtex->projz-1];
}
else dxt[2]= dyt[2]= 0.0;
}
do_2d_mapping(mtex, texvec, shi->vlr, dxt, dyt);
/* translate and scale */
@ -1531,8 +1563,21 @@ void do_material_tex(ShadeInput *shi)
else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
if(shi->osatex) {
VECCOPY(dxt, dx);
VECCOPY(dyt, dy);
if(mtex->projx) {
dxt[0]= mtex->size[0]*dx[mtex->projx-1];
dyt[0]= mtex->size[0]*dy[mtex->projx-1];
}
else dxt[0]= 0.0;
if(mtex->projy) {
dxt[1]= mtex->size[1]*dx[mtex->projy-1];
dyt[1]= mtex->size[1]*dy[mtex->projy-1];
}
else dxt[1]= 0.0;
if(mtex->projz) {
dxt[2]= mtex->size[2]*dx[mtex->projz-1];
dyt[2]= mtex->size[2]*dy[mtex->projz-1];
}
else dxt[2]= 0.0;
}
}
@ -1685,9 +1730,18 @@ void do_material_tex(ShadeInput *shi)
shi->tang[2]+= Tnor*tex->norfac*texres.nor[2];
}
else {
shi->vn[0]+= Tnor*tex->norfac*texres.nor[0];
shi->vn[1]+= Tnor*tex->norfac*texres.nor[1];
shi->vn[2]+= Tnor*tex->norfac*texres.nor[2];
float nor[3], dot;
/* prevent bump to become negative normal */
nor[0]= Tnor*tex->norfac*texres.nor[0];
nor[1]= Tnor*tex->norfac*texres.nor[1];
nor[2]= Tnor*tex->norfac*texres.nor[2];
dot= 0.5f + 0.5f*INPR(nor, shi->vn);
shi->vn[0]+= dot*nor[0];
shi->vn[1]+= dot*nor[1];
shi->vn[2]+= dot*nor[2];
}
}
Normalise(shi->vn);

@ -498,37 +498,48 @@ DispListMesh *NewBooleanMeshDLM(Object *ob, Object *ob_select, int int_op_type)
InterpFaceVertexData
);
}
if (success) {
// descriptions of the output;
CSG_VertexIteratorDescriptor vd_o;
CSG_FaceIteratorDescriptor fd_o;
dlm = MEM_callocN(sizeof(*dlm),"dlm");
CSG_OutputFaceDescriptor(bool_op,&fd_o);
CSG_OutputVertexDescriptor(bool_op,&vd_o);
switch( success ) {
case 1:
{
// descriptions of the output;
CSG_VertexIteratorDescriptor vd_o;
CSG_FaceIteratorDescriptor fd_o;
dlm = MEM_callocN(sizeof(*dlm),"dlm");
// iterate through results of operation and insert into new object
CSG_OutputFaceDescriptor(bool_op,&fd_o);
CSG_OutputVertexDescriptor(bool_op,&vd_o);
ConvertCSGDescriptorsToDLM(
dlm,
NULL,
&output_mpd,
&fd_o,
&vd_o,
inv_mat
);
// iterate through results of operation and insert into new object
// free up the memory
ConvertCSGDescriptorsToDLM(
dlm,
NULL,
&output_mpd,
&fd_o,
&vd_o,
inv_mat
);
CSG_FreeVertexDescriptor(&vd_o);
CSG_FreeFaceDescriptor(&fd_o);
// free up the memory
CSG_FreeVertexDescriptor(&vd_o);
CSG_FreeFaceDescriptor(&fd_o);
}
break;
case -1:
error("Selected meshes must have faces to perform boolean operations");
break;
case -2:
error("Both meshes must be closed");
break;
default:
error("unknown internal error");
break;
}
CSG_FreeBooleanOperation(bool_op);
bool_op = NULL;
}
// We may need to map back the tfaces to mcols here.

@ -3243,8 +3243,8 @@ static void editing_panel_mesh_tools(Object *ob, Mesh *me)
uiBlockBeginAlign(block);
//uiDefButBitS(block, TOG, B_AUTOFGON, 0, "FGon", 10,195,30,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "Causes 'Subdivide' To create FGon on inner edges where possible");
uiDefButBitS(block, TOG, B_BEAUTY, 0, "Beauty", 10,195,40,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "Causes 'Subdivide' to split faces in halves instead of quarters using Long Edges Unless short is selected");
uiDefButBitS(block, TOG, B_BEAUTY_SHORT, 0, "Short", 50,195,40,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "Causes 'Subdivide' to split faces in halves instead of quarters using Short Edges");
uiDefButBitS(block, TOG, B_BEAUTY, 0, "Beauty", 10,195,40,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "Causes 'Subdivide' to split faces in halves instead of quarters using long edges unless 'Short' is selected");
uiDefButBitS(block, TOG, B_BEAUTY_SHORT, 0, "Short", 50,195,40,19, &G.scene->toolsettings->editbutflag, 0, 0, 0, 0, "If Beauty is set, 'Subdivide' splits faces in halves using short edges");
uiDefBut(block, BUT,B_SUBDIV,"Subdivide", 90,195,80,19, 0, 0, 0, 0, 0, "Splits selected faces into halves or quarters");

@ -2795,8 +2795,6 @@ static void material_panel_texture(Material *ma)
uiBlockSetCol(block, TH_AUTO);
uiDefBut(block, BUT, B_TEXCLEAR, "Clear", 122, 130, 72, 20, 0, 0, 0, 0, 0, "Erases link to texture");
uiDefButBitS(block, TOG, MTEX_VIEWSPACE, B_DIFF, "Correct Nor Map", 100,18,163,19, &(mtex->texflag), 0, 0, 0, 0, "This channel will correct normal mapping for View space and Object space");
}
else
uiDefButS(block, TOG, B_EXTEXBROWSE, "Add New" ,100, 150, 163, 20, &(G.buts->texnr), -1.0, 32767.0, 0, 0, "Adds a new texture datablock");

@ -2292,6 +2292,8 @@ int view2dmove(unsigned short event)
else left= 0.0;
leftret= 0;
}
if((event==WHEELUPMOUSE) || (event==WHEELDOWNMOUSE))
facy= -facy;
}
else if(IN_2D_HORIZ_SCROLL((int)mvalo)) {
facx= -(G.v2d->tot.xmax-G.v2d->tot.xmin)/(float)(G.v2d->mask.xmax-G.v2d->mask.xmin);

@ -553,9 +553,9 @@ static void drawlamp(Object *ob)
/* Inner Circle */
VECCOPY(vec, ob->obmat[3]);
glEnable(GL_BLEND);
drawcircball(GL_LINE_LOOP, vec, lampsize/2, imat);
drawcircball(GL_LINE_LOOP, vec, lampsize, imat);
glDisable(GL_BLEND);
drawcircball(GL_POLYGON, vec, lampsize/2, imat);
drawcircball(GL_POLYGON, vec, lampsize, imat);
/* restore */
if(ob->id.us>1)

@ -87,7 +87,7 @@ void boundbox_oops(short sel)
oops= G.soops->oops.first;
while(oops) {
if (oops->hide==0 && !sel || (sel && oops->flag & SELECT )) {
if ((oops->hide==0 && !sel) || (sel && oops->flag & SELECT )) {
ok= 1;
min[0]= MIN2(min[0], oops->x);
@ -132,7 +132,9 @@ void draw_oopslink(Oops *oops)
if(oops->type==ID_SCE) {
if(oops->flag & SELECT) {
if(oops->id->lib) cpack(0x4080A0);
/* when using python Mesh to make meshes a file was saved
that had an oops with no ID, stops a segfault when looking for lib */
if(oops->id && oops->id->lib) cpack(0x4080A0);
else cpack(0x808080);
}
else cpack(0x606060);
@ -346,7 +348,10 @@ void draw_oops(Oops *oops)
glRectf(x1, y1, x2, y2);
}
if(oops->id->lib) {
/* it has never happened that an oops was missing an ID at
this point but has occured elseware so lets be safe */
if(oops->id && oops->id->lib) {
if(oops->id->flag & LIB_INDIRECT) cpack(0x1144FF);
else cpack(0x11AAFF);
@ -369,8 +374,8 @@ void draw_oops(Oops *oops)
} else { /* NO ICON, UNINDENT*/
v1[0] -= 1.3 / oopscalex;
}
if(oops->flag & SELECT) cpack(0xFFFFFF);
else cpack(0x0);
if(oops->flag & SELECT) BIF_ThemeColor(TH_TEXT_HI);
else BIF_ThemeColor(TH_TEXT);
glRasterPos3f(v1[0], v1[1], 0.0);
BMF_DrawString(font, str);
@ -423,6 +428,12 @@ void drawoopsspace(ScrArea *sa, void *spacedata)
float col[3];
BIF_GetThemeColor3fv(TH_BACK, col);
/* darker background for oops */
if(soops->type!=SO_OUTLINER) {
col[0] = col[0] * 0.75; col[1] = col[1] * 0.75; col[2] = col[2] * 0.75;
}
glClearColor(col[0], col[1], col[2], 0.0);
glClear(GL_COLOR_BUFFER_BIT);
if(soops==0) return;
@ -438,7 +449,20 @@ void drawoopsspace(ScrArea *sa, void *spacedata)
oopscalex= .14*((float)curarea->winx)/(G.v2d->cur.xmax-G.v2d->cur.xmin);
calc_ipogrid(); /* for scrollvariables */
/* Draw a page about the oops */
BIF_GetThemeColor3fv(TH_BACK, col);
glColor3fv(col);
glRectf(G.v2d->tot.xmin-2, G.v2d->tot.ymin-2, G.v2d->tot.xmax+2, G.v2d->tot.ymax+2); /* light square in the centre */
BIF_ThemeColorShade(TH_BACK, -96); /* drop shadow color */
glRectf(G.v2d->tot.xmin-1, G.v2d->tot.ymin-2, G.v2d->tot.xmax+3, G.v2d->tot.ymin-3); /* bottom dropshadow */
glRectf(G.v2d->tot.xmax+2, G.v2d->tot.ymin-2, G.v2d->tot.xmax+3, G.v2d->tot.ymax+1); /* right hand dropshadow */
/* box around the oops. */
cpack(0x0);
mysbox(G.v2d->tot.xmin-2, G.v2d->tot.ymin-2, G.v2d->tot.xmax+2, G.v2d->tot.ymax+2);
/* Set the font size for the oops based on the zoom level */
if (oopscalex > 6.0) font = BMF_GetFont(BMF_kScreen15);
else if (oopscalex > 3.5) font = G.font;

@ -62,7 +62,7 @@
#include "DNA_scene_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_userdef_types.h" /* for U.dupflag */
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "BLI_editVert.h"
@ -1592,7 +1592,7 @@ void duplicate_context_selected(void)
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) adduplicate_nurb();
}
else {
adduplicate(0);
adduplicate(0, U.dupflag);
}
}

@ -351,7 +351,7 @@ void apply_rot_armature (Object *ob, float mat[3][3])
}
}
void join_armature(void)
int join_armature(void)
{
Object *ob;
Base *base, *nextbase;
@ -360,13 +360,10 @@ 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;
if(ob->type!=OB_ARMATURE) return 0;
/* Put the active armature into editmode and join the bones from the other one*/
@ -436,7 +433,7 @@ void join_armature(void)
exit_editmode(1);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWOOPS, 0);
return 1;
}
/* **************** END tools on Editmode Armature **************** */

@ -375,9 +375,7 @@ void separate_nurb()
oldob= G.obedit;
oldbase= BASACT;
G.qual |= LR_ALTKEY; /* patch to make sure we get a linked dupli */
adduplicate(1);
G.qual &= ~LR_ALTKEY;
adduplicate(1, 0); /* no transform and zero so do get a linked dupli */
G.obedit= BASACT->object; /* basact is set in adduplicate() */
@ -3277,7 +3275,7 @@ void nurb_set_smooth(short event)
else if(event==0) BIF_undo_push("Set Solid");
}
void join_curve(int type)
int join_curve(int type)
{
Base *base, *nextb;
Object *ob;
@ -3289,18 +3287,11 @@ void join_curve(int type)
float imat[4][4], cmat[4][4];
int a;
if(G.obedit) return;
ob= OBACT;
if(ob->type!=type) return;
if(ob->lay & G.vd->lay); else return;
if(ob->type!=type) return 0;
if(ob->lay & G.vd->lay); else return 0;
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);
@ -3360,7 +3351,7 @@ void join_curve(int type)
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
BIF_undo_push("Join");
return 1;
}

@ -1327,9 +1327,7 @@ void separate_mesh(void)
oldob= G.obedit;
oldbase= BASACT;
G.qual |= LR_ALTKEY; /* patch to make sure we get a linked duplicate */
adduplicate(1);
G.qual &= ~LR_ALTKEY;
adduplicate(1, 0); /* notrans and a linked duplicate*/
G.obedit= BASACT->object; /* basact was set in adduplicate() */
@ -1494,9 +1492,7 @@ void separate_mesh_loose(void)
oldob= G.obedit;
oldbase= BASACT;
G.qual |= LR_ALTKEY; /* patch to make sure we get a linked duplicate */
adduplicate(1);
G.qual &= ~LR_ALTKEY;
adduplicate(1, 0); /* notrans and 0 for linked duplicate */
G.obedit= BASACT->object; /* basact was set in adduplicate() */

@ -1462,7 +1462,8 @@ void reveal_mesh(void)
EM_fgon_flags(); // redo flags and indices for fgons
EM_selectmode_flush();
countall();
allqueue(REDRAWVIEW3D, 0);
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
BIF_undo_push("Reveal");

@ -377,7 +377,7 @@ int removedoublesflag(short flag, float limit) /* return amount */
efa= em->faces.first;
while(efa) {
efa->f1= 0;
if(faceselectedAND(efa, 1)) {
if(faceselectedOR(efa, 1)) {
efa->f1= 1;
amount++;
}

@ -1892,7 +1892,7 @@ void split_font()
int i;
for (i = 0; i<=slen; p++, i++) {
adduplicate(1);
adduplicate(1, U.dupflag);
cu= OBACT->data;
cu->sepchar = i+1;
text_to_curve(OBACT, 0); // pass 1: only one letter, adapt position
@ -4197,7 +4197,19 @@ static void adduplicate__forwardModifierLinks(void *userData, Object *ob, Object
ID_NEW(*obpoin);
}
void adduplicate(int noTrans)
/* This function duplicated the current visible selection, its used by Duplicate and Linked Duplicate
Alt+D/Shift+D as well as Pythons Object.Duplicate(), it takes
mode:
0: Duplicate with transform, Redraw.
1: Duplicate, no transform, Redraw
2: Duplicate, no transform, no redraw (Only used by python)
if true the user will not be dropped into grab mode directly after and..
dupflag: a flag made from constants declared in DNA_userdef_types.h
The flag tells adduplicate() weather to copy data linked to the object, or to reference the existing data.
U.dupflag for default operations or you can construct a flag as python does
if the dupflag is 0 then no data will be copied (linked duplicate) */
void adduplicate(int mode, int dupflag)
{
Base *base, *basen;
Object *ob, *obn;
@ -4205,15 +4217,12 @@ void adduplicate(int noTrans)
ID *id;
Ipo *ipo;
bConstraintChannel *chan;
int a, didit, dupflag;
int a, didit;
if(G.scene->id.lib) return;
clear_id_newpoins();
clear_sca_new_poins(); /* sensor/contr/act */
if( G.qual & LR_ALTKEY ) dupflag= 0;
else dupflag= U.dupflag;
base= FIRSTBASE;
while(base) {
if TESTBASELIB(base) {
@ -4261,7 +4270,7 @@ void adduplicate(int noTrans)
}
}
}
if(dupflag & USER_DUP_ACT){
if(dupflag & USER_DUP_ACT){ /* Not buttons in the UI to modify this, add later? */
id= (ID *)obn->action;
if (id){
ID_NEW_US(obn->action)
@ -4467,16 +4476,17 @@ void adduplicate(int noTrans)
clear_id_newpoins();
countall();
if(!noTrans) {
if(mode==0) {
BIF_TransformSetUndo("Add Duplicate");
initTransform(TFM_TRANSLATION, CTX_NONE);
Transform();
}
set_active_base(BASACT);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWACTION, 0); /* also oops */
allqueue(REDRAWIPO, 0); /* also oops */
if(mode!=2) { /* mode of 2 is used by python to avoid unrequested redraws */
allqueue(REDRAWNLA, 0);
allqueue(REDRAWACTION, 0); /* also oops */
allqueue(REDRAWIPO, 0); /* also oops */
}
}
void selectlinks_menu(void)

@ -56,6 +56,7 @@
#include "DNA_space_types.h"
#include "DNA_scene_types.h"
#include "DNA_image_types.h"
#include "DNA_ipo_types.h"
#include "BKE_global.h"
#include "BKE_scene.h"
@ -428,13 +429,25 @@ static void do_activate_oops(Oops *oops)
case ID_IM:
if(oops->id && G.sima) {
/* only set if the new image isnt alredy active */
if (G.sima->image != (Image *)oops->id) {
if ((ID *)G.sima->image != oops->id) {
G.sima->image = (Image *)oops->id;
allqueue(REDRAWIMAGE, 0);
scrarea_queue_winredraw(curarea);
}
}
break;
/*
case ID_IP:
if(oops->id && G.sipo) {
*//* only set if the new ipo isnt alredy active *//*
if ((ID *)G.sipo->ipo != oops->id) {
G.sipo->ipo = (Ipo *)oops->id;
allqueue(REDRAWIPO, 0);
scrarea_queue_winredraw(curarea);
}
}
break;
*/
}
}

@ -597,7 +597,7 @@ static uiBlock *ipo_editmenu(void *arg_unused)
uiDefIconTextBlockBut(block, ipo_editmenu_joinmenu, NULL, ICON_RIGHTARROW_THIN, "Join", 0, yco-=20, 120, 19, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Clamped Handles|ALT H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Auto Clamped Handles|Alt H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
if (!G.sipo->showkey){
uiDefIconTextBlockBut(block, ipo_editmenu_extendmenu, NULL, ICON_RIGHTARROW_THIN, "Extend Mode", 0, yco-=20, 120, 19, "");

@ -1992,9 +1992,7 @@ static void do_view3d_edit_objectmenu(void *arg, int event)
duplicate_context_selected();
break;
case 3: /* duplicate linked */
G.qual |= LR_ALTKEY;
adduplicate(0);
G.qual &= ~LR_ALTKEY;
adduplicate(0, 0);
break;
case 5: /* make single user */
single_user();
@ -2003,12 +2001,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();
@ -2176,7 +2169,7 @@ static uiBlock *view3d_edit_mesh_verticesmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Smooth|W, 0", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Remove Doubles|W, 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Remove Doubles|W, 6", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@ -2260,15 +2253,15 @@ static uiBlock *view3d_edit_mesh_edgesmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bevel|W, Alt 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Bevel|W, Alt 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Loop Subdivide...|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Knife Subdivide...|Shift K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide|W, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide Fractal|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide Smooth|W, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide Fractal|W, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide Smooth|W, 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@ -2347,8 +2340,8 @@ static uiBlock *view3d_edit_mesh_facesmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Smooth|W, Alt 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Solid|W, Alt 5", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Smooth|W, Alt 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Solid|W, Alt 4", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
@ -2384,7 +2377,7 @@ static uiBlock *view3d_edit_mesh_normalsmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip|W, 9", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip|W, 0", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);

@ -34,7 +34,7 @@
meshtools.c: no editmode, tools operating on meshes
void join_mesh(void);
int join_mesh(void);
void fasterdraw(void);
void slowerdraw(void);
@ -115,7 +115,9 @@ static int testSelected_TfaceMesh(void)
return 0;
}
void join_mesh(void)
/* join selected meshes into the active mesh, context sensitive
return 0 if no join is made (error) and 1 of the join is done */
int join_mesh(void)
{
Base *base, *nextb;
Object *ob;
@ -132,10 +134,10 @@ void join_mesh(void)
bDeformGroup *dg, *odg;
MDeformVert *dvert, *dvertmain;
if(G.obedit) return;
if(G.obedit) return 0;
ob= OBACT;
if(!ob || ob->type!=OB_MESH) return;
if(!ob || ob->type!=OB_MESH) return 0;
/* count */
base= FIRSTBASE;
@ -159,14 +161,13 @@ void join_mesh(void)
if(haskey) {
error("Can't join meshes with vertex keys");
return;
return 0;
}
/* that way the active object is always selected */
if(ok==0) return;
if(ok==0) return 0;
if(totvert==0 || totvert>MESH_MAX_VERTS) return;
if(totvert==0 || totvert>MESH_MAX_VERTS) return 0;
if(okee("Join selected meshes")==0) return;
/* if needed add edges to other meshes */
@ -439,6 +440,7 @@ void join_mesh(void)
allqueue(REDRAWBUTSSHADING, 0);
BIF_undo_push("Join Mesh");
return 1;
}

@ -644,7 +644,7 @@ void calc_renderwin_rectangle(int posmask, int renderpos_r[2], int rendersize_r[
rendersize_r[1]= CLAMPIS(rendersize_r[1], 0, scr_h-44-RW_HEADERY);
renderpos_r[1]= -44-RW_HEADERY+(scr_h-rendersize_r[1])*(ndc_y*0.5 + 0.5);
#else
renderpos_r[1]= (scr_h-rendersize_r[1])*(ndc_y*0.5 + 0.5);
renderpos_r[1]= -RW_HEADERY+(scr_h-rendersize_r[1])*(ndc_y*0.5 + 0.5);
#endif
}

@ -624,6 +624,26 @@ static void select_grouped_menu(void)
select_grouped(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 ();
}
}
}
static unsigned short convert_for_nonumpad(unsigned short event)
{
@ -1198,7 +1218,7 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(ob && (ob->flag & OB_POSEMODE))
error ("Duplicate not possible in posemode.");
else if((G.obedit==NULL))
adduplicate(0);
adduplicate(0, 0);
}
else if(G.qual==LR_CTRLKEY) {
imagestodisplist();
@ -1378,14 +1398,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();

@ -961,11 +961,11 @@ static KX_GameObject *gameobject_from_blenderobject(
// If this is a skin object, make Skin Controller
if (ob->parent && ob->parent->type == OB_ARMATURE && ob->partype==PARSKEL && ((Mesh*)ob->data)->dvert){
BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj);
BL_SkinDeformer *dcont = new BL_SkinDeformer(ob, (BL_SkinMeshObject*)meshobj,ob->parent);
((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
}
else if (((Mesh*)ob->data)->dvert){
BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj);
BL_MeshDeformer *dcont = new BL_MeshDeformer(ob, (BL_SkinMeshObject*)meshobj,ob->parent);
((BL_DeformableGameObject*)gameobj)->m_pDeformer = dcont;
}

@ -48,12 +48,14 @@ public:
void VerifyStorage();
void RecalcNormals();
virtual void Relink(GEN_Map<class GEN_HashedPtr, void*>*map){};
BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj):
BL_MeshDeformer(struct Object* obj, class BL_SkinMeshObject *meshobj,struct Object* armatureObj):
m_pMeshObject(meshobj),
m_bmesh((struct Mesh*)(obj->data)),
m_transnors(NULL),
m_transverts(NULL),
m_tvtot(0)
m_tvtot(0),
m_blenderMeshObject(obj),
m_blenderArmatureObj(armatureObj)
{};
virtual ~BL_MeshDeformer();
virtual void SetSimulatedTime(double time){};
@ -67,6 +69,8 @@ protected:
MT_Point3 *m_transnors;
MT_Point3 *m_transverts;
int m_tvtot;
Object* m_blenderMeshObject;
Object* m_blenderArmatureObj;
};

@ -145,6 +145,10 @@ void BL_SkinDeformer::ProcessReplica()
{
}
//void where_is_pose (Object *ob);
//void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag);
extern "C" void armature_deform_verts(struct Object *armOb, struct Object *target, float (*vertexCos)[3], int numVerts, int deformflag);
void BL_SkinDeformer::Update(void)
{
@ -156,7 +160,8 @@ void BL_SkinDeformer::Update(void)
/* XXX note: where_is_pose() (from BKE_armature.h) calculates all matrices needed to start deforming */
/* but it requires the blender object pointer... */
// void where_is_pose (Object *ob);
//void where_is_pose (Object *ob);
where_is_pose (m_blenderArmatureObj);
/* store verts locally */
for (int v =0; v<m_bmesh->totvert; v++){
@ -165,6 +170,11 @@ void BL_SkinDeformer::Update(void)
m_transverts[v]=MT_Point3(m_bmesh->mvert[v].co);
}
float test[1000][3];
armature_deform_verts(m_blenderArmatureObj,m_blenderMeshObject,test,m_bmesh->totvert,ARM_DEF_VGROUP);
/* XXX note: now use this call instead */
// void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts, int deformflag)
// - armOb = armature object

@ -63,9 +63,10 @@ public:
m_armobj=NULL;
}
void SetArmature (class BL_ArmatureObject *armobj);
BL_SkinDeformer( struct Object *bmeshobj,
class BL_SkinMeshObject *mesh)
:BL_MeshDeformer(bmeshobj, mesh),
BL_SkinDeformer( struct Object *bmeshobj,
class BL_SkinMeshObject *mesh,struct Object* blenderArmatureObj)
:BL_MeshDeformer(bmeshobj, mesh,blenderArmatureObj),
m_armobj(NULL),
m_lastUpdate(-1),
m_defbase(&bmeshobj->defbase)
@ -85,8 +86,8 @@ public:
BL_SkinDeformer( struct Object *bmeshobj_old,
struct Object *bmeshobj_new,
class BL_SkinMeshObject *mesh)
:BL_MeshDeformer(bmeshobj_old, mesh),
class BL_SkinMeshObject *mesh,struct Object *bArmatureObj)
:BL_MeshDeformer(bmeshobj_old, mesh,bArmatureObj),
m_armobj(NULL),
m_lastUpdate(-1),
m_defbase(&bmeshobj_old->defbase)

@ -77,6 +77,12 @@ PyTypeObject PyObjectPlus::Type = {
0, /*tp_call */
};
PyObjectPlus::~PyObjectPlus()
{
_Py_ForgetReference(this);
// assert(ob_refcnt==0);
}
PyObjectPlus::PyObjectPlus(PyTypeObject *T) // constructor
{
MT_assert(T != NULL);

@ -136,18 +136,18 @@ class PyObjectPlus : public PyObject
public:
PyObjectPlus(PyTypeObject *T);
virtual ~PyObjectPlus() {}; // destructor
virtual ~PyObjectPlus(); // destructor
static void PyDestructor(PyObject *P) // python wrapper
{
delete ((PyObjectPlus *) P);
};
//void INCREF(void) {
// Py_INCREF(this);
// }; // incref method
//void DECREF(void) {
// Py_DECREF(this);
// }; // decref method
// void INCREF(void) {
// Py_INCREF(this);
// }; // incref method
// void DECREF(void) {
// Py_DECREF(this);
// }; // decref method
virtual PyObject *_getattr(const STR_String& attr); // _getattr method
static PyObject *__getattr(PyObject * PyObj, char *attr) // This should be the entry in Type.

@ -558,6 +558,10 @@ void CValue::DisableRefCount()
void CValue::AddDataToReplica(CValue *replica)
{
replica->m_refcount = 1;
//register with Python
_Py_NewReference(replica);
#ifdef _DEBUG
//gRefCountValue++;
#endif

@ -7,6 +7,14 @@
#include "Dynamics/RigidBody.h"
#include "SG_Spatial.h"
#include "KX_GameObject.h"
#include "KX_MotionState.h"
#include "KX_ClientObjectInfo.h"
#include "PHY_IPhysicsEnvironment.h"
KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna)
: KX_IPhysicsController(dyna,(PHY_IPhysicsController*)this),
CcdPhysicsController(ci)
@ -38,6 +46,16 @@ void KX_BulletPhysicsController::applyImpulse(const MT_Point3& attach, const MT_
void KX_BulletPhysicsController::SetObject (SG_IObject* object)
{
SG_Controller::SetObject(object);
// cheating here...
//should not be necessary, is it for duplicates ?
KX_GameObject* gameobj = (KX_GameObject*) object->GetSGClientObject();
gameobj->SetPhysicsController(this,gameobj->IsDynamic());
//GetSumoObject()->setClientObject(gameobj->getClientInfo());
}
void KX_BulletPhysicsController::RelativeTranslate(const MT_Vector3& dloc,bool local)
@ -55,22 +73,25 @@ void KX_BulletPhysicsController::RelativeRotate(const MT_Matrix3x3& drot,bool lo
void KX_BulletPhysicsController::ApplyTorque(const MT_Vector3& torque,bool local)
{
CcdPhysicsController::ApplyTorque(torque.x(),torque.y(),torque.z(),local);
}
void KX_BulletPhysicsController::ApplyForce(const MT_Vector3& force,bool local)
{
CcdPhysicsController::ApplyForce(force.x(),force.y(),force.z(),local);
}
MT_Vector3 KX_BulletPhysicsController::GetLinearVelocity()
{
assert(0);
return MT_Vector3(0.f,0.f,0.f);
float angVel[3];
CcdPhysicsController::GetAngularVelocity(angVel[0],angVel[1],angVel[2]);
return MT_Vector3(angVel[0],angVel[1],angVel[2]);
}
MT_Vector3 KX_BulletPhysicsController::GetVelocity(const MT_Point3& pos)
{
assert(0);
return MT_Vector3(0.f,0.f,0.f);
float linVel[3];
CcdPhysicsController::GetLinearVelocity(linVel[0],linVel[1],linVel[2]);
return MT_Vector3(linVel[0],linVel[1],linVel[2]);
}
void KX_BulletPhysicsController::SetAngularVelocity(const MT_Vector3& ang_vel,bool local)
{
CcdPhysicsController::SetAngularVelocity(ang_vel.x(),ang_vel.y(),ang_vel.z(),local);
@ -82,16 +103,21 @@ void KX_BulletPhysicsController::SetLinearVelocity(const MT_Vector3& lin_vel,boo
}
void KX_BulletPhysicsController::getOrientation(MT_Quaternion& orn)
{
float myorn[4];
CcdPhysicsController::getOrientation(myorn[0],myorn[1],myorn[2],myorn[3]);
orn = MT_Quaternion(myorn[0],myorn[1],myorn[2],myorn[3]);
}
void KX_BulletPhysicsController::setOrientation(const MT_Quaternion& orn)
{
CcdPhysicsController::setOrientation(orn.x(),orn.y(),orn.z(),orn.w());
}
void KX_BulletPhysicsController::setPosition(const MT_Point3& pos)
{
CcdPhysicsController::setPosition(pos.x(),pos.y(),pos.z());
}
void KX_BulletPhysicsController::setScaling(const MT_Vector3& scaling)
{
CcdPhysicsController::setScaling(scaling.x(),scaling.y(),scaling.z());
}
MT_Scalar KX_BulletPhysicsController::GetMass()
{
@ -113,6 +139,7 @@ void KX_BulletPhysicsController::setRigidBody(bool rigid)
void KX_BulletPhysicsController::SuspendDynamics()
{
}
void KX_BulletPhysicsController::RestoreDynamics()
{
@ -120,8 +147,42 @@ void KX_BulletPhysicsController::RestoreDynamics()
SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode)
{
assert(0);
return 0;
PHY_IMotionState* motionstate = new KX_MotionState(destnode);
KX_BulletPhysicsController* physicsreplica = new KX_BulletPhysicsController(*this);
//parentcontroller is here be able to avoid collisions between parent/child
PHY_IPhysicsController* parentctrl = NULL;
if (destnode != destnode->GetRootSGParent())
{
KX_GameObject* clientgameobj = (KX_GameObject*) destnode->GetRootSGParent()->GetSGClientObject();
if (clientgameobj)
{
parentctrl = (KX_BulletPhysicsController*)clientgameobj->GetPhysicsController();
} else
{
// it could be a false node, try the children
NodeList::const_iterator childit;
for (
childit = destnode->GetSGChildren().begin();
childit!= destnode->GetSGChildren().end();
++childit
) {
KX_GameObject *clientgameobj = static_cast<KX_GameObject*>( (*childit)->GetSGClientObject());
if (clientgameobj)
{
parentctrl = (KX_BulletPhysicsController*)clientgameobj->GetPhysicsController();
}
}
}
}
physicsreplica->PostProcessReplica(motionstate,parentctrl);
return physicsreplica;
}

@ -673,6 +673,7 @@ void KX_ConvertODEEngineObject(KX_GameObject* gameobj,
#include "CollisionShapes/ConvexHullShape.h"
#include "CollisionShapes/TriangleMesh.h"
#include "CollisionShapes/TriangleMeshShape.h"
#include "CollisionShapes/BvhTriangleMeshShape.h"
static GEN_Map<GEN_HashedPtr,CollisionShape*> map_gamemesh_to_bulletshape;
@ -770,8 +771,8 @@ static CollisionShape* CreateBulletShapeFromMesh(RAS_MeshObject* meshobj, bool p
} else
{
collisionMeshData = new TriangleMesh();
concaveShape = new TriangleMeshShape(collisionMeshData);
collisionMeshShape = concaveShape;
// concaveShape = new TriangleMeshShape(collisionMeshData);
//collisionMeshShape = concaveShape;
}
@ -843,7 +844,20 @@ static CollisionShape* CreateBulletShapeFromMesh(RAS_MeshObject* meshobj, bool p
if (numvalidpolys > 0)
{
//map_gamemesh_to_bulletshape.insert(GEN_HashedPtr(meshobj),collisionMeshShape);
if (!polytope)
{
concaveShape = new BvhTriangleMeshShape( collisionMeshData );
//concaveShape = new TriangleMeshShape( collisionMeshData );
concaveShape->RecalcLocalAabb();
collisionMeshShape = concaveShape;
}
return collisionMeshShape;
}
@ -1000,17 +1014,21 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj,
ci.m_collisionShape = bm;
ci.m_broadphaseHandle = 0;
ci.m_friction = smmaterial->m_friction;
ci.m_friction = 5.f* smmaterial->m_friction;//tweak the friction a bit, so the default 0.5 works nice
ci.m_restitution = smmaterial->m_restitution;
ci.m_physicsEnv = env;
// drag / damping is inverted
ci.m_linearDamping = 1.f - shapeprops->m_lin_drag;
ci.m_angularDamping = 1.f - shapeprops->m_ang_drag;
//need a bit of damping, else system doesn't behave well
ci.m_inertiaFactor = shapeprops->m_inertia/0.4f;//defaults to 0.4, don't want to change behaviour
KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna);
env->addCcdPhysicsController( physicscontroller);
if (objprop->m_in_active_layer)
{
env->addCcdPhysicsController( physicscontroller);
}
gameobj->SetPhysicsController(physicscontroller,isbulletdyna);

@ -35,3 +35,7 @@
#include <config.h>
#endif
KX_EmptyObject::~KX_EmptyObject()
{
}

@ -39,7 +39,7 @@ public:
KX_EmptyObject(void* sgReplicationInfo,SG_Callbacks callbacks) :
KX_GameObject(sgReplicationInfo,callbacks)
{};
virtual ~KX_EmptyObject() {};
virtual ~KX_EmptyObject();
};

@ -364,10 +364,14 @@ void KX_KetsjiEngine::NextFrame()
scene->setSuspendedDelta(scene->getSuspendedDelta()+curtime-scene->getSuspendedTime());
m_suspendeddelta = scene->getSuspendedDelta();
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
m_logger->StartLog(tc_network, m_kxsystem->GetTimeInSeconds(), true);
scene->GetNetworkScene()->proceed(localtime);
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
scene->UpdateParents(localtime);
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
// set Python hooks for each scene
PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
PHY_SetActiveScene(scene);
@ -399,11 +403,11 @@ void KX_KetsjiEngine::NextFrame()
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
scene->UpdateParents(localtime);
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
scene->GetPhysicsEnvironment()->beginFrame();
// Perform physics calculations on the scene. This can involve
// many iterations of the physics solver.
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
scene->GetPhysicsEnvironment()->proceedDeltaTime(localtime,realDeltaTime);
m_previoustime = curtime;
@ -462,6 +466,9 @@ void KX_KetsjiEngine::NextFrame()
PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
PHY_SetActiveScene(scene);
m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
scene->UpdateParents(curtime);
// Perform physics calculations on the scene. This can involve
// many iterations of the physics solver.
m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);

@ -732,7 +732,7 @@ void KX_Scene::ReplaceMesh(class CValue* gameobj,void* meshobj)
Object* blendobj = (struct Object*)m_logicmgr->FindBlendObjByGameObj(newobj);
Object* oldblendobj = (struct Object*)m_logicmgr->FindBlendObjByGameMeshName(mesh->GetName());
if (blendobj->parent && blendobj->parent->type == OB_ARMATURE && blendobj->partype==PARSKEL && ((Mesh*)blendobj->data)->dvert) {
BL_SkinDeformer* skindeformer = new BL_SkinDeformer(oldblendobj, blendobj, (BL_SkinMeshObject*)mesh);
BL_SkinDeformer* skindeformer = new BL_SkinDeformer(oldblendobj, blendobj, (BL_SkinMeshObject*)mesh,blendobj->parent);
skindeformer->SetArmature((BL_ArmatureObject*) newobj->GetParent());
// FIXME: should the old m_pDeformer be deleted?
@ -741,7 +741,7 @@ void KX_Scene::ReplaceMesh(class CValue* gameobj,void* meshobj)
((BL_DeformableGameObject*)newobj)->m_pDeformer = skindeformer;
}
else if (((Mesh*)blendobj->data)->dvert) {
BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(oldblendobj, (BL_SkinMeshObject*)mesh);
BL_MeshDeformer* meshdeformer = new BL_MeshDeformer(oldblendobj, (BL_SkinMeshObject*)mesh,oldblendobj->parent);
// FIXME: should the old m_pDeformer be deleted?
// delete ((BL_DeformableGameObject*)newobj)->m_pDeformer

@ -4,6 +4,8 @@
#include "PHY_IMotionState.h"
#include "BroadphaseCollision/BroadphaseProxy.h"
#include "CollisionShapes/ConvexShape.h"
#include "CcdPhysicsEnvironment.h"
class BP_Proxy;
@ -20,6 +22,7 @@ float gAngularSleepingTreshold = 1.0f;
SimdVector3 startVel(0,0,0);//-10000);
CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
:m_cci(ci)
{
m_collisionDelay = 0;
m_newClientInfo = 0;
@ -27,6 +30,22 @@ CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
m_MotionState = ci.m_MotionState;
m_broadphaseHandle = ci.m_broadphaseHandle;
m_collisionShape = ci.m_collisionShape;
CreateRigidbody();
#ifdef WIN32
if (m_body->getInvMass())
m_body->setLinearVelocity(startVel);
#endif
}
void CcdPhysicsController::CreateRigidbody()
{
SimdTransform trans;
float tmp[3];
m_MotionState->getWorldPosition(tmp[0],tmp[1],tmp[2]);
@ -36,31 +55,19 @@ CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
m_MotionState->getWorldOrientation(orn[0],orn[1],orn[2],orn[3]);
trans.setRotation(orn);
MassProps mp(ci.m_mass, ci.m_localInertiaTensor);
MassProps mp(m_cci.m_mass, m_cci.m_localInertiaTensor);
m_body = new RigidBody(mp,0,0,ci.m_friction,ci.m_restitution);
m_body = new RigidBody(mp,0,0,m_cci.m_friction,m_cci.m_restitution);
m_broadphaseHandle = ci.m_broadphaseHandle;
m_collisionShape = ci.m_collisionShape;
//
// init the rigidbody properly
//
m_body->setMassProps(ci.m_mass, ci.m_localInertiaTensor);
m_body->setGravity( ci.m_gravity);
m_body->setDamping(ci.m_linearDamping, ci.m_angularDamping);
m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
m_body->setGravity( m_cci.m_gravity);
m_body->setDamping(m_cci.m_linearDamping, m_cci.m_angularDamping);
m_body->setCenterOfMassTransform( trans );
#ifdef WIN32
if (m_body->getInvMass())
m_body->setLinearVelocity(startVel);
#endif
}
@ -68,6 +75,7 @@ CcdPhysicsController::~CcdPhysicsController()
{
//will be reference counted, due to sharing
//delete m_collisionShape;
m_cci.m_physicsEnv->removeCcdPhysicsController(this);
delete m_MotionState;
delete m_body;
}
@ -87,11 +95,9 @@ bool CcdPhysicsController::SynchronizeMotionStates(float time)
float scale[3];
m_MotionState->getWorldScaling(scale[0],scale[1],scale[2]);
SimdVector3 scaling(scale[0],scale[1],scale[2]);
m_collisionShape->setLocalScaling(scaling);
return true;
}
@ -109,6 +115,45 @@ void CcdPhysicsController::WriteDynamicsToMotionState()
// controller replication
void CcdPhysicsController::PostProcessReplica(class PHY_IMotionState* motionstate,class PHY_IPhysicsController* parentctrl)
{
m_MotionState = motionstate;
m_broadphaseHandle = 0;
m_body = 0;
CreateRigidbody();
m_cci.m_physicsEnv->addCcdPhysicsController(this);
/* SM_Object* dynaparent=0;
SumoPhysicsController* sumoparentctrl = (SumoPhysicsController* )parentctrl;
if (sumoparentctrl)
{
dynaparent = sumoparentctrl->GetSumoObject();
}
SM_Object* orgsumoobject = m_sumoObj;
m_sumoObj = new SM_Object(
orgsumoobject->getShapeHandle(),
orgsumoobject->getMaterialProps(),
orgsumoobject->getShapeProps(),
dynaparent);
m_sumoObj->setRigidBody(orgsumoobject->isRigidBody());
m_sumoObj->setMargin(orgsumoobject->getMargin());
m_sumoObj->setPosition(orgsumoobject->getPosition());
m_sumoObj->setOrientation(orgsumoobject->getOrientation());
//if it is a dyna, register for a callback
m_sumoObj->registerCallback(*this);
m_sumoScene->add(* (m_sumoObj));
*/
}
// kinematic methods
@ -190,15 +235,26 @@ void CcdPhysicsController::resolveCombinedVelocities(float linvelX,float linvel
void CcdPhysicsController::getPosition(PHY__Vector3& pos) const
{
assert(0);
const SimdTransform& xform = m_body->getCenterOfMassTransform();
pos[0] = xform.getOrigin().x();
pos[1] = xform.getOrigin().y();
pos[2] = xform.getOrigin().z();
}
void CcdPhysicsController::setScaling(float scaleX,float scaleY,float scaleZ)
{
if (m_body && m_body->GetCollisionShape())
if (!SimdFuzzyZero(m_cci.m_scaling.x()-scaleX) ||
!SimdFuzzyZero(m_cci.m_scaling.y()-scaleY) ||
!SimdFuzzyZero(m_cci.m_scaling.z()-scaleZ))
{
SimdVector3 scaling(scaleX,scaleY,scaleZ);
m_body->GetCollisionShape()->setLocalScaling(scaling);
m_cci.m_scaling = SimdVector3(scaleX,scaleY,scaleZ);
if (m_body && m_body->GetCollisionShape())
{
m_body->GetCollisionShape()->setLocalScaling(m_cci.m_scaling);
m_body->GetCollisionShape()->CalculateLocalInertia(m_cci.m_mass, m_cci.m_localInertiaTensor);
m_body->setMassProps(m_cci.m_mass, m_cci.m_localInertiaTensor * m_cci.m_inertiaFactor);
}
}
}
@ -269,6 +325,15 @@ void CcdPhysicsController::GetLinearVelocity(float& linvX,float& linvY,float& l
linvZ = linvel.z();
}
void CcdPhysicsController::GetAngularVelocity(float& angVelX,float& angVelY,float& angVelZ)
{
const SimdVector3& angvel= m_body->getAngularVelocity();
angVelX = angvel.x();
angVelY = angvel.y();
angVelZ = angvel.z();
}
void CcdPhysicsController::GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ)
{
SimdVector3 pos(posX,posY,posZ);

@ -16,6 +16,7 @@ extern float gDeactivationTime;
extern float gLinearSleepingTreshold;
extern float gAngularSleepingTreshold;
extern bool gDisableDeactivation;
class CcdPhysicsEnvironment;
struct CcdConstructionInfo
@ -27,12 +28,16 @@ struct CcdConstructionInfo
m_linearDamping(0.1f),
m_angularDamping(0.1f),
m_MotionState(0),
m_collisionShape(0)
m_collisionShape(0),
m_physicsEnv(0),
m_inertiaFactor(1.f),
m_scaling(1.f,1.f,1.f)
{
}
SimdVector3 m_localInertiaTensor;
SimdVector3 m_gravity;
SimdVector3 m_scaling;
SimdScalar m_mass;
SimdScalar m_restitution;
SimdScalar m_friction;
@ -42,7 +47,8 @@ struct CcdConstructionInfo
class PHY_IMotionState* m_MotionState;
CollisionShape* m_collisionShape;
CcdPhysicsEnvironment* m_physicsEnv; //needed for self-replication
float m_inertiaFactor;//tweak the inertia (hooked up to Blender 'formfactor'
};
@ -56,8 +62,11 @@ class CcdPhysicsController : public PHY_IPhysicsController
CollisionShape* m_collisionShape;
void* m_newClientInfo;
CcdConstructionInfo m_cci;//needed for replication
void GetWorldOrientation(SimdMatrix3x3& mat);
void CreateRigidbody();
public:
int m_collisionDelay;
@ -110,6 +119,7 @@ class CcdPhysicsController : public PHY_IPhysicsController
// reading out information from physics
virtual void GetLinearVelocity(float& linvX,float& linvY,float& linvZ);
virtual void GetAngularVelocity(float& angVelX,float& angVelY,float& angVelZ);
virtual void GetVelocity(const float posX,const float posY,const float posZ,float& linvX,float& linvY,float& linvZ);
virtual void getReactionForce(float& forceX,float& forceY,float& forceZ);

@ -226,11 +226,13 @@ void CcdPhysicsEnvironment::removeCcdPhysicsController(CcdPhysicsController* ctr
if (removeFromBroadphase)
{
}
//
// only clear the cached algorithms
//
scene->CleanProxyFromPairs(bp);
scene->DestroyProxy(bp);//??
}
{
std::vector<CcdPhysicsController*>::iterator i =
@ -294,7 +296,10 @@ void CcdPhysicsEnvironment::UpdateActivationState()
}
void CcdPhysicsEnvironment::beginFrame()
{
}
/// Perform an integration step of duration 'timeStep'.
bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
@ -320,8 +325,8 @@ bool CcdPhysicsEnvironment::proceedDeltaTime(double curTime,float timeStep)
//this is needed because scaling is not known in advance, and scaling has to propagate to the shape
if (!m_scalingPropagated)
{
//SyncMotionStates(timeStep);
//m_scalingPropagated = true;
SyncMotionStates(timeStep);
m_scalingPropagated = true;
}

@ -59,7 +59,7 @@ class CcdPhysicsEnvironment : public PHY_IPhysicsEnvironment
virtual void setLinearAirDamping(float damping);
virtual void setUseEpa(bool epa) ;
virtual void beginFrame() {};
virtual void beginFrame();
virtual void endFrame() {};
/// Perform an integration step of duration 'timeStep'.
virtual bool proceedDeltaTime(double curTime,float timeStep);