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:
-rw-r--r--source/blender/blenkernel/BKE_idprop.h1
-rw-r--r--source/blender/blenkernel/bad_level_call_stubs/stubs.c3
-rw-r--r--source/blender/blenkernel/intern/constraint.c4
-rw-r--r--source/blender/blenkernel/intern/idprop.c15
-rw-r--r--source/blender/blenkernel/intern/softbody.c6
-rw-r--r--source/blender/blenlib/intern/arithb.c5
-rw-r--r--source/blender/blenloader/intern/readfile.c28
-rw-r--r--source/blender/blenloader/intern/writefile.c1
-rw-r--r--source/blender/include/BDR_gpencil.h2
-rw-r--r--source/blender/makesdna/DNA_ID.h3
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h8
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_material.c3
-rw-r--r--source/blender/nodes/intern/SHD_util.c4
-rw-r--r--source/blender/nodes/intern/SHD_util.h13
-rw-r--r--source/blender/python/BPY_interface.c2
-rw-r--r--source/blender/python/api2_2x/IDProp.c57
-rw-r--r--source/blender/python/api2_2x/doc/IDProp.py4
-rw-r--r--source/blender/python/api2_2x/sceneRender.c4
-rw-r--r--source/blender/src/drawaction.c30
-rw-r--r--source/blender/src/drawgpencil.c118
-rw-r--r--source/blender/src/editnode.c16
-rw-r--r--source/blender/src/gpencil.c32
-rw-r--r--source/blender/src/interface_draw.c1
-rw-r--r--source/blender/src/space.c18
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp10
-rw-r--r--source/gameengine/Converter/KX_IpoConvert.cpp59
-rw-r--r--source/gameengine/Converter/KX_IpoConvert.h2
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp21
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h1
-rw-r--r--source/gameengine/Ketsji/KX_MaterialIpoController.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_MaterialIpoController.h8
-rw-r--r--source/gameengine/Ketsji/KX_PyMath.h23
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp8
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp5
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h1
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp15
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h1
37 files changed, 382 insertions, 151 deletions
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 2d7d0e9286f..2274c54ad3b 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -46,6 +46,7 @@ struct ID;
typedef union {
int i;
float f;
+ double d;
char *str;
struct ID *id;
struct {
diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c
index 856816e619e..dd079f69a0b 100644
--- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c
+++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c
@@ -1,4 +1,3 @@
-
/**
* $Id$
*
@@ -352,6 +351,8 @@ TimeMarker *get_frame_marker(int frame){return 0;};
/* editseq.c */
Sequence *get_forground_frame_seq(int frame){return 0;};
void set_last_seq(Sequence *seq){};
+void clear_last_seq(Sequence *seq){};
+
/* modifier.c stub */
void harmonic_coordinates_bind(struct MeshDeformModifierData *mmd,
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 068501780bc..f13fd5f9963 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -558,8 +558,8 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
if (dgroup < 0) return;
/* get DerivedMesh */
- if (G.obedit && G.editMesh) {
- /* we are in editmode, so get a special derived mesh */
+ if ((G.obedit == ob) && (G.editMesh)) {
+ /* target is in editmode, so get a special derived mesh */
dm = CDDM_from_editmesh(G.editMesh, ob->data);
}
else {
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 2ef2f3a1b77..b16f52571f6 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -54,7 +54,8 @@ static char idp_size_table[] = {
sizeof(float)*16, /*Matrix type, deprecated*/
0, /*arrays don't have a fixed size*/
sizeof(ListBase), /*Group type*/
- sizeof(void*)
+ sizeof(void*),
+ sizeof(double)
};
@@ -365,10 +366,14 @@ IDProperty *IDP_New(int type, IDPropertyTemplate val, char *name)
prop = MEM_callocN(sizeof(IDProperty), "IDProperty float");
*(float*)&prop->data.val = val.f;
break;
+ case IDP_DOUBLE:
+ prop = MEM_callocN(sizeof(IDProperty), "IDProperty float");
+ *(double*)&prop->data.val = val.d;
+ break;
case IDP_ARRAY:
{
- /*for now, we only support float and int arrays*/
- if (val.array.type == IDP_FLOAT || val.array.type == IDP_INT) {
+ /*for now, we only support float and int and double arrays*/
+ if (val.array.type == IDP_FLOAT || val.array.type == IDP_INT || val.array.type == IDP_DOUBLE) {
prop = MEM_callocN(sizeof(IDProperty), "IDProperty array");
prop->len = prop->totallen = val.array.len;
prop->subtype = val.array.type;
@@ -411,6 +416,10 @@ IDProperty *IDP_New(int type, IDPropertyTemplate val, char *name)
prop->type = type;
strncpy(prop->name, name, MAX_IDPROP_NAME);
+
+ /*security null byte*/
+ prop->name[MAX_IDPROP_NAME-1] = 0;
+
return prop;
}
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 9005db1312f..d5b5ab6d63e 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -2053,7 +2053,6 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
/* check conditions for various options */
do_deflector= query_external_colliders(ob);
- do_effector= pdInitEffectors(ob,NULL);
do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
do_springcollision=do_deflector && (ob->softflag & OB_SB_EDGES) &&(ob->softflag & OB_SB_EDGECOLL);
do_aero=((sb->aeroedge)&& (ob->softflag & OB_SB_EDGES));
@@ -2061,9 +2060,10 @@ static void softbody_calc_forces(Object *ob, float forcetime, float timenow, int
iks = 1.0f/(1.0f-sb->inspring)-1.0f ;/* inner spring constants function */
bproot= sb->bpoint; /* need this for proper spring addressing */
-
-
if (do_springcollision || do_aero) scan_for_ext_spring_forces(ob,timenow);
+ /* after spring scan because it uses Effoctors too */
+ do_effector= pdInitEffectors(ob,NULL);
+
if (do_deflector) {
float defforce[3];
do_deflector = sb_detect_aabb_collisionCached(defforce,ob->lay,ob,timenow);
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 486ff623b5a..108f24bef49 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -2544,11 +2544,6 @@ int IsectPQ2Df(float pt[2], float v1[2], float v2[2], float v3[2], float v4[2])
}
-
- /* copied from Geometry.c - todo - move to arithb.c or some other generic place we can reuse */
-#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
-#define POINT_IN_TRI(p0,p1,p2,p3) ((SIDE_OF_LINE(p1,p2,p0)>=0) && (SIDE_OF_LINE(p2,p3,p0)>=0) && (SIDE_OF_LINE(p3,p1,p0)>=0))
-
/**
*
* @param min
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 2a72f27dbc1..d42e381fff7 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1356,8 +1356,14 @@ void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, void *fd)
prop->data.pointer = newdataadr(fd, prop->data.pointer);
if (switch_endian) {
- for (i=0; i<prop->len; i++) {
- SWITCH_INT(((int*)prop->data.pointer)[i]);
+ if (prop->subtype != IDP_DOUBLE) {
+ for (i=0; i<prop->len; i++) {
+ SWITCH_INT(((int*)prop->data.pointer)[i]);
+ }
+ } else {
+ for (i=0; i<prop->len; i++) {
+ SWITCH_LONGINT(((double*)prop->data.pointer)[i]);
+ }
}
}
}
@@ -1394,6 +1400,24 @@ void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, void *fd)
case IDP_ARRAY:
IDP_DirectLinkArray(prop, switch_endian, fd);
break;
+ case IDP_DOUBLE:
+ /*erg, stupid doubles. since I'm storing them
+ in the same field as int val; val2 in the
+ IDPropertyData struct, they have to deal with
+ endianness specifically
+
+ in theory, val and val2 would've already been swapped
+ if switch_endian is true, so we have to first unswap
+ them then reswap them as a single 64-bit entity.
+ */
+
+ if (switch_endian) {
+ SWITCH_INT(prop->data.val);
+ SWITCH_INT(prop->data.val2);
+ SWITCH_LONGINT(prop->data.val);
+ }
+
+ break;
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 34dfa15e875..02cc5cab6d5 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -533,6 +533,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
if(part->id.us>0 || wd->current) {
/* write LibData */
writestruct(wd, ID_PA, "ParticleSettings", 1, part);
+ if (part->id.properties) IDP_WriteProperty(part->id.properties, wd);
writestruct(wd, DATA, "PartDeflect", 1, part->pd);
}
part= part->id.next;
diff --git a/source/blender/include/BDR_gpencil.h b/source/blender/include/BDR_gpencil.h
index 8f3d6b92963..d2fc7be29ea 100644
--- a/source/blender/include/BDR_gpencil.h
+++ b/source/blender/include/BDR_gpencil.h
@@ -69,6 +69,6 @@ void gpencil_delete_operation(short mode);
void gpencil_delete_menu(void);
//short gpencil_paint(short mousebutton);
-short gpencil_do_paint(struct ScrArea *sa);
+short gpencil_do_paint(struct ScrArea *sa, short mousebutton);
#endif /* BDR_GPENCIL_H */
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 22649abefa2..784335c1144 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -46,7 +46,7 @@ struct ID;
typedef struct IDPropertyData {
void *pointer;
ListBase group;
- int val, pad;
+ int val, val2; /*note, we actually fit a double into these two ints*/
} IDPropertyData;
typedef struct IDProperty {
@@ -77,6 +77,7 @@ typedef struct IDProperty {
/*the ID link property type hasn't been implemented yet, this will require
some cleanup of blenkernel, most likely.*/
#define IDP_ID 7
+#define IDP_DOUBLE 8
/*add any future new id property types here.*/
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 2ac5faab066..b88dd698c3f 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -59,6 +59,8 @@ typedef struct bGPDstroke {
#define GP_STROKE_3DSPACE (1<<0)
/* stroke is in 2d-space */
#define GP_STROKE_2DSPACE (1<<1)
+ /* stroke is an "eraser" stroke */
+#define GP_STROKE_ERASER (1<<2)
/* Grease-Pencil Annotations - 'Frame'
@@ -127,12 +129,12 @@ typedef struct bGPdata {
} bGPdata;
/* bGPdata->flag */
- /* draw this datablock's data (not used) */
-#define GP_DATA_DISP (1<<0)
+ /* don't allow painting to occur at all */
+#define GP_DATA_LMBPLOCK (1<<0)
/* show debugging info in viewport (i.e. status print) */
#define GP_DATA_DISPINFO (1<<1)
/* in Action Editor, show as expanded channel */
-#define GP_DATA_EXPAND (1<<2)
+#define GP_DATA_EXPAND (1<<2)
/* is the block overriding all clicks? */
#define GP_DATA_EDITPAINT (1<<3)
/* new strokes are added in viewport space */
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_material.c b/source/blender/nodes/intern/SHD_nodes/SHD_material.c
index 6773baff98f..c0a2534ac4a 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_material.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_material.c
@@ -54,7 +54,6 @@ static bNodeSocketType sh_node_material_ext_in[]= {
{ SOCK_VALUE, 1, "Refl", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_VECTOR, 1, "Normal", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f},
{ SOCK_RGBA, 1, "Mirror", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 1, "AmbCol", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 1, "Ambient", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 1, "Emit", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
{ SOCK_VALUE, 1, "SpecTra", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f},
@@ -117,8 +116,6 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in,
if (node->type == SH_NODE_MATERIAL_EXT) {
if(in[MAT_IN_MIR]->hasinput)
nodestack_get_vec(&shi->mirr, SOCK_VECTOR, in[MAT_IN_MIR]);
- if(in[MAT_IN_AMBCOL]->hasinput)
- nodestack_get_vec(&shi->ambr, SOCK_VECTOR, in[MAT_IN_AMBCOL]);
if(in[MAT_IN_AMB]->hasinput)
nodestack_get_vec(&shi->amb, SOCK_VALUE, in[MAT_IN_AMB]);
if(in[MAT_IN_EMIT]->hasinput)
diff --git a/source/blender/nodes/intern/SHD_util.c b/source/blender/nodes/intern/SHD_util.c
index c9f58fbce49..f673834d2b7 100644
--- a/source/blender/nodes/intern/SHD_util.c
+++ b/source/blender/nodes/intern/SHD_util.c
@@ -164,7 +164,7 @@ void nodeShaderSynchronizeID(bNode *node, int copyto)
case MAT_IN_MIR:
VECCOPY(&ma->mirr, sock->ns.vec); break;
case MAT_IN_AMB:
- VECCOPY(&ma->ambr, sock->ns.vec); break;
+ ma->amb= sock->ns.vec[0]; break;
case MAT_IN_EMIT:
ma->emit= sock->ns.vec[0]; break;
case MAT_IN_SPECTRA:
@@ -188,7 +188,7 @@ void nodeShaderSynchronizeID(bNode *node, int copyto)
case MAT_IN_MIR:
VECCOPY(sock->ns.vec, &ma->mirr); break;
case MAT_IN_AMB:
- VECCOPY(sock->ns.vec, &ma->ambr); break;
+ sock->ns.vec[0]= ma->amb; break;
case MAT_IN_EMIT:
sock->ns.vec[0]= ma->emit; break;
case MAT_IN_SPECTRA:
diff --git a/source/blender/nodes/intern/SHD_util.h b/source/blender/nodes/intern/SHD_util.h
index 3044d72e3ac..eda985529c1 100644
--- a/source/blender/nodes/intern/SHD_util.h
+++ b/source/blender/nodes/intern/SHD_util.h
@@ -119,13 +119,12 @@ typedef struct ShaderCallData {
#define MAT_IN_REFL 2
#define MAT_IN_NORMAL 3
#define MAT_IN_MIR 4
-#define MAT_IN_AMBCOL 5
-#define MAT_IN_AMB 6
-#define MAT_IN_EMIT 7
-#define MAT_IN_SPECTRA 8
-#define MAT_IN_RAY_MIRROR 9
-#define MAT_IN_ALPHA 10
-#define MAT_IN_TRANSLUCENCY 11
+#define MAT_IN_AMB 5
+#define MAT_IN_EMIT 6
+#define MAT_IN_SPECTRA 7
+#define MAT_IN_RAY_MIRROR 8
+#define MAT_IN_ALPHA 9
+#define MAT_IN_TRANSLUCENCY 10
/* output socket defines */
#define MAT_OUT_COLOR 0
diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c
index e94bb335912..5c2ffa7e615 100644
--- a/source/blender/python/BPY_interface.c
+++ b/source/blender/python/BPY_interface.c
@@ -410,12 +410,14 @@ void BPY_rebuild_syspath( void )
mod = PyImport_ImportModule( "sys" );
if (!mod) {
printf("error: could not import python sys module. some modules may not import.\n");
+ PyGILState_Release(gilstate);
return;
}
if (!bpy_orig_syspath_List) { /* should never happen */
printf("error refershing python path\n");
Py_DECREF(mod);
+ PyGILState_Release(gilstate);
return;
}
diff --git a/source/blender/python/api2_2x/IDProp.c b/source/blender/python/api2_2x/IDProp.c
index f60ebf8dee1..4a51619aec4 100644
--- a/source/blender/python/api2_2x/IDProp.c
+++ b/source/blender/python/api2_2x/IDProp.c
@@ -60,6 +60,8 @@ PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop )
return PyInt_FromLong( (long)prop->data.val );
case IDP_FLOAT:
return PyFloat_FromDouble( (double)(*(float*)(&prop->data.val)) );
+ case IDP_DOUBLE:
+ return PyFloat_FromDouble( (*(double*)(&prop->data.val)) );
case IDP_GROUP:
/*blegh*/
{
@@ -128,7 +130,19 @@ int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject *value)
Py_XDECREF(value);
break;
}
-
+ case IDP_DOUBLE:
+ {
+ double dvalue;
+ if (!PyNumber_Check(value))
+ return EXPP_ReturnIntError(PyExc_TypeError, "expected a float!");
+ value = PyNumber_Float(value);
+ if (!value)
+ return EXPP_ReturnIntError(PyExc_TypeError, "expected a float!");
+ dvalue = (float) PyFloat_AsDouble(value);
+ *(double*)&self->prop->data.val = dvalue;
+ Py_XDECREF(value);
+ break;
+ }
default:
return EXPP_ReturnIntError(PyExc_AttributeError, "attempt to set read-only attribute!");
}
@@ -204,8 +218,8 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
IDPropertyTemplate val = {0};
if (PyFloat_Check(ob)) {
- val.f = (float) PyFloat_AsDouble(ob);
- prop = IDP_New(IDP_FLOAT, val, name);
+ val.d = PyFloat_AsDouble(ob);
+ prop = IDP_New(IDP_DOUBLE, val, name);
} else if (PyInt_Check(ob)) {
val.i = (int) PyInt_AsLong(ob);
prop = IDP_New(IDP_INT, val, name);
@@ -223,7 +237,7 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
val.array.len = PySequence_Length(ob);
for (i=0; i<val.array.len; i++) {
item = PySequence_GetItem(ob, i);
- if (PyFloat_Check(item)) val.array.type = IDP_FLOAT;
+ if (PyFloat_Check(item)) val.array.type = IDP_DOUBLE;
else if (!PyInt_Check(item)) return "only floats and ints are allowed in ID property arrays";
Py_XDECREF(item);
}
@@ -236,7 +250,7 @@ char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObje
((int*)prop->data.pointer)[i] = (int)PyInt_AsLong(item);
} else {
item = PyNumber_Float(item);
- ((float*)prop->data.pointer)[i] = (float)PyFloat_AsDouble(item);
+ ((double*)prop->data.pointer)[i] = (float)PyFloat_AsDouble(item);
}
Py_XDECREF(item);
}
@@ -334,6 +348,9 @@ PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
case IDP_FLOAT:
return PyFloat_FromDouble(*((float*)&prop->data.val));
break;
+ case IDP_DOUBLE:
+ return PyFloat_FromDouble(*((double*)&prop->data.val));
+ break;
case IDP_INT:
return PyInt_FromLong( (long)prop->data.val );
break;
@@ -347,12 +364,15 @@ PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
"PyList_New() failed" );
for (i=0; i<prop->len; i++) {
- if (prop->subtype == IDP_FLOAT)
+ if (prop->subtype == IDP_FLOAT) {
PyList_SetItem(seq, i,
PyFloat_FromDouble(((float*)prop->data.pointer)[i]));
-
- else PyList_SetItem(seq, i,
- PyInt_FromLong(((int*)prop->data.pointer)[i]));
+ } else if (prop->subtype == IDP_DOUBLE) {
+ PyList_SetItem(seq, i,
+ PyFloat_FromDouble(((double*)prop->data.pointer)[i]));
+ } else { PyList_SetItem(seq, i,
+ PyInt_FromLong(((int*)prop->data.pointer)[i]));
+ }
}
return seq;
}
@@ -451,7 +471,7 @@ PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self)
/*set correct group length*/
self->prop->len = i;
- /*free the old list*/
+ /*free the list*/
Py_DECREF(seq);
/*call self again*/
@@ -688,6 +708,9 @@ PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, int index)
case IDP_FLOAT:
return PyFloat_FromDouble( (double)(((float*)self->prop->data.pointer)[index]));
break;
+ case IDP_DOUBLE:
+ return PyFloat_FromDouble( (((double*)self->prop->data.pointer)[index]));
+ break;
case IDP_INT:
return PyInt_FromLong( (long)((int*)self->prop->data.pointer)[index] );
break;
@@ -700,7 +723,8 @@ int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *val)
{
int i;
float f;
-
+ double d;
+
if (index < 0 || index >= self->prop->len)
return EXPP_ReturnIntError( PyExc_RuntimeError,
"index out of range!");
@@ -717,6 +741,17 @@ int BPy_IDArray_SetItem(BPy_IDArray *self, int index, PyObject *val)
((float*)self->prop->data.pointer)[index] = f;
Py_XDECREF(val);
break;
+ case IDP_DOUBLE:
+ if (!PyNumber_Check(val)) return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a float");
+ val = PyNumber_Float(val);
+ if (!val) return EXPP_ReturnIntError( PyExc_TypeError,
+ "expected a float");
+
+ d = (double) PyFloat_AsDouble(val);
+ ((double*)self->prop->data.pointer)[index] = d;
+ Py_XDECREF(val);
+ break;
case IDP_INT:
if (!PyNumber_Check(val)) return EXPP_ReturnIntError( PyExc_TypeError,
"expected an int");
diff --git a/source/blender/python/api2_2x/doc/IDProp.py b/source/blender/python/api2_2x/doc/IDProp.py
index 0a0df335fa3..01d5136cd70 100644
--- a/source/blender/python/api2_2x/doc/IDProp.py
+++ b/source/blender/python/api2_2x/doc/IDProp.py
@@ -18,7 +18,9 @@ class IDGroup:
Note that for arrays, the array type defaults to int unless a float is found
while scanning the template list; if any floats are found, then the whole
- array is float.
+ array is float. Note that double-precision floating point numbers are used for
+ python-created float ID properties and arrays (though the internal C api does
+ support single-precision floats, and the python code will read them).
You can also delete properties with the del operator. For example:
diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c
index d382d450970..8f251fc8452 100644
--- a/source/blender/python/api2_2x/sceneRender.c
+++ b/source/blender/python/api2_2x/sceneRender.c
@@ -565,6 +565,8 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args )
PyObject *RenderData_RenderAnim( BPy_RenderData * self )
{
Scene *oldsce;
+ /* this prevents a deadlock when there are pynodes: */
+ PyThreadState *tstate = PyEval_SaveThread();
if (!G.background) {
oldsce = G.scene;
@@ -582,9 +584,9 @@ PyObject *RenderData_RenderAnim( BPy_RenderData * self )
if (G.scene->r.sfra > G.scene->r.efra)
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
"start frame must be less or equal to end frame");
-
RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra);
}
+ PyEval_RestoreThread(tstate);
Py_RETURN_NONE;
}
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index fc629b7c1b0..0782ccfc7ee 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -646,7 +646,7 @@ static void draw_channel_names(void)
case SPACE_VIEW3D:
{
/* this shouldn't cause any overflow... */
- sprintf(name, "3D-View: <%s>", view3d_get_name(sa->spacedata.first));
+ sprintf(name, "3DView: %s", view3d_get_name(sa->spacedata.first));
special= ICON_VIEW3D;
}
break;
@@ -684,8 +684,10 @@ static void draw_channel_names(void)
break;
default:
- sprintf(name, "GP-Data");
+ {
+ sprintf(name, "<Unknown GP-Data Source>");
special= -1;
+ }
break;
}
}
@@ -775,13 +777,19 @@ static void draw_channel_names(void)
offset += 17;
}
- /* draw special icon indicating type of ipo-blocktype?
- * only for expand widgets for Ipo and Constraint Channels
- */
- if (special > 0) {
- offset = (group) ? 29 : 24;
- BIF_icon_draw(x+offset, yminc, special);
- offset += 17;
+ /* draw special icon indicating certain data-types */
+ if (special > -1) {
+ if (group == 3) {
+ /* for gpdatablock channels */
+ BIF_icon_draw(x+offset, yminc, special);
+ offset += 17;
+ }
+ else {
+ /* for ipo/constraint channels */
+ offset = (group) ? 29 : 24;
+ BIF_icon_draw(x+offset, yminc, special);
+ offset += 17;
+ }
}
/* draw name */
@@ -797,13 +805,13 @@ static void draw_channel_names(void)
offset = 0;
/* draw protect 'lock' */
- if (protect > 0) {
+ if (protect > -1) {
offset = 16;
BIF_icon_draw(NAMEWIDTH-offset, yminc, protect);
}
/* draw mute 'eye' */
- if (mute > 0) {
+ if (mute > -1) {
offset += 16;
BIF_icon_draw(NAMEWIDTH-offset, yminc, mute);
}
diff --git a/source/blender/src/drawgpencil.c b/source/blender/src/drawgpencil.c
index 2e1586c369b..aacae08d972 100644
--- a/source/blender/src/drawgpencil.c
+++ b/source/blender/src/drawgpencil.c
@@ -94,7 +94,7 @@
void gp_ui_activelayer_cb (void *gpd, void *gpl)
{
gpencil_layer_setactive(gpd, gpl);
- force_draw_plus(SPACE_ACTION, 0);
+ allqueue(REDRAWACTION, 0);
}
/* rename layer and set active */
@@ -105,21 +105,21 @@ void gp_ui_renamelayer_cb (void *gpd_arg, void *gpl_arg)
BLI_uniquename(&gpd->layers, gpl, "GP_Layer", offsetof(bGPDlayer, info[0]), 128);
gpencil_layer_setactive(gpd, gpl);
- force_draw_plus(SPACE_ACTION, 0);
+ allqueue(REDRAWACTION, 0);
}
/* add a new layer */
void gp_ui_addlayer_cb (void *gpd, void *dummy)
{
gpencil_layer_addnew(gpd);
- force_draw_plus(SPACE_ACTION, 0);
+ allqueue(REDRAWACTION, 0);
}
/* delete active layer */
void gp_ui_dellayer_cb (void *gpd, void *dummy)
{
gpencil_layer_delactive(gpd);
- force_draw_plus(SPACE_ACTION, 0);
+ allqueue(REDRAWACTION, 0);
}
/* delete last stroke of active layer */
@@ -139,7 +139,7 @@ void gp_ui_delframe_cb (void *gpd, void *gpl)
gpencil_layer_setactive(gpd, gpl);
gpencil_layer_delframe(gpl, gpf);
- force_draw_plus(SPACE_ACTION, 0);
+ allqueue(REDRAWACTION, 0);
}
/* ------- Drawing Code ------- */
@@ -148,6 +148,7 @@ void gp_ui_delframe_cb (void *gpd, void *gpl)
static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short *xco, short *yco)
{
uiBut *but;
+ short active= (gpl->flag & GP_LAYER_ACTIVE);
short width= 314;
short height;
int rb_col;
@@ -160,10 +161,10 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
uiBlockSetEmboss(block, UI_EMBOSSN);
/* rounded header */
- //uiBlockSetCol(block, TH_BUT_SETTING1); // FIXME: maybe another color
- rb_col= (gpl->flag & GP_LAYER_ACTIVE)?50:20;
+ if (active) uiBlockSetCol(block, TH_BUT_ACTION);
+ rb_col= (active)?-20:20;
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15 , rb_col-20, "");
- //uiBlockSetCol(block, TH_AUTO);
+ if (active) uiBlockSetCol(block, TH_AUTO);
/* lock toggle */
uiDefIconButBitI(block, ICONTOG, GP_LAYER_LOCKED, B_REDR, ICON_UNLOCKED, *xco-7, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Layer cannot be modified");
@@ -212,9 +213,9 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
}
/* draw backdrop */
- //uiBlockSetCol(block, TH_BUT_SETTING1); // fixme: maybe another color
+ if (active) uiBlockSetCol(block, TH_BUT_ACTION);
uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12, rb_col, "");
- //uiBlockSetCol(block, TH_AUTO);
+ if (active) uiBlockSetCol(block, TH_AUTO);
/* draw settings */
{
@@ -235,11 +236,13 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
uiBlockEndAlign(block);
/* options */
- but= uiDefBut(block, BUT, B_REDR, "Del Active Frame", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Erases the the active frame for this layer");
- uiButSetFunc(but, gp_ui_delframe_cb, gpd, gpl);
-
- but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame");
- uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl);
+ uiBlockBeginAlign(block);
+ but= uiDefBut(block, BUT, B_REDR, "Del Active Frame", *xco+160, *yco-75, 140, 20, NULL, 0, 0, 0, 0, "Erases the the active frame for this layer (Hotkey = Alt-XKEY/DEL)");
+ uiButSetFunc(but, gp_ui_delframe_cb, gpd, gpl);
+
+ but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame (Hotkey = Alt-XKEY/DEL)");
+ uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl);
+ uiBlockEndAlign(block);
//uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco+160, *yco-75, 130, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes");
}
@@ -268,8 +271,14 @@ short draw_gpencil_panel (uiBlock *block, bGPdata *gpd, ScrArea *sa)
uiButSetFunc(but, gp_ui_addlayer_cb, gpd, NULL);
- /* show override lmb-clicks button */
- uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret LMB-click as new strokes (same as holding Shift-Key per stroke)");
+ /* show override lmb-clicks button + painting lock */
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret LMB-click as new strokes (same as holding Shift-Key per stroke)");
+
+ uiBlockSetCol(block, TH_BUT_SETTING);
+ uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED, 300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)");
+ uiBlockSetCol(block, TH_AUTO);
+ uiBlockEndAlign(block);
/* 'view align' button (naming depends on context) */
if (sa->spacetype == SPACE_VIEW3D)
@@ -406,6 +415,45 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness,
}
}
+/* draw a set of strokes */
+static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, short debug,
+ short lthick, float color[4])
+{
+ bGPDstroke *gps;
+
+ /* set color first (may need to reset it again later too) */
+ glColor4f(color[0], color[1], color[2], color[3]);
+
+ for (gps= gpf->strokes.first; gps; gps= gps->next) {
+ /* handle 'eraser' strokes differently */
+ if (gps->flag & GP_STROKE_ERASER) {
+ // FIXME: this method is a failed experiment
+#if 0
+ /* draw stroke twice, first time with 'white' to set a mask to invert
+ * contents of framebuffer, then second-time the same again but to restore
+ * the contents
+ */
+ glEnable(GL_COLOR_LOGIC_OP);
+ glLogicOp(GL_XOR);
+
+ glColor4f(1, 1, 1, 1); /* white */
+
+ gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, 0, winx, winy);
+ gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, 0, winx, winy);
+
+ glDisable(GL_COLOR_LOGIC_OP);
+
+ /* reset color for drawing next stroke */
+ glColor4f(color[0], color[1], color[2], color[3]);
+#endif
+ }
+ else {
+ /* just draw the stroke once */
+ gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
+ }
+ }
+}
+
/* draw grease-pencil datablock */
static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
{
@@ -421,11 +469,10 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* loop over layers, drawing them */
for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
bGPDframe *gpf;
- bGPDstroke *gps;
short debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? 1 : 0;
short lthick= gpl->thickness;
- float color[4];
+ float color[4], tcolor[4];
/* don't draw layer if hidden */
if (gpl->flag & GP_LAYER_HIDE)
@@ -443,6 +490,7 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* set color, stroke thickness, and point size */
glLineWidth(lthick);
QUATCOPY(color, gpl->color); // just for copying 4 array elements
+ QUATCOPY(tcolor, gpl->color); // additional copy of color (for ghosting)
glColor4f(color[0], color[1], color[2], color[3]);
glPointSize(gpl->thickness + 2);
@@ -458,11 +506,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* check if frame is drawable */
if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
/* alpha decreases with distance from curframe index */
- glColor4f(color[0], color[1], color[2], (color[3]-(i*0.7)));
-
- for (gps= gf->strokes.first; gps; gps= gps->next) {
- gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
- }
+ tcolor[3] = color[3] - (i * 0.7);
+ gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
}
else
break;
@@ -473,11 +518,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
/* check if frame is drawable */
if ((gf->framenum - gpf->framenum) <= gpl->gstep) {
/* alpha decreases with distance from curframe index */
- glColor4f(color[0], color[1], color[2], (color[3]-(i*0.7)));
-
- for (gps= gf->strokes.first; gps; gps= gps->next) {
- gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
- }
+ tcolor[3] = color[3] - (i * 0.7);
+ gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
}
else
break;
@@ -488,19 +530,14 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
}
else {
/* draw the strokes for the ghost frames (at half of the alpha set by user) */
- glColor4f(color[0], color[1], color[2], (color[3] / 7));
-
if (gpf->prev) {
- for (gps= gpf->prev->strokes.first; gps; gps= gps->next) {
- gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
- }
+ tcolor[3] = (color[3] / 7);
+ gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
}
- glColor4f(color[0], color[1], color[2], (color[3] / 4));
if (gpf->next) {
- for (gps= gpf->next->strokes.first; gps; gps= gps->next) {
- gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
- }
+ tcolor[3] = (color[3] / 4);
+ gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
}
/* restore alpha */
@@ -509,9 +546,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
}
/* draw the strokes already in active frame */
- for (gps= gpf->strokes.first; gps; gps= gps->next) {
- gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
- }
+ tcolor[3]= color[3];
+ gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
/* Check if may need to draw the active stroke cache, only if this layer is the active layer
* that is being edited. (Stroke cache is currently stored in gp-data)
diff --git a/source/blender/src/editnode.c b/source/blender/src/editnode.c
index 5c137e67c1a..98f4f1bb46f 100644
--- a/source/blender/src/editnode.c
+++ b/source/blender/src/editnode.c
@@ -2400,7 +2400,7 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
switch(event) {
case LEFTMOUSE:
- if(gpencil_do_paint(sa)) {
+ if(gpencil_do_paint(sa, L_MOUSE)) {
return;
}
else if(fromlib) {
@@ -2421,7 +2421,10 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case RIGHTMOUSE:
- if(find_indicated_socket(snode, &actnode, &actsock, SOCK_IN)) {
+ if(gpencil_do_paint(sa, R_MOUSE)) {
+ return;
+ }
+ else if(find_indicated_socket(snode, &actnode, &actsock, SOCK_IN)) {
if(actsock->flag & SOCK_SEL) {
snode->edittree->selin= NULL;
actsock->flag&= ~SOCK_SEL;
@@ -2568,8 +2571,13 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case DELKEY:
case XKEY:
- if(fromlib) fromlib= -1;
- else node_delete(snode);
+ if(G.qual==LR_ALTKEY) {
+ gpencil_delete_menu();
+ }
+ else {
+ if(fromlib) fromlib= -1;
+ else node_delete(snode);
+ }
break;
}
}
diff --git a/source/blender/src/gpencil.c b/source/blender/src/gpencil.c
index d8299fc2a61..e9f023bdd5c 100644
--- a/source/blender/src/gpencil.c
+++ b/source/blender/src/gpencil.c
@@ -616,7 +616,7 @@ void gpencil_delete_actframe (bGPdata *gpd)
* 2 - active frame
* 3 - active layer
*/
-void gpencil_delete_operation (short mode) // unused
+void gpencil_delete_operation (short mode)
{
bGPdata *gpd;
@@ -642,11 +642,15 @@ void gpencil_delete_operation (short mode) // unused
}
/* display a menu for deleting different grease-pencil elements */
-void gpencil_delete_menu (void) // unused
+void gpencil_delete_menu (void)
{
+ bGPdata *gpd= gpencil_data_getactive(NULL);
short mode;
- mode= pupmenu("Erase...%t|Last Stroke%x1|Active Frame%x2|Active Layer%x3");
+ /* only show menu if it will be relevant */
+ if (gpd == NULL) return;
+
+ mode= pupmenu("Grease Pencil Erase...%t|Last Stroke%x1|Active Frame%x2|Active Layer%x3");
if (mode <= 0) return;
gpencil_delete_operation(mode);
@@ -658,7 +662,7 @@ void gpencil_delete_menu (void) // unused
/* ---------- 'Globals' and Defines ----------------- */
/* maximum sizes of gp-session buffer */
-#define GP_STROKE_BUFFER_MAX 500
+#define GP_STROKE_BUFFER_MAX 5000
/* ------ */
@@ -968,7 +972,7 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
/* ---------- 'Paint' Tool ------------ */
/* init new stroke */
-static void gp_paint_initstroke (tGPsdata *p)
+static void gp_paint_initstroke (tGPsdata *p, short mousebutton)
{
/* get active layer (or add a new one if non-existent) */
p->gpl= gpencil_layer_getactive(p->gpd);
@@ -991,8 +995,17 @@ static void gp_paint_initstroke (tGPsdata *p)
}
else
p->gpf->flag |= GP_FRAME_PAINT;
+
+ /* set 'eraser' for this stroke if using eraser or right-mouse in action */
+ if ( get_activedevice() == 2 || (mousebutton & R_MOUSE) ) {
+ p->gpd->sbuffer_sflag |= GP_STROKE_ERASER;
- /* check if points will need to be made in 3d-space */
+ // for now: eraser isn't ready for prime-time yet, so no painting available here yet
+ p->status= GP_STATUS_ERROR;
+ return;
+ }
+
+ /* check if points will need to be made in view-aligned space */
if (p->gpd->flag & GP_DATA_VIEWALIGN) {
switch (p->sa->spacetype) {
case SPACE_VIEW3D:
@@ -1065,7 +1078,7 @@ short gpencil_paint (short mousebutton)
gp_session_cleanup(&p);
return 0;
}
- gp_paint_initstroke(&p);
+ gp_paint_initstroke(&p, mousebutton);
if (p.status == GP_STATUS_ERROR) {
gp_session_cleanup(&p);
return 0;
@@ -1154,10 +1167,9 @@ short gpencil_paint (short mousebutton)
/* All event (loops) handling checking if stroke drawing should be initiated
* should call this function.
*/
-short gpencil_do_paint (ScrArea *sa)
+short gpencil_do_paint (ScrArea *sa, short mousebutton)
{
bGPdata *gpd = gpencil_data_getactive(sa);
- short mousebutton = L_MOUSE; /* for now, this is always on L_MOUSE*/
short retval= 0;
/* check if possible to do painting */
@@ -1173,7 +1185,7 @@ short gpencil_do_paint (ScrArea *sa)
/* try to paint */
retval = gpencil_paint(mousebutton);
}
- else if (G.qual == LR_SHIFTKEY) {
+ else if (!(gpd->flag & GP_DATA_LMBPLOCK) && (G.qual == LR_SHIFTKEY)) {
/* try to paint */
retval = gpencil_paint(mousebutton);
}
diff --git a/source/blender/src/interface_draw.c b/source/blender/src/interface_draw.c
index 0403e5d5b37..83ae449b989 100644
--- a/source/blender/src/interface_draw.c
+++ b/source/blender/src/interface_draw.c
@@ -2351,7 +2351,6 @@ static void ui_draw_roundbox(uiBut *but)
{
glEnable(GL_BLEND);
- //BIF_ThemeColorShadeAlpha(TH_PANEL, but->a2, but->a2);
BIF_ThemeColorShadeAlpha(but->themecol, but->a2, but->a2);
uiSetRoundBox(but->a1);
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 723bb5205d7..f4cfaba0fda 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -1215,9 +1215,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
return; /* return if event was processed (swallowed) by handler(s) */
}
- if(gpencil_do_paint(sa)) return;
+ if(gpencil_do_paint(sa, L_MOUSE)) return;
if(BIF_do_manipulator(sa)) return;
}
+ else if(event==RIGHTMOUSE) {
+ if(gpencil_do_paint(sa, R_MOUSE)) return;
+ }
/* swap mouse buttons based on user preference */
if (U.flag & USER_LMOUSESELECT) {
@@ -2720,6 +2723,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case DELKEY:
if(G.qual==0 || G.qual==LR_SHIFTKEY)
delete_context_selected();
+ if(G.qual==LR_ALTKEY)
+ gpencil_delete_menu();
break;
case YKEY:
if((G.qual==0) && (G.obedit)) {
@@ -4841,8 +4846,11 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
/* grease-pencil defaults to leftmouse */
- if(event==LEFTMOUSE) {
- if(gpencil_do_paint(sa)) return;
+ if (event == LEFTMOUSE) {
+ if(gpencil_do_paint(sa, L_MOUSE)) return;
+ }
+ else if (event == RIGHTMOUSE) {
+ if(gpencil_do_paint(sa, R_MOUSE)) return;
}
/* swap mouse buttons based on user preference */
@@ -5117,6 +5125,10 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if((G.qual==0))
del_seq();
}
+ else if(G.qual==LR_ALTKEY) {
+ if(sseq->mainb)
+ gpencil_delete_menu();
+ }
break;
case PAD1: case PAD2: case PAD4: case PAD8:
seq_viewzoom(event, (G.qual & LR_SHIFTKEY)==0);
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index c0051657658..3f5246fd893 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -1920,10 +1920,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->NodeUpdateGS(0,true);
BL_ConvertIpos(blenderobject,gameobj,converter);
- // TODO: expand to multiple ipos per mesh
- Material *mat = give_current_material(blenderobject, 1);
- if(mat) BL_ConvertMaterialIpos(mat, gameobj, converter);
-
+ BL_ConvertMaterialIpos(blenderobject, gameobj, converter);
+
sumolist->Add(gameobj->AddRef());
BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
@@ -2102,9 +2100,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
gameobj->NodeUpdateGS(0,true);
BL_ConvertIpos(blenderobject,gameobj,converter);
- // TODO: expand to multiple ipos per mesh
- Material *mat = give_current_material(blenderobject, 1);
- if(mat) BL_ConvertMaterialIpos(mat, gameobj, converter);
+ BL_ConvertMaterialIpos(blenderobject,gameobj, converter);
sumolist->Add(gameobj->AddRef());
diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Converter/KX_IpoConvert.cpp
index 75ca59d01e7..7410beecaf4 100644
--- a/source/gameengine/Converter/KX_IpoConvert.cpp
+++ b/source/gameengine/Converter/KX_IpoConvert.cpp
@@ -36,6 +36,7 @@
#pragma warning (disable:4786)
#endif
+#include "BKE_material.h" /* give_current_material */
#include "KX_GameObject.h"
#include "KX_IpoConvert.h"
@@ -68,6 +69,8 @@
#include "SG_Node.h"
+#include "STR_HashedString.h"
+
static BL_InterpolatorList *GetIpoList(struct Ipo *for_ipo, KX_BlenderSceneConverter *converter) {
BL_InterpolatorList *ipoList= converter->FindInterpolatorList(for_ipo);
@@ -560,16 +563,15 @@ void BL_ConvertWorldIpos(struct World* blenderworld,KX_BlenderSceneConverter *co
}
}
-
-void BL_ConvertMaterialIpos(
- Material* blendermaterial,
+static void ConvertMaterialIpos(
+ Material* blendermaterial,
+ dword matname_hash,
KX_GameObject* gameobj,
KX_BlenderSceneConverter *converter
)
{
if (blendermaterial->ipo) {
-
- KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController();
+ KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
@@ -596,7 +598,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_COL_R);
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -610,7 +612,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_COL_G);
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -624,7 +626,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_COL_B);
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -638,7 +640,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_ALPHA);
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -653,7 +655,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_SPEC_R );
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -667,7 +669,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_SPEC_G);
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -681,7 +683,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_SPEC_B);
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -696,7 +698,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_HARD);
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -710,7 +712,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_SPEC);
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -725,7 +727,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_REF);
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -739,7 +741,7 @@ void BL_ConvertMaterialIpos(
ipo = ipoList->GetScalarInterpolator(MA_EMIT);
if (ipo) {
if (!ipocontr) {
- ipocontr = new KX_MaterialIpoController();
+ ipocontr = new KX_MaterialIpoController(matname_hash);
gameobj->GetSGNode()->AddSGController(ipocontr);
ipocontr->SetObject(gameobj->GetSGNode());
}
@@ -752,3 +754,28 @@ void BL_ConvertMaterialIpos(
}
}
+void BL_ConvertMaterialIpos(
+ struct Object* blenderobject,
+ KX_GameObject* gameobj,
+ KX_BlenderSceneConverter *converter
+ )
+{
+ if (blenderobject->totcol==1)
+ {
+ Material *mat = give_current_material(blenderobject, 1);
+ // if there is only one material attached to the mesh then set material_index in BL_ConvertMaterialIpos to NULL
+ // --> this makes the UpdateMaterialData function in KX_GameObject.cpp use the old hack of using SetObjectColor
+ // because this yields a better performance as not all the vertex colors need to be edited
+ if(mat) ConvertMaterialIpos(mat, NULL, gameobj, converter);
+ }
+ else
+ {
+ for (int material_index=1; material_index <= blenderobject->totcol; material_index++)
+ {
+ Material *mat = give_current_material(blenderobject, material_index);
+ STR_HashedString matname = mat->id.name;
+ if(mat) ConvertMaterialIpos(mat, matname.hash(), gameobj, converter);
+ }
+ }
+}
+
diff --git a/source/gameengine/Converter/KX_IpoConvert.h b/source/gameengine/Converter/KX_IpoConvert.h
index afcb1b22821..4ec9bd31062 100644
--- a/source/gameengine/Converter/KX_IpoConvert.h
+++ b/source/gameengine/Converter/KX_IpoConvert.h
@@ -46,7 +46,7 @@ void BL_ConvertCameraIpos(struct Camera* blendercamera,
class KX_GameObject* cameraobj,
class KX_BlenderSceneConverter *converter);
-void BL_ConvertMaterialIpos(struct Material* blendermaterial,
+void BL_ConvertMaterialIpos(struct Object* blenderobject,
class KX_GameObject* materialobj,
class KX_BlenderSceneConverter *converter);
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 969873abeee..3d9c7aafd70 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -442,6 +442,7 @@ void KX_GameObject::UpdateIPO(float curframetime,
// IPO update
void
KX_GameObject::UpdateMaterialData(
+ dword matname_hash,
MT_Vector4 rgba,
MT_Vector3 specrgb,
MT_Scalar hard,
@@ -461,7 +462,25 @@ KX_GameObject::UpdateMaterialData(
if(poly->GetFlag() & RAS_BLENDERMAT )
{
KX_BlenderMaterial *m = static_cast<KX_BlenderMaterial*>(poly);
- m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
+
+ if (matname_hash == NULL)
+ {
+ m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
+ // if mesh has only one material attached to it then use original hack with no need to edit vertices (better performance)
+ SetObjectColor(rgba);
+ }
+ else
+ {
+ if (matname_hash == poly->GetMaterialNameHash())
+ {
+ m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
+ m_meshes[mesh]->SetVertexColor(poly,rgba);
+
+ // no break here, because one blender material can be split into several game engine materials
+ // (e.g. one uvsphere material is split into one material at poles with ras_mode TRIANGLE and one material for the body
+ // if here was a break then would miss some vertices if material was split
+ }
+ }
}
}
}
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 6051cf850b5..1d36798b12f 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -521,6 +521,7 @@ public:
*/
void
UpdateMaterialData(
+ dword matname_hash,
MT_Vector4 rgba,
MT_Vector3 specrgb,
MT_Scalar hard,
diff --git a/source/gameengine/Ketsji/KX_MaterialIpoController.cpp b/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
index c0757a32b9c..2ce5d469380 100644
--- a/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
+++ b/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
@@ -37,6 +37,7 @@ bool KX_MaterialIpoController::Update(double currentTime)
//kxgameobj->SetObjectColor(m_rgba);
kxgameobj->UpdateMaterialData(
+ m_matname_hash,
m_rgba,
m_specrgb,
m_hard,
diff --git a/source/gameengine/Ketsji/KX_MaterialIpoController.h b/source/gameengine/Ketsji/KX_MaterialIpoController.h
index e76ddeefb04..4d2e258bf94 100644
--- a/source/gameengine/Ketsji/KX_MaterialIpoController.h
+++ b/source/gameengine/Ketsji/KX_MaterialIpoController.h
@@ -7,6 +7,8 @@
#include "SG_Spatial.h"
#include "KX_IInterpolator.h"
+#include "STR_String.h" //typedef dword
+
class KX_MaterialIpoController : public SG_Controller
{
public:
@@ -23,10 +25,12 @@ private:
bool m_modified;
double m_ipotime;
+ dword m_matname_hash;
public:
- KX_MaterialIpoController() :
+ KX_MaterialIpoController(dword matname_hash) :
m_modified(true),
- m_ipotime(0.0)
+ m_ipotime(0.0),
+ m_matname_hash(matname_hash)
{}
virtual ~KX_MaterialIpoController();
virtual SG_Controller* GetReplica(class SG_Node* destnode);
diff --git a/source/gameengine/Ketsji/KX_PyMath.h b/source/gameengine/Ketsji/KX_PyMath.h
index e1715c9275f..4e383e9b3d4 100644
--- a/source/gameengine/Ketsji/KX_PyMath.h
+++ b/source/gameengine/Ketsji/KX_PyMath.h
@@ -84,7 +84,10 @@ bool PyMatTo(PyObject* pymat, T& mat)
}
} else
noerror = false;
-
+
+ if (noerror==false)
+ PyErr_SetString(PyExc_TypeError, "could not be converted to a matrix (sequence of sequences)");
+
return noerror;
}
@@ -97,9 +100,13 @@ bool PyVecTo(PyObject* pyval, T& vec)
if (PySequence_Check(pyval))
{
unsigned int numitems = PySequence_Size(pyval);
- if (numitems != Size(vec))
+ if (numitems != Size(vec)) {
+ char err[128];
+ sprintf(err, "error setting vector, %d args, should be %d", numitems, Size(vec));
+ PyErr_SetString(PyExc_AttributeError, err);
return false;
-
+ }
+
for (unsigned int x = 0; x < numitems; x++)
{
PyObject *item = PySequence_GetItem(pyval, x); /* new ref */
@@ -107,7 +114,17 @@ bool PyVecTo(PyObject* pyval, T& vec)
Py_DECREF(item);
}
+ if (PyErr_Occurred()) {
+ PyErr_SetString(PyExc_AttributeError, "one or more of the items in the sequence was not a float");
+ return false;
+ }
+
return true;
+ } else
+ {
+ char err[128];
+ sprintf(err, "not a sequence type, expected a sequence of numbers size %d", Size(vec));
+ PyErr_SetString(PyExc_AttributeError, err);
}
return false;
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
index c580aa4d4e5..d4bd109de1a 100644
--- a/source/gameengine/Ketsji/KX_TrackToActuator.cpp
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -146,19 +146,19 @@ void compatible_eulFast(float *eul, float *oldrot)
{
float dx, dy, dz;
- /* verschillen van ong 360 graden corrigeren */
+ /* angular difference of 360 degrees */
dx= eul[0] - oldrot[0];
dy= eul[1] - oldrot[1];
dz= eul[2] - oldrot[2];
- if( fabs(dx) > 5.1) {
+ if( fabs(dx) > MT_PI) {
if(dx > 0.0) eul[0] -= MT_2_PI; else eul[0]+= MT_2_PI;
}
- if( fabs(dy) > 5.1) {
+ if( fabs(dy) > MT_PI) {
if(dy > 0.0) eul[1] -= MT_2_PI; else eul[1]+= MT_2_PI;
}
- if( fabs(dz) > 5.1 ) {
+ if( fabs(dz) > MT_PI ) {
if(dz > 0.0) eul[2] -= MT_2_PI; else eul[2]+= MT_2_PI;
}
}
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
index 6f04ce5d866..3c0014ab3ba 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
@@ -143,6 +143,11 @@ const STR_String& RAS_IPolyMaterial::GetMaterialName() const
return m_materialname;
}
+dword RAS_IPolyMaterial::GetMaterialNameHash() const
+{
+ return m_materialname.hash();
+}
+
const STR_String& RAS_IPolyMaterial::GetTextureName() const
{
return m_texturename;
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index fd5c6d5a59f..2951a21507d 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -140,6 +140,7 @@ public:
unsigned int hash() const;
int GetDrawingMode() const;
const STR_String& GetMaterialName() const;
+ dword GetMaterialNameHash() const;
const STR_String& GetTextureName() const;
const unsigned int GetFlag() const;
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 4420f16c56d..5087f62500e 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -201,7 +201,20 @@ void RAS_MeshObject::DebugColor(unsigned int abgr)
m_debugcolor = abgr;
}
-
+void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba)
+{
+ RAS_TexVert* vertex = NULL;
+ const vecVertexArray & vertexvec = GetVertexCache(mat);
+
+ for (vector<KX_VertexArray*>::const_iterator it = vertexvec.begin(); it != vertexvec.end(); ++it)
+ {
+ KX_VertexArray::iterator vit;
+ for (vit=(*it)->begin(); vit != (*it)->end(); vit++)
+ {
+ vit->SetRGBA(rgba);
+ }
+ }
+}
void RAS_MeshObject::SchedulePoly(const KX_VertexIndex& idx,
int numverts,
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index 0d06748f91f..44ad508d1e8 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -189,6 +189,7 @@ public:
);
void DebugColor(unsigned int abgr);
+ void SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba);
/**
* Sorts the polygons by their transformed z values.