Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2006-01-04 00:43:31 +0300
committerTon Roosendaal <ton@blender.org>2006-01-04 00:43:31 +0300
commitf47899fc0f716464625f43045458e222ce11603d (patch)
tree1051359e7eb24a5d40826a0ea7aaa925da7d92c0
parent9557c3a66dccc357f7a8cfecca8e23639208afd2 (diff)
parent14d5cd1c3145e6f7d6645e1d9623eb9d5d244ad9 (diff)
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... :)
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c10
-rw-r--r--source/blender/blenkernel/intern/modifier.c10
-rw-r--r--source/blender/blenloader/intern/readfile.c13
-rw-r--r--source/blender/imbuf/intern/tiff.c6
-rw-r--r--source/blender/include/BDR_editcurve.h2
-rw-r--r--source/blender/include/BDR_editobject.h2
-rw-r--r--source/blender/include/BIF_editarmature.h2
-rw-r--r--source/blender/include/BIF_meshtools.h2
-rw-r--r--source/blender/include/BIF_space.h1
-rw-r--r--source/blender/python/api2_2x/Armature.c17
-rw-r--r--source/blender/python/api2_2x/BezTriple.c54
-rw-r--r--source/blender/python/api2_2x/Lamp.c19
-rw-r--r--source/blender/python/api2_2x/Material.c11
-rw-r--r--source/blender/python/api2_2x/Mesh.c70
-rw-r--r--source/blender/python/api2_2x/NMesh.c106
-rw-r--r--source/blender/python/api2_2x/Object.c202
-rw-r--r--source/blender/python/api2_2x/Scene.c59
-rw-r--r--source/blender/python/api2_2x/doc/Ipo.py11
-rw-r--r--source/blender/python/api2_2x/doc/Lamp.py4
-rw-r--r--source/blender/python/api2_2x/doc/Mesh.py8
-rw-r--r--source/blender/python/api2_2x/doc/Object.py135
-rw-r--r--source/blender/python/api2_2x/gen_utils.c14
-rw-r--r--source/blender/render/intern/source/envmap.c2
-rw-r--r--source/blender/render/intern/source/imagetexture.c12
-rw-r--r--source/blender/render/intern/source/texture.c74
-rw-r--r--source/blender/src/booleanops.c57
-rw-r--r--source/blender/src/buttons_editing.c4
-rw-r--r--source/blender/src/buttons_shading.c2
-rw-r--r--source/blender/src/drawipo.c2
-rw-r--r--source/blender/src/drawobject.c4
-rw-r--r--source/blender/src/drawoops.c36
-rw-r--r--source/blender/src/edit.c4
-rw-r--r--source/blender/src/editarmature.c11
-rw-r--r--source/blender/src/editcurve.c19
-rw-r--r--source/blender/src/editmesh.c8
-rw-r--r--source/blender/src/editmesh_mods.c3
-rw-r--r--source/blender/src/editmesh_tools.c2
-rw-r--r--source/blender/src/editobject.c34
-rw-r--r--source/blender/src/editoops.c15
-rw-r--r--source/blender/src/header_ipo.c2
-rw-r--r--source/blender/src/header_view3d.c25
-rw-r--r--source/blender/src/meshtools.c18
-rw-r--r--source/blender/src/renderwin.c2
-rw-r--r--source/blender/src/space.c31
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp4
-rw-r--r--source/gameengine/Converter/BL_MeshDeformer.h8
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp12
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h11
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp6
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h14
-rw-r--r--source/gameengine/Expressions/Value.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_BulletPhysicsController.cpp79
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp30
-rw-r--r--source/gameengine/Ketsji/KX_EmptyObject.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_EmptyObject.h2
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp11
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp4
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.cpp111
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h16
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp9
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h2
62 files changed, 1092 insertions, 362 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index aed1b3eeea9..13fd55d244f 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -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);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 090c1c71884..ae187c0e0f7 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -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 */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 3b37c2aba6c..34777930b4b 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -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;
}
/***/
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 970d0306fd6..5095cc42836 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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;
- }
}
}
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 5b86a2c2dfa..616531b3a77 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -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)
diff --git a/source/blender/include/BDR_editcurve.h b/source/blender/include/BDR_editcurve.h
index 9355eebb85d..9cddad4bf67 100644
--- a/source/blender/include/BDR_editcurve.h
+++ b/source/blender/include/BDR_editcurve.h
@@ -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);
diff --git a/source/blender/include/BDR_editobject.h b/source/blender/include/BDR_editobject.h
index 99c9655a763..a3f2a1061f1 100644
--- a/source/blender/include/BDR_editobject.h
+++ b/source/blender/include/BDR_editobject.h
@@ -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);
diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h
index 75aa02bfa57..7766accdab6 100644
--- a/source/blender/include/BIF_editarmature.h
+++ b/source/blender/include/BIF_editarmature.h
@@ -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);
diff --git a/source/blender/include/BIF_meshtools.h b/source/blender/include/BIF_meshtools.h
index 8df5e7255a5..e926d41faf1 100644
--- a/source/blender/include/BIF_meshtools.h
+++ b/source/blender/include/BIF_meshtools.h
@@ -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);
diff --git a/source/blender/include/BIF_space.h b/source/blender/include/BIF_space.h
index 7970ed5e41d..8213192a2ae 100644
--- a/source/blender/include/BIF_space.h
+++ b/source/blender/include/BIF_space.h
@@ -115,6 +115,7 @@ extern void set_rects_butspace(struct SpaceButs *buts);
extern void test_butspace(void);
extern void start_game(void);
extern void select_grouped(short nr);
+extern void join_menu(void);
extern void BIF_undo_push(char *str);
extern void BIF_undo(void);
diff --git a/source/blender/python/api2_2x/Armature.c b/source/blender/python/api2_2x/Armature.c
index 05a89dbda21..a2a3db05bc8 100644
--- a/source/blender/python/api2_2x/Armature.c
+++ b/source/blender/python/api2_2x/Armature.c
@@ -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);
}
diff --git a/source/blender/python/api2_2x/BezTriple.c b/source/blender/python/api2_2x/BezTriple.c
index 98e53d2fef8..3d610e38fd6 100644
--- a/source/blender/python/api2_2x/BezTriple.c
+++ b/source/blender/python/api2_2x/BezTriple.c
@@ -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" );
}
/****************************************************************************
diff --git a/source/blender/python/api2_2x/Lamp.c b/source/blender/python/api2_2x/Lamp.c
index a54e2988763..f60e68697ee 100644
--- a/source/blender/python/api2_2x/Lamp.c
+++ b/source/blender/python/api2_2x/Lamp.c
@@ -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" );
diff --git a/source/blender/python/api2_2x/Material.c b/source/blender/python/api2_2x/Material.c
index b9f9937d1fd..aa3c86e30fd 100644
--- a/source/blender/python/api2_2x/Material.c
+++ b/source/blender/python/api2_2x/Material.c
@@ -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 );
}
diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c
index ec5d75f16df..0bb882a046c 100644
--- a/source/blender/python/api2_2x/Mesh.c
+++ b/source/blender/python/api2_2x/Mesh.c
@@ -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 );
diff --git a/source/blender/python/api2_2x/NMesh.c b/source/blender/python/api2_2x/NMesh.c
index a22307c7574..f285557d5ee 100644
--- a/source/blender/python/api2_2x/NMesh.c
+++ b/source/blender/python/api2_2x/NMesh.c
@@ -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 );
diff --git a/source/blender/python/api2_2x/Object.c b/source/blender/python/api2_2x/Object.c
index f74a0a176e4..af945ea09c0 100644
--- a/source/blender/python/api2_2x/Object.c
+++ b/source/blender/python/api2_2x/Object.c
@@ -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;
+ list = PyList_New( 0 );
+
if( G.vd == NULL ) {
- // No 3d view has been initialized yet, simply return None
- Py_INCREF( Py_None );
- return Py_None;
+ /* No 3d view has been initialized yet, simply return an empty list */
+ return list;
}
- list = PyList_New( 0 );
+
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 */
diff --git a/source/blender/python/api2_2x/Scene.c b/source/blender/python/api2_2x/Scene.c
index d90b5843540..90aa548d7ce 100644
--- a/source/blender/python/api2_2x/Scene.c
+++ b/source/blender/python/api2_2x/Scene.c
@@ -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 */
diff --git a/source/blender/python/api2_2x/doc/Ipo.py b/source/blender/python/api2_2x/doc/Ipo.py
index b4a99c0216b..8621bd18ca0 100644
--- a/source/blender/python/api2_2x/doc/Ipo.py
+++ b/source/blender/python/api2_2x/doc/Ipo.py
@@ -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.
diff --git a/source/blender/python/api2_2x/doc/Lamp.py b/source/blender/python/api2_2x/doc/Lamp.py
index e6ac1c05f4a..52ec301f994 100644
--- a/source/blender/python/api2_2x/doc/Lamp.py
+++ b/source/blender/python/api2_2x/doc/Lamp.py
@@ -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'):
diff --git a/source/blender/python/api2_2x/doc/Mesh.py b/source/blender/python/api2_2x/doc/Mesh.py
index 9e1b3e6610f..f60d84ff02a 100644
--- a/source/blender/python/api2_2x/doc/Mesh.py
+++ b/source/blender/python/api2_2x/doc/Mesh.py
@@ -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
diff --git a/source/blender/python/api2_2x/doc/Object.py b/source/blender/python/api2_2x/doc/Object.py
index 4fd3edc42cd..dac594d9259 100644
--- a/source/blender/python/api2_2x/doc/Object.py
+++ b/source/blender/python/api2_2x/doc/Object.py
@@ -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
diff --git a/source/blender/python/api2_2x/gen_utils.c b/source/blender/python/api2_2x/gen_utils.c
index 4e42c06d2a8..4460a93d38f 100644
--- a/source/blender/python/api2_2x/gen_utils.c
+++ b/source/blender/python/api2_2x/gen_utils.c
@@ -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;
}
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index aba3a34929c..c728c51038d 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -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);
}
}
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index f412df84bca..7e0a26e2116 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -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);
}
}
}
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index 518ab581efc..b3d053b3f34 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -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);
diff --git a/source/blender/src/booleanops.c b/source/blender/src/booleanops.c
index 1b1d5705ab9..17850d08aaa 100644
--- a/source/blender/src/booleanops.c
+++ b/source/blender/src/booleanops.c
@@ -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.
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 77a9b8580ed..5137af7a12b 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -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");
diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c
index f76b5021922..cc247cae715 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -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");
diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c
index f2f8fa6f062..407d5779354 100644
--- a/source/blender/src/drawipo.c
+++ b/source/blender/src/drawipo.c
@@ -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);
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 5b3b27b2c3e..26c8c30d611 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -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)
diff --git a/source/blender/src/drawoops.c b/source/blender/src/drawoops.c
index 0fc22ceea91..dbf245179df 100644
--- a/source/blender/src/drawoops.c
+++ b/source/blender/src/drawoops.c
@@ -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;
diff --git a/source/blender/src/edit.c b/source/blender/src/edit.c
index 3d0bee6f080..355aee6e6c9 100644
--- a/source/blender/src/edit.c
+++ b/source/blender/src/edit.c
@@ -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);
}
}
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index fc54e50a251..0c315e65005 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -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 **************** */
diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c
index d87450e7a72..b660836f9d2 100644
--- a/source/blender/src/editcurve.c
+++ b/source/blender/src/editcurve.c
@@ -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;
}
diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c
index 79faf918c52..e54bb0c156d 100644
--- a/source/blender/src/editmesh.c
+++ b/source/blender/src/editmesh.c
@@ -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() */
diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c
index 44b1f8be055..8cefaf4221b 100644
--- a/source/blender/src/editmesh_mods.c
+++ b/source/blender/src/editmesh_mods.c
@@ -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");
diff --git a/source/blender/src/editmesh_tools.c b/source/blender/src/editmesh_tools.c
index ffb10a215ab..c244f1d249c 100644
--- a/source/blender/src/editmesh_tools.c
+++ b/source/blender/src/editmesh_tools.c
@@ -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++;
}
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index 00855a5fef6..5c3655094cc 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -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)
diff --git a/source/blender/src/editoops.c b/source/blender/src/editoops.c
index 6c8fa7d5f9d..2b4a3e869f8 100644
--- a/source/blender/src/editoops.c
+++ b/source/blender/src/editoops.c
@@ -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;
+ */
}
}
diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c
index c61c726c868..36334a7d295 100644
--- a/source/blender/src/header_ipo.c
+++ b/source/blender/src/header_ipo.c
@@ -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, "");
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index c52704e4020..a95ee43a311 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -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);
diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c
index 2b96bbc20b6..3a7df18c584 100644
--- a/source/blender/src/meshtools.c
+++ b/source/blender/src/meshtools.c
@@ -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;
}
diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c
index ae6ffee5df5..c629beee9c3 100644
--- a/source/blender/src/renderwin.c
+++ b/source/blender/src/renderwin.c
@@ -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
}
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index b2b091f572b..4fdc764bc76 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -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();
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index f6136d52684..fe0cf281a1a 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -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;
}
diff --git a/source/gameengine/Converter/BL_MeshDeformer.h b/source/gameengine/Converter/BL_MeshDeformer.h
index 04e0f3b0628..c9030ceca36 100644
--- a/source/gameengine/Converter/BL_MeshDeformer.h
+++ b/source/gameengine/Converter/BL_MeshDeformer.h
@@ -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;
};
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
index ee298d70baf..84a3b8dcc5c 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.cpp
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -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
diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h
index a61ebf59b22..49c69298336 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.h
+++ b/source/gameengine/Converter/BL_SkinDeformer.h
@@ -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)
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
index b75da2c12a2..55cd76824c9 100644
--- a/source/gameengine/Expressions/PyObjectPlus.cpp
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -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);
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index c261012a3bc..026a58cdbca 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -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.
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
index 1a09123c107..bb9ad81f245 100644
--- a/source/gameengine/Expressions/Value.cpp
+++ b/source/gameengine/Expressions/Value.cpp
@@ -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
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
index 5857c614e2d..7806b77257a 100644
--- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
+++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
@@ -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;
+
}
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index e9a6c2442b0..fb5037345a8 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -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);
diff --git a/source/gameengine/Ketsji/KX_EmptyObject.cpp b/source/gameengine/Ketsji/KX_EmptyObject.cpp
index 8a72ba62f51..4636f2f0a3e 100644
--- a/source/gameengine/Ketsji/KX_EmptyObject.cpp
+++ b/source/gameengine/Ketsji/KX_EmptyObject.cpp
@@ -35,3 +35,7 @@
#include <config.h>
#endif
+KX_EmptyObject::~KX_EmptyObject()
+{
+
+}
diff --git a/source/gameengine/Ketsji/KX_EmptyObject.h b/source/gameengine/Ketsji/KX_EmptyObject.h
index b2038eb4816..46858b5c46d 100644
--- a/source/gameengine/Ketsji/KX_EmptyObject.h
+++ b/source/gameengine/Ketsji/KX_EmptyObject.h
@@ -39,7 +39,7 @@ public:
KX_EmptyObject(void* sgReplicationInfo,SG_Callbacks callbacks) :
KX_GameObject(sgReplicationInfo,callbacks)
{};
- virtual ~KX_EmptyObject() {};
+ virtual ~KX_EmptyObject();
};
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index e82ecd83fee..bd7ce6cc36d 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -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);
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 6ad420375e6..f13df6bfa44 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -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
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
index d9c5575f657..7051b8f7e13 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
@@ -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);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 4f189b7f324..3becd14028a 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -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);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index c1bfa43d788..75a67e3cb37 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -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;
}
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
index 8bacbad8914..329239db667 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h
@@ -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);