diff options
author | Andre Susano Pinto <andresusanopinto@gmail.com> | 2008-08-02 01:37:36 +0400 |
---|---|---|
committer | Andre Susano Pinto <andresusanopinto@gmail.com> | 2008-08-02 01:37:36 +0400 |
commit | 289d875dfdd00165dacd92b554c472cc818dbd8f (patch) | |
tree | 97ef62b3769573cd50d8525453368de9066ff577 /source/blender | |
parent | 9e1ca2c1bef2d0e8db5e22a284134c37b2f6a457 (diff) |
svn merge -r 15688:15908 https://svn.blender.org/svnroot/bf-blender/trunk/blender
Diffstat (limited to 'source/blender')
74 files changed, 1616 insertions, 571 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index f61b300f708..7dc10c53e22 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -437,5 +437,7 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb); /* determines required DerivedMesh data according to view and edit modes */ CustomDataMask get_viewedit_datamask(); +void DM_add_tangent_layer(DerivedMesh *dm); + #endif diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index f76cdbc64b7..d951c8401e3 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -41,7 +41,7 @@ struct ListBase; struct MemFile; #define BLENDER_VERSION 246 -#define BLENDER_SUBVERSION 0 +#define BLENDER_SUBVERSION 1 #define BLENDER_MINVERSION 245 #define BLENDER_MINSUBVERSION 15 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/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index 739027fc95f..1b07ce50741 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -29,6 +29,13 @@ #ifndef BKE_SHRINKWRAP_H #define BKE_SHRINKWRAP_H +/* mesh util */ +//TODO move this somewhere else +#include "BKE_customdata.h" +struct DerivedMesh; +struct Object; +struct DerivedMesh *object_get_derived_final(struct Object *ob, CustomDataMask dataMask); + /* bitset stuff */ //TODO: should move this to other generic lib files? typedef char* BitSet; diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index 78a8f60caeb..fade0f8cbaa 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -62,6 +62,7 @@ struct Tex *copy_texture(struct Tex *tex); void make_local_texture(struct Tex *tex); void autotexname(struct Tex *tex); struct Tex *give_current_texture(struct Object *ob, int act); +struct Tex *give_current_world_texture(void); struct TexMapping *add_mapping(void); void init_mapping(struct TexMapping *texmap); diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index c913820205b..3ad11a61de3 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$ * @@ -355,7 +354,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/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 4d3f9143b85..67cf89d5ee2 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -59,6 +59,7 @@ #include "BLI_edgehash.h" #include "BLI_editVert.h" #include "BLI_linklist.h" +#include "BLI_memarena.h" #include "BKE_cdderivedmesh.h" #include "BKE_customdata.h" @@ -2844,6 +2845,127 @@ int editmesh_get_first_deform_matrices(float (**deformmats)[3][3], float (**defo return numleft; } +void DM_add_tangent_layer(DerivedMesh *dm) +{ + /* mesh vars */ + MTFace *mtface, *tf; + MFace *mface, *mf; + MVert *mvert, *v1, *v2, *v3, *v4; + MemArena *arena= NULL; + VertexTangent **vtangents= NULL; + float (*orco)[3]= NULL, (*tangent)[3]; + float *uv1, *uv2, *uv3, *uv4, *vtang; + float fno[3], tang[3], uv[4][2]; + int i, j, len, mf_vi[4], totvert, totface; + + if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) != -1) + return; + + /* check we have all the needed layers */ + totvert= dm->getNumVerts(dm); + totface= dm->getNumFaces(dm); + + mvert= dm->getVertArray(dm); + mface= dm->getFaceArray(dm); + mtface= dm->getFaceDataArray(dm, CD_MTFACE); + + if(!mtface) { + orco= dm->getVertDataArray(dm, CD_ORCO); + if(!orco) + return; + } + + /* create tangent layer */ + DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL); + tangent= DM_get_face_data_layer(dm, CD_TANGENT); + + /* allocate some space */ + arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE); + BLI_memarena_use_calloc(arena); + vtangents= MEM_callocN(sizeof(VertexTangent*)*totvert, "VertexTangent"); + + /* sum tangents at connected vertices */ + for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++) { + v1= &mvert[mf->v1]; + v2= &mvert[mf->v2]; + v3= &mvert[mf->v3]; + + if (mf->v4) { + v4= &mvert[mf->v4]; + CalcNormFloat4(v4->co, v3->co, v2->co, v1->co, fno); + } + else { + v4= NULL; + CalcNormFloat(v3->co, v2->co, v1->co, fno); + } + + if(mtface) { + uv1= tf->uv[0]; + uv2= tf->uv[1]; + uv3= tf->uv[2]; + uv4= tf->uv[3]; + } + else { + uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3]; + spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]); + spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]); + spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]); + if(v4) + spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]); + } + + tangent_from_uv(uv1, uv2, uv3, v1->co, v2->co, v3->co, fno, tang); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v2], tang, uv2); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3); + + if(mf->v4) { + v4= &mvert[mf->v4]; + + tangent_from_uv(uv1, uv3, uv4, v1->co, v3->co, v4->co, fno, tang); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v1], tang, uv1); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v3], tang, uv3); + sum_or_add_vertex_tangent(arena, &vtangents[mf->v4], tang, uv4); + } + } + + /* write tangent to layer */ + for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++, tangent+=4) { + len= (mf->v4)? 4 : 3; + + if(mtface) { + uv1= tf->uv[0]; + uv2= tf->uv[1]; + uv3= tf->uv[2]; + uv4= tf->uv[3]; + } + else { + uv1= uv[0]; uv2= uv[1]; uv3= uv[2]; uv4= uv[3]; + spheremap(orco[mf->v1][0], orco[mf->v1][1], orco[mf->v1][2], &uv[0][0], &uv[0][1]); + spheremap(orco[mf->v2][0], orco[mf->v2][1], orco[mf->v2][2], &uv[1][0], &uv[1][1]); + spheremap(orco[mf->v3][0], orco[mf->v3][1], orco[mf->v3][2], &uv[2][0], &uv[2][1]); + if(len==4) + spheremap(orco[mf->v4][0], orco[mf->v4][1], orco[mf->v4][2], &uv[3][0], &uv[3][1]); + } + + mf_vi[0]= mf->v1; + mf_vi[1]= mf->v2; + mf_vi[2]= mf->v3; + mf_vi[3]= mf->v4; + + for(j=0; j<len; j++) { + vtang= find_vertex_tangent(vtangents[mf_vi[j]], mtface ? tf->uv[j] : uv[j]); + + VECCOPY(tangent[j], vtang); + Normalize(tangent[j]); + } + } + + BLI_memarena_free(arena); + MEM_freeN(vtangents); +} + + /* ************************* fluidsim bobj file handling **************************** */ #ifndef DISABLE_ELBEEM diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 6dfb77504fb..5b3cec25772 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1547,7 +1547,7 @@ int cloth_bvh_objcollision ( Object *ob, ClothModifierData * clmd, float step, f { Cloth *cloth=NULL; BVHTree *cloth_bvh=NULL; - long i=0, numfaces = 0, numverts = 0; + int i=0, numfaces = 0, numverts = 0; int rounds = 0; // result counts applied collisions; ic is for debug output; ClothVertex *verts = NULL; int ret = 0, ret2 = 0; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 068501780bc..93ba30f8c9b 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -40,6 +40,7 @@ #include "DNA_armature_types.h" #include "DNA_constraint_types.h" +#include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_action_types.h" #include "DNA_curve_types.h" @@ -63,6 +64,7 @@ #include "BKE_global.h" #include "BKE_library.h" #include "BKE_idprop.h" +#include "BKE_shrinkwrap.h" #include "BPY_extern.h" @@ -457,7 +459,6 @@ void constraint_mat_convertspace (Object *ob, bPoseChannel *pchan, float mat[][4 Mat4CpyMat3(offs_bone, pchan->bone->bone_mat); VECCOPY(offs_bone[3], pchan->bone->head); offs_bone[3][1]+= pchan->bone->parent->length; - if (pchan->bone->flag & BONE_HINGE) { /* pose_mat = par_pose-space_location * chan_mat */ float tmat[4][4]; @@ -558,8 +559,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 { @@ -3228,6 +3229,140 @@ static bConstraintTypeInfo CTI_TRANSFORM = { transform_evaluate /* evaluate */ }; +/* ---------- Shrinkwrap Constraint ----------- */ +static void shrinkwrap_new_data (void *cdata) +{ + bShrinkwrapConstraint *data= (bShrinkwrapConstraint *)cdata; + + data->target = NULL; + data->dist = 0.0f; + data->shrinkType = MOD_SHRINKWRAP_NEAREST_SURFACE; +} + +static int shrinkwrap_get_tars (bConstraint *con, ListBase *list) +{ + if (con && list) { + bShrinkwrapConstraint *data = con->data; + bConstraintTarget *ct; + + SINGLETARGETNS_GET_TARS(con, data->target, ct, list) + + return 1; + } + + return 0; +} + +static void shrinkwrap_flush_tars (bConstraint *con, ListBase *list, short nocopy) +{ + if (con && list) { + bShrinkwrapConstraint *data = con->data; + bConstraintTarget *ct= list->first; + + SINGLETARGETNS_FLUSH_TARS(con, data->target, ct, list, nocopy) + } +} + +static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime) +{ + if (ct) + Mat4One(ct->matrix); +} + +static void shrinkwrap_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets) +{ + bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data; + bConstraintTarget *ct = targets->first; + + if( VALID_CONS_TARGET(ct) && (ct->tar->type == OB_MESH) ) + { + float co[3] = {0.0f, 0.0f, 0.0f}; + float no[3] = {0.0f, 0.0f, 1.0f}; + float dist; + + SpaceTransform transform; + DerivedMesh *target = CDDM_copy( object_get_derived_final(ct->tar, CD_MASK_BAREMESH) ); + BVHTreeRayHit hit; + BVHTreeNearest nearest; + + //TODO + //Its stupid to create a bvhtree.. if we are only going to project one vertex + //But lets do it this way.. (so that in future maybe bvhtree gets a cache system and then the tree would already be build) + BVHTreeFromMesh treeData; + memset( &treeData, 0, sizeof(treeData) ); + + nearest.index = -1; + nearest.dist = 100000.0f; //TODO should use FLT_MAX.. but normal projection doenst yet supports it + + if(target != NULL) + { + + space_transform_from_matrixs(&transform, cob->matrix, ct->matrix); + + space_transform_apply(&transform, co); + space_transform_apply_normal(&transform, no); + + + switch(scon->shrinkType) + { + case MOD_SHRINKWRAP_NEAREST_SURFACE: + if(bvhtree_from_mesh_faces(&treeData, target, 0.0, 2, 6) == NULL) return; + BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData); + VECCOPY(co, nearest.co); + + dist = VecLenf(co, nearest.co); + VecLerpf(co, co, nearest.co, (dist - scon->dist)/dist); //linear interpolation + break; + + case MOD_SHRINKWRAP_NEAREST_VERTEX: + if(bvhtree_from_mesh_verts(&treeData, target, 0.0, 2, 6) == NULL) return; + BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData); + VECCOPY(co, nearest.co); + + dist = VecLenf(co, nearest.co); + VecLerpf(co, co, nearest.co, (dist - scon->dist)/dist); //linear interpolation + break; + + case MOD_SHRINKWRAP_NORMAL: + if(bvhtree_from_mesh_faces(&treeData, target, scon->dist, 4, 6) == NULL) return; + if(normal_projection_project_vertex(0, co, no, &transform, treeData.tree, &hit, treeData.raycast_callback, &treeData) == FALSE) + return; + + VECCOPY(co, hit.co); + break; + } + + space_transform_invert(&transform, co); + VECADD(cob->matrix[3], cob->matrix[3], co); + + + if(treeData.tree) + BLI_bvhtree_free(treeData.tree); + + target->release(target); + } + + + } +} + +static bConstraintTypeInfo CTI_SHRINKWRAP = { + CONSTRAINT_TYPE_SHRINKWRAP, /* type */ + sizeof(bShrinkwrapConstraint), /* size */ + "Shrinkwrap", /* name */ + "bShrinkwrapConstraint", /* struct name */ + NULL, /* free data */ + NULL, /* relink data */ + NULL, /* copy data */ + shrinkwrap_new_data, /* new data */ + shrinkwrap_get_tars, /* get constraint targets */ + shrinkwrap_flush_tars, /* flush constraint targets */ + shrinkwrap_get_tarmat, /* get a target matrix */ + shrinkwrap_evaluate /* evaluate */ +}; + + + /* ************************* Constraints Type-Info *************************** */ /* All of the constraints api functions use bConstraintTypeInfo structs to carry out * and operations that involve constraint specifc code. @@ -3259,6 +3394,7 @@ static void constraints_init_typeinfo () { constraintsTypeInfo[17]= &CTI_RIGIDBODYJOINT; /* RigidBody Constraint */ constraintsTypeInfo[18]= &CTI_CLAMPTO; /* ClampTo Constraint */ constraintsTypeInfo[19]= &CTI_TRANSFORM; /* Transformation Constraint */ + constraintsTypeInfo[20]= &CTI_SHRINKWRAP; /* Shrinkwrap Constraint */ } /* This function should be used for getting the appropriate type-info when only diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 501293ecd81..9012adb09b7 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -532,13 +532,14 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL}, {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL}, - {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol} + {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol}, + {sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL} }; const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty", - "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol"}; + "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent"}; const CustomDataMask CD_MASK_BAREMESH = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE; @@ -552,7 +553,7 @@ const CustomDataMask CD_MASK_EDITMESH = const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | - CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO; + CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT; const CustomDataMask CD_MASK_BMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; const CustomDataMask CD_MASK_FACECORNERS = 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/scene.c b/source/blender/blenkernel/intern/scene.c index 2898dca767c..553107dd264 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -303,7 +303,7 @@ void set_scene_bg(Scene *sce) int flag; // Note: this here is defined in editseq.c (BIF_editseq.h), NOT in blenkernel! - set_last_seq(NULL); + clear_last_seq(); G.scene= sce; 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/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 37804bf68ac..ad139220785 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -53,6 +53,7 @@ #include "DNA_world_types.h" #include "DNA_brush_types.h" #include "DNA_node_types.h" +#include "DNA_scene_types.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -731,7 +732,7 @@ Tex *give_current_texture(Object *ob, int act) bNode *node; if(ob==0) return 0; - if(ob->totcol==0) return 0; + if(ob->totcol==0 && !(ob->type==OB_LAMP)) return 0; if(ob->type==OB_LAMP) { la=(Lamp *)ob->data; @@ -775,6 +776,18 @@ Tex *give_current_texture(Object *ob, int act) return tex; } +Tex *give_current_world_texture(void) +{ + MTex *mtex = 0; + Tex *tex = 0; + + if(!(G.scene->world)) return 0; + + mtex= G.scene->world->mtex[(int)(G.scene->world->texact)]; + if(mtex) tex= mtex->tex; + + return tex; +} /* ------------------------------------------------------------------------- */ diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index a31c769a5b3..c1edb7d3ac1 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2535,11 +2535,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/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 8b979f9ed23..74f152ac635 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -405,7 +405,7 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile * pf) lcode = charcode; } - err = FT_Set_Charmap( face, (FT_CharMap) FT_ENCODING_UNICODE ); + err = FT_Select_Charmap( face, FT_ENCODING_UNICODE ); return vfd; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 090b1d7c6b6..ad19cde3c9b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1347,8 +1347,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]); + } } } } @@ -1385,6 +1391,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; } } @@ -4161,15 +4185,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc) link_gpencil(fd, sseq->gpd); } } - else if(sl->spacetype==SPACE_ACTION) { - SpaceAction *sact= (SpaceAction *)sl; - - /* WARNING: action-editor doesn't have it's own gpencil data! - * so only adjust pointer, but DON'T LINK - */ - if (sact->gpd) - sact->gpd= newdataadr(fd, sact->gpd); - } } sa->v1= newdataadr(fd, sa->v1); @@ -4855,6 +4870,49 @@ void idproperties_fix_group_lengths(ListBase idlist) } } +void alphasort_version_246(FileData *fd, Library *lib, Mesh *me) +{ + Material *ma; + MFace *mf; + MTFace *tf; + int a, b, texalpha; + + /* verify we have a tface layer */ + for(b=0; b<me->fdata.totlayer; b++) + if(me->fdata.layers[b].type == CD_MTFACE) + break; + + if(b == me->fdata.totlayer) + return; + + /* if we do, set alpha sort if the game engine did it before */ + for(a=0, mf=me->mface; a<me->totface; a++, mf++) { + if(mf->mat_nr < me->totcol) { + ma= newlibadr(fd, lib, me->mat[mf->mat_nr]); + texalpha = 0; + + for(b=0; ma && b<MAX_MTEX; b++) + if(ma->mtex && ma->mtex[b] && ma->mtex[b]->mapto & MAP_ALPHA) + texalpha = 1; + } + else { + ma= NULL; + texalpha = 0; + } + + for(b=0; b<me->fdata.totlayer; b++) { + if(me->fdata.layers[b].type == CD_MTFACE) { + tf = ((MTFace*)me->fdata.layers[b].data) + a; + + tf->mode &= ~TF_ALPHASORT; + if(ma && (ma->mode & MA_ZTRA)) + if(ELEM(tf->transp, TF_ALPHA, TF_ADD) || (texalpha && (tf->transp != TF_CLIP))) + tf->mode |= TF_ALPHASORT; + } + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -7699,8 +7757,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } /* sun/sky */ - if ((main->versionfile < 246) ){ + if(main->versionfile < 246) { Lamp *la; + for(la=main->lamp.first; la; la= la->id.next) { la->sun_effect_type = 0; la->horizon_brightness = 1.0; @@ -7716,6 +7775,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if(main->versionfile <= 246 && main->subversionfile < 1){ + Mesh *me; + + for(me=main->mesh.first; me; me= me->id.next) + alphasort_version_246(fd, lib, me); + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index b59dd851dfe..73abf362d12 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 d0ebd096ecb..eb749cf28ec 100644 --- a/source/blender/include/BDR_gpencil.h +++ b/source/blender/include/BDR_gpencil.h @@ -38,6 +38,15 @@ struct bGPdata; struct bGPDlayer; struct bGPDframe; +/* ------------- Grease-Pencil Helpers -------------- */ + +/* Temporary 'Stroke Point' data */ +typedef struct tGPspoint { + short x, y; /* x and y coordinates of cursor (in relative to area) */ + float xf, yf; /* same as x and y, but as floats */ + float pressure; /* pressure of tablet at this point */ +} tGPspoint; + /* ------------ Grease-Pencil API ------------------ */ void free_gpencil_strokes(struct bGPDframe *gpf); @@ -53,8 +62,6 @@ struct bGPdata *gpencil_data_duplicate(struct bGPdata *gpd); struct bGPdata *gpencil_data_getactive(struct ScrArea *sa); short gpencil_data_setactive(struct ScrArea *sa, struct bGPdata *gpd); -struct bGPdata *gpencil_data_getetime(struct bScreen *sc); -void gpencil_data_setetime(struct bScreen *sc, struct bGPdata *gpd); void gpencil_frame_delete_laststroke(struct bGPDframe *gpf); @@ -71,6 +78,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/include/BIF_editaction.h b/source/blender/include/BIF_editaction.h index 9f6751daeff..77c2f19bb9b 100644 --- a/source/blender/include/BIF_editaction.h +++ b/source/blender/include/BIF_editaction.h @@ -49,7 +49,9 @@ enum { ACTTYPE_FILLCON, ACTTYPE_IPO, ACTTYPE_SHAPEKEY, - ACTTYPE_GPLAYER + ACTTYPE_GPDATABLOCK, + ACTTYPE_GPLAYER, + ACTTYPE_SPECIALDATA }; /* Macros for easier/more consistant state testing */ @@ -70,6 +72,8 @@ enum { #define EDITABLE_ICU(icu) ((icu->flag & IPO_PROTECT)==0) #define SEL_ICU(icu) (icu->flag & IPO_SELECT) +#define EXPANDED_GPD(gpd) (gpd->flag & GP_DATA_EXPAND) + #define EDITABLE_GPL(gpl) ((gpl->flag & GP_LAYER_LOCKED)==0) #define SEL_GPL(gpl) ((gpl->flag & GP_LAYER_ACTIVE) || (gpl->flag & GP_LAYER_SELECT)) @@ -185,7 +189,7 @@ void action_remove_localmarkers(struct bAction *act); /* Grease-Pencil Data */ void gplayer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, short onlysel); -void deselect_gpencil_layers(struct bGPdata *gpd, short select_mode); +void deselect_gpencil_layers(void *data, short select_mode); short is_gplayer_frame_selected(struct bGPDlayer *gpl); void set_gplayer_frame_selection(struct bGPDlayer *gpl, short mode); @@ -204,7 +208,7 @@ void mirror_gplayer_frames(struct bGPDlayer *gpl, short mode); struct Key *get_action_mesh_key(void); int get_nearest_key_num(struct Key *key, short *mval, float *x); -void *get_nearest_act_channel(short mval[], short *ret_type); +void *get_nearest_act_channel(short mval[], short *ret_type, void **owner); /* Action */ struct bActionChannel *get_hilighted_action_channel(struct bAction* action); diff --git a/source/blender/include/BIF_editarmature.h b/source/blender/include/BIF_editarmature.h index 24112c7f11a..da98eb3d4f1 100644 --- a/source/blender/include/BIF_editarmature.h +++ b/source/blender/include/BIF_editarmature.h @@ -134,6 +134,7 @@ void transform_armature_mirror_update(void); void hide_selected_armature_bones(void); void hide_unselected_armature_bones(void); void show_all_armature_bones(void); +void set_locks_armature_bones(short lock); #define BONESEL_ROOT 0x10000000 #define BONESEL_TIP 0x20000000 diff --git a/source/blender/include/BIF_editview.h b/source/blender/include/BIF_editview.h index 4ed3d0df367..d2c6c56d01a 100644 --- a/source/blender/include/BIF_editview.h +++ b/source/blender/include/BIF_editview.h @@ -34,9 +34,12 @@ struct Base; struct Object; struct Camera; struct View3D; +struct rcti; void arrows_move_cursor(unsigned short event); +void lasso_select_boundbox(struct rcti *rect, short mcords[][2], short moves); int lasso_inside(short mcords[][2], short moves, short sx, short sy); +int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1); void borderselect(void); void circle_select(void); void deselectall(void); diff --git a/source/blender/include/BSE_drawview.h b/source/blender/include/BSE_drawview.h index 83031ff3bad..e6f22a4fb67 100644 --- a/source/blender/include/BSE_drawview.h +++ b/source/blender/include/BSE_drawview.h @@ -76,6 +76,7 @@ void inner_play_anim_loop(int init, int mode); int play_anim(int mode); void make_axis_color(char *col, char *col2, char axis); +char *view3d_get_name(struct View3D *v3d); /* SMOOTHVIEW */ void smooth_view(struct View3D *v3d, float *ofs, float *quat, float *dist, float *lens); diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index c0542e3f34c..af74946f0e6 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -721,7 +721,8 @@ enum { B_CONSTRAINT_ADD_PYTHON, B_CONSTRAINT_ADD_CLAMPTO, B_CONSTRAINT_ADD_TRANSFORM, - B_CONSTRAINT_INF + B_CONSTRAINT_INF, + B_CONSTRAINT_ADD_SHRINKWRAP }; /* *********************** */ diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 60050ea010e..3054e038ba2 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_action_types.h b/source/blender/makesdna/DNA_action_types.h index d7969a7379b..2e8d95335cc 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -184,7 +184,6 @@ typedef struct SpaceAction { View2D v2d; bAction *action; /* the currently active action */ - bGPdata *gpd; /* the currently active gpencil block (for editing) */ char mode, autosnap; /* mode: editing context; autosnap: automatic keyframe snapping mode */ short flag, actnr; /* flag: bitmapped settings; */ diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h index ac9761f165d..7444ce95f56 100644 --- a/source/blender/makesdna/DNA_actuator_types.h +++ b/source/blender/makesdna/DNA_actuator_types.h @@ -368,9 +368,9 @@ typedef struct FreeCamera { #define ACT_CONST_DIRPX 1 #define ACT_CONST_DIRPY 2 #define ACT_CONST_DIRPZ 4 -#define ACT_CONST_DIRMX 8 -#define ACT_CONST_DIRMY 16 -#define ACT_CONST_DIRMZ 32 +#define ACT_CONST_DIRNX 8 +#define ACT_CONST_DIRNY 16 +#define ACT_CONST_DIRNZ 32 /* constraint type */ #define ACT_CONST_TYPE_LOC 0 diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 673855a6932..0648c535353 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -154,7 +154,8 @@ typedef enum eBone_Flag { BONE_NO_SCALE = (1<<15), /* No parent scale */ BONE_HIDDEN_PG = (1<<16), /* hidden bone when drawing PoseChannels (for ghost drawing) */ BONE_DRAWWIRE = (1<<17), /* bone should be drawn as OB_WIRE, regardless of draw-types of view+armature */ - BONE_NO_CYCLICOFFSET = (1<<18) /* when no parent, bone will not get cyclic offset */ + BONE_NO_CYCLICOFFSET = (1<<18), /* when no parent, bone will not get cyclic offset */ + BONE_EDITMODE_LOCKED = (1<<19), /* bone transforms are locked in EditMode */ } eBone_Flag; #endif diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 0fe0dace016..e78855b8de6 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -317,6 +317,13 @@ typedef struct bDistLimitConstraint { int pad; } bDistLimitConstraint; +typedef struct bShrinkwrapConstraint { + Object *target; + float dist; /* distance to kept from target */ + short shrinkType; /* shrink type (look on MOD shrinkwrap for values) */ + short pad[5]; +} bShrinkwrapConstraint; + /* ------------------------------------------ */ /* bConstraint->type @@ -344,10 +351,9 @@ typedef enum B_CONSTAINT_TYPES { CONSTRAINT_TYPE_RIGIDBODYJOINT, /* rigidbody constraint */ CONSTRAINT_TYPE_CLAMPTO, /* clampto constraint */ CONSTRAINT_TYPE_TRANSFORM, /* transformation (loc/rot/size -> loc/rot/size) constraint */ + CONSTRAINT_TYPE_SHRINKWRAP, /* shrinkwrap (loc/rot) constraint */ - - /* NOTE: everytime a new constraint is added, update this */ - NUM_CONSTRAINT_TYPES= CONSTRAINT_TYPE_TRANSFORM + NUM_CONSTRAINT_TYPES } B_CONSTRAINT_TYPES; /* bConstraint->flag */ @@ -375,11 +381,13 @@ typedef enum B_CONSTRAINT_SPACETYPES { /* for objects (relative to parent/without parent influence), * for bones (along normals of bone, without parent/restpositions) */ - CONSTRAINT_SPACE_LOCAL, + CONSTRAINT_SPACE_LOCAL, /* = 1 */ /* for posechannels - pose space */ - CONSTRAINT_SPACE_POSE, - /* for posechannels - local with parent */ - CONSTRAINT_SPACE_PARLOCAL, + CONSTRAINT_SPACE_POSE, /* = 2 */ + /* for posechannels - local with parent */ + CONSTRAINT_SPACE_PARLOCAL, /* = 3 */ + /* for files from between 2.43-2.46 (should have been parlocal) */ + CONSTRAINT_SPACE_INVALID, /* = 4. do not exchange for anything! */ } B_CONSTRAINT_SPACETYPES; /* bConstraintChannel.flag */ diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 72557145270..6c098e220bb 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -71,7 +71,8 @@ typedef struct CustomData { #define CD_MTEXPOLY 15 #define CD_MLOOPUV 16 #define CD_MLOOPCOL 17 -#define CD_NUMTYPES 18 +#define CD_TANGENT 18 +#define CD_NUMTYPES 19 /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) @@ -92,6 +93,7 @@ typedef struct CustomData { #define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY) #define CD_MASK_MLOOPUV (1 << CD_MLOOPUV) #define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL) +#define CD_MASK_TANGENT (1 << CD_TANGENT) /* CustomData.flag */ diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index eafd886981b..dca4e28688d 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' @@ -123,16 +125,16 @@ typedef struct bGPdata { */ short sbuffer_size; /* number of elements currently in cache */ short sbuffer_sflag; /* flags for stroke that cache represents */ - bGPDspoint *sbuffer; /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */ + void *sbuffer; /* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */ } 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) - /* is the block being shown in Action Editor */ -#define GP_DATA_EDITTIME (1<<2) + /* in Action Editor, show as expanded channel */ +#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/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 6d025839ac8..4e427ed733c 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -228,7 +228,7 @@ typedef struct PartialVisibility { /* mtface->mode */ #define TF_DYNAMIC 1 -#define TF_DEPRECATED 2 +#define TF_ALPHASORT 2 #define TF_TEX 4 #define TF_SHAREDVERT 8 #define TF_LIGHT 16 diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index c4e8cb4925b..85c49a03569 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -466,9 +466,11 @@ extern Object workob; #define OB_LOCK_ROTX 8 #define OB_LOCK_ROTY 16 #define OB_LOCK_ROTZ 32 +#define OB_LOCK_ROT 56 #define OB_LOCK_SCALEX 64 #define OB_LOCK_SCALEY 128 #define OB_LOCK_SCALEZ 256 +#define OB_LOCK_SCALE 448 /* ob->softflag in DNA_object_force.h */ diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index c0b9a6b9590..7bad8ec3b44 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -257,6 +257,7 @@ typedef struct SpeedControlVars { #define SEQ_USE_CROP 131072 #define SEQ_USE_COLOR_BALANCE 262144 #define SEQ_USE_PROXY_CUSTOM_DIR 524288 +#define SEQ_ACTIVE 1048576 #define SEQ_COLOR_BALANCE_INVERSE_GAIN 1 #define SEQ_COLOR_BALANCE_INVERSE_GAMMA 2 diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_material.c b/source/blender/nodes/intern/SHD_nodes/SHD_material.c index bdceb134c0d..9396410f850 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 f75802b7c15..bdb2bb3707d 100644 --- a/source/blender/nodes/intern/SHD_util.h +++ b/source/blender/nodes/intern/SHD_util.h @@ -117,13 +117,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 226657655fa..7120e97a62f 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/Armature.c b/source/blender/python/api2_2x/Armature.c index e9dff098773..0db87c00dd2 100644 --- a/source/blender/python/api2_2x/Armature.c +++ b/source/blender/python/api2_2x/Armature.c @@ -1469,6 +1469,8 @@ PyObject *Armature_Init(void) PyConstant_NewInt("BONE_SELECTED", BONE_SELECTED)); PyModule_AddObject(module, "TIP_SELECTED", PyConstant_NewInt("TIP_SELECTED", BONE_TIPSEL)); + PyModule_AddObject(module, "LOCKED_EDIT", + PyConstant_NewInt("LOCKED_EDIT", BONE_EDITMODE_LOCKED)); PyModule_AddObject(module, "OCTAHEDRON", PyConstant_NewInt("OCTAHEDRON", ARM_OCTA)); diff --git a/source/blender/python/api2_2x/Bone.c b/source/blender/python/api2_2x/Bone.c index 84faf416c5f..948eb007803 100644 --- a/source/blender/python/api2_2x/Bone.c +++ b/source/blender/python/api2_2x/Bone.c @@ -368,6 +368,10 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure) if (PyList_Append(list, EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1) goto RuntimeError; + if(self->editbone->flag & BONE_EDITMODE_LOCKED) + if (PyList_Append(list, + EXPP_GetModuleConstant("Blender.Armature", "LOCKED_EDIT")) == -1) + goto RuntimeError; }else{ if(self->flag & BONE_CONNECTED) if (PyList_Append(list, @@ -401,6 +405,10 @@ static PyObject *EditBone_getOptions(BPy_EditBone *self, void *closure) if (PyList_Append(list, EXPP_GetModuleConstant("Blender.Armature", "TIP_SELECTED")) == -1) goto RuntimeError; + if(self->flag & BONE_EDITMODE_LOCKED) + if (PyList_Append(list, + EXPP_GetModuleConstant("Blender.Armature", "LOCKED_EDIT")) == -1) + goto RuntimeError; } return list; @@ -422,7 +430,7 @@ static int EditBone_CheckValidConstant(PyObject *constant) return 0; if (!STREQ3(PyString_AsString(name), "CONNECTED", "HINGE", "NO_DEFORM") && !STREQ3(PyString_AsString(name), "ROOT_SELECTED", "BONE_SELECTED", "TIP_SELECTED") && - !STREQ2(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT")) + !STREQ3(PyString_AsString(name), "MULTIPLY", "HIDDEN_EDIT", "LOCKED_EDIT")) return 0; else return 1; 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/Armature.py b/source/blender/python/api2_2x/doc/Armature.py index 68916af6166..9aceb0105e3 100644 --- a/source/blender/python/api2_2x/doc/Armature.py +++ b/source/blender/python/api2_2x/doc/Armature.py @@ -89,6 +89,8 @@ Example:: @type BONE_SELECTED: Constant @var TIP_SELECTED: Tip of the Bone is selected @type TIP_SELECTED: Constant +@var LOCKED_EDIT: Prevents the bone from being transformed in editmode +@type LOCKED_EDIT: Constant @var OCTAHEDRON: Bones drawn as octahedrons @type OCTAHEDRON: Constant @var STICK: Bones drawn as a line @@ -286,6 +288,7 @@ class Bone: - Armature.ROOT_SELECTED: Selection of root ball of bone - Armature.BONE_SELECTED: Selection of bone - Armature.TIP_SELECTED: Selection of tip ball of bone + - Armature.LOCKED_EDIT: Prevents the bone from being transformed in editmode @type options: List of Constants @ivar subdivision: The number of bone subdivisions. @type subdivision: 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/doc/Ipo.py b/source/blender/python/api2_2x/doc/Ipo.py index c479926ccf3..d1c72f8cb86 100644 --- a/source/blender/python/api2_2x/doc/Ipo.py +++ b/source/blender/python/api2_2x/doc/Ipo.py @@ -250,7 +250,7 @@ class Ipo: OfsZ, SizeX, SizeY, SizeZ, texR, texG, texB, DefVar, Col, Nor, Var, Disp. 3. Object Ipo: LocX, LocY, LocZ, dLocX, dLocY, dLocZ, RotX, RotY, RotZ, - dRotX, dRotY, dRotZ, SizeX, SizeY, SizeZ, dSizeX, dSizeY, dSizeZ, + dRotX, dRotY, dRotZ, ScaleX, ScaleY, ScaleZ, dScaleX, dScaleY, dScaleZ, Layer, Time, ColR, ColG, ColB, ColA, FStreng, FFall, Damping, RDamp, Perm. 4. Lamp Ipo: Energ, R, G, B, Dist, SpoSi, SpoBl, Quad1, Quad2, HaInt. @@ -289,7 +289,7 @@ class Ipo: OfsZ, SizeX, SizeY, SizeZ, texR, texG, texB, DefVar, Col, Nor, Var, Disp. 3. Object Ipo: LocX, LocY, LocZ, dLocX, dLocY, dLocZ, RotX, RotY, RotZ, - dRotX, dRotY, dRotZ, SizeX, SizeY, SizeZ, dSizeX, dSizeY, dSizeZ, + dRotX, dRotY, dRotZ, ScaleX, ScaleY, ScaleZ, dScaleX, dScaleY, dScaleZ, Layer, Time, ColR, ColG, ColB, ColA, FStreng, FFall, Damping, RDamp, Perm. 4. Lamp Ipo: Energ, R, G, B, Dist, SpoSi, SpoBl, Quad1, Quad2, HaInt. diff --git a/source/blender/python/api2_2x/sceneRender.c b/source/blender/python/api2_2x/sceneRender.c index d382d450970..22e165cbe9f 100644 --- a/source/blender/python/api2_2x/sceneRender.c +++ b/source/blender/python/api2_2x/sceneRender.c @@ -56,6 +56,7 @@ struct View3D; /* keep me up here */ #include "gen_utils.h" #include "gen_library.h" +#include "../BPY_extern.h" /* for BPY_do_all_scripts() */ #include "Scene.h" #include "Group.h" @@ -469,19 +470,20 @@ PyObject *M_Render_EnableDispWin( PyObject * self ) PyObject *RenderData_Render( BPy_RenderData * self ) { Scene *oldsce; + /* unlock to prevent a deadlock when there are pynodes: */ + PyThreadState *tstate = NULL; if (!G.background) { oldsce = G.scene; set_scene( self->scene ); + tstate = PyEval_SaveThread(); BIF_do_render( 0 ); set_scene( oldsce ); } - else { /* background mode (blender -b file.blend -P script) */ + int slink_flag = 0; Render *re= RE_NewRender(G.scene->id.name); - - int end_frame = G.scene->r.efra; if (G.scene != self->scene) @@ -490,11 +492,25 @@ PyObject *RenderData_Render( BPy_RenderData * self ) G.scene->r.efra = G.scene->r.sfra; + if (G.f & G_DOSCRIPTLINKS) { + BPY_do_all_scripts(SCRIPT_RENDER); + G.f &= ~G_DOSCRIPTLINKS; /* avoid FRAMECHANGED events*/ + slink_flag = 1; + } + + tstate = PyEval_SaveThread(); + RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra); + if (slink_flag) { + G.f |= G_DOSCRIPTLINKS; + BPY_do_all_scripts(SCRIPT_POSTRENDER); + } + G.scene->r.efra = end_frame; } + PyEval_RestoreThread(tstate); Py_RETURN_NONE; } @@ -565,10 +581,13 @@ PyObject *RenderData_SaveRenderedImage ( BPy_RenderData * self, PyObject *args ) PyObject *RenderData_RenderAnim( BPy_RenderData * self ) { Scene *oldsce; - + /* unlock to prevent a deadlock when there are pynodes: */ + PyThreadState *tstate = NULL; + if (!G.background) { oldsce = G.scene; set_scene( self->scene ); + tstate = PyEval_SaveThread(); BIF_do_render( 1 ); set_scene( oldsce ); } @@ -582,9 +601,18 @@ 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"); - + + if (G.f & G_DOSCRIPTLINKS) + BPY_do_all_scripts(SCRIPT_RENDER); + + tstate = PyEval_SaveThread(); RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra); + + if (G.f & G_DOSCRIPTLINKS) + BPY_do_all_scripts(SCRIPT_POSTRENDER); } + + PyEval_RestoreThread(tstate); Py_RETURN_NONE; } diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 252350ea72b..31f4596c264 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -2013,7 +2013,7 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiBlockBeginAlign(block); uiDefButF(block, NUM, B_MODIFIER_RECALC, "Width: ", lx, (cy -= 19), buttonWidth, 19, &bmd->value, - 0.0, 0.5, 5, 2, + 0.0, 0.5, 5, 4, "Bevel value/amount"); /*uiDefButI(block, NUM, B_MODIFIER_RECALC, "Recurs", lx, (cy -= 19), buttonWidth, 19, &bmd->res, @@ -4518,11 +4518,12 @@ static void editing_panel_armature_bones(Object *ob, bArmature *arm) uiDefButF(block, NUM,B_ARM_RECALCDATA, "Weight:", 225, by-19,105, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight"); /* bone types */ - uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); - uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S", 70,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit scale from parent Bone"); - uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 90, by-38, 80, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry"); - uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 170,by-38,80,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup"); - uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", 250,by-38,80,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode"); + uiDefButBitI(block, TOG, BONE_HINGE, B_ARM_RECALCDATA, "Hinge", -10,by-38,60,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit rotation or scale from parent Bone"); + uiDefButBitI(block, TOG, BONE_NO_SCALE, B_ARM_RECALCDATA, "S", 50,by-38,20,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Don't inherit scale from parent Bone"); + uiDefButBitI(block, TOGN, BONE_NO_DEFORM, B_ARM_RECALCDATA, "Deform", 70, by-38, 80, 18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "Indicate if Bone deforms geometry"); + uiDefButBitI(block, TOG, BONE_MULT_VG_ENV, B_ARM_RECALCDATA, "Mult", 150,by-38,60,18, &curBone->flag, 1.0, 32.0, 0.0, 0.0, "Multiply Bone Envelope with VertexGroup"); + uiDefButBitI(block, TOG, BONE_HIDDEN_A, REDRAWVIEW3D, "Hide", 210,by-38,60,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in Edit Mode"); + uiDefButBitI(block, TOG, BONE_EDITMODE_LOCKED, REDRAWVIEW3D, "Lock", 270,by-38,60,18, &curBone->flag, 0, 0, 0, 0, "Prevents this bone from being transformed in Edit Mode"); /* layers */ uiBlockBeginAlign(block); @@ -6335,6 +6336,7 @@ static void editing_panel_mesh_texface(void) uiDefButBitS(block, TOG, TF_BILLBOARD2, B_TFACE_BILLB, "Billboard",660,110,60,19, &tf->mode, 0, 0, 0, 0, "Billboard with Z-axis constraint"); uiDefButBitS(block, TOG, TF_SHADOW, REDRAWVIEW3D, "Shadow", 720,110,60,19, &tf->mode, 0, 0, 0, 0, "Face is used for shadow"); uiDefButBitS(block, TOG, TF_BMFONT, REDRAWVIEW3D, "Text", 780,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable bitmap text on face"); + uiDefButBitS(block, TOG, TF_ALPHASORT, REDRAWVIEW3D, "Sort", 840,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable sorting of faces for correct alpha drawing (slow, use Clip Alpha instead when possible)"); uiBlockBeginAlign(block); uiBlockSetCol(block, TH_BUT_SETTING1); diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c index 441d00ffc30..5cf1958678e 100644 --- a/source/blender/src/buttons_logic.c +++ b/source/blender/src/buttons_logic.c @@ -1654,53 +1654,66 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh wval = (width-100)/3; if (oa->type == ACT_OBJECT_NORMAL) { - ysize= 175; - + if ( ob->gameflag & OB_DYNAMIC ) + { + ysize= 175; + } + else + { + ysize= 72; + } + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefBut(block, LABEL, 0, "Force", xco, yco-45, 55, 19, NULL, 0, 0, 0, 0, "Sets the force"); - uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, ""); - - uiDefBut(block, LABEL, 0, "Torque", xco, yco-64, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque"); - uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, ""); + uiDefBut(block, LABEL, 0, "Loc", xco, yco-45, 45, 19, NULL, 0, 0, 0, 0, "Sets the location"); + uiDefButF(block, NUM, 0, "", xco+45, yco-45, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-45, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-45, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, ""); - uiDefBut(block, LABEL, 0, "dLoc", xco, yco-87, 45, 19, NULL, 0, 0, 0, 0, "Sets the dLoc"); - uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->dloc, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->dloc+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->dloc+2, -10000.0, 10000.0, 10, 0, ""); - - uiDefBut(block, LABEL, 0, "dRot", xco, yco-106, 45, 19, NULL, 0, 0, 0, 0, "Sets the dRot"); - uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, ""); + uiDefBut(block, LABEL, 0, "Rot", xco, yco-64, 45, 19, NULL, 0, 0, 0, 0, "Sets the rotation"); + uiDefButF(block, NUM, 0, "", xco+45, yco-64, wval, 19, oa->drot, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-64, wval, 19, oa->drot+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-64, wval, 19, oa->drot+2, -10000.0, 10000.0, 10, 0, ""); + + uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + + if ( ob->gameflag & OB_DYNAMIC ) + { + uiDefBut(block, LABEL, 0, "Force", xco, yco-87, 55, 19, NULL, 0, 0, 0, 0, "Sets the force"); + uiDefButF(block, NUM, 0, "", xco+45, yco-87, wval, 19, oa->forceloc, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-87, wval, 19, oa->forceloc+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-87, wval, 19, oa->forceloc+2, -10000.0, 10000.0, 10, 0, ""); - uiDefBut(block, LABEL, 0, "linV", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity"); - uiDefButF(block, NUM, 0, "", xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); + uiDefBut(block, LABEL, 0, "Torque", xco, yco-106, 55, 19, NULL, 0, 0, 0, 0, "Sets the torque"); + uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-6106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, ""); + } - uiDefBut(block, LABEL, 0, "angV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity"); - uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, ""); + if ( ob->gameflag & OB_DYNAMIC ) + { + uiDefBut(block, LABEL, 0, "LinV", xco, yco-129, 45, 19, NULL, 0, 0, 0, 0, "Sets the linear velocity"); + uiDefButF(block, NUM, 0, "", xco+45, yco-129, wval, 19, oa->linearvelocity, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); - uiDefBut(block, LABEL, 0, "damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity"); - uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, ""); - - uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefBut(block, LABEL, 0, "AngV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity"); + uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, ""); - uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV"); + uiDefBut(block, LABEL, 0, "Damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity"); + uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, ""); + + uiDefButBitS(block, TOG, ACT_FORCE_LOCAL, 0, "L", xco+45+3*wval, yco-87, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); + uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "add",xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV"); + } } else if (oa->type == ACT_OBJECT_SERVO) { ysize= 172; @@ -2062,7 +2075,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh coa->time = 0; uiDefButS(block, MENU, 1, str, xco+10, yco-65, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, ""); - uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, ""); + uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); uiDefBut(block, LABEL, 0, "Min", xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); @@ -2084,12 +2097,12 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32"; uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray"); - uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, ""); + uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); uiDefBut(block, LABEL, 0, "Range", xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum length of ray"); uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, "Dist", xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 0.0, 0, 0, "Force distance of object to point of impact of ray"); - if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRMX)) fp= coa->minloc; - else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRMY)) fp= coa->minloc+1; + if(coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc; + else if(coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1; else fp= coa->minloc+2; uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray"); @@ -2124,7 +2137,7 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4"; uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Select the axis to be aligned along the reference direction"); - uiDefButS(block, NUM, 0, "Damp:", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, ""); + uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); uiDefBut(block, LABEL, 0, "X", xco+80, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); uiDefBut(block, LABEL, 0, "Y", xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); uiDefBut(block, LABEL, 0, "Z", xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); @@ -2133,7 +2146,9 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh uiDefButF(block, NUM, 0, "", xco+80+(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[1], -2000.0, 2000.0, 10, 0, "Y component of reference direction"); uiDefButF(block, NUM, 0, "", xco+80+2*(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[2], -2000.0, 2000.0, 10, 0, "Z component of reference direction"); - uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70+(width-115)/3, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); + uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); + uiDefButF(block, NUM, 0, "min", xco+80, yco-84, (width-115)/2, 19, &(coa->minloc[0]), 0.0, 180.0, 10, 1, "Minimum angle (in degree) to maintain with target direction. No correction is done if angle with target direction is between min and max"); + uiDefButF(block, NUM, 0, "max", xco+80+(width-115)/2, yco-84, (width-115)/2, 19, &(coa->maxloc[0]), 0.0, 180.0, 10, 1, "Maximum angle (in degree) allowed with target direction. No correction is done if angle with target direction is between min and max"); } str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2"; but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, ""); diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index ebe770c89e7..c2643aa479b 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -480,7 +480,7 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short /* Target-Space */ if (target == 1) { - uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1", + uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x2|Local with Parent %x3|Local Space %x1", tarx, yco, bwidth, 18, &con->tarspace, 0, 0, 0, 0, "Choose space that target is evaluated in"); } else if (target == 0) { @@ -490,7 +490,7 @@ static void draw_constraint_spaceselect (uiBlock *block, bConstraint *con, short /* Owner-Space */ if (owner == 1) { - uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Owner Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1", + uiDefButC(block, MENU, B_CONSTRAINT_TEST, "Owner Space %t|World Space %x0|Pose Space %x2|Local with Parent %x3|Local Space %x1", ownx, yco, bwidth, 18, &con->ownspace, 0, 0, 0, 0, "Choose space that owner is evaluated in"); } else if (owner == 0) { @@ -1739,6 +1739,16 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-10, *yco-height, width+40,height-1, NULL, 5.0, 0.0, 12, rb_col, ""); } break; + + case CONSTRAINT_TYPE_SHRINKWRAP: + { + bShrinkwrapConstraint *data = con->data; + + height = 44; + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->target, "Target Object"); + uiDefButF(block, NUM, B_CONSTRAINT_TEST, "dist", *xco+120, *yco-44, 135, 18, &data->dist, 0.0f, 100.0f, 1.0f, 0.0f, "Distance to target"); + } + break; default: height = 0; break; @@ -1800,6 +1810,7 @@ static uiBlock *add_constraintmenu(void *arg_unused) uiDefBut(block, BUTM, B_CONSTRAINT_ADD_MINMAX, "Floor", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK, "Locked Track", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH, "Follow Path", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); + uiDefBut(block, BUTM, B_CONSTRAINT_ADD_SHRINKWRAP, "Shrinkwrap" , 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); @@ -2035,6 +2046,14 @@ void do_constraintbuts(unsigned short event) BIF_undo_push("Add constraint"); } break; + case B_CONSTRAINT_ADD_SHRINKWRAP: + { + con = add_new_constraint(CONSTRAINT_TYPE_SHRINKWRAP); + add_constraint_to_active(ob, con); + + BIF_undo_push("Add constraint"); + } + break; default: break; diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c index 9b1af3f1a06..0782ccfc7ee 100644 --- a/source/blender/src/drawaction.c +++ b/source/blender/src/drawaction.c @@ -89,6 +89,7 @@ #include "BSE_drawnla.h" #include "BSE_drawipo.h" +#include "BSE_drawview.h" #include "BSE_editaction_types.h" #include "BSE_editipo.h" #include "BSE_time.h" @@ -467,7 +468,7 @@ static void draw_channel_names(void) bActionGroup *grp = NULL; short indent= 0, offset= 0, sel= 0, group=0; int expand= -1, protect = -1, special= -1, mute = -1; - char name[32]; + char name[64]; /* determine what needs to be drawn */ switch (ale->type) { @@ -625,6 +626,72 @@ static void draw_channel_names(void) sprintf(name, "Constraint"); } break; + case ACTTYPE_GPDATABLOCK: /* gpencil datablock */ + { + bGPdata *gpd = (bGPdata *)ale->data; + ScrArea *sa = (ScrArea *)ale->owner; + + indent = 0; + group= 3; + + /* only show expand if there are any channels */ + if (gpd->layers.first) { + if (gpd->flag & GP_DATA_EXPAND) + expand = ICON_TRIA_DOWN; + else + expand = ICON_TRIA_RIGHT; + } + + switch (sa->spacetype) { + case SPACE_VIEW3D: + { + /* this shouldn't cause any overflow... */ + sprintf(name, "3DView: %s", view3d_get_name(sa->spacedata.first)); + special= ICON_VIEW3D; + } + break; + case SPACE_NODE: + { + SpaceNode *snode= sa->spacedata.first; + char treetype[12]; + + if (snode->treetype == 1) + sprintf(treetype, "Composite"); + else + sprintf(treetype, "Material"); + sprintf(name, "Nodes: %s", treetype); + + special= ICON_NODE; + } + break; + case SPACE_SEQ: + { + SpaceSeq *sseq= sa->spacedata.first; + char imgpreview[10]; + + switch (sseq->mainb) { + case 1: sprintf(imgpreview, "Image..."); break; + case 2: sprintf(imgpreview, "Luma..."); break; + case 3: sprintf(imgpreview, "Chroma..."); break; + case 4: sprintf(imgpreview, "Histogram"); break; + + default: sprintf(imgpreview, "Sequence"); break; + } + sprintf(name, "Sequencer: %s", imgpreview); + + special= ICON_SEQUENCE; + } + break; + + default: + { + sprintf(name, "<Unknown GP-Data Source>"); + special= -1; + } + break; + } + } + break; case ACTTYPE_GPLAYER: /* gpencil layer */ { bGPDlayer *gpl = (bGPDlayer *)ale->data; @@ -632,7 +699,8 @@ static void draw_channel_names(void) indent = 0; special = -1; expand = -1; - + group = 1; + if (EDITABLE_GPL(gpl)) protect = ICON_UNLOCKED; else @@ -651,8 +719,19 @@ static void draw_channel_names(void) /* now, start drawing based on this information */ /* draw backing strip behind channel name */ - if (group == 2) { - /* only for group-channels */ + if (group == 3) { + /* only for gp-data channels */ + if (ale->owner == curarea) // fixme... currently useless + BIF_ThemeColorShade(TH_GROUP_ACTIVE, 10); + else + BIF_ThemeColorShade(TH_GROUP, 20); + uiSetRoundBox((expand == ICON_TRIA_DOWN)? (1):(1|8)); + gl_round_box(GL_POLYGON, x, yminc, (float)NAMEWIDTH, ymaxc, 8); + + offset = 0; + } + else if (group == 2) { + /* only for action group channels */ if (ale->flag & AGRP_ACTIVE) BIF_ThemeColorShade(TH_GROUP_ACTIVE, 10); else @@ -698,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 */ @@ -720,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); } @@ -1148,12 +1233,6 @@ void drawactionspace(ScrArea *sa, void *spacedata) G.saction->action= NULL; } break; - case SACTCONT_GPENCIL: - { - /* this searching could be slow (so users should pin after this is found) */ - G.saction->gpd= gpencil_data_getetime(G.curscreen); - } - break; } } diff --git a/source/blender/src/drawgpencil.c b/source/blender/src/drawgpencil.c index 55d0464b9af..733310bfda7 100644 --- a/source/blender/src/drawgpencil.c +++ b/source/blender/src/drawgpencil.c @@ -94,6 +94,7 @@ void gp_ui_activelayer_cb (void *gpd, void *gpl) { gpencil_layer_setactive(gpd, gpl); + allqueue(REDRAWACTION, 0); } /* rename layer and set active */ @@ -104,18 +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); + allqueue(REDRAWACTION, 0); } /* add a new layer */ void gp_ui_addlayer_cb (void *gpd, void *dummy) { gpencil_layer_addnew(gpd); + allqueue(REDRAWACTION, 0); } /* delete active layer */ void gp_ui_dellayer_cb (void *gpd, void *dummy) { gpencil_layer_delactive(gpd); + allqueue(REDRAWACTION, 0); } /* delete last stroke of active layer */ @@ -134,28 +138,17 @@ void gp_ui_delframe_cb (void *gpd, void *gpl) gpencil_layer_setactive(gpd, gpl); gpencil_layer_delframe(gpl, gpf); -} - - -/* set this set of gpencil data for editing in action editor */ -void gp_ui_dotime_cb (void *gpd_arg, void *dummy) -{ - bGPdata *gpd= (bGPdata *)gpd_arg; - /* check if setting or clearing (note: setting was just set...) */ - if (gpd->flag & GP_DATA_EDITTIME) - gpencil_data_setetime(G.curscreen, gpd); - else - gpencil_data_setetime(G.curscreen, NULL); + allqueue(REDRAWACTION, 0); } - /* ------- Drawing Code ------- */ /* draw the controls for a given layer */ 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; @@ -168,40 +161,41 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short uiBlockSetEmboss(block, UI_EMBOSSN); /* rounded header */ - rb_col= (gpl->flag & GP_LAYER_ACTIVE)?50:20; - uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-2, width, 24, NULL, 5.0, 0.0, 15 , rb_col-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, ""); + 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"); } - /* when layer is locked or hidden, don't draw the rest of its settings */ + /* when layer is locked or hidden, only draw header */ if (gpl->flag & (GP_LAYER_LOCKED|GP_LAYER_HIDE)) { - height= 26; + char name[256]; /* gpl->info is 128, but we need space for 'locked/hidden' as well */ - /* draw rest of header */ - { - /* visibility button (only if hidden but not locked!) */ - if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) - uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer"); - - /* name */ - uiDefBut(block, LABEL, 1, gpl->info, *xco+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "Short description of what this layer is for (optional)"); - } + height= 26; - /* draw backdrop */ - uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12, rb_col, ""); + /* visibility button (only if hidden but not locked!) */ + if ((gpl->flag & GP_LAYER_HIDE) && !(gpl->flag & GP_LAYER_LOCKED)) + uiDefIconButBitI(block, ICONTOG, GP_LAYER_HIDE, B_REDR, ICON_RESTRICT_VIEW_OFF, *xco+12, *yco-1, 20, 20, &gpl->flag, 0.0, 0.0, 0, 0, "Visibility of layer"); - /* draw settings... (i.e. just warning for this one) */ + /* name */ if (gpl->flag & GP_LAYER_HIDE) - uiDefBut(block, LABEL, 1, "Grease Pencil Layer Hidden", *xco+60, *yco-26, 205, 20, NULL, 0.0, 0.0, 0, 0, ""); + sprintf(name, "%s (Hidden)", gpl->info); else - uiDefBut(block, LABEL, 1, "Grease Pencil Layer Locked", *xco+60, *yco-26, 205, 20, NULL, 0.0, 0.0, 0, 0, ""); + sprintf(name, "%s (Locked)", gpl->info); + uiDefBut(block, LABEL, 1, name, *xco+35, *yco, 240, 20, NULL, 0.0, 0.0, 0, 0, "Short description of what this layer is for (optional)"); + /* delete button (only if hidden but not locked!) */ + if ((gpl->flag & GP_LAYER_HIDE) & !(gpl->flag & GP_LAYER_LOCKED)) { + but= uiDefIconBut(block, BUT, B_REDR, ICON_X, *xco+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete layer"); + uiButSetFunc(but, gp_ui_dellayer_cb, gpd, NULL); + } uiBlockSetEmboss(block, UI_EMBOSS); } else { - height= 100; + height= 97; /* draw rest of header */ { @@ -211,7 +205,7 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short uiBlockSetEmboss(block, UI_EMBOSS); /* name */ - but= uiDefButC(block, TEX, B_REDR, "Info:", *xco+35, *yco, 240, 20, gpl->info, 0, 127, 0, 0, "Short description of what this layer is for (optional)"); + but= uiDefButC(block, TEX, B_REDR, "Info:", *xco+36, *yco, 240, 19, gpl->info, 0, 127, 0, 0, "Short description of what this layer is for (optional)"); uiButSetFunc(but, gp_ui_renamelayer_cb, gpd, gpl); /* delete 'button' */ @@ -224,7 +218,9 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short } /* draw backdrop */ - uiDefBut(block, ROUNDBOX, B_DIFF, "", *xco-8, *yco-height, width, height-1, NULL, 5.0, 0.0, 12, rb_col, ""); + 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, ""); + if (active) uiBlockSetCol(block, TH_AUTO); /* draw settings */ { @@ -237,21 +233,25 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short /* stroke thickness */ uiDefButS(block, NUMSLI, B_REDR, "Thickness:", *xco, *yco-75, 150, 20, &gpl->thickness, 1, 10, 0, 0, "Thickness of strokes (in pixels)"); + /* debugging options */ + if (G.f & G_DEBUG) { + uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco, *yco-95, 150, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes"); + } /* onion-skinning */ uiBlockBeginAlign(block); uiDefButBitI(block, TOG, GP_LAYER_ONIONSKIN, B_REDR, "Onion-Skin", *xco+160, *yco-26, 140, 20, &gpl->flag, 0, 0, 0, 0, "Ghost frames on either side of frame"); - uiDefButS(block, NUMSLI, B_REDR, "GStep:", *xco+160, *yco-46, 140, 20, &gpl->gstep, 0, 120, 0, 0, "Maximum frame range on either side of active frame to show (0 = just 'first' available frame on either side)"); + uiDefButS(block, NUMSLI, B_REDR, "GStep:", *xco+160, *yco-46, 140, 20, &gpl->gstep, 0, 120, 0, 0, "Max number of frames on either side of active frame to show (0 = just 'first' available sketch on either side)"); 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); - - //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"); + 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); } } @@ -262,36 +262,40 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short /* Draw the contents for a grease-pencil panel. This assumes several things: * - that panel has been created, is 318 x 204. max yco is 225 * - that a toggle for turning on/off gpencil drawing is 150 x 20, starting from (10,225) + * which is basically the top left-hand corner * It will return the amount of extra space to extend the panel by */ short draw_gpencil_panel (uiBlock *block, bGPdata *gpd, ScrArea *sa) { uiBut *but; bGPDlayer *gpl; - short xco= 10, yco= 155; + short xco= 10, yco= 170; /* draw gpd settings first */ { - /* show status info button */ - uiDefButBitI(block, TOG, GP_DATA_DISPINFO, B_REDR, "Show Status Info", 10, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "Display status info about current status of Grease Pencil"); - - /* add new/duplicate layer buttons */ - but= uiDefBut(block, BUT, B_REDR, "Add New Layer", 10,182,150,20, 0, 0, 0, 0, 0, "Adds a new Grease Pencil Layer"); + /* add new layer buttons */ + but= uiDefBut(block, BUT, B_REDR, "Add New Layer", 10,205,150,20, 0, 0, 0, 0, 0, "Adds a new Grease Pencil Layer"); 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); + if ((gpd->flag & GP_DATA_EDITPAINT)==0) { + uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes"); + + 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); + } + else + uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes"); + uiBlockEndAlign(block); /* 'view align' button (naming depends on context) */ if (sa->spacetype == SPACE_VIEW3D) - uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Draw in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space"); + uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Sketch in 3D", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added in 3D-space"); else if (sa->spacetype != SPACE_SEQ) /* not available for sequencer yet */ uiDefButBitI(block, TOG, GP_DATA_VIEWALIGN, B_REDR, "Stick to View", 170, 205, 150, 20, &gpd->flag, 0, 0, 0, 0, "New strokes are added on 2d-canvas"); - - /* show edit-in-action button */ - but= uiDefButBitI(block, TOG, GP_DATA_EDITTIME, B_REDR, "Edit Timing", 170, 182, 150, 20, &gpd->flag, 0, 0, 0, 0, "Edit timing of frames for the Grease Pencil block"); - uiButSetFunc(but, gp_ui_dotime_cb, gpd, NULL); } /* draw for each layer */ @@ -313,6 +317,66 @@ enum { GP_DRAWDATA_ONLYV2D = (1<<2), /* only draw 'canvas' strokes */ }; +/* draw stroke in buffer */ +static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thickness, short dflag, short sflag) +{ + tGPspoint *pt; + int i; + + /* error checking */ + if ((points == NULL) || (totpoints <= 0)) + return; + + /* check if buffer can be drawn */ + if (dflag & (GP_DRAWDATA_ONLY3D|GP_DRAWDATA_ONLYV2D)) + return; + + /* if drawing a single point, draw it larger */ + if (totpoints == 1) { + /* draw point */ + glBegin(GL_POINTS); + glVertex2f(points->x, points->y); + glEnd(); + } + else if (sflag & GP_STROKE_ERASER) { + /* draw stroke curve - just standard thickness */ + setlinestyle(4); + glLineWidth(1.0f); + + glBegin(GL_LINE_STRIP); + for (i=0, pt=points; i < totpoints && pt; i++, pt++) { + glVertex2f(pt->x, pt->y); + } + glEnd(); + + setlinestyle(0); + } + else { + float oldpressure = 0.0f; + + /* draw stroke curve */ + setlinestyle(2); + + glBegin(GL_LINE_STRIP); + for (i=0, pt=points; i < totpoints && pt; i++, pt++) { + if (fabs(pt->pressure - oldpressure) > 0.2f) { + glEnd(); + glLineWidth(pt->pressure * thickness); + glBegin(GL_LINE_STRIP); + + glVertex2f(pt->x, pt->y); + + oldpressure = pt->pressure; + } + else + glVertex2f(pt->x, pt->y); + } + glEnd(); + + setlinestyle(0); + } +} + /* draw a given stroke */ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy) { @@ -422,6 +486,21 @@ 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) { + /* 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) { @@ -437,11 +516,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) @@ -459,6 +537,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); @@ -474,11 +553,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/gpl->gstep); + gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor); } else break; @@ -489,11 +565,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/gpl->gstep); + gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor); } else break; @@ -504,19 +577,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->prev, 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->next, winx, winy, dflag, debug, lthick, tcolor); } /* restore alpha */ @@ -525,20 +593,17 @@ 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) + * that is being edited. (Stroke buffer is currently stored in gp-data) */ if ((G.f & G_GREASEPENCIL) && (gpl->flag & GP_LAYER_ACTIVE) && (gpf->flag & GP_FRAME_PAINT)) { /* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */ - setlinestyle(2); - gp_draw_stroke(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, debug, winx, winy); - setlinestyle(0); + gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag); } } diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index 3a73ee84ead..853df3bedfc 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -3336,7 +3336,7 @@ static void nodes_panel_gpencil(short cntrl) // NODES_HANDLER_GREASEPENCIL uiNewPanelHeight(block, 204); /* draw button for showing gpencil settings and drawings */ - uiDefButBitS(block, TOG, SNODE_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &snode->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Node Editor"); + uiDefButBitS(block, TOG, SNODE_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &snode->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Node Editor (draw using Shift-LMB)"); /* extend the panel if the contents won't fit */ newheight= draw_gpencil_panel(block, gpd, curarea); diff --git a/source/blender/src/drawseq.c b/source/blender/src/drawseq.c index c8c74ad8279..cc431c73a2e 100644 --- a/source/blender/src/drawseq.c +++ b/source/blender/src/drawseq.c @@ -134,7 +134,7 @@ static void seq_panel_gpencil(short cntrl) // SEQ_HANDLER_GREASEPENCIL uiNewPanelHeight(block, 204); /* draw button for showing gpencil settings and drawings */ - uiDefButBitI(block, TOG, SEQ_DRAW_GPENCIL, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sseq->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Sequencer View"); + uiDefButBitI(block, TOG, SEQ_DRAW_GPENCIL, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &sseq->flag, 0, 0, 0, 0, "Display freehand annotations overlay over this Sequencer View (draw using Shift-LMB)"); /* extend the panel if the contents won't fit */ newheight= draw_gpencil_panel(block, gpd, curarea); diff --git a/source/blender/src/drawview.c b/source/blender/src/drawview.c index 14434504e7a..2030eb658de 100644 --- a/source/blender/src/drawview.c +++ b/source/blender/src/drawview.c @@ -1502,44 +1502,52 @@ static void draw_view_icon(void) glDisable(GL_BLEND); } -static void draw_viewport_name(ScrArea *sa) +char *view3d_get_name(View3D *v3d) { char *name = NULL; - char *printable = NULL; - switch(G.vd->view) { + switch (v3d->view) { case 1: - if (G.vd->persp == V3D_ORTHO) - name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Ortho" : "Front Ortho"; + if (v3d->persp == V3D_ORTHO) + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Ortho" : "Front Ortho"; else - name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Persp" : "Front Persp"; + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Back Persp" : "Front Persp"; break; case 3: - if (G.vd->persp == V3D_ORTHO) - name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Ortho" : "Right Ortho"; + if (v3d->persp == V3D_ORTHO) + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Ortho" : "Right Ortho"; else - name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Persp" : "Right Persp"; + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Left Persp" : "Right Persp"; break; case 7: - if (G.vd->persp == V3D_ORTHO) - name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Ortho" : "Top Ortho"; + if (v3d->persp == V3D_ORTHO) + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Ortho" : "Top Ortho"; else - name = (G.vd->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Persp" : "Top Persp"; + name = (v3d->flag2 & V3D_OPP_DIRECTION_NAME) ? "Bottom Persp" : "Top Persp"; break; default: - if (G.vd->persp==V3D_CAMOB) { - if ((G.vd->camera) && (G.vd->camera->type == OB_CAMERA)) { + if (v3d->persp==V3D_CAMOB) { + if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) { Camera *cam; - cam = G.vd->camera->data; + cam = v3d->camera->data; name = (cam->type != CAM_ORTHO) ? "Camera Persp" : "Camera Ortho"; } else { name = "Object as Camera"; } } else { - name = (G.vd->persp == V3D_ORTHO) ? "User Ortho" : "User Persp"; + name = (v3d->persp == V3D_ORTHO) ? "User Ortho" : "User Persp"; } + break; } + return name; +} + +static void draw_viewport_name(ScrArea *sa) +{ + char *name = view3d_get_name(sa->spacedata.first); + char *printable = NULL; + if (G.vd->localview) { printable = malloc(strlen(name) + strlen(" (Local)_")); /* '_' gives space for '\0' */ strcpy(printable, name); @@ -1987,6 +1995,8 @@ static void v3d_editarmature_buts(uiBlock *block, Object *ob, float lim) tfp->ob_eul[0]= 180.0*ebone->roll/M_PI; uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:", 10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, ""); + uiDefButBitI(block, TOG, BONE_EDITMODE_LOCKED, REDRAWVIEW3D, "Lock", 160, 100, 140, 19, &(ebone->flag), 0, 0, 0, 0, "Prevents bone from being transformed in edit mode"); + uiBlockBeginAlign(block); uiDefButF(block, NUM, B_ARMATUREPANEL1, "TailRadius:", 10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, ""); if (ebone->parent && ebone->flag & BONE_CONNECTED ) @@ -2654,7 +2664,7 @@ static void view3d_panel_gpencil(short cntrl) // VIEW3D_HANDLER_GREASEPENCIL uiNewPanelHeight(block, 204); /* draw button for showing gpencil settings and drawings */ - uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &vd->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View"); + uiDefButBitS(block, TOG, V3D_DISPGP, B_REDR, "Use Grease Pencil", 10, 225, 150, 20, &vd->flag2, 0, 0, 0, 0, "Display freehand annotations overlay over this 3D View (draw using Shift-LMB)"); /* extend the panel if the contents won't fit */ newheight= draw_gpencil_panel(block, gpd, curarea); diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c index 3251cb33b53..c454715b1df 100644 --- a/source/blender/src/editaction.c +++ b/source/blender/src/editaction.c @@ -517,23 +517,43 @@ static void actdata_filter_shapekey (ListBase *act_data, Key *key, int filter_mo } } -static void actdata_filter_gpencil (ListBase *act_data, bGPdata *gpd, int filter_mode) + +static void actdata_filter_gpencil (ListBase *act_data, bScreen *sc, int filter_mode) { bActListElem *ale; + ScrArea *sa; + bGPdata *gpd; bGPDlayer *gpl; /* check if filtering types are appropriate */ if ( !(filter_mode & (ACTFILTER_IPOKEYS|ACTFILTER_ONLYICU|ACTFILTER_ACTGROUPED)) ) { - /* loop over layers as the conditions are acceptable */ - for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { - /* only if selected */ - if (!(filter_mode & ACTFILTER_SEL) || SEL_GPL(gpl)) { - /* only if editable */ - if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_GPL(gpl)) { - /* add to list */ - ale= make_new_actlistelem(gpl, ACTTYPE_GPLAYER, NULL, ACTTYPE_NONE); - if (ale) BLI_addtail(act_data, ale); + /* loop over spaces in current screen, finding gpd blocks (could be slow!) */ + for (sa= sc->areabase.first; sa; sa= sa->next) { + /* try to get gp data */ + gpd= gpencil_data_getactive(sa); + if (gpd == NULL) continue; + + /* add gpd as channel too (if for drawing, and it has layers) */ + if ((filter_mode & ACTFILTER_FORDRAWING) && (gpd->layers.first)) { + /* add to list */ + ale= make_new_actlistelem(gpd, ACTTYPE_GPDATABLOCK, sa, ACTTYPE_SPECIALDATA); + if (ale) BLI_addtail(act_data, ale); + } + + /* only add layers if they will be visible (if drawing channels) */ + if ( !(filter_mode & ACTFILTER_VISIBLE) || (EXPANDED_GPD(gpd)) ) { + /* loop over layers as the conditions are acceptable */ + for (gpl= gpd->layers.first; gpl; gpl= gpl->next) { + /* only if selected */ + if (!(filter_mode & ACTFILTER_SEL) || SEL_GPL(gpl)) { + /* only if editable */ + if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_GPL(gpl)) { + /* add to list */ + ale= make_new_actlistelem(gpl, ACTTYPE_GPLAYER, gpd, ACTTYPE_GPDATABLOCK); + if (ale) BLI_addtail(act_data, ale); + } + } } } } @@ -637,11 +657,8 @@ int get_nearest_key_num (Key *key, short *mval, float *x) return (num + 1); } -/* this function is used to get a pointer to an action or shapekey - * datablock, thus simplying that process. - */ -/* this function is intended for use */ -void *get_nearest_act_channel (short mval[], short *ret_type) +/* this function finds the channel that mouse is floating over */ +void *get_nearest_act_channel (short mval[], short *ret_type, void **owner) { ListBase act_data = {NULL, NULL}; bActListElem *ale; @@ -652,6 +669,9 @@ void *get_nearest_act_channel (short mval[], short *ret_type) int clickmin, clickmax; float x,y; + /* init 'owner' return val */ + *owner= NULL; + /* determine what type of data we are operating on */ data = get_action_context(&datatype); if (data == NULL) { @@ -679,6 +699,7 @@ void *get_nearest_act_channel (short mval[], short *ret_type) /* found match */ *ret_type= ale->type; data= ale->data; + *owner= ale->owner; BLI_freelistN(&act_data); @@ -854,10 +875,7 @@ void *get_action_context (short *datatype) case SACTCONT_GPENCIL: *datatype= ACTCONT_GPENCIL; - if (G.saction->pin) - return G.saction->gpd; - else - return gpencil_data_getetime(G.curscreen); + return G.curscreen; // FIXME: add that dopesheet type thing here! default: /* includes SACTCONT_DOPESHEET for now */ *datatype= ACTCONT_NONE; @@ -2327,7 +2345,7 @@ static void numbuts_action () void *data; short datatype; - void *act_channel; + void *act_channel, *channel_owner; short chantype; bActionGroup *agrp= NULL; @@ -2335,6 +2353,7 @@ static void numbuts_action () bConstraintChannel *conchan= NULL; IpoCurve *icu= NULL; KeyBlock *kb= NULL; + bGPdata *gpd= NULL; bGPDlayer *gpl= NULL; short mval[2]; @@ -2353,7 +2372,7 @@ static void numbuts_action () getmouseco_areawin(mval); if (mval[0] > NAMEWIDTH) return; - act_channel= get_nearest_act_channel(mval, &chantype); + act_channel= get_nearest_act_channel(mval, &chantype, &channel_owner); /* create items for clever-numbut */ if (chantype == ACTTYPE_ACHAN) { @@ -2451,6 +2470,7 @@ static void numbuts_action () } else if (chantype == ACTTYPE_GPLAYER) { /* Grease-Pencil Layer */ + gpd= (bGPdata *)channel_owner; gpl= (bGPDlayer *)act_channel; strcpy(str, gpl->info); @@ -2511,7 +2531,7 @@ static void numbuts_action () } else if (gpl) { strcpy(gpl->info, str); - BLI_uniquename(&( ((bGPdata *)data)->layers ), gpl, "GP_Layer", offsetof(bGPDlayer, info), 128); + BLI_uniquename(&gpd->layers, gpl, "GP_Layer", offsetof(bGPDlayer, info), 128); if (mute) gpl->flag |= GP_LAYER_HIDE; else gpl->flag &= ~GP_LAYER_HIDE;; @@ -2871,9 +2891,10 @@ int select_gplayer_channel (bGPdata *gpd, bGPDlayer *gpl, int selectmode) gpl->flag ^= GP_LAYER_SELECT; break; } + flag = (gpl->flag & GP_LAYER_SELECT) ? 1 : 0; - - gpencil_layer_setactive(gpd, gpl); + if (flag) + gpencil_layer_setactive(gpd, gpl); return flag; } @@ -3100,11 +3121,11 @@ void selectall_action_keys (short mval[], short mode, short select_mode) switch (mode) { case 0: /* all in channel*/ { - void *act_channel; + void *act_channel, *channel_owner; short chantype; /* get channel, and act according to type */ - act_channel= get_nearest_act_channel(mval, &chantype); + act_channel= get_nearest_act_channel(mval, &chantype, &channel_owner); switch (chantype) { case ACTTYPE_GROUP: { @@ -3939,8 +3960,7 @@ static void mouse_action (int selectmode) static void mouse_actionchannels (short mval[]) { bAction *act= G.saction->action; - bGPdata *gpd= G.saction->gpd; - void *data, *act_channel; + void *data, *act_channel, *channel_owner; short datatype, chantype; /* determine what type of data we are operating on */ @@ -3948,7 +3968,7 @@ static void mouse_actionchannels (short mval[]) if (data == NULL) return; /* get channel to work on */ - act_channel= get_nearest_act_channel(mval, &chantype); + act_channel= get_nearest_act_channel(mval, &chantype, &channel_owner); /* action to take depends on what channel we've got */ switch (chantype) { @@ -4086,8 +4106,17 @@ static void mouse_actionchannels (short mval[]) } } break; + case ACTTYPE_GPDATABLOCK: + { + bGPdata *gpd= (bGPdata *)act_channel; + + /* toggle expand */ + gpd->flag ^= GP_DATA_EXPAND; + } + break; case ACTTYPE_GPLAYER: { + bGPdata *gpd= (bGPdata *)channel_owner; bGPDlayer *gpl= (bGPDlayer *)act_channel; if (mval[0] >= (NAMEWIDTH-16)) { @@ -4100,7 +4129,13 @@ static void mouse_actionchannels (short mval[]) } else { /* select/deselect */ - select_gplayer_channel(gpd, gpl, SELECT_INVERT); + if (G.qual & LR_SHIFTKEY) { + select_gplayer_channel(gpd, gpl, SELECT_INVERT); + } + else { + deselect_gpencil_layers(data, 0); + select_gplayer_channel(gpd, gpl, SELECT_INVERT); + } } } break; diff --git a/source/blender/src/editaction_gpencil.c b/source/blender/src/editaction_gpencil.c index b91c5a8b332..14269080b1f 100644 --- a/source/blender/src/editaction_gpencil.c +++ b/source/blender/src/editaction_gpencil.c @@ -246,7 +246,7 @@ void borderselect_gplayer_frames (bGPDlayer *gpl, float min, float max, short se /* De-selects or inverts the selection of Layers for a grease-pencil block * mode: 0 = default behaviour (select all), 1 = test if (de)select all, 2 = invert all */ -void deselect_gpencil_layers (bGPdata *gpd, short mode) +void deselect_gpencil_layers (void *data, short mode) { ListBase act_data = {NULL, NULL}; bActListElem *ale; @@ -254,7 +254,7 @@ void deselect_gpencil_layers (bGPdata *gpd, short mode) /* filter data */ filter= ACTFILTER_VISIBLE; - actdata_filter(&act_data, filter, gpd, ACTCONT_GPENCIL); + actdata_filter(&act_data, filter, data, ACTCONT_GPENCIL); /* See if we should be selecting or deselecting */ if (mode == 1) { @@ -294,7 +294,6 @@ void delete_gpencil_layers (void) { ListBase act_data = {NULL, NULL}; bActListElem *ale, *next; - bGPdata *gpd; void *data; short datatype; int filter; @@ -303,7 +302,6 @@ void delete_gpencil_layers (void) data = get_action_context(&datatype); if (data == NULL) return; if (datatype != ACTCONT_GPENCIL) return; - gpd= (bGPdata *)data; /* filter data */ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_CHANNELS | ACTFILTER_SEL); @@ -311,6 +309,7 @@ void delete_gpencil_layers (void) /* clean up grease-pencil layers */ for (ale= act_data.first; ale; ale= next) { + bGPdata *gpd= (bGPdata *)ale->owner; bGPDlayer *gpl= (bGPDlayer *)ale->data; next= ale->next; diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c index 6310dd0a262..3d0f26960d6 100644 --- a/source/blender/src/editarmature.c +++ b/source/blender/src/editarmature.c @@ -2709,6 +2709,32 @@ void show_all_armature_bones(void) BIF_undo_push("Reveal Bones"); } +/* Sets editmode transform locks for bones (adds if lock==1, clears otherwise) */ +void set_locks_armature_bones(short lock) +{ + bArmature *arm= G.obedit->data; + EditBone *ebone; + + for (ebone = G.edbo.first; ebone; ebone=ebone->next) { + if (arm->layer & ebone->layer) { + if (ebone->flag & BONE_SELECTED) { + if (lock) + ebone->flag |= BONE_EDITMODE_LOCKED; + else + ebone->flag &= ~BONE_EDITMODE_LOCKED; + } + } + } + countall(); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + + if (lock) + BIF_undo_push("Lock Bones"); + else + BIF_undo_push("Unlock Bones"); +} + /* check for null, before calling! */ static void bone_connect_to_existing_parent(EditBone *bone) { diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index c5dd41e16d5..63c301658f2 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -82,6 +82,7 @@ #include "BKE_group.h" #include "BKE_ipo.h" #include "BKE_key.h" +#include "BKE_main.h" #include "BKE_material.h" #include "BKE_particle.h" #include "BKE_texture.h" @@ -933,6 +934,9 @@ static void make_editipo(void) ob->ipowin= ID_TE; make_texture_editipo(G.sipo); } + else if(G.scene->world && give_current_world_texture()) { + make_texture_editipo(G.sipo); + } } else if(G.sipo->blocktype==ID_CA) { if (ob) { @@ -1120,6 +1124,11 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname *from= (ID *)tex; if(tex) *ipo= tex->ipo; } + else if(G.scene->world) { + Tex *tex= give_current_world_texture(); + *from= (ID *)tex; + if(tex) *ipo= tex->ipo; + } } else if(blocktype==ID_MA) { if(ob) { @@ -6002,4 +6011,4 @@ void move_to_frame(void) } } BIF_undo_push("Set frame to selected Ipo vertex"); -} +}
\ No newline at end of file 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/editobject.c b/source/blender/src/editobject.c index 6af4f47ed11..cbf7691754d 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -2760,7 +2760,7 @@ void special_editmenu(void) DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } else if(G.obedit->type==OB_ARMATURE) { - nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6"); + nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6|%l|Lock%x7|Unlock%x8"); if(nr==1) subdivide_armature(1); if(nr==2) { @@ -2773,6 +2773,10 @@ void special_editmenu(void) else if(ELEM3(nr, 4, 5, 6)) { armature_autoside_names(nr-4); } + else if(nr==7) + set_locks_armature_bones(1); + else if(nr==8) + set_locks_armature_bones(0); } else if(G.obedit->type==OB_LATTICE) { static float weight= 1.0f; @@ -3502,6 +3506,17 @@ void copy_attr(short event) base->object->damping= ob->damping; base->object->rdamping= ob->rdamping; } + else if(event==11) { /* all physical attributes */ + base->object->gameflag = ob->gameflag; + base->object->inertia = ob->inertia; + base->object->formfactor = ob->formfactor; + base->object->damping= ob->damping; + base->object->rdamping= ob->rdamping; + base->object->mass= ob->mass; + if (ob->gameflag & OB_BOUNDS) { + base->object->boundtype = ob->boundtype; + } + } else if(event==17) { /* tex space */ copy_texture_space(base->object, ob); } @@ -3688,7 +3703,7 @@ void copy_attr_menu() * view3d_edit_object_copyattrmenu() and in toolbox.c */ - strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|Time Offset%x5|Dupli%x6|%l|Mass%x7|Damping%x8|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l"); + strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|Time Offset%x5|Dupli%x6|%l|Mass%x7|Damping%x8|All Physical Attributes%x11|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l"); strcat (str, "|Object Constraints%x22"); strcat (str, "|NLA Strips%x26"); diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c index f9432f8e69a..12019a9dab9 100644 --- a/source/blender/src/editseq.c +++ b/source/blender/src/editseq.c @@ -122,13 +122,28 @@ Sequence *get_last_seq() if(!_last_seq_init) { Editing *ed; Sequence *seq; + Sequence *l_sel = NULL; + Sequence *l_act = NULL; ed= G.scene->ed; if(!ed) return NULL; - for(seq= ed->seqbasep->first; seq; seq=seq->next) + for(seq= ed->seqbasep->first; seq; seq=seq->next) { + if(seq->flag & SEQ_ACTIVE) + l_act = seq; if(seq->flag & SELECT) - _last_seq= seq; + l_sel = seq; + } + + if (l_act) { + _last_seq = l_act; + } else { + _last_seq = l_sel; + } + + if (_last_seq) { + _last_seq->flag |= SEQ_ACTIVE; + } _last_seq_init = 1; } @@ -138,12 +153,23 @@ Sequence *get_last_seq() void set_last_seq(Sequence *seq) { + if (_last_seq_init && _last_seq) { + _last_seq->flag &= ~SEQ_ACTIVE; + } + _last_seq = seq; _last_seq_init = 1; + + if (_last_seq) { + _last_seq->flag |= SEQ_ACTIVE; + } } -void clear_last_seq(Sequence *seq) +void clear_last_seq() { + if (_last_seq_init && _last_seq) { + _last_seq->flag &= ~SEQ_ACTIVE; + } _last_seq = NULL; _last_seq_init = 0; } @@ -2261,6 +2287,8 @@ static Sequence *dupli_seq(Sequence *seq) "handled in duplicate!\nExpect a crash" " now...\n"); } + + seqn->flag &= ~SEQ_ACTIVE; return seqn; } diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c index e3ec69975de..a3fcad7885c 100644 --- a/source/blender/src/editview.c +++ b/source/blender/src/editview.c @@ -298,7 +298,7 @@ int lasso_inside(short mcords[][2], short moves, short sx, short sy) } /* edge version for lasso select. we assume boundbox check was done */ -static int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1) +int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1) { short v1[2], v2[2]; int a; @@ -371,7 +371,7 @@ static void do_lasso_select_objects(short mcords[][2], short moves, short select } } -static void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves) +void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves) { short a; diff --git a/source/blender/src/gpencil.c b/source/blender/src/gpencil.c index fa32b0ac7d4..eef21323a44 100644 --- a/source/blender/src/gpencil.c +++ b/source/blender/src/gpencil.c @@ -48,6 +48,7 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_userdef_types.h" +#include "DNA_vec_types.h" #include "DNA_view3d_types.h" #include "BKE_global.h" @@ -57,6 +58,7 @@ #include "BIF_gl.h" #include "BIF_glutil.h" #include "BIF_butspace.h" +#include "BIF_editview.h" #include "BIF_graphics.h" #include "BIF_interface.h" #include "BIF_mywindow.h" @@ -383,111 +385,6 @@ short gpencil_data_setactive (ScrArea *sa, bGPdata *gpd) return 0; } -/* Find gp-data destined for editing in animation editor (for editing time) */ -bGPdata *gpencil_data_getetime (bScreen *sc) -{ - bGPdata *gpd= NULL; - ScrArea *sa; - - /* error checking */ - if (sc == NULL) - return NULL; - - /* search through areas, checking if an appropriate gp-block is available - * (this assumes that only one will have the active flag set) - */ - for (sa= sc->areabase.first; sa; sa= sa->next) { - /* handle depending on space type */ - switch (sa->spacetype) { - case SPACE_VIEW3D: /* 3d-view */ - { - View3D *v3d= sa->spacedata.first; - gpd= v3d->gpd; - } - break; - case SPACE_NODE: /* Node Editor */ - { - SpaceNode *snode= sa->spacedata.first; - gpd= snode->gpd; - } - break; - case SPACE_SEQ: /* Sequence Editor - Image Preview */ - { - SpaceSeq *sseq= sa->spacedata.first; - - if (sseq->mainb) - gpd= sseq->gpd; - else - gpd= NULL; - } - break; - - default: /* unsupported space-type */ - gpd= NULL; - break; - } - - /* check if ok */ - if ((gpd) && (gpd->flag & GP_DATA_EDITTIME)) - return gpd; - } - - /* didn't find a match */ - return NULL; -} - -/* make sure only the specified view can have gp-data for time editing - * - gpd can be NULL, if we wish to make sure no gp-data is being edited - */ -void gpencil_data_setetime (bScreen *sc, bGPdata *gpd) -{ - bGPdata *gpdn= NULL; - ScrArea *sa; - - /* error checking */ - if (sc == NULL) - return; - - /* search through areas, checking if an appropriate gp-block is available - * (this assumes that only one will have the active flag set) - */ - for (sa= sc->areabase.first; sa; sa= sa->next) { - /* handle depending on space type */ - switch (sa->spacetype) { - case SPACE_VIEW3D: /* 3d-view */ - { - View3D *v3d= sa->spacedata.first; - gpdn= v3d->gpd; - } - break; - case SPACE_NODE: /* Node Editor */ - { - SpaceNode *snode= sa->spacedata.first; - gpdn= snode->gpd; - } - break; - case SPACE_SEQ: /* Sequence Editor - Image Preview */ - { - SpaceSeq *sseq= sa->spacedata.first; - gpdn= sseq->gpd; - } - break; - - default: /* unsupported space-type */ - gpdn= NULL; - break; - } - - /* clear flag if a gp-data block found */ - if (gpdn) - gpdn->flag &= ~GP_DATA_EDITTIME; - } - - /* set active flag for this block (if it is provided) */ - if (gpd) - gpd->flag |= GP_DATA_EDITTIME; -} - /* -------- GP-Frame API ---------- */ /* delete the last stroke of the given frame */ @@ -721,7 +618,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; @@ -747,11 +644,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); @@ -763,7 +664,14 @@ 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 + +/* Hardcoded sensitivity thresholds... */ +// TODO: one day, these might be added to the UI if it is necessary + /* minimum number of pixels mouse should move before new point created */ +#define MIN_MANHATTEN_PX 3 + /* minimum length of new segment before new point can be added */ +#define MIN_EUCLIDEAN_PX 20 /* ------ */ @@ -777,7 +685,7 @@ typedef struct tGPsdata { bGPDframe *gpf; /* frame we're working on */ short status; /* current status of painting */ - short paintmode; /* mode for painting (L_MOUSE or R_MOUSE for now) */ + short paintmode; /* mode for painting */ } tGPsdata; /* values for tGPsdata->status */ @@ -787,6 +695,12 @@ enum { GP_STATUS_DONE /* painting done */ }; +/* values for tGPsdata->paintmode */ +enum { + GP_PAINTMODE_DRAW = 0, + GP_PAINTMODE_ERASER +}; + /* Return flags for adding points to stroke buffer */ enum { GP_STROKEADD_INVALID = -2, /* error occurred - insufficient info to do so */ @@ -804,9 +718,9 @@ static void gp_session_validatebuffer (tGPsdata *p) /* clear memory of buffer (or allocate it if starting a new session) */ if (gpd->sbuffer) - memset(gpd->sbuffer, 0, sizeof(bGPDspoint)*GP_STROKE_BUFFER_MAX); + memset(gpd->sbuffer, 0, sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX); else - gpd->sbuffer= MEM_callocN(sizeof(bGPDspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer"); + gpd->sbuffer= MEM_callocN(sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer"); /* reset indices */ gpd->sbuffer_size = 0; @@ -944,6 +858,25 @@ static void gp_session_cleanup (tGPsdata *p) gpd->sbuffer_sflag= 0; } +/* check if the current mouse position is suitable for adding a new point */ +static short gp_stroke_filtermval (tGPsdata *p, short mval[2], short pmval[2]) +{ + short dx= abs(mval[0] - pmval[0]); + short dy= abs(mval[1] - pmval[1]); + + /* check if mouse moved at least certain distance on both axes (best case) */ + if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) + return 1; + + /* check if the distance since the last point is significant enough */ + else if (sqrt(dx*dx + dy*dy) > MIN_EUCLIDEAN_PX) + return 1; + + /* mouse 'didn't move' */ + else + return 0; +} + /* convert screen-coordinates to buffer-coordinates */ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) { @@ -979,23 +912,23 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) } /* add current stroke-point to buffer (returns whether point was successfully added) */ -static short gp_stroke_addpoint (tGPsdata *p, short mval[], float pressure) +static short gp_stroke_addpoint (tGPsdata *p, short mval[2], float pressure) { bGPdata *gpd= p->gpd; - bGPDspoint *pt; + tGPspoint *pt; /* check if still room in buffer */ if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX) return GP_STROKEADD_OVERFLOW; - /* get pointer to destination point */ - pt= gpd->sbuffer + gpd->sbuffer_size; - - /* convert screen-coordinates to appropriate coordinates (and store them) */ - gp_stroke_convertcoords(p, mval, &pt->x); + pt= ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size); - /* store other settings */ + /* store settings */ + pt->x= mval[0]; + pt->y= mval[1]; + pt->xf= (float)mval[0]; + pt->yf= (float)mval[0]; pt->pressure= pressure; /* increment counters */ @@ -1008,35 +941,13 @@ static short gp_stroke_addpoint (tGPsdata *p, short mval[], float pressure) return GP_STROKEADD_NORMAL; } -/* smooth a stroke (in buffer) before storing it */ -static void gp_stroke_smooth (tGPsdata *p) -{ - bGPdata *gpd= p->gpd; - int i=0, cmx=gpd->sbuffer_size; - - /* don't try if less than 2 points in buffer */ - if ((cmx <= 2) || (gpd->sbuffer == NULL)) - return; - - /* apply weighting-average (note doing this along path sequentially does introduce slight error) */ - for (i=0; i < gpd->sbuffer_size; i++) { - bGPDspoint *pc= (gpd->sbuffer + i); - bGPDspoint *pb= (i-1 > 0)?(pc-1):(pc); - bGPDspoint *pa= (i-2 > 0)?(pc-2):(pb); - bGPDspoint *pd= (i+1 < cmx)?(pc+1):(pc); - bGPDspoint *pe= (i+2 < cmx)?(pc+2):(pd); - - pc->x= (0.1*pa->x + 0.2*pb->x + 0.4*pc->x + 0.2*pd->x + 0.1*pe->x); - pc->y= (0.1*pa->y + 0.2*pb->y + 0.4*pc->y + 0.2*pd->y + 0.1*pe->y); - } -} - /* make a new stroke from the buffer data */ static void gp_stroke_newfrombuffer (tGPsdata *p) { bGPdata *gpd= p->gpd; bGPDstroke *gps; - bGPDspoint *pt, *ptc; + bGPDspoint *pt; + tGPspoint *ptc; int i, totelem; /* get total number of points to allocate space for */ @@ -1062,7 +973,12 @@ static void gp_stroke_newfrombuffer (tGPsdata *p) /* copy points from the buffer to the stroke */ for (i=0, ptc=gpd->sbuffer; i < gpd->sbuffer_size && ptc; i++, ptc++) { - memcpy(pt, ptc, sizeof(bGPDspoint)); + /* convert screen-coordinates to appropriate coordinates (and store them) */ + gp_stroke_convertcoords(p, &ptc->x, &pt->x); + + /* copy pressure */ + pt->pressure= ptc->pressure; + pt++; } @@ -1070,10 +986,220 @@ static void gp_stroke_newfrombuffer (tGPsdata *p) BLI_addtail(&p->gpf->strokes, gps); } +/* --- 'Eraser' for 'Paint' Tool ------ */ +/* User should draw 'circles' around the parts of the sketches they wish to + * delete instead of drawing squiggles over existing lines. This should be + * easier to manage than if it was done otherwise. + */ + +/* convert gp-buffer stroke into mouse-coordinates array */ +static short (*gp_stroke_eraser_2mco (bGPdata *gpd))[2] +{ + tGPspoint *pt; + short (*mcoords)[2]; + int i; + + /* allocate memory for coordinates array */ + mcoords= MEM_mallocN(sizeof(*mcoords)*gpd->sbuffer_size,"gp_buf_mcords"); + + /* copy coordinates */ + for (pt=gpd->sbuffer, i=0; i < gpd->sbuffer_size; i++, pt++) { + mcoords[i][0]= pt->x; + mcoords[i][1]= pt->y; + } + + /* return */ + return mcoords; +} + +/* eraser tool - remove segment from stroke/split stroke (after lasso inside) */ +static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i) +{ + bGPDspoint *pt_tmp= gps->points; + bGPDstroke *gsn = NULL; + + /* if stroke only had two points, get rid of stroke */ + if (gps->totpoints == 2) { + /* free stroke points, then stroke */ + MEM_freeN(pt_tmp); + BLI_freelinkN(&gpf->strokes, gps); + + /* nothing left in stroke, so stop */ + return 1; + } + + /* if last segment, just remove segment from the stroke */ + else if (i == gps->totpoints - 2) { + /* allocate new points array, and assign most of the old stroke there */ + gps->totpoints--; + gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points"); + memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*gps->totpoints); + + /* free temp buffer */ + MEM_freeN(pt_tmp); + + /* nothing left in stroke, so stop */ + return 1; + } + + /* if first segment, just remove segment from the stroke */ + else if (i == 0) { + /* allocate new points array, and assign most of the old stroke there */ + gps->totpoints--; + gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points"); + memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint)*gps->totpoints); + + /* free temp buffer */ + MEM_freeN(pt_tmp); + + /* no break here, as there might still be stuff to remove in this stroke */ + return 0; + } + + /* segment occurs in 'middle' of stroke, so split */ + else { + /* duplicate stroke, and assign 'later' data to that stroke */ + gsn= MEM_dupallocN(gps); + gsn->prev= gsn->next= NULL; + BLI_insertlinkafter(&gpf->strokes, gps, gsn); + + gsn->totpoints= gps->totpoints - i; + gsn->points= MEM_callocN(sizeof(bGPDspoint)*gsn->totpoints, "gp_stroke_points"); + memcpy(gsn->points, pt_tmp + i, sizeof(bGPDspoint)*gsn->totpoints); + + /* adjust existing stroke */ + gps->totpoints= i; + gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points"); + memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*i); + + /* free temp buffer */ + MEM_freeN(pt_tmp); + + /* nothing left in stroke, so stop */ + return 1; + } +} + +/* eraser tool - evaluation per stroke */ +static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short moves, rcti *rect, bGPDframe *gpf, bGPDstroke *gps) +{ + bGPDspoint *pt1, *pt2; + short x0=0, y0=0, x1=0, y1=0; + short xyval[2]; + int i; + + if (gps->totpoints == 0) { + /* just free stroke */ + if (gps->points) + MEM_freeN(gps->points); + BLI_freelinkN(&gpf->strokes, gps); + } + else if (gps->totpoints == 1) { + /* get coordinates */ + if (gps->flag & GP_STROKE_3DSPACE) { + // FIXME: this may not be the correct correction + project_short(&gps->points->x, xyval); + x0= xyval[0]; + x1= xyval[1]; + } + else if (gps->flag & GP_STROKE_2DSPACE) { + ipoco_to_areaco_noclip(p->v2d, &gps->points->x, xyval); + x0= xyval[0]; + y0= xyval[1]; + } + else { + x0= (gps->points->x / 1000 * p->sa->winx); + y0= (gps->points->y / 1000 * p->sa->winy); + } + + /* do boundbox check first */ + if (BLI_in_rcti(rect, x0, y0)) { + /* only check if point is inside */ + if (lasso_inside(mcoords, moves, x0, y0)) { + /* free stroke */ + MEM_freeN(gps->points); + BLI_freelinkN(&gpf->strokes, gps); + } + } + } + else { + /* loop over the points in the stroke, checking for intersections + * - an intersection will require the stroke to be split + */ + for (i=0; (i+1) < gps->totpoints; i++) { + /* get points to work with */ + pt1= gps->points + i; + pt2= gps->points + i + 1; + + /* get coordinates */ + if (gps->flag & GP_STROKE_3DSPACE) { + // FIXME: may not be correct correction + project_short(&gps->points->x, xyval); + x0= xyval[0]; + x1= xyval[1]; + } + else if (gps->flag & GP_STROKE_2DSPACE) { + ipoco_to_areaco_noclip(p->v2d, &pt1->x, xyval); + x0= xyval[0]; + y0= xyval[1]; + + ipoco_to_areaco_noclip(p->v2d, &pt2->x, xyval); + x1= xyval[0]; + y1= xyval[1]; + } + else { + x0= (pt1->x / 1000 * p->sa->winx); + y0= (pt1->y / 1000 * p->sa->winy); + x1= (pt2->x / 1000 * p->sa->winx); + y1= (pt2->y / 1000 * p->sa->winy); + } + + /* check that point segment of the boundbox of the eraser stroke */ + if (BLI_in_rcti(rect, x0, y0) || BLI_in_rcti(rect, x1, y1)) { + /* check if point segment of stroke had anything to do with + * eraser region (either within stroke painted, or on its lines) + * - this assumes that linewidth is irrelevant + * - handled using the lasso-select checking code + */ + if (lasso_inside_edge(mcoords, moves, x0, y0, x1, x1)) { + /* if function returns true, break this loop (as no more point to check) */ + if (gp_stroke_eraser_splitdel(gpf, gps, i)) + break; + } + } + } + } +} + +/* -------- */ + +/* erase strokes which fall under the eraser strokes */ +static void gp_stroke_doeraser (tGPsdata *p) +{ + bGPdata *gpd= p->gpd; + bGPDframe *gpf= p->gpf; + bGPDstroke *gps, *gpn; + short (*mcoords)[2]; + rcti rect; + + /* get buffer-stroke coordinates as shorts array, and then get bounding box */ + mcoords= gp_stroke_eraser_2mco(gpd); + lasso_select_boundbox(&rect, mcoords, gpd->sbuffer_size); + + /* loop over strokes, checking segments for intersections */ + for (gps= gpf->strokes.first; gps; gps= gpn) { + gpn= gps->next; + gp_stroke_eraser_dostroke(p, mcoords, gpd->sbuffer_size, &rect, gpf, gps); + } + + /* free mcoords array */ + MEM_freeN(mcoords); +} + /* ---------- 'Paint' Tool ------------ */ /* init new stroke */ -static void gp_paint_initstroke (tGPsdata *p) +static void gp_paint_initstroke (tGPsdata *p, short paintmode) { /* get active layer (or add a new one if non-existent) */ p->gpl= gpencil_layer_getactive(p->gpd); @@ -1096,8 +1222,13 @@ static void gp_paint_initstroke (tGPsdata *p) } else p->gpf->flag |= GP_FRAME_PAINT; - - /* check if points will need to be made in 3d-space */ + + /* set 'eraser' for this stroke if using eraser */ + p->paintmode= paintmode; + if (p->paintmode == GP_PAINTMODE_ERASER) + p->gpd->sbuffer_sflag |= GP_STROKE_ERASER; + + /* 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: @@ -1125,11 +1256,15 @@ static void gp_paint_initstroke (tGPsdata *p) /* finish off a stroke (clears buffer, but doesn't finish the paint operation) */ static void gp_paint_strokeend (tGPsdata *p) { - /* sanitize stroke-points in buffer */ - gp_stroke_smooth(p); - - /* transfer stroke to frame */ - gp_stroke_newfrombuffer(p); + /* check if doing eraser or not */ + if (p->gpd->sbuffer_sflag & GP_STROKE_ERASER) { + /* get rid of relevant sections of strokes */ + gp_stroke_doeraser(p); + } + else { + /* transfer stroke to frame */ + gp_stroke_newfrombuffer(p); + } /* clean up buffer now */ gp_session_validatebuffer(p); @@ -1151,13 +1286,13 @@ static void gp_paint_cleanup (tGPsdata *p) //BIF_undo_push("GPencil Stroke"); /* force redraw after drawing action */ - force_draw(0); + force_draw_plus(SPACE_ACTION, 0); } /* -------- */ /* main call to paint a new stroke */ -short gpencil_paint (short mousebutton) +short gpencil_paint (short mousebutton, short paintmode) { tGPsdata p; short prevmval[2], mval[2]; @@ -1170,7 +1305,7 @@ short gpencil_paint (short mousebutton) gp_session_cleanup(&p); return 0; } - gp_paint_initstroke(&p); + gp_paint_initstroke(&p, paintmode); if (p.status == GP_STATUS_ERROR) { gp_session_cleanup(&p); return 0; @@ -1202,7 +1337,7 @@ short gpencil_paint (short mousebutton) pressure = get_pressure(); /* only add current point to buffer if mouse moved (otherwise wait until it does) */ - if ((mval[0] != prevmval[0]) || (mval[1] != prevmval[1])) { + if (gp_stroke_filtermval(&p, mval, prevmval)) { /* try to add point */ ok= gp_stroke_addpoint(&p, mval, pressure); @@ -1245,7 +1380,10 @@ short gpencil_paint (short mousebutton) setcursor_space(p.sa->spacetype, CURSOR_STD); /* check size of buffer before cleanup, to determine if anything happened here */ - ok= p.gpd->sbuffer_size; + if (paintmode == GP_PAINTMODE_ERASER) + ok= (p.gpd->sbuffer_size > 1); + else + ok= p.gpd->sbuffer_size; /* cleanup */ gp_paint_cleanup(&p); @@ -1259,28 +1397,52 @@ 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 mbut) { 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 */ if (gpd == NULL) return 0; - /* currently, we will only paint if: + /* currently, we will only 'paint' if: * 1. draw-mode on gpd is set (for accessibility reasons) * (single 'dots' are only available via this method) * 2. if shift-modifier is held + lmb -> 'quick paint' + * + * OR + * + * draw eraser stroke if: + * 1. using the eraser on a tablet + * 2. draw-mode on gpd is set (for accessiblity reasons) + * (eraser is mapped to right-mouse) + * 3. Alt + 'select' mouse-button + * i.e. if LMB = select: Alt-LMB + * if RMB = select: Alt-RMB */ - if (gpd->flag & GP_DATA_EDITPAINT) { - /* try to paint */ - retval = gpencil_paint(mousebutton); + if (get_activedevice() == 2) { + /* eraser on a tablet - always try to erase strokes */ + retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER); + } + else if (gpd->flag & GP_DATA_EDITPAINT) { + /* try to paint/erase */ + if (mbut == L_MOUSE) + retval = gpencil_paint(mbut, GP_PAINTMODE_DRAW); + else if (mbut == R_MOUSE) + retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER); } - else if (G.qual == LR_SHIFTKEY) { - /* try to paint */ - retval = gpencil_paint(mousebutton); + else if (!(gpd->flag & GP_DATA_LMBPLOCK)) { + /* try to paint/erase as not locked */ + if ((G.qual == LR_SHIFTKEY) && (mbut == L_MOUSE)) { + retval = gpencil_paint(mbut, GP_PAINTMODE_DRAW); + } + else if (G.qual == LR_ALTKEY) { + if ((U.flag & USER_LMOUSESELECT) && (mbut == L_MOUSE)) + retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER); + else if (!(U.flag & USER_LMOUSESELECT) && (mbut == R_MOUSE)) + retval = gpencil_paint(mbut, GP_PAINTMODE_ERASER); + } } /* return result of trying to paint */ diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c index 50d343ca470..4bb7bb9677e 100644 --- a/source/blender/src/header_action.c +++ b/source/blender/src/header_action.c @@ -1683,7 +1683,7 @@ void action_buttons(void) "Channel", xco, -2, xmax-3, 24, ""); xco+= xmax; } - else if ((G.saction->gpd) && (G.saction->mode==SACTCONT_GPENCIL)) { + else if (G.saction->mode==SACTCONT_GPENCIL) { xmax= GetButStringLength("Channel"); uiDefPulldownBut(block, action_gplayermenu, NULL, "Channel", xco, -2, xmax-3, 24, ""); @@ -1722,24 +1722,7 @@ void action_buttons(void) xco += (90 + 8); /* MODE-DEPENDENT DRAWING */ - if (G.saction->mode == SACTCONT_GPENCIL) { - char gp_name[64]; - - /* pin button */ - uiDefIconButS(block, ICONTOG, B_ACTPIN, ICON_PIN_DEHLT, xco,0,XIC,YIC, &G.saction->pin, 0, 0, 0, 0, "Keeps this view displaying the current data regardless of what Grease Pencil set is active"); - xco += (XIC + 5); - - /* just a simple string to help identify if any content */ - glRasterPos2f((float)xco, 5.0); - BIF_RasterPos((float)xco, 5.0); // stupid texture fonts - BIF_ThemeColor(TH_TEXT); - - sprintf(gp_name, (G.saction->gpd)?"Grease Pencil Data":"<None>"); - xmax= GetButStringLength(gp_name); - BIF_DrawString(uiBlockGetCurFont(block), gp_name, (U.transopts & USER_TR_BUTTONS)); - xco += xmax; - } - else { + if (G.saction->mode != SACTCONT_GPENCIL) { /* NAME ETC */ ob= OBACT; from = (ID *)ob; diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c index 15caf325ec6..59d542e72ec 100644 --- a/source/blender/src/header_ipo.c +++ b/source/blender/src/header_ipo.c @@ -970,7 +970,7 @@ static char *ipo_modeselect_pup(void) if(ob && ob->type==OB_LAMP) str += sprintf(str,formatstring, "Lamp",ID_LA, ICON_LAMP); - if(ob && give_current_texture(ob, ob->actcol)) + if((ob && give_current_texture(ob, ob->actcol))||(give_current_world_texture())) str += sprintf(str,formatstring, "Texture",ID_TE, ICON_TEXTURE); if(ob){ diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c index 71bf0cd9bd4..0b48db461e6 100644 --- a/source/blender/src/header_view3d.c +++ b/source/blender/src/header_view3d.c @@ -2196,6 +2196,7 @@ static uiBlock *view3d_edit_object_copyattrmenu(void *arg_unused) uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mass|Ctrl C, 7", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Damping|Ctrl C, 8", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "All Physical Attributes|Ctrl C, 11", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Properties|Ctrl C, 9", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Logic Bricks|Ctrl C, 10", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Protected Transform |Ctrl C", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 29, ""); diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c index ba8649eaa86..e7b5b176979 100644 --- a/source/blender/src/interface.c +++ b/source/blender/src/interface.c @@ -532,7 +532,7 @@ static int ui_but_copy_paste(uiBut *but, char mode) /* give butfunc the original text too */ /* feature used for bone renaming, channels, etc */ if(but->func_arg2==NULL) { - strncpy(backstr, but->drawstr, UI_MAX_DRAW_STR); + strncpy(backstr, but->poin, UI_MAX_DRAW_STR); but->func_arg2= backstr; } strncpy(but->poin, but_copypaste_str, but->max); @@ -5651,6 +5651,8 @@ static int ui_auto_themecol(uiBut *but) // (weak!) detect if it is a blockloop if(but->block->dt == UI_EMBOSSP) return TH_MENU_ITEM; return TH_BUT_POPUP; + case ROUNDBOX: + return TH_PANEL; default: return TH_BUT_NEUTRAL; } diff --git a/source/blender/src/interface_draw.c b/source/blender/src/interface_draw.c index e7041e60003..83ae449b989 100644 --- a/source/blender/src/interface_draw.c +++ b/source/blender/src/interface_draw.c @@ -2351,7 +2351,7 @@ 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); gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, but->min); diff --git a/source/blender/src/meshlaplacian.c b/source/blender/src/meshlaplacian.c index 4d84672185a..60f569ecf0e 100644 --- a/source/blender/src/meshlaplacian.c +++ b/source/blender/src/meshlaplacian.c @@ -1281,9 +1281,9 @@ static int meshdeform_inside_cage(MeshDeformBind *mdb, float *co) outside[1] = co[1] + (mdb->max[1] - mdb->min[1] + 1.0f)*MESHDEFORM_OFFSET[i][1]; outside[2] = co[2] + (mdb->max[2] - mdb->min[2] + 1.0f)*MESHDEFORM_OFFSET[i][2]; + VECCOPY(start, co); VECSUB(dir, outside, start); Normalize(dir); - VECCOPY(start, co); isect = meshdeform_ray_tree_intersect(mdb, start, outside); if(isect && !isect->facing) diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c index 683b06aafc4..3f328a0cfb2 100644 --- a/source/blender/src/outliner.c +++ b/source/blender/src/outliner.c @@ -68,6 +68,7 @@ #include "BKE_main.h" #include "BKE_material.h" #include "BKE_modifier.h" +#include "BKE_object.h" #include "BKE_screen.h" #include "BKE_scene.h" #include "BKE_utildefines.h" @@ -698,6 +699,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i for (index=0,md=ob->modifiers.first; md; index++,md=md->next) { TreeElement *te = outliner_add_element(soops, &temod->subtree, ob, temod, TSE_MODIFIER, index); te->name= md->name; + te->directdata = md; if (md->type==eModifierType_Lattice) { outliner_add_element(soops, &te->subtree, ((LatticeModifierData*) md)->object, te, TSE_LINKED_OB, 0); @@ -3523,6 +3525,27 @@ static void restrictbutton_r_lay_cb(void *poin, void *poin2) allqueue(REDRAWBUTSSCENE, 0); } +static void restrictbutton_modifier_cb(void *poin, void *poin2) +{ + Object *ob = (Object *)poin; + + DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); + object_handle_update(ob); + countall(); + + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSOBJECT, 0); +} + +static void restrictbutton_bone_cb(void *poin, void *poin2) +{ + allqueue(REDRAWOOPS, 0); + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); +} + static void namebutton_cb(void *tep, void *oldnamep) { SpaceOops *soops= curarea->spacedata.first; @@ -3631,7 +3654,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, SpaceOops *soops, ListBas uiBut *bt; TreeElement *te; TreeStoreElem *tselem; - Object *ob; + Object *ob = NULL; for(te= lb->first; te; te= te->next) { tselem= TREESTORE(te); @@ -3639,7 +3662,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, SpaceOops *soops, ListBas /* objects have toggle-able restriction flags */ if(tselem->type==0 && te->idcode==ID_OB) { ob = (Object *)tselem->id; - + uiBlockSetEmboss(block, UI_EMBOSSN); bt= uiDefIconButBitS(block, ICONTOG, OB_RESTRICT_VIEW, REDRAWALL, ICON_RESTRICT_VIEW_OFF, (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, te->ys, 17, OL_H-1, &(ob->restrictflag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); @@ -3685,6 +3708,40 @@ static void outliner_draw_restrictbuts(uiBlock *block, SpaceOops *soops, ListBas uiBlockSetEmboss(block, UI_EMBOSS); } + else if(tselem->type==TSE_MODIFIER) { + ModifierData *md= (ModifierData *)te->directdata; + ob = (Object *)tselem->id; + + uiBlockSetEmboss(block, UI_EMBOSSN); + bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, REDRAWALL, ICON_RESTRICT_VIEW_OFF, + (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + uiButSetFunc(bt, restrictbutton_modifier_cb, ob, NULL); + uiButSetFlag(bt, UI_NO_HILITE); + + bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, REDRAWALL, ICON_RESTRICT_RENDER_OFF, + (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability"); + uiButSetFunc(bt, restrictbutton_modifier_cb, ob, NULL); + uiButSetFlag(bt, UI_NO_HILITE); + } + else if(tselem->type==TSE_POSE_CHANNEL) { + bPoseChannel *pchan= (bPoseChannel *)te->directdata; + Bone *bone = pchan->bone; + + uiBlockSetEmboss(block, UI_EMBOSSN); + bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, REDRAWALL, ICON_RESTRICT_VIEW_OFF, + (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL); + uiButSetFlag(bt, UI_NO_HILITE); + } + else if(tselem->type==TSE_EBONE) { + EditBone *ebone= (EditBone *)te->directdata; + + uiBlockSetEmboss(block, UI_EMBOSSN); + bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, REDRAWALL, ICON_RESTRICT_VIEW_OFF, + (int)soops->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL); + uiButSetFlag(bt, UI_NO_HILITE); + } } if((tselem->flag & TSE_CLOSED)==0) outliner_draw_restrictbuts(block, soops, &te->subtree); diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c index cc08bf53a72..b054b435002 100644 --- a/source/blender/src/poseobject.c +++ b/source/blender/src/poseobject.c @@ -180,27 +180,26 @@ bPoseChannel *get_active_posechannel (Object *ob) return NULL; } -/* if a selected or active bone is protected, throw error and return 1 */ +/* if a selected or active bone is protected, throw error (oonly if warn==1) and return 1 */ /* only_selected==1 : the active bone is allowed to be protected */ -static int pose_has_protected_selected(Object *ob, int only_selected) +static short pose_has_protected_selected(Object *ob, short only_selected, short warn) { - /* check protection */ - if(ob->proxy) { + if (ob->proxy) { bPoseChannel *pchan; bArmature *arm= ob->data; - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone && (pchan->bone->layer & arm->layer)) { - if(pchan->bone->layer & arm->layer_protected) { - if(only_selected && (pchan->bone->flag & BONE_ACTIVE)); - else if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if (pchan->bone && (pchan->bone->layer & arm->layer)) { + if (pchan->bone->layer & arm->layer_protected) { + if (only_selected && (pchan->bone->flag & BONE_ACTIVE)); + else if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) break; } } } - if(pchan) { - error("Cannot change Proxy protected bones"); + if (pchan) { + if (warn) error("Cannot change Proxy protected bones"); return 1; } } @@ -540,7 +539,7 @@ void pose_clear_IK(void) if(!ob && !ob->pose) return; if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return; - if(pose_has_protected_selected(ob, 0)) + if(pose_has_protected_selected(ob, 0, 1)) return; if(okee("Remove IK constraint(s)")==0) return; @@ -581,7 +580,7 @@ void pose_clear_constraints(void) if(!ob && !ob->pose) return; if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return; - if(pose_has_protected_selected(ob, 0)) + if(pose_has_protected_selected(ob, 0, 1)) return; if(okee("Remove Constraints")==0) return; @@ -612,38 +611,49 @@ void pose_copy_menu(void) Object *ob= OBACT; bArmature *arm= ob->data; bPoseChannel *pchan, *pchanact; - short nr; + short nr=0; int i=0; /* paranoia checks */ - if(!ob && !ob->pose) return; - if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return; + if (ELEM(NULL, ob, ob->pose)) return; + if ((ob==G.obedit) || (ob->flag & OB_POSEMODE)==0) return; /* find active */ - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if(pchan->bone->flag & BONE_ACTIVE) break; + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if (pchan->bone->flag & BONE_ACTIVE) + break; } - if(pchan==NULL) return; - - if(pose_has_protected_selected(ob, 1)) - return; - + if (pchan==NULL) return; pchanact= pchan; - i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ - if (i<25) - nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8"); - else - nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8"); + /* if proxy-protected bones selected, some things (such as locks + displays) shouldn't be changable, + * but for constraints (just add local constraints) + */ + if (pose_has_protected_selected(ob, 1, 0)) { + i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ + if (i < 25) + nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5"); + else + nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4"); + } + else { + i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */ + if (i < 25) + nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8"); + else + nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8"); + } - if(nr==-1) return; - if(nr!=5) { - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if( (arm->layer & pchan->bone->layer) && - (pchan->bone->flag & BONE_SELECTED) && - (pchan!=pchanact) - ) { + if (nr <= 0) + return; + + if (nr != 5) { + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if ( (arm->layer & pchan->bone->layer) && + (pchan->bone->flag & BONE_SELECTED) && + (pchan != pchanact) ) + { switch (nr) { case 1: /* Local Location */ VECCOPY(pchan->loc, pchanact->loc); @@ -656,13 +666,26 @@ void pose_copy_menu(void) break; case 4: /* All Constraints */ { - free_constraints(&pchan->constraints); - copy_constraints(&pchan->constraints, &pchanact->constraints); - pchan->constflag = pchanact->constflag; + ListBase tmp_constraints = {NULL, NULL}; - if (ob->pose) { - ob->pose->flag |= POSE_RECALC; + /* copy constraints to tmpbase and apply 'local' tags before + * appending to list of constraints for this channel + */ + copy_constraints(&tmp_constraints, &pchanact->constraints); + if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) { + bConstraint *con; + + /* add proxy-local tags */ + for (con= tmp_constraints.first; con; con= con->next) + con->flag |= CONSTRAINT_PROXY_LOCAL; } + addlisttolist(&pchan->constraints, &tmp_constraints); + + /* update flags (need to add here, not just copy) */ + pchan->constflag |= pchanact->constflag; + + if (ob->pose) + ob->pose->flag |= POSE_RECALC; } break; case 6: /* Transform Locks */ @@ -703,12 +726,13 @@ void pose_copy_menu(void) } } } - } else { /* constraints, optional */ + } + else { /* constraints, optional (note: max we can have is 24 constraints) */ bConstraint *con, *con_back; int const_toggle[24]; - ListBase const_copy={0, 0}; + ListBase const_copy = {NULL, NULL}; - duplicatelist (&const_copy, &(pchanact->constraints)); + duplicatelist(&const_copy, &(pchanact->constraints)); /* build the puplist of constraints */ for (con = pchanact->constraints.first, i=0; con; con=con->next, i++){ @@ -723,32 +747,46 @@ void pose_copy_menu(void) /* now build a new listbase from the options selected */ for (i=0, con=const_copy.first; con; i++) { + /* if not selected, free/remove it from the list */ if (!const_toggle[i]) { con_back= con->next; BLI_freelinkN(&const_copy, con); con= con_back; - } else { + } + else con= con->next; - } } /* Copy the temo listbase to the selected posebones */ - for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { - if( (arm->layer & pchan->bone->layer) && - (pchan->bone->flag & BONE_SELECTED) && - (pchan!=pchanact) - ) { - free_constraints(&pchan->constraints); - copy_constraints(&pchan->constraints, &const_copy); - pchan->constflag = pchanact->constflag; + for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if ( (arm->layer & pchan->bone->layer) && + (pchan->bone->flag & BONE_SELECTED) && + (pchan!=pchanact) ) + { + ListBase tmp_constraints = {NULL, NULL}; + + /* copy constraints to tmpbase and apply 'local' tags before + * appending to list of constraints for this channel + */ + copy_constraints(&tmp_constraints, &const_copy); + if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) { + bConstraint *con; + + /* add proxy-local tags */ + for (con= tmp_constraints.first; con; con= con->next) + con->flag |= CONSTRAINT_PROXY_LOCAL; + } + addlisttolist(&pchan->constraints, &tmp_constraints); + + /* update flags (need to add here, not just copy) */ + pchan->constflag |= pchanact->constflag; } } BLI_freelistN(&const_copy); update_pose_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */ - if (ob->pose) { + if (ob->pose) ob->pose->flag |= POSE_RECALC; - } } DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); // and all its relations @@ -808,7 +846,7 @@ void paste_posebuf (int flip) /* // disabled until protected bones in proxies follow the rules everywhere else! - if(pose_has_protected_selected(ob, 1)) + if(pose_has_protected_selected(ob, 1, 1)) return; */ @@ -1249,7 +1287,7 @@ void pose_flip_names(void) if(!ob && !ob->pose) return; if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return; - if(pose_has_protected_selected(ob, 0)) + if(pose_has_protected_selected(ob, 0, 1)) return; for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { @@ -1282,7 +1320,7 @@ void pose_autoside_names(short axis) if (ELEM(NULL, ob, ob->pose)) return; if (ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return; - if (pose_has_protected_selected(ob, 0)) + if (pose_has_protected_selected(ob, 0, 1)) return; for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { @@ -1415,7 +1453,7 @@ void pose_movetolayer(void) /* pose-channel layers */ bPoseChannel *pchan; - if (pose_has_protected_selected(ob, 0)) + if (pose_has_protected_selected(ob, 0, 1)) return; for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { diff --git a/source/blender/src/sequence.c b/source/blender/src/sequence.c index 9426548dc38..7e2ffc3ba63 100644 --- a/source/blender/src/sequence.c +++ b/source/blender/src/sequence.c @@ -1473,8 +1473,8 @@ static void input_preprocess(Sequence * seq, TStripElem* se, int cfra) dy = sy; if (seq->flag & SEQ_USE_TRANSFORM) { - dx = seqrectx; - dy = seqrecty; + dx = G.scene->r.xsch; + dy = G.scene->r.ysch; } if (c.top + c.bottom >= se->ibuf->y || diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 92efb477095..b4702788e0c 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -1205,9 +1205,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) { @@ -2711,6 +2714,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)) { @@ -4823,8 +4828,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 */ @@ -5099,6 +5107,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); @@ -5107,7 +5119,10 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } } - if(doredraw) scrarea_queue_winredraw(curarea); + if(doredraw) { + scrarea_queue_winredraw(curarea); + scrarea_queue_headredraw(curarea); + } } diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c index 706b079432c..8f83434e528 100644 --- a/source/blender/src/transform_conversions.c +++ b/source/blender/src/transform_conversions.c @@ -1089,6 +1089,8 @@ static void createTransArmatureVerts(TransInfo *t) VECCOPY (td->center, td->iloc); td->loc= ebo->tail; td->flag= TD_SELECTED; + if (ebo->flag & BONE_EDITMODE_LOCKED) + td->protectflag = OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE; Mat3CpyMat3(td->smtx, smtx); Mat3CpyMat3(td->mtx, mtx); @@ -1104,6 +1106,8 @@ static void createTransArmatureVerts(TransInfo *t) VECCOPY (td->center, td->iloc); td->loc= ebo->head; td->flag= TD_SELECTED; + if (ebo->flag & BONE_EDITMODE_LOCKED) + td->protectflag = OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE; Mat3CpyMat3(td->smtx, smtx); Mat3CpyMat3(td->mtx, mtx); diff --git a/source/blender/src/transform_manipulator.c b/source/blender/src/transform_manipulator.c index 050360887b4..709879f142b 100644 --- a/source/blender/src/transform_manipulator.c +++ b/source/blender/src/transform_manipulator.c @@ -170,6 +170,13 @@ static void stats_pose(View3D *v3d, bPoseChannel *pchan) } } +/* for editmode*/ +static void stats_editbone(View3D *v3d, EditBone *ebo) +{ + if (ebo->flag & BONE_EDITMODE_LOCKED) + protectflag_to_drawflags(OB_LOCK_LOC|OB_LOCK_ROT|OB_LOCK_SCALE, &v3d->twdrawflag); +} + /* only counts the parent selection, and tags transform flag */ /* bad call... should re-use method from transform_conversion once */ static void count_bone_select(TransInfo *t, bArmature *arm, ListBase *lb, int do_it) @@ -258,6 +265,9 @@ int calc_manipulator_stats(ScrArea *sa) calc_tw_center(ebo->head); totsel++; } + if (ebo->flag & BONE_SELECTED) { + stats_editbone(v3d, ebo); + } } } } |